在AT32F403A上实现文件系统与CherryUSB U盘动态切换需解决关键问题:同一块设备无法同时被文件系统和U盘驱动访问。以下是分步解决方案:
在CherryUSB的USB连接/断开事件中动态切换文件系统和U盘模式:
#include "fal.h"
#include "elm_fatfs.h"
#include "usbd_msc.h"
// 定义块设备及挂载点
static struct fal_blk_device *blk_dev; // FAL块设备指针
const char *mount_point = "/"; // 文件系统挂载点
// 挂载文件系统
int mount_filesystem(void) {
FRESULT res = f_mount(&blk_dev->fatfs, mount_point, 1);
return (res == FR_OK) ? 0 : -1;
}
// 卸载文件系统
void unmount_filesystem(void) {
f_mount(NULL, mount_point, 0); // 卸载
fatfs_device_unlock(); // 解锁块设备 (见下文关键点)
}
// CherryUSB事件回调
void usbd_event_handler(uint8_t event, void *arg) {
switch (event) {
case USBD_EVENT_CONNECTED: // USB插入
unmount_filesystem(); // 卸载文件系统
usbd_msc_init(); // 初始化MSC设备 (需关联blk_dev)
break;
case USBD_EVENT_DISCONNECTED: // USB拔出
usbd_msc_deinit(); // 反初始化MSC
mount_filesystem(); // 重新挂载文件系统
break;
}
}块设备互斥访问
// 在FAL驱动中实现设备锁
void fal_blk_device_lock(struct fal_blk_device *dev) {
rt_mutex_take(&dev->lock, RT_WAITING_FOREVER);
}
void fal_blk_device_unlock(struct fal_blk_device *dev) {
rt_mutex_release(&dev->lock);
}CherryUSB事件触发时机
usbd_desc_register(usbd_descriptor); // 描述符
usbd_msc_class_register(); // MSC类
usbd_event_handler_register(usbd_event_handler); // !!! 关键注册 !!!
usbd_initialize(); // 初始化USBFatFS与MSC共享块设备
void usbd_msc_init(void) {
// 将FAL块设备绑定到MSC
usbd_msc_storage_set(0, (struct msc_block_dev *)blk_dev);
}msc_block_ops接口(对接FAL):const struct msc_block_ops fal_block_ops = {
.read_block = fal_blk_read, // 从FAL读取扇区
.write_block = fal_blk_write, // 写入FAL扇区
};初始状态(无USB连接)
USB插入事件
USBD_EVENT_CONNECTED →USB拔出事件
USBD_EVENT_DISCONNECTED →确认事件触发
在usbd_event_handler中加入调试输出:
printf("[USB] Event: %dn", event);观察插入/拔出时是否打印事件。
检查卸载/挂载返回值
FRESULT res = f_mount(NULL, mount_point, 0);
if (res != FR_OK) {
printf("Unmount failed: %dn", res);
}确保USB中断使能
在board_init()中确认USB时钟和中断已配置:
at32_msp_init(AT32_USB_DEVICE); // AT32库的USB初始化
nvic_irq_enable(USB_LP_CAN1_RX0_IRQn, 0, 0); // 使能中断
为何之前回调不执行?
最常见原因:未正确注册事件回调(usbd_event_handler_register),或USB配置/中断问题。参考CherryUSB设备模式示例检查初始化流程。
通过动态卸载/挂载文件系统和USB事件驱动,即可实现无缝切换。最终效果:
无USB → 文件系统工作 | 插入USB → U盘工作 | 拔出USB → 文件系统恢复。
举报
更多回帖