目录
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
//文件: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);
}
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);
}
// 文件: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;
}
}
..... //省略
}
#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;
}
/**
* @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;
}
}
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);
}
/**
* @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);
}
}
}
/**
* @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;
}
}
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");
}
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;
}
/* 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;