硬汉嵌入式论坛

 找回密码
 立即注册
查看: 158|回复: 2
收起左侧

[FatFs] FreeRTOS+Fatfs+USB_Host,挂载U盘和spiflash(w25q32),出现问题

[复制链接]

12

主题

62

回帖

98

积分

初级会员

积分
98
发表于 2025-12-30 18:32:12 | 显示全部楼层 |阅读模式
本帖最后由 quanshimutou 于 2025-12-30 18:35 编辑

芯片STM32H750VB,cubemx生成代码。
FreeRTOS+Fatfs+USB_Host,挂载U盘和spiflash(w25q32),出现以下问题,

问题一:MX_USB_HOST_Init(); 执行之前,使用 res = f_mount(&USERFatFS, USERPath, 1); 挂载flash不成功,返回 NO_SYSTEM。延时500ms,等 MX_USB_HOST_Init() 执行后正常挂载。
问题二:使用 f_mkfs() 格式化flash失败,进入 MemManage_Handler() 错误中断。
调用关系如下:
[C] 纯文本查看 复制代码
f_mkfs(USERPath, FM_ANY, c_size, work_buff, sizeof(work_buff));
->
if (_MULTI_PARTITION && part != 0) {
  ......
} else {
  /* Create a single-partition in this function */
  if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_vol) != RES_OK) return FR_DISK_ERR;
->
DRESULT disk_ioctl (
        BYTE pdrv,                /* Physical drive nmuber (0..) */
        BYTE cmd,                /* Control code */
        void *buff                /* Buffer to send/receive control data */
)
->
res = disk.drv[pdrv]->disk_ioctl(disk.lun[pdrv], cmd, buff);
->
DRESULT USBH_ioctl(BYTE lun, BYTE cmd, void *buff)
{
  /* Get number of sectors on the disk (DWORD) */
  case GET_SECTOR_COUNT :
    if(USBH_MSC_GetLUNInfo(&hUSB_Host, lun, &info) == USBH_OK)
->
USBH_StatusTypeDef USBH_MSC_GetLUNInfo(USBH_HandleTypeDef *phost, uint8_t lun, MSC_LUNTypeDef *info)
{
  MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
  /* Store the current lun */
  MSC_Handle->current_lun = lun;
  ->
  MemManage_Handler()



cubemx 的设置:
下载.png 下载 (1).png 下载 (2).png

其他地方没改,目前找到的解决办法是,先分配USERPath
[C] 纯文本查看 复制代码
void MX_FATFS_Init(void)
{
  /*## FatFS: Link the USER driver ###########################*/
  retUSER = FATFS_LinkDriver(&USER_Driver, USERPath); // 先分配USERPath
  /*## FatFS: Link the USBH driver ###########################*/
  retUSBH = FATFS_LinkDriver(&USBH_Driver, USBHPath);
}



file_test.zip (13.06 MB, 下载次数: 2)



回复

使用道具 举报

1万

主题

7万

回帖

12万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
120428
QQ
发表于 2025-12-31 11:26:34 | 显示全部楼层
这个有必要锁定下MemManage_Handler() 的异常位置。这样方便排查问题。

另外还有一点测试下,不要同时都挂载,分别挂载分别测试是否正常。


回复

使用道具 举报

12

主题

62

回帖

98

积分

初级会员

积分
98
 楼主| 发表于 2025-12-31 15:05:09 | 显示全部楼层
单独挂载都正常,并且不使用RTOS,f_mkfs也会进入错误中断。f_mkfs函数中的这一行:if (disk_ioctl(pdrv, GET_SECTOR_SIZE, &ss) != RES_OK) return FR_DISK_ERR; ,会把pdrv由1变成0,不知道为什么.
然后下边调用的都是 USB 的 FATFS 函数了,然后就错误了。

这是我移植的函数,
[C] 纯文本查看 复制代码
DRESULT USER_ioctl (
	BYTE pdrv,      /* Physical drive nmuber (0..) */
	BYTE cmd,       /* Control code */
	void *buff      /* Buffer to send/receive control data */
)
{
  /* USER CODE BEGIN IOCTL */
	DRESULT res = RES_OK;
	switch(cmd)
	{
    case CTRL_SYNC:   //完成挂起的写操作过程,在 _FS_READONLY == 0时用到
      break;
    case GET_SECTOR_COUNT:  /* 获取存储介质容量 (_USE_MKFS == 1 时需要) */
      *(DWORD *)buff=W25Q32_SECTOR_COUNT;  //总的扇区个数
      break;
    case GET_SECTOR_SIZE:  /* 获取扇区大小 (_MAX_SS != _MIN_SS 时需要) */
      *(DWORD *)buff=W25Qxx_SECTOR_SIZE;  //每个扇区的大小
      break;
    case GET_BLOCK_SIZE:  /* 获取擦除块的大小(_USE_MKFS == 1 时需要) */
      *(DWORD *)buff=16;  //一个 Block有几个扇区
      break;
    default:
      res = RES_ERROR;
	}
  return res;
  /* USER CODE END IOCTL */
}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2026-1-10 07:55 , Processed in 0.047022 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表