STM32F723E -USB_Host\MSC_RTOS 示例分析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xiaohua0877/article/details/88936903

目录

 

1入口函数

1.1 初始化函数

1.2 USB初始化

1.3 注册函数

1.4 创建 USBH_Process_OS

1.5 USBH_Init

2. USB连接和断开

2.1  中断向量表stm32f7xx_it.c

2.2 USBH_UserProcess 使用者处理函数

2.3 Phost ->puser 断开

3.0 USB读写接口

4.0 hUSBHost


1入口函数

1.1 初始化函数

//文件:STM32F723E-Discovery\Applications\USB_Host\MSC_RTOS\Src\main.c
static void MSC_InitApplication(void)
{
  /* Configure Key Button */
  BSP_PB_Init(BUTTON_USER, BUTTON_MODE_GPIO);
  /* Initialize the LCD */
  BSP_LCD_Init();
  /* Initialize the TS in IT mode if not already initialized */
  if (TouchScreen_IsCalibrationDone() == 0)
  {
    Touchscreen_Calibration();
  }
  BSP_TS_ITConfig();
  /* Init the LCD Log module */
  LCD_LOG_Init();
#ifdef USE_USB_HS
  LCD_LOG_SetHeader((uint8_t *) " USB OTG HS MSC Host");
#else
  LCD_LOG_SetHeader((uint8_t *) " USB OTG FS MSC Host");
#endif
  LCD_UsrLog("USB Host library started.\n");
  /* Start MSC Interface */
  USBH_UsrLog("Starting MSC Demo");
  Menu_Init();    //初始化menu 
}

void Menu_Init(void)
{
  USBH_UsrLog("Starting MSC Demo");
  /* Create Menu Semaphore */
  osSemaphoreDef(osSem);
  MenuEvent = osSemaphoreCreate(osSemaphore(osSem), 1);
  /* Force menu to show Item 0 by default */
  osSemaphoreRelease(MenuEvent);
  /* Menu task */
  osThreadDef(Menu_Thread, MSC_MenuThread, osPriorityHigh, 0,
              8 * configMINIMAL_STACK_SIZE);
  osThreadCreate(osThread(Menu_Thread), NULL);
}

1.2 USB初始化

static void StartThread(void const *argument)
{
  osEvent event;
  /* Init MSC Application */
  MSC_InitApplication();
  /* Start Host Library */
  USBH_Init(&hUSBHost, USBH_UserProcess, 0);
  /* Add Supported Class */
  USBH_RegisterClass(&hUSBHost, USBH_MSC_CLASS);
  /* Start Host Process */
  USBH_Start(&hUSBHost);
}

1.3 注册函数

// 文件:STM32CubeF7_V1.14.0\Middlewares\ST\STM32_USB_Host_Library\Class\MSC\Src\usbh_msc.c

USBH_ClassTypeDef  USBH_msc =
{
    "MSC",
    USB_MSC_CLASS,
    USBH_MSC_InterfaceInit,
    USBH_MSC_InterfaceDeInit,
    USBH_MSC_ClassRequest,
    USBH_MSC_Process,
    USBH_MSC_SOFProcess,
    NULL,
};

  /* Add Supported Class */
  USBH_RegisterClass(&hUSBHost, USBH_MSC_CLASS);
USBH_RegisterClass(&hUSBHost, USBH_MSC_CLASS);
// STM32CubeF7_V1.14.0\Projects\STM32F723E-Discovery\Applications\USB_Host\MSC_RTOS\Src\main.c
//初始化结构体 phost->pClass

USBH_StatusTypeDef  USBH_RegisterClass(USBH_HandleTypeDef *phost, USBH_ClassTypeDef *pclass)
{
    USBH_StatusTypeDef   status = USBH_OK;
    if (pclass != 0)
    {
        if (phost->ClassNumber < USBH_MAX_NUM_SUPPORTED_CLASS)
        {
            /* link the class to the USB Host handle */
            phost->pClass[phost->ClassNumber++] = pclass;
            status = USBH_OK;
        }
        else
        {
            USBH_ErrLog("Max Class Number reached");
            status = USBH_FAIL;
        }
    }
    ..... //省略 
}

1.4 创建 USBH_Process_OS

#if (USBH_USE_OS == 1U)
    /* Create USB Host Queue */
    osMessageQDef(USBH_Queue, 10, uint16_t);
    phost->os_event = osMessageCreate(osMessageQ(USBH_Queue), NULL);
    /*Create USB Host Task */
#if defined (USBH_PROCESS_STACK_SIZE)
    osThreadDef(USBH_Thread, USBH_Process_OS, USBH_PROCESS_PRIO, 0, USBH_PROCESS_STACK_SIZE);
#else
    osThreadDef(USBH_Thread, USBH_Process_OS, USBH_PROCESS_PRIO, 0, 8 * configMINIMAL_STACK_SIZE);
#endif
    phost->thread = osThreadCreate(osThread(USBH_Thread), phost);
#endif

//1.文件:STM32CubeF7_V1.14.0\Middlewares\ST\STM32_USB_Host_Library\Core\Src\usbh_core.c
//2. 获取消息时,会处理 USBH_Process
static void USBH_Process_OS(void const *argument)
{
    osEvent event;
    for (;;)
    {
        event = osMessageGet(((USBH_HandleTypeDef *)argument)->os_event, osWaitForever);
        if (event.status == osEventMessage)
        {
            USBH_Process((USBH_HandleTypeDef *)argument);
        }
    }
}

/**
  * @brief  USBH_Process
  *         Background process of the USB Core.
  * @param  phost: Host Handle
  * @retval USBH Status
  */
USBH_StatusTypeDef  USBH_Process(USBH_HandleTypeDef *phost)
{
    __IO USBH_StatusTypeDef status = USBH_FAIL;
    uint8_t idx = 0U;

      case HOST_CLASS:
        /* process class state machine */
        if (phost->pActiveClass != NULL)
        {
            phost->pActiveClass->BgndProcess(phost);
        }
        break;
}

1.5 USBH_Init

/**
  * @brief  HCD_Init
  *         Initialize the HOST Core.
  * @param  phost: Host Handle
  * @param  pUsrFunc: User Callback
  * @retval USBH Status
  */
USBH_StatusTypeDef  USBH_Init(USBH_HandleTypeDef *phost, void (*pUsrFunc)(USBH_HandleTypeDef *phost,                                                                          uint8_t id), uint8_t id)
{
    /* Set DRiver ID */
    phost->id = id;
    /* Unlink class*/
    phost->pActiveClass = NULL;
    phost->ClassNumber = 0U;
    /* Assign User process */
    if (pUsrFunc != NULL)
    {
        phost->pUser = pUsrFunc;
    }

}

2. USB连接和断开

    case HOST_USER_CONNECTION:
        if (FATFS_LinkDriver(&USBH_Driver, USBDISKPath) == 0)
        {
            if (f_mount(&USBH_fatfs, "", 0) != FR_OK)
            {
                LCD_ErrLog("ERROR : Cannot Initialize FatFs! \n");
            }
        }
        break;

中断
/**
  * @brief  Connect callback.
  * @param  hhcd: HCD handle
  * @retval None
  */
void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd)
{
  USBH_LL_Connect(hhcd->pData);
}
/**
  * @brief  Disconnect callback.
  * @param  hhcd: HCD handle
  * @retval None
  */
void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd)
{
  USBH_LL_Disconnect(hhcd->pData);
}

2.1  中断向量表stm32f7xx_it.c

/**
  * @brief  This function handles USB-On-The-Go FS/HS global interrupt request.
  * @param  None
  * @retval None
  */
#ifdef USE_USB_FS
void OTG_FS_IRQHandler(void)
#else
void OTG_HS_IRQHandler(void)
#endif
{
  HAL_HCD_IRQHandler(&hhcd);
}
// 第二级:
 /* Check whether Port Enable Changed */
  if((hprt0 & USB_OTG_HPRT_PENCHNG) == USB_OTG_HPRT_PENCHNG)
  {
    hprt0_dup |= USB_OTG_HPRT_PENCHNG;
    if((hprt0 & USB_OTG_HPRT_PENA) == USB_OTG_HPRT_PENA)
    {
      if(hhcd->Init.phy_itface  == USB_OTG_EMBEDDED_PHY)
      {
        if ((hprt0 & USB_OTG_HPRT_PSPD) == (HPRT0_PRTSPD_LOW_SPEED << 17))
        {
          (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_6_MHZ);
        }
        else
        {
          (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_48_MHZ);
        }
      }
      else
      {
        if(hhcd->Init.speed == HCD_SPEED_FULL)
        {
          USBx_HOST->HFIR = 60000U;
        }
      }
      HAL_HCD_PortEnabled_Callback(hhcd);
      HAL_HCD_Connect_Callback(hhcd);     //
    }
/**
  * @brief  Connect callback.
  * @param  hhcd: HCD handle
  * @retval None
  */
void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd)
{
  USBH_LL_Connect(hhcd->pData);
}


USBH_StatusTypeDef  USBH_LL_Connect(USBH_HandleTypeDef *phost)
{
    if (phost->gState == HOST_IDLE)
    {
        phost->device.is_connected = 1U;
        if (phost->pUser != NULL)
        {
            phost->pUser(phost, HOST_USER_CONNECTION);
        }
    }
}

2.2 USBH_UserProcess 使用者处理函数

/**
  * @brief  User Process
  * @param  phost: Host Handle
  * @param  id: Host Library user message ID
  * @retval None
  */
static void USBH_UserProcess(USBH_HandleTypeDef *phost, uint8_t id)
{
    switch (id)
    {
    case HOST_USER_SELECT_CONFIGURATION:
        break;
    case HOST_USER_DISCONNECTION:
        osMessagePut(AppliEvent, APPLICATION_DISCONNECT, 0);
        if (f_mount(NULL, "", 0) != FR_OK)
        {
            LCD_ErrLog("ERROR : Cannot DeInitialize FatFs! \n");
        }
        if (FATFS_UnLinkDriver(USBDISKPath) != 0)
        {
            LCD_ErrLog("ERROR : Cannot UnLink FatFS Driver! \n");
        }
        break;
    case HOST_USER_CLASS_ACTIVE:
        osMessagePut(AppliEvent, APPLICATION_READY, 0);
        break;
    case HOST_USER_CONNECTION: 
        if (FATFS_LinkDriver(&USBH_Driver, USBDISKPath) == 0)   //初始化 FATFS接口
        {
            if (f_mount(&USBH_fatfs, "", 0) != FR_OK)           //初始化文件系统f_mount 
            {
                LCD_ErrLog("ERROR : Cannot Initialize FatFs! \n");
            }
        }
        break;
    default:
        break;
    }
}

2.3 Phost ->puser 断开

USBH_StatusTypeDef  USBH_LL_Disconnect(USBH_HandleTypeDef *phost)
{
    /*Stop Host */
    USBH_LL_Stop(phost);
    /* FRee Control Pipes */
    USBH_FreePipe(phost, phost->Control.pipe_in);
    USBH_FreePipe(phost, phost->Control.pipe_out);
    phost->device.is_connected = 0U;
    if (phost->pUser != NULL)
    {
        phost->pUser(phost, HOST_USER_DISCONNECTION);
    }
    USBH_UsrLog("USB Device disconnected");

}

3.0 USB读写接口

disk结构体

​​const Diskio_drvTypeDef  USBH_Driver =
{
  USBH_initialize,
  USBH_status,
  USBH_read,
#if  _USE_WRITE == 1
  USBH_write,
#endif /* _USE_WRITE == 1 */
#if  _USE_IOCTL == 1
  USBH_ioctl,
#endif /* _USE_IOCTL == 1 */
};

结构声明
/**
  * @brief  Disk IO Driver structure definition
  */
typedef struct
{
  DSTATUS (*disk_initialize) (BYTE);         /*!< Initialize Disk Drive             */
  DSTATUS (*disk_status)     (BYTE);       /*!< Get Disk Status                     */
  DRESULT (*disk_read)       (BYTE, BYTE*, DWORD, UINT);     /*!< Read Sector(s)                   */
#if _USE_WRITE == 1
  DRESULT (*disk_write)      (BYTE, const BYTE*, DWORD, UINT); 
/*!< Write Sector(s) when _USE_WRITE = 0 */
#endif /* _USE_WRITE == 1 */
#if _USE_IOCTL == 1
  DRESULT (*disk_ioctl)      (BYTE, BYTE, void*); 
/*!< I/O control operation when _USE_IOCTL = 1 */
#endif /* _USE_IOCTL == 1 */
}Diskio_drvTypeDef;
/**
  * @brief  Global Disk IO Drivers structure definition
  */
typedef struct
{
  uint8_t                 is_initialized[_VOLUMES];
  const Diskio_drvTypeDef *drv[_VOLUMES];
  uint8_t                 lun[_VOLUMES];
  volatile uint8_t        nbr;
}Disk_drvTypeDef;
    case HOST_USER_CONNECTION:
        if (FATFS_LinkDriver(&USBH_Driver, USBDISKPath) == 0) //初始化结构
        {
            if (f_mount(&USBH_fatfs, "", 0) != FR_OK)
            {
                LCD_ErrLog("ERROR : Cannot Initialize FatFs! \n");
            }
        }
        break;

//路径:TM32CubeF7_V1.14.0\Middlewares\Third_Party\FatFs\src\ff_gen_drv.c  LINE:69
uint8_t FATFS_LinkDriverEx(const Diskio_drvTypeDef *drv, char *path, uint8_t lun)
{
  uint8_t ret = 1;
  uint8_t DiskNum = 0;
  if(disk.nbr < _VOLUMES)
  {
    disk.is_initialized[disk.nbr] = 0;
    disk.drv[disk.nbr] = drv;
    disk.lun[disk.nbr] = lun;
    DiskNum = disk.nbr++;
    path[0] = DiskNum + '0';
    path[1] = ':';
    path[2] = '/';
    path[3] = 0;
    ret = 0;
  }
  return ret;
}

4.0 hUSBHost


/* Private variables ---------------------------------------------------------*/
USBH_HandleTypeDef hUSBHost;

函数调用 
//Projects\STM32F723E-Discovery\Applications\USB_Host\MSC_RTOS\Src
main.c () line 53 : USBH_HandleTypeDef hUSBHost;
StartThread in main.c () :     USBH_Init(&hUSBHost, USBH_UserProcess, 0);
StartThread in main.c () :     USBH_RegisterClass(&hUSBHost, USBH_MSC_CLASS);
StartThread in main.c () :     USBH_Start(&hUSBHost);


接口DMA读写
//Projects\STM32F723E-Discovery\Applications\USB_Host\MSC_RTOS\Src
usbh_diskio_dma.c line 57 : extern USBH_HandleTypeDef  hUSBHost;
USBH_status in usbh_diskio_dma.c :   if(USBH_MSC_UnitIsReady(&hUSBHost, lun))
USBH_read in usbh_diskio_dma.c :   if (((DWORD)buff & 3) && (((HCD_HandleTypeDef *)hUSBHost.pData)->Init.dma_enable))
USBH_read in usbh_diskio_dma.c :       status = USBH_MSC_Read(&hUSBHost, lun, sector + count, (uint8_t *)scratch, 1);
USBH_read in usbh_diskio_dma.c :     status = USBH_MSC_Read(&hUSBHost, lun, sector, buff, count);
USBH_read in usbh_diskio_dma.c :     USBH_MSC_GetLUNInfo(&hUSBHost, lun, &info);
USBH_write in usbh_diskio_dma.c :   if (((DWORD)buff & 3) && (((HCD_HandleTypeDef *)hUSBHost.pData)->Init.dma_enable))
USBH_write in usbh_diskio_dma.c :       status = USBH_MSC_Write(&hUSBHost, lun, sector + count, (BYTE *)scratch, 1) ;
USBH_write in usbh_diskio_dma.c :     status = USBH_MSC_Write(&hUSBHost, lun, sector, (BYTE *)buff, count);
USBH_write in usbh_diskio_dma.c :     USBH_MSC_GetLUNInfo(&hUSBHost, lun, &info);
USBH_ioctl in usbh_diskio_dma.c :     if(USBH_MSC_GetLUNInfo(&hUSBHost, lun, &info) == USBH_OK)
USBH_ioctl in usbh_diskio_dma.c :     if(USBH_MSC_GetLUNInfo(&hUSBHost, lun, &info) == USBH_OK)
USBH_ioctl in usbh_diskio_dma.c :     if(USBH_MSC_GetLUNInfo(&hUSBHost, lun, &info) == USBH_OK)

结构体解析

//STM32CubeF7_V1.14.0\Middlewares\ST\STM32_USB_Host_Library\Core\Inc\usbh_def.h

/* Attached device structure */
typedef struct
{
#if (USBH_KEEP_CFG_DESCRIPTOR == 1U)
  uint8_t                           CfgDesc_Raw[USBH_MAX_SIZE_CONFIGURATION];
#endif
  uint8_t                           Data[USBH_MAX_DATA_BUFFER];
  uint8_t                           address;
  uint8_t                           speed;
  __IO uint8_t                      is_connected;
  uint8_t                           PortEnabled;
  uint8_t                           current_interface;
  USBH_DevDescTypeDef               DevDesc;
  USBH_CfgDescTypeDef               CfgDesc;
}USBH_DeviceTypeDef;
/* USB Host Class structure */
typedef struct
{
  const char          *Name;
  uint8_t              ClassCode;
  USBH_StatusTypeDef  (*Init)        (struct _USBH_HandleTypeDef *phost);
  USBH_StatusTypeDef  (*DeInit)      (struct _USBH_HandleTypeDef *phost);
  USBH_StatusTypeDef  (*Requests)    (struct _USBH_HandleTypeDef *phost);
  USBH_StatusTypeDef  (*BgndProcess) (struct _USBH_HandleTypeDef *phost);
  USBH_StatusTypeDef  (*SOFProcess) (struct _USBH_HandleTypeDef *phost);
  void*                pData;
} USBH_ClassTypeDef;
/* USB Host handle structure */
typedef struct _USBH_HandleTypeDef
{
  __IO HOST_StateTypeDef     gState;       /*  Host State Machine Value */
  ENUM_StateTypeDef     EnumState;    /* Enumeration state Machine */
  CMD_StateTypeDef      RequestState;
  USBH_CtrlTypeDef      Control;
  USBH_DeviceTypeDef    device;                  //设备类型描述符
  USBH_ClassTypeDef*    pClass[USBH_MAX_NUM_SUPPORTED_CLASS];
  USBH_ClassTypeDef*    pActiveClass;
  uint32_t              ClassNumber;
  uint32_t              Pipes[15];
  __IO uint32_t         Timer;
  uint8_t               id;
  void*                 pData;
  void                 (* pUser )(struct _USBH_HandleTypeDef *pHandle, uint8_t id);
#if (USBH_USE_OS == 1U)
  osMessageQId          os_event;
  osThreadId            thread;
#endif
} USBH_HandleTypeDef;

猜你喜欢

转载自blog.csdn.net/xiaohua0877/article/details/88936903