2016-01-15 5 views
11

Ich versuche, eine Datei mit FatFs auf USB-Flash zu erstellen, aber meine f_open Aufruf versucht, Boot-Sektor zum ersten Mal zu lesen Dateisystem-Mount hängt an dieser Funktion.STM32 USB OTG HOST Bibliothek hängt versucht, Datei mit FatFs erstellen

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; 

} 

Das Hauptproblem ist die Schleife weicht Zustand So

while(status == USBH_MSC_BUSY); 

Ich weiß nicht, schafft hängen, was dies zu vermeiden, zu tun. Debuger benutzend, finde ich, dass der Zustand durch den Parameter CmdStateMachine der Struktur USBH_MSC_BOTXferParam verursacht wird, der Typ USBH_BOTXfer_TypeDef ist gleich CMD_UNINITIALIZED_STATE was tatsächlich zu einer Fehlfunktion der Schalteranweisung von USBH_MSC_Read10 führt.

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

Hier ist USBH_BOTXfer_TypeDef Typ Erklärung;

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; 

Während des Debuggens entdecke ich, dass alle Felder davon 0x00 ist.

Hier sind meine FATFS Anrufe

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 Funktion:

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

und Gerätezustände sind:

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; 

Der Wert g_USB_MSC_HostStatus wird durch Standard-USB-Host-Benutzer empfangen Rückrufe.

+1

Stellen Sie eine [mcve] bereit. Aber das könnte tl sein; dr. Die ST-Bibliotheken sind keine Blowarware. Wenn das ** wirklich ** dort hängt, überprüfe, wo die Flagge gesetzt ist und warum sie nicht gelöscht wird. Wahrscheinlich ein Interrupt-Handler. Verwenden Sie Haltepunkte und einen Debugger. – Olaf

+0

Ich kann nicht sehen, wo Sie disk_read() aufrufen. Können Sie das Beispiel des Codes angeben, der gerade ausgeführt wird? –

+1

@ Ivan Angelov: Seine HAL-Ebene Funktion Fatfs stellen Schnittstelle für es in disio.h, Datei als seine manuelle implementiert mit Gerätetreibern Verwendung in unserem Fall STM32F4 USB OTG HOST-Treiber in Datei (usbh_msc_fatfs.c). FatFs rufen diese Funktion auf, um vom physikalischen Gerät in meinem Fall FLASH DRIVE zu lesen. – Mykola

Antwort

1

Ich denke, es ist ein Fehler in der ST-Host-Bibliothek. Ich habe es gejagt, da mein USB-Host die Enumerationsstufe nicht passieren konnte. Nach einer Behebung ist der Stack Ok.

Es gibt union _USB_Setup in usbh_def.h Datei in "STM32Cube/Repository/STM32Cube_FW_F7_V1.13.0/Middlewares/ST/STM32_USB_Host_Library/Kern/Inc" (jeder Chip, nicht nur F7, eine Version, nicht nur V1.13.0). Es hat uint16_t bmRequestType und uint16_t bRequest. Diese beiden Dateien müssen uint8_t gemäß den USB-Spezifikationen sein. Durch die Behebung dieses Problems wurde der USB-Host nach Bedarf aktiviert. Die Enumerationsphase läuft gut und alle anderen Stufen ebenfalls.

+0

Alle diese Felder haben standardmäßig den Typ 'uint8_t', aber es funktioniert nicht. – Mykola

+0

Ok, wird Ihr Flash-Laufwerk vom USB-Host aufgezählt? Und dann wird die Geräteklasse gestartet? – elephant

+0

Vielen Dank für Ihre Aufmerksamkeit, aber zur Zeit habe ich keinen Zugang zum Mikrocontroller, also gebe ich Ihnen eine Belohnung. – Mykola

Verwandte Themen