2016-01-15 17 views
11

USBフラッシュでFatFを使用してファイルを作成しようとしていますが、この機能で初めてブートセクタを読み込もうとするとf_openコールがハングアップします。STM32 USB OTG HOSTライブラリがFatFでファイルを作成しようとしています

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); 

を作成しています。デバッガを使用すると、その状態は、構造USBH_MSC_BOTXferParamのパラメータCmdStateMachineによって引き起こされ、タイプUSBH_BOTXfer_TypeDefCMD_UNINITIALIZED_STATEと同じであることがわかりました。実際には、スイッチのステートメントが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

@Ivan Angelov:そのHALレベル関数fatfsは、私たちの場合のSTM32F4 USB OTG HOSTドライバ(usbh_msc_fatfs.c)のデバイスドライバの使用法で実装されているmanualioよりもdisio.hのファイルのためのインタフェースを提供します。 FatFsはこの機能を私のケースでは物理デバイスからの読み出しを実行するために呼び出します。 – Mykola

答えて

1

STホストライブラリのバグだと思います。私のUSBホストは列挙ステージを通過することができなかったので、私はそれを捜した。修正後、スタックはOkです。

union _USB_Setupusbh_def.hファイルは、(任意のチップだけでなく、F7、任意のバージョンだけでなく、V1.13.0 "STM32Cube /リポジトリ/ STM32Cube_FW_F7_V1.13.0 /ミドルウェア/ ST/STM32_USB_Host_Library /コア/株式会社" にあり)。 uint16_t bmRequestTypeとuint16_t bRequestを持っています。これらの2つのファイルはUSB仕様のuint8_tでなければなりません。この問題を修正することで、必要に応じてUSBホストが動作します。 EnumerationステージはOKになり、他のステージもすべて終了します。

+0

すべてのこれらのフィールドは、デフォルトでは 'uint8_t'を入力しているが、それは動作しません。 – Mykola

+0

あなたのフラッシュドライブはUSBホストによって列挙されますか?そして、デバイスクラスは開始されますか? – elephant

+0

ご注意いただきありがとうございますが、現在はマイクロコントローラにはまだアクセスしていませんので、いくつかの報酬をいただきます。 – Mykola

関連する問題