2016-01-15 1 views
11

Я пытаюсь создать файл с FatFs на USB-флеше, но мой вызов f_open, пытающийся прочитать загрузочный сектор для установки файловой системы впервые, зависает этой функцией.STM32 USB OTG HOST Библиотека висит, пытаясь создать файл с FatFs

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 wich create hanging state 
    } 

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

} 

Основной проблемой является цикл создает которым висит государству

while(status == USBH_MSC_BUSY); 

Так что я не знаю, что делать, чтобы избежать этого. Используя debuger, я обнаружил, что состояние вызвано параметром CmdStateMachine структуры USBH_MSC_BOTXferParam, тип USBH_BOTXfer_TypeDef равен CMD_UNINITIALIZED_STATE с фактической причиной пропущения оператора switch USBH_MSC_Read10.

/** 
    * @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 relevent 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 
     magage 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; 

Во время отладки я обнаружил, что все его поля равны 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 обратные вызовы.

+1

Предоставить [mcve]. Но это может быть tl; dr. Библиотеки ST являются злоумышленниками. Если это действительно **, там он зависает, проверьте, где установлен флаг и почему он не очищается. Вероятно, обработчик прерываний. Используйте точки останова и отладчик. – Olaf

+0

Я не вижу, где вы называете disk_read(). Можете ли вы привести пример кода, который выполняется? –

+1

@ Иван Анжелов: Функция fatfs уровня HAL обеспечивает интерфейс для него в disio.h, файл, чем его мануал, реализованный с использованием драйвера устройства в нашем случае. Драйвер STM32F4 USB OTG HOST в файле (usbh_msc_fatfs.c). FatFs вызывают эту функцию для чтения с физического устройства в моем случае FLASH DRIVE. – Mykola

ответ

1

Я думаю, что это ошибка в библиотеке хостов ST. Я преследовал это, так как мой хозяин usb не смог пройти этап перечисления. После исправления стопка работает нормально.

union _USB_Setup Существует в usbh_def.h файл в "STM32Cube/Repository/STM32Cube_FW_F7_V1.13.0/ST/промежуточное программное/STM32_USB_Host_Library/CORE/Inc" (любой чип, а не только F7, любой вариант, не только V1.13.0). Он имеет uint16_t bmRequestType и uint16_t bRequest. Эти две области должны быть uint8_t по спецификации USB. Исправление этой проблемы привело к тому, что usb-хост пошел по мере необходимости. Этап переписи проходит нормально и все остальные этапы.

+0

По умолчанию все эти поля имеют тип 'uint8_t', но это не работает. – Mykola

+0

Хорошо, ваш флеш-накопитель перечислил хост usb? И тогда начинается ли класс устройства? – elephant

+0

Благодарим за внимание, но в настоящее время у меня нет доступа к микроконтроллеру сейчас, поэтому я дам вам некоторую награду. – Mykola

Смежные вопросы