STM32的USB主机读取STM32的USB从机的文件
项目描述:使用STM32的USB主机设备连接STM32的USB从机设备,都是大容量存储类设备,并且都移植了FATFS文件操作系统目前实现了主机外接U盘可以成功枚举并且正常读写文件,从机接上电脑也可成功枚举且正常读写文件,但是主机接从机时,显示枚举成功,但是获取不到从机的容量(通过FATFS提供的API)与读写文件(通过FATFS提供的API),在枚举成功后挂载从机文件系统返回FR_DISK_ERR,这一块应该是代码的问题,但是没法确定问题的所在,求教大神指点一二,谢谢
从机不用加FatFS。
eric2013 发表于 2021-10-16 09:24
从机不用加FatFS。
目前这个产品中从机是主要设备,运行过程中会使用文件系统读取配置文件与字库文件,所以必须使用文件系统,而主机只是作为生产的工装模块来用,不会量产,只是给从机传递配置文件与字库文件的。。。目前缺芯状况太严重了,只能使用国产替代了,而这个替代的芯片的USB只有从机功能,所以只能这样来搞。。。
如果从机不用文件系统,是否可以被主机识别并正常读写文件,你这边之前有没有做过这样的测试,还请指点一二 lyjunnan 发表于 2021-10-17 20:27
目前这个产品中从机是主要设备,运行过程中会使用文件系统读取配置文件与字库文件,所以必须使用文件系统 ...
方便的话,我看下你的USB接口文件实现,仅接口文件实现。 eric2013 发表于 2021-10-18 15:27
方便的话,我看下你的USB接口文件实现,仅接口文件实现。
主机芯片用的是STM32F105RBT6, 从机用的是国产的一款M4内核的但是USB只有从机的芯片,为了改善SPI Flash的写入速度,在文件系统与USB的几个地方做了修改
ffconfig.h
#define _MIN_SS 512
#define _MAX_SS 4096
diskiio.c
#define FLASH_SECTOR_SIZE 4096
#define FLASH_BLOCK_SIZE 16
#define FLASH_SECTOR_COUNT1024
DRESULT disk_read(
BYTE pdrv, /* Physical drive nmuber (0..) */
BYTE *buff, /* Data buffer to store read data */
DWORD sector, /* Sector address (LBA) */
UINT count /* Number of sectors to read (1..128) */
)
{
u8 res = 0;
if(!count)return RES_PARERR; //count不能等于0,否则返回参数错误
switch(pdrv)
{
case FLASH_1: //外部flash0
for(; count > 0; count--)
{
W25QXX_Read(buff, sector * FLASH_SECTOR_SIZE, FLASH_SECTOR_SIZE, 1);
sector++;
buff += FLASH_SECTOR_SIZE;
}
res = 0;
break;
case FLASH_2: //内部flash1
for(; count > 0; count--)
{
W25QXX_Read(buff, sector * FLASH_SECTOR_SIZE, FLASH_SECTOR_SIZE, 2);
sector++;
buff += FLASH_SECTOR_SIZE;
}
res = 0;
break;
case USB_DISK:
res = USBH_UDISK_Read((u8*)buff, sector, count);
break;
default:
res = 1;
}
//处理返回值,将SPI_SD_driver.c的返回值转成ff.c的返回值
if(res == 0x00)return RES_OK;
else return RES_ERROR;
}
//读写函数参数一样
#if _USE_IOCTL
DRESULT disk_ioctl(
BYTE pdrv, /* Physical drive nmuber (0..) */
BYTE cmd, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
DRESULT res;
if(pdrv == FLASH_1) //外部FLASH0
{
switch(cmd)
{
case CTRL_SYNC:
res = RES_OK;
break;
case GET_SECTOR_SIZE:
*(WORD*)buff = FLASH_SECTOR_SIZE;
res = RES_OK;
break;
case GET_BLOCK_SIZE:
*(WORD*)buff = FLASH_BLOCK_SIZE;
res = RES_OK;
break;
case GET_SECTOR_COUNT:
*(DWORD*)buff = FLASH_SECTOR_COUNT;
res = RES_OK;
break;
default:
res = RES_PARERR;
break;
}
}
else if(pdrv == FLASH_2)//外部FLASH1
{
switch(cmd)
{
case CTRL_SYNC:
res = RES_OK;
break;
case GET_SECTOR_SIZE:
*(WORD*)buff = FLASH_SECTOR_SIZE;
res = RES_OK;
break;
case GET_BLOCK_SIZE:
*(WORD*)buff = FLASH_BLOCK_SIZE;
res = RES_OK;
break;
case GET_SECTOR_COUNT:
*(DWORD*)buff = FLASH_SECTOR_COUNT;
res = RES_OK;
break;
default:
res = RES_PARERR;
break;
}
}
else if(pdrv == USB_DISK)
{
switch(cmd)
{
case CTRL_SYNC:
res = RES_OK;
break;
case GET_SECTOR_SIZE:
*(WORD*)buff = 4096;
res = RES_OK;
break;
case GET_BLOCK_SIZE:
*(WORD*)buff = 4096;
res = RES_OK;
break;
case GET_SECTOR_COUNT:
*(DWORD*)buff = (DWORD) USBH_MSC_Param.MSCapacity;
res = RES_OK;
break;
default:
res = RES_PARERR;
break;
}
}
else res = RES_ERROR; //其他的不支持
return res;
}
usbh_msc_usr.c
void USBH_USR_DeInit(void)
{
USBH_USR_ApplicationState = USH_USR_FS_INIT;
}
extern USBH_HOST USB_Host;
uint8_t USBH_UDISK_Status(void)
{
return HCD_IsDeviceConnected((USB_OTG_CORE_HANDLE*)&USB_OTG_Core);
}
uint8_t USBH_UDISK_Read(uint8_t *buf, uint32_t sector, uint32_t cnt)
{
u8 res = 1;
if(HCD_IsDeviceConnected((USB_OTG_CORE_HANDLE*)&USB_OTG_Core) )
{
do
{
res = USBH_MSC_Read10((USB_OTG_CORE_HANDLE*)&USB_OTG_Core, buf, sector, 4096 * cnt);
USBH_MSC_HandleBOTXfer((USB_OTG_CORE_HANDLE*)&USB_OTG_Core ,&USB_Host);
if(!HCD_IsDeviceConnected((USB_OTG_CORE_HANDLE*)&USB_OTG_Core))
{
res = 1;
break;
}
}
while(res == USBH_MSC_BUSY );
}else res = 1;
if(res == USBH_MSC_OK)
res = 0;
return res;
}
uint8_t USBH_UDISK_Write(uint8_t* buf,uint32_t sector,uint32_t cnt)
{
uint8_t res=1;
if(HCD_IsDeviceConnected((USB_OTG_CORE_HANDLE*)&USB_OTG_Core))//连接还存在,且是APP测试状态
{
do
{
res=USBH_MSC_Write10((USB_OTG_CORE_HANDLE*)&USB_OTG_Core,buf,sector, 4096 * cnt);
USBH_MSC_HandleBOTXfer((USB_OTG_CORE_HANDLE*)&USB_OTG_Core ,&USB_Host);
if(!HCD_IsDeviceConnected((USB_OTG_CORE_HANDLE*)&USB_OTG_Core))
{
res=1;
break;
};
}while(res==USBH_MSC_BUSY);
}else res=1;
if(res==USBH_MSC_OK)res=0;
return res;
}
usb_host处理函数的一部分
void USB_Application(void)
{
uint8_t res = 1;
uint32_t total, free;
uint8_t file = 1;
uint8_t sta = 0;
if(Enum_Done == 1)
{
delay_ms(10);
res = exf_get_free("2:", &total, &free);
SEGGER_RTT_SetTerminal(2);
SEGGER_RTT_printf(0, "> Rrturn exf_get_free is :%d\r\n", res);
if(res == 0)
{
/* 检测到磁盘并可以正常获取磁盘状态,LED常亮 */
led_toggle_flag = DISABLE;
led_on();
SEGGER_RTT_SetTerminal(2);
SEGGER_RTT_printf(0, "> U Disk FATFS OK!\r\n");
SEGGER_RTT_printf(0, "> U Disk Total Size: %d KB\r\n", total);
SEGGER_RTT_printf(0, "> U Disk Total Size: %d KB\r\n", free);
exf_scan_files("2:");
}
}
}
从机文件系统和主机差不多,USB这是修改了mass_mal.c中的这个函数
uint16_t MAL_GetStatus (uint8_t lun)
{
switch(lun)
{
case 0:
Mass_Memory_Size = 1024 * 1024 * 4; //4M字节
Mass_Block_Size = 4096; //设置SPI FLASH的操作扇区大小为4096
Mass_Block_Count= Mass_Memory_Size / Mass_Block_Size;
break;
default:
return MAL_FAIL;
}
return MAL_OK;
}
目前有点进展,主机插上从机偶尔会正常检索从机的文件,有时又不正常
不正常的情况就是在主机处理程序获取从机磁盘容量那一块 res = exf_get_free("2:", &total, &free);,返回值1(FR_DISK_ERR),查了FATFS官网有如下说明
C:\Users\Administrator\Desktop\1.jpg
lyjunnan 发表于 2021-10-19 13:59
主机芯片用的是STM32F105RBT6, 从机用的是国产的一款M4内核的但是USB只有从机的芯片,为了改善SPI Flash ...
exf_get_free是你自己封装的函数吧,fatfs没有这个函数。
你应该封装的是f_getfree eric2013 发表于 2021-10-20 10:30
exf_get_free是你自己封装的函数吧,fatfs没有这个函数。
你应该封装的是f_getfree
是的,调用f_mount也是一样的情况 lyjunnan 发表于 2021-10-21 13:42
是的,调用f_mount也是一样的情况
别的问题,不清楚了。
页:
[1]