gpt4 book ai didi

c - STM32 USB OTG HOST 库在尝试使用 FatFs 创建文件时挂起

转载 作者:太空狗 更新时间:2023-10-29 16:45:24 26 4
gpt4 key购买 nike

我正在尝试在 USB 闪存上使用 FatFs 创建一个文件,但我的 f_open 调用尝试读取引导扇区以进行首次文件系统装载时卡在该函数上。

DRESULT disk_read (
BYTE drv, /* Physical drive number (0) */
BYTE *buff, /* Pointer to the data buffer to store read data */
DWORD sector, /* Start sector number (LBA) */
BYTE count /* Sector count (1..255) */
)
{
BYTE status = USBH_MSC_OK;

if (drv || !count) return RES_PARERR;
if (Stat & STA_NOINIT) return RES_NOTRDY;


if(HCD_IsDeviceConnected(&USB_OTG_Core))
{

do
{
status = USBH_MSC_Read10(&USB_OTG_Core, buff,sector,512 * count);
USBH_MSC_HandleBOTXfer(&USB_OTG_Core ,&USB_Host);

if(!HCD_IsDeviceConnected(&USB_OTG_Core))
{
return RES_ERROR;
}
}
while(status == USBH_MSC_BUSY ); // Loop which create hanging state
}

if(status == USBH_MSC_OK)
return RES_OK;
return RES_ERROR;

}

主要问题是创建挂起状态的循环

while(status == USBH_MSC_BUSY );

所以我不知道该怎么做才能避免这种情况。使用调试器我发现状态是由结构 USBH_MSC_BOTXferParam 的参数 CmdStateMachine 引起的,类型 USBH_BOTXfer_TypeDef 等于 CMD_UNINITIALIZED_STATE 实际上导致错过 USBH_MSC_Read10 函数的 switch 语句。

/**
* @brief USBH_MSC_Read10
* Issue the read command to the device. Once the response received,
* it updates the status to upper layer
* @param dataBuffer : DataBuffer will contain the data to be read
* @param address : Address from which the data will be read
* @param nbOfbytes : NbOfbytes to be read
* @retval Status
*/
uint8_t USBH_MSC_Read10(USB_OTG_CORE_HANDLE *pdev,
uint8_t *dataBuffer,
uint32_t address,
uint32_t nbOfbytes)
{
uint8_t index;
static USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY;
uint16_t nbOfPages;
status = USBH_MSC_BUSY;

if(HCD_IsDeviceConnected(pdev))
{
switch(USBH_MSC_BOTXferParam.CmdStateMachine)
{
case CMD_SEND_STATE:
/*Prepare the CBW and relevant field*/
USBH_MSC_CBWData.field.CBWTransferLength = nbOfbytes;
USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN;
USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH;

USBH_MSC_BOTXferParam.pRxTxBuff = dataBuffer;

for(index = CBW_CB_LENGTH; index != 0; index--)
{
USBH_MSC_CBWData.field.CBWCB[index] = 0x00;
}

USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_READ10;

/*logical block address*/

USBH_MSC_CBWData.field.CBWCB[2] = (((uint8_t*)&address)[3]);
USBH_MSC_CBWData.field.CBWCB[3] = (((uint8_t*)&address)[2]);
USBH_MSC_CBWData.field.CBWCB[4] = (((uint8_t*)&address)[1]);
USBH_MSC_CBWData.field.CBWCB[5] = (((uint8_t*)&address)[0]);

/*USBH_MSC_PAGE_LENGTH = 512*/
nbOfPages = nbOfbytes/ USBH_MSC_PAGE_LENGTH;

/*Tranfer length */
USBH_MSC_CBWData.field.CBWCB[7] = (((uint8_t *)&nbOfPages)[1]) ;
USBH_MSC_CBWData.field.CBWCB[8] = (((uint8_t *)&nbOfPages)[0]) ;


USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW;
/* Start the transfer, then let the state machine
manage the other transactions */
USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS;
USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY;
USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS;

status = USBH_MSC_BUSY;

break;

case CMD_WAIT_STATUS:

if((USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK) && \
(HCD_IsDeviceConnected(pdev)))
{
/* Commands successfully sent and Response Received */
USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
status = USBH_MSC_OK;
}
else if (( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL ) && \
(HCD_IsDeviceConnected(pdev)))
{
/* Failure Mode */
USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
}

else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR )
{
/* Failure Mode */
USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
status = USBH_MSC_PHASE_ERROR;
}
else
{
/* Wait for the Commands to get Completed */
/* NO Change in state Machine */
}
break;

default:
break;
}
}
return status;
}

这里是USBH_BOTXfer_TypeDef类型声明;

typedef struct _BOTXfer
{
uint8_t MSCState;
uint8_t MSCStateBkp;
uint8_t MSCStateCurrent;
uint8_t CmdStateMachine;
uint8_t BOTState;
uint8_t BOTStateBkp;
uint8_t* pRxTxBuff;
uint16_t DataLength;
uint8_t BOTXferErrorCount;
uint8_t BOTXferStatus;
} USBH_BOTXfer_TypeDef;

在debug过程中发现所有字段都是0x00。

这是我的 FatFs 调用

int main(void)
{
FATFS Fat;
FIL file;
FRESULT fr;

RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN;

/* Enable SWO output */
DBGMCU->CR = 0x00000020;

GPIOD->MODER=0x55000000;
GPIOD->OTYPER = 0x00000000;
GPIOD->OSPEEDR = 0x00000001;

while(1)
{
if (!USB_MSC_IsInitialized())
{
USB_MSC_Initialize();
}

if (USB_MSC_IsConnected())
{
GPIOD->ODR = (1 << 15);

disk_initialize(0);

fr = f_mount(0, &Fat);

if(fr == FR_OK)
{
fr = f_open(&file,"0:DP_lab8.pdf",(FA_CREATE_ALWAYS | FA_WRITE));

if (fr == FR_OK)
{
f_close(&file);
}

f_mount(0, NULL);
}
}
else
{
GPIOD->ODR = (1 << 14);
}

USB_MSC_Main();
}
}

USB_MSC_IsConnected 函数是:

int USB_MSC_IsConnected(void)
{
if (g_USB_MSC_HostStatus == USB_DEV_NOT_SUPPORTED)
{
USB_MSC_Uninitialize();
}

return !(g_USB_MSC_HostStatus == USB_DEV_DETACHED ||
g_USB_MSC_HostStatus == USB_HOST_NO_INIT ||
g_USB_MSC_HostStatus == USB_DEV_NOT_SUPPORTED);
}

设备状态是:

typedef enum
{
USB_HOST_NO_INIT = 0, /* USB interface not initialized */
USB_DEV_DETACHED, /* no device connected */
USB_SPEED_ERROR, /* unsupported USB speed */
USB_DEV_NOT_SUPPORTED, /* unsupported device */
USB_DEV_WRITE_PROTECT, /* device is write protected */
USB_OVER_CURRENT, /* overcurrent detected */
USB_DEV_CONNECTED /* device connected and ready */
} USB_HostStatus;

g_USB_MSC_HostStatus 的值由标准 USB HOST 用户回调接收。

最佳答案

我认为这是 ST 主机库中的错误。我已经找到它了,因为我的 USB 主机无法通过枚举阶段。修复后堆栈正常。

在“STM32Cube/Repository/STM32Cube_FW_F7_V1.13.0/Middlewares/ST/STM32_USB_Host_Library/Core/Inc”(任何芯片,不仅是 F7,任何版本,不仅是 V1.13.0)。它有 uint16_t bmRequestType 和 uint16_t bRequest。根据 USB 规范,这两个字段必须是 uint8_t。解决此问题使 USB 主机按需运行。枚举阶段顺利通过,所有其他阶段也顺利通过。

关于c - STM32 USB OTG HOST 库在尝试使用 FatFs 创建文件时挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34820931/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com