2016-01-15 15 views
11

Sto provando a creare un file con FatFs su flash USB, ma la mia chiamata f_open tenta di leggere il settore di avvio per il primo blocco del sistema di file si blocca su questa funzione.STM32 USB OTG libreria HOST si blocca cercando di creare file con 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; 

} 

il problema principale è wich ciclo crea appeso stato

while(status == USBH_MSC_BUSY); 

Quindi non so cosa fare per evitare questo. Usando il debuger, scopro che lo stato è causato dal parametro CmdStateMachine della struttura USBH_MSC_BOTXferParam, il tipo USBH_BOTXfer_TypeDef è uguale a CMD_UNINITIALIZED_STATE che effettivamente causa il mancato aggiornamento della dichiarazione di 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; 
} 

Ecco USBH_BOTXfer_TypeDef dichiarazione del tipo;

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; 

Durante il debug scopro che tutti i campi di esso sono 0x00.

Qui sono i miei FatFs chiamate

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 funzione è:

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

E gli stati del dispositivo sono:

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; 

Il valore di g_USB_MSC_HostStatus viene ricevuto da utente standard USB HOST callback.

+1

Fornire un [mcve]. Ma quello potrebbe essere tl; dr. Le librerie ST sono notoriamente bloatware. Se questo è ** veramente **, si blocca, controlla dove è impostato il flag e perché non è cancellato. Probabilmente un gestore di interruzioni. Usa punti di interruzione e un debugger. – Olaf

+0

Non riesco a vedere dove chiami disk_read(). Puoi fornire l'esempio del codice che viene eseguito? –

+1

@Ivan Angelov: La sua funzione di livello HAL fatfs fornisce un'interfaccia per esso in disio.h, file rispetto alla sua manualità implementata con l'utilizzo del driver di periferica nel nostro caso il driver HOST OTG STM32F4 USB nel file (usbh_msc_fatfs.c). FatFs chiama questa funzione per eseguire la lettura dal dispositivo fisico nel mio caso FLASH DRIVE. – Mykola

risposta

1

Penso che sia un errore nella libreria host ST. L'ho cercato, perché il mio host USB non era in grado di superare lo stadio di enumerazione. Dopo una correzione lo stack è Ok.

C'è union _USB_Setup in file di usbh_def.h in "STM32Cube/Repository/STM32Cube_FW_F7_V1.13.0/Middleware/ST/STM32_USB_Host_Library/core/Inc" (qualsiasi circuito integrato, non solo F7, qualsiasi versione, non solo V1.13.0). Ha uint16_t bmRequestType e uint16_t bRequest. Questi due campi devono essere uint8_t come da specifiche USB. La risoluzione di questo problema ha reso l'host USB disponibile quando necessario. La fase di enumerazione passa ok e anche tutte le altre fasi.

+0

Tutti questi campi hanno tipo 'uint8_t' di default, ma non funziona. – Mykola

+0

Ok, la tua chiavetta viene enumerata dall'host usb? E poi, la classe del dispositivo inizia? – elephant

+0

Grazie per l'attenzione, ma attualmente non ho accesso al microcontrollore ora, quindi ti darò qualche ricompensa. – Mykola

Problemi correlati