硬汉嵌入式论坛

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

STM32的USB主机读取STM32的USB从机的文件

[复制链接]

2

主题

5

回帖

11

积分

新手上路

积分
11
发表于 2021-10-15 16:24:45 | 显示全部楼层 |阅读模式
项目描述:使用STM32的USB主机设备连接STM32的USB从机设备,都是大容量存储类设备,并且都移植了FATFS文件操作系统
目前实现了主机外接U盘可以成功枚举并且正常读写文件,从机接上电脑也可成功枚举且正常读写文件,但是主机接从机时,显示枚举成功,但是获取不到从机的容量(通过FATFS提供的API)与读写文件(通过FATFS提供的API),在枚举成功后挂载从机文件系统返回FR_DISK_ERR,这一块应该是代码的问题,但是没法确定问题的所在,求教大神指点一二,谢谢
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106746
QQ
发表于 2021-10-16 09:24:03 | 显示全部楼层
从机不用加FatFS。

回复

使用道具 举报

2

主题

5

回帖

11

积分

新手上路

积分
11
 楼主| 发表于 2021-10-17 20:27:24 | 显示全部楼层
eric2013 发表于 2021-10-16 09:24
从机不用加FatFS。

目前这个产品中从机是主要设备,运行过程中会使用文件系统读取配置文件与字库文件,所以必须使用文件系统,而主机只是作为生产的工装模块来用,不会量产,只是给从机传递配置文件与字库文件的。。。目前缺芯状况太严重了,只能使用国产替代了,而这个替代的芯片的USB只有从机功能,所以只能这样来搞。。。
如果从机不用文件系统,是否可以被主机识别并正常读写文件,你这边之前有没有做过这样的测试,还请指点一二
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106746
QQ
发表于 2021-10-18 15:27:21 | 显示全部楼层
lyjunnan 发表于 2021-10-17 20:27
目前这个产品中从机是主要设备,运行过程中会使用文件系统读取配置文件与字库文件,所以必须使用文件系统 ...

方便的话,我看下你的USB接口文件实现,仅接口文件实现。
回复

使用道具 举报

2

主题

5

回帖

11

积分

新手上路

积分
11
 楼主| 发表于 2021-10-19 13:59:09 | 显示全部楼层
eric2013 发表于 2021-10-18 15:27
方便的话,我看下你的USB接口文件实现,仅接口文件实现。

主机芯片用的是STM32F105RBT6, 从机用的是国产的一款M4内核的但是USB只有从机的芯片,为了改善SPI Flash的写入速度,在文件系统与USB的几个地方做了修改
ffconfig.h
  1. #define        _MIN_SS                512
  2. #define        _MAX_SS                4096
复制代码

diskiio.c
  1. #define FLASH_SECTOR_SIZE   4096
  2. #define FLASH_BLOCK_SIZE    16                  
  3. #define FLASH_SECTOR_COUNT  1024               
  4. DRESULT disk_read(
  5.     BYTE pdrv,      /* Physical drive nmuber (0..) */
  6.     BYTE *buff,     /* Data buffer to store read data */
  7.     DWORD sector,   /* Sector address (LBA) */
  8.     UINT count      /* Number of sectors to read (1..128) */
  9. )
  10. {
  11.     u8 res = 0;
  12.     if(!count)return RES_PARERR; //count不能等于0,否则返回参数错误
  13.     switch(pdrv)
  14.     {
  15.     case FLASH_1:                        //外部flash0
  16.         for(; count > 0; count--)
  17.         {
  18.             W25QXX_Read(buff, sector * FLASH_SECTOR_SIZE, FLASH_SECTOR_SIZE, 1);
  19.             sector++;
  20.             buff += FLASH_SECTOR_SIZE;
  21.         }
  22.         res = 0;
  23.         break;
  24.     case FLASH_2:                        //内部flash1
  25.         for(; count > 0; count--)
  26.         {
  27.             W25QXX_Read(buff, sector * FLASH_SECTOR_SIZE, FLASH_SECTOR_SIZE, 2);
  28.             sector++;
  29.             buff += FLASH_SECTOR_SIZE;
  30.         }
  31.         res = 0;
  32.         break;
  33.     case USB_DISK:
  34.         res = USBH_UDISK_Read((u8*)buff, sector, count);
  35.         break;
  36.     default:
  37.         res = 1;
  38.     }
  39.     //处理返回值,将SPI_SD_driver.c的返回值转成ff.c的返回值
  40.     if(res == 0x00)return RES_OK;
  41.     else return RES_ERROR;
  42. }
  43. //读写函数参数一样
  44. #if _USE_IOCTL
  45. DRESULT disk_ioctl(
  46.     BYTE pdrv,      /* Physical drive nmuber (0..) */
  47.     BYTE cmd,       /* Control code */
  48.     void *buff      /* Buffer to send/receive control data */
  49. )
  50. {
  51.     DRESULT res;
  52.     if(pdrv == FLASH_1) //外部FLASH0
  53.     {
  54.         switch(cmd)
  55.         {
  56.                         case CTRL_SYNC:
  57.                                 res = RES_OK;
  58.                                 break;
  59.                         case GET_SECTOR_SIZE:
  60.                                 *(WORD*)buff = FLASH_SECTOR_SIZE;
  61.                                 res = RES_OK;
  62.                                 break;
  63.                         case GET_BLOCK_SIZE:
  64.                                 *(WORD*)buff = FLASH_BLOCK_SIZE;
  65.                                 res = RES_OK;
  66.                                 break;
  67.                         case GET_SECTOR_COUNT:
  68.                                 *(DWORD*)buff = FLASH_SECTOR_COUNT;
  69.                                 res = RES_OK;
  70.                                 break;
  71.                         default:
  72.                                 res = RES_PARERR;
  73.                                 break;
  74.         }
  75.     }
  76.     else if(pdrv == FLASH_2)  //外部FLASH1
  77.     {
  78.         switch(cmd)
  79.         {
  80.                         case CTRL_SYNC:
  81.                                 res = RES_OK;
  82.                                 break;
  83.                         case GET_SECTOR_SIZE:
  84.                                 *(WORD*)buff = FLASH_SECTOR_SIZE;
  85.                                 res = RES_OK;
  86.                                 break;
  87.                         case GET_BLOCK_SIZE:
  88.                                 *(WORD*)buff = FLASH_BLOCK_SIZE;
  89.                                 res = RES_OK;
  90.                                 break;
  91.                         case GET_SECTOR_COUNT:
  92.                                 *(DWORD*)buff = FLASH_SECTOR_COUNT;
  93.                                 res = RES_OK;
  94.                                 break;
  95.                         default:
  96.                                 res = RES_PARERR;
  97.                                 break;
  98.         }
  99.     }
  100.     else if(pdrv == USB_DISK)
  101.     {
  102.         switch(cmd)
  103.         {
  104.                         case CTRL_SYNC:
  105.                                 res = RES_OK;
  106.                                 break;
  107.                         case GET_SECTOR_SIZE:
  108.                                 *(WORD*)buff = 4096;
  109.                                 res = RES_OK;
  110.                                 break;
  111.                         case GET_BLOCK_SIZE:
  112.                                 *(WORD*)buff = 4096;
  113.                                 res = RES_OK;
  114.                                 break;
  115.                         case GET_SECTOR_COUNT:
  116.                                 *(DWORD*)buff = (DWORD) USBH_MSC_Param.MSCapacity;
  117.                                 res = RES_OK;
  118.                                 break;
  119.                         default:
  120.                                 res = RES_PARERR;
  121.                                 break;
  122.         }
  123.     }
  124.     else res = RES_ERROR; //其他的不支持
  125.     return res;
  126. }
复制代码

usbh_msc_usr.c
  1. void USBH_USR_DeInit(void)
  2. {
  3.         USBH_USR_ApplicationState = USH_USR_FS_INIT;
  4. }

  5. extern USBH_HOST                USB_Host;
  6. uint8_t USBH_UDISK_Status(void)
  7. {
  8.         return HCD_IsDeviceConnected((USB_OTG_CORE_HANDLE*)&USB_OTG_Core);
  9. }
  10. uint8_t USBH_UDISK_Read(uint8_t *buf, uint32_t sector, uint32_t cnt)
  11. {
  12.         u8 res = 1;
  13.         if(HCD_IsDeviceConnected((USB_OTG_CORE_HANDLE*)&USB_OTG_Core) )
  14.         {  
  15.                 do
  16.                 {
  17.                         res = USBH_MSC_Read10((USB_OTG_CORE_HANDLE*)&USB_OTG_Core, buf, sector, 4096 * cnt);
  18.                         USBH_MSC_HandleBOTXfer((USB_OTG_CORE_HANDLE*)&USB_OTG_Core ,&USB_Host);
  19.                   
  20.                         if(!HCD_IsDeviceConnected((USB_OTG_CORE_HANDLE*)&USB_OTG_Core))
  21.                         {
  22.                                 res = 1;
  23.                                 break;
  24.                         }      
  25.                 }
  26.                 while(res == USBH_MSC_BUSY );
  27.         }else res = 1;

  28.         if(res == USBH_MSC_OK)
  29.                 res = 0;
  30.         return res;
  31. }
  32. uint8_t USBH_UDISK_Write(uint8_t* buf,uint32_t sector,uint32_t cnt)
  33. {
  34.         uint8_t res=1;
  35.         if(HCD_IsDeviceConnected((USB_OTG_CORE_HANDLE*)&USB_OTG_Core))//连接还存在,且是APP测试状态
  36.         {                      
  37.                 do
  38.                 {
  39.                         res=USBH_MSC_Write10((USB_OTG_CORE_HANDLE*)&USB_OTG_Core,buf,sector, 4096 * cnt);
  40.                         USBH_MSC_HandleBOTXfer((USB_OTG_CORE_HANDLE*)&USB_OTG_Core ,&USB_Host);                     
  41.                         if(!HCD_IsDeviceConnected((USB_OTG_CORE_HANDLE*)&USB_OTG_Core))
  42.                         {
  43.                                 res=1;
  44.                                 break;
  45.                         };   
  46.                 }while(res==USBH_MSC_BUSY);
  47.         }else res=1;                  
  48.         if(res==USBH_MSC_OK)res=0;       
  49.         return res;
  50. }
复制代码

usb_host处理函数的一部分
  1. void USB_Application(void)
  2. {
  3.     uint8_t res = 1;
  4.         uint32_t total, free;
  5.         uint8_t file = 1;
  6.         uint8_t sta = 0;
  7.         if(Enum_Done == 1)
  8.         {               
  9.                 delay_ms(10);
  10.                 res = exf_get_free("2:", &total, &free);
  11.                 SEGGER_RTT_SetTerminal(2);
  12.                 SEGGER_RTT_printf(0, "> Rrturn exf_get_free is :%d\r\n", res);
  13.                 if(res == 0)
  14.                 {       
  15.                         /* 检测到磁盘并可以正常获取磁盘状态,LED常亮 */
  16.                         led_toggle_flag = DISABLE;
  17.                         led_on();
  18.                         SEGGER_RTT_SetTerminal(2);
  19.                         SEGGER_RTT_printf(0, "> U Disk FATFS OK!\r\n");
  20.                         SEGGER_RTT_printf(0, "> U Disk Total Size: %d KB\r\n", total);
  21.                         SEGGER_RTT_printf(0, "> U Disk Total Size: %d KB\r\n", free);
  22.                        
  23.                         exf_scan_files("2:");       
  24.                 }
  25.          }
复制代码


从机文件系统和主机差不多,USB这是修改了mass_mal.c中的这个函数
  1. uint16_t MAL_GetStatus (uint8_t lun)
  2. {
  3.     switch(lun)
  4.     {
  5.                 case 0:
  6.                         Mass_Memory_Size[0] = 1024 * 1024 * 4;        //4M字节
  7.                         Mass_Block_Size[0] = 4096;                        //设置SPI FLASH的操作扇区大小为4096
  8.                         Mass_Block_Count[0]= Mass_Memory_Size[0] / Mass_Block_Size[0];
  9.             break;
  10.                 default:
  11.                         return MAL_FAIL;
  12.     }
  13.     return MAL_OK;
  14. }
复制代码

目前有点进展,主机插上从机偶尔会正常检索从机的文件,有时又不正常
不正常的情况就是在主机处理程序获取从机磁盘容量那一块 res = exf_get_free("2:", &total, &free);,返回值1(FR_DISK_ERR),查了FATFS官网有如下说明
C:\Users\Administrator\Desktop\1.jpg
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106746
QQ
发表于 2021-10-20 10:30:40 | 显示全部楼层
lyjunnan 发表于 2021-10-19 13:59
主机芯片用的是STM32F105RBT6, 从机用的是国产的一款M4内核的但是USB只有从机的芯片,为了改善SPI Flash ...

exf_get_free是你自己封装的函数吧,fatfs没有这个函数。

你应该封装的是f_getfree
回复

使用道具 举报

2

主题

5

回帖

11

积分

新手上路

积分
11
 楼主| 发表于 2021-10-21 13:42:04 | 显示全部楼层
eric2013 发表于 2021-10-20 10:30
exf_get_free是你自己封装的函数吧,fatfs没有这个函数。

你应该封装的是f_getfree

是的,调用f_mount也是一样的情况
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106746
QQ
发表于 2021-10-22 09:50:56 | 显示全部楼层
lyjunnan 发表于 2021-10-21 13:42
是的,调用f_mount也是一样的情况

别的问题,不清楚了。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-3 18:08 , Processed in 0.177269 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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