usb

学习Hal库的usbdisk记录

生成usbdisk的代码里面有
usb_host.c中
/*
* user callbak definition
*/
static void USBH_UserProcess (USBH_HandleTypeDef *phost, uint8_t id)
{

/* USER CODE BEGIN 2 */
switch(id)
{
case HOST_USER_SELECT_CONFIGURATION:
break;

case HOST_USER_DISCONNECTION:
Appli_state = APPLICATION_DISCONNECT;
break;

case HOST_USER_CLASS_ACTIVE:
Appli_state = APPLICATION_READY;
break;

case HOST_USER_CONNECTION:
Appli_state = APPLICATION_START;
break;

default:
break;
}
/* USER CODE END 2 */
}
查看定义得到 usbh_core.h
#define HOST_USER_SELECT_CONFIGURATION          1
#define HOST_USER_CLASS_ACTIVE 2
#define HOST_USER_CLASS_SELECTED 3
#define HOST_USER_CONNECTION 4
#define HOST_USER_DISCONNECTION 5
#define HOST_USER_UNRECOVERED_ERROR 6
英文文件usbh_core说明这个就是usb的核心处理文件
查看其中随意一个引用的地方,找到
/**
* @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 = 0;

switch (phost->gState)
{
case HOST_IDLE :

if (phost->device.is_connected)
{
/* Wait for 200 ms after connection */
phost->gState = HOST_DEV_WAIT_FOR_ATTACHMENT;
USBH_Delay(200);
USBH_LL_ResetPort(phost);
#if (USBH_USE_OS == 1)
osMessagePut ( phost->os_event, USBH_PORT_EVENT, 0);
#endif
}
break;

case HOST_DEV_WAIT_FOR_ATTACHMENT:
break;

case HOST_DEV_ATTACHED :

USBH_UsrLog("USB Device Attached");

/* Wait for 100 ms after Reset */
USBH_Delay(100);

phost->device.speed = USBH_LL_GetSpeed(phost);

phost->gState = HOST_ENUMERATION;

phost->Control.pipe_out = USBH_AllocPipe (phost, 0x00);
phost->Control.pipe_in = USBH_AllocPipe (phost, 0x80);


/* Open Control pipes */
USBH_OpenPipe (phost,
phost->Control.pipe_in,
0x80,
phost->device.address,
phost->device.speed,
USBH_EP_CONTROL,
phost->Control.pipe_size);

/* Open Control pipes */
USBH_OpenPipe (phost,
phost->Control.pipe_out,
0x00,
phost->device.address,
phost->device.speed,
USBH_EP_CONTROL,
phost->Control.pipe_size);

#if (USBH_USE_OS == 1)
osMessagePut ( phost->os_event, USBH_PORT_EVENT, 0);
#endif

break;

case HOST_ENUMERATION:
/* Check for enumeration status */
if ( USBH_HandleEnum(phost) == USBH_OK)
{
/* The function shall return USBH_OK when full enumeration is complete */
USBH_UsrLog ("Enumeration done.");
phost->device.current_interface = 0;
if(phost->device.DevDesc.bNumConfigurations == 1)
{
USBH_UsrLog ("This device has only 1 configuration.");
phost->gState = HOST_SET_CONFIGURATION;

}
else
{
phost->gState = HOST_INPUT;
}

}
break;

case HOST_INPUT:
{
/* user callback for end of device basic enumeration */
if(phost->pUser != NULL)
{
phost->pUser(phost, HOST_USER_SELECT_CONFIGURATION);
phost->gState = HOST_SET_CONFIGURATION;

#if (USBH_USE_OS == 1)
osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
#endif
}
}
break;

case HOST_SET_CONFIGURATION:
/* set configuration */
if (USBH_SetCfg(phost, phost->device.CfgDesc.bConfigurationValue) == USBH_OK)
{
phost->gState = HOST_CHECK_CLASS;
USBH_UsrLog ("Default configuration set.");

}

break;

case HOST_CHECK_CLASS:

if(phost->ClassNumber == 0)
{
USBH_UsrLog ("No Class has been registered.");
}
else
{
phost->pActiveClass = NULL;

for (idx = 0; idx < USBH_MAX_NUM_SUPPORTED_CLASS ; idx ++)
{
if(phost->pClass[idx]->ClassCode == phost->device.CfgDesc.Itf_Desc[0].bInterfaceClass)
{
phost->pActiveClass = phost->pClass[idx];
}
}

if(phost->pActiveClass != NULL)
{
if(phost->pActiveClass->Init(phost)== USBH_OK)
{
phost->gState = HOST_CLASS_REQUEST;
USBH_UsrLog ("%s class started.", phost->pActiveClass->Name);

/* Inform user that a class has been activated */
phost->pUser(phost, HOST_USER_CLASS_SELECTED);
}
else
{
phost->gState = HOST_ABORT_STATE;
USBH_UsrLog ("Device not supporting %s class.", phost->pActiveClass->Name);
}
}
else
{
phost->gState = HOST_ABORT_STATE;
USBH_UsrLog ("No registered class for this device.");
}
}

#if (USBH_USE_OS == 1)
osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
#endif
break;

case HOST_CLASS_REQUEST:
/* process class standard control requests state machine */
if(phost->pActiveClass != NULL)
{
status = phost->pActiveClass->Requests(phost);

if(status == USBH_OK)
{
phost->gState = HOST_CLASS;
}
}
else
{
phost->gState = HOST_ABORT_STATE;
USBH_ErrLog ("Invalid Class Driver.");

#if (USBH_USE_OS == 1)
osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
#endif
}

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

case HOST_DEV_DISCONNECTED :

DeInitStateMachine(phost);

/* Re-Initilaize Host for new Enumeration */
if(phost->pActiveClass != NULL)
{
phost->pActiveClass->DeInit(phost);
phost->pActiveClass = NULL;
}
break;

case HOST_ABORT_STATE:
default :
break;
}
return USBH_OK;
}
已邀请:

admin

赞同来自:

可以得出usb_user的方式类似callback
主循环体里时刻查询usb状态,然后分别调用不同的usb状态callback
typedef enum {
APPLICATION_IDLE = 0,
APPLICATION_START,
APPLICATION_READY,
APPLICATION_DISCONNECT,
}ApplicationTypeDef;
这个是自定义的
static void USBH_UserProcess  (USBH_HandleTypeDef *phost, uint8_t id)
{

/* USER CODE BEGIN 2 */
switch(id)
{
case HOST_USER_SELECT_CONFIGURATION:
break;

case HOST_USER_DISCONNECTION:
Appli_state = APPLICATION_DISCONNECT;
break;

case HOST_USER_CLASS_ACTIVE:
Appli_state = APPLICATION_READY;
break;

case HOST_USER_CONNECTION:
Appli_state = APPLICATION_START;
break;

default:
break;
}
/* USER CODE END 2 */
}
上面针对不同的usb完成状态进行不同的状态切换,来实现用户功能
 

admin

赞同来自:

这个
  case HOST_USER_DISCONNECTION:
Appli_state = APPLICATION_DISCONNECT;
break;

对应usb的底层函数
 
/**
* @brief USBH_LL_Disconnect
* Handle USB Host disconnection event
* @param phost: Host Handle
* @retval USBH_Status
*/
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 = 0;

if(phost->pUser != NULL)
{
phost->pUser(phost, HOST_USER_DISCONNECTION);
}
USBH_UsrLog("USB Device disconnected");

/* Start the low level driver */
USBH_LL_Start(phost);

phost->gState = HOST_DEV_DISCONNECTED;

#if (USBH_USE_OS == 1)
osMessagePut ( phost->os_event, USBH_PORT_EVENT, 0);
#endif

return USBH_OK;
}
看它的意思是,usb未连接...那么我们是不是就可以写一个提示到显示器上啊?

case HOST_USER_DISCONNECTION: 
Appli_state = APPLICATION_DISCONNECT; 
//输出到显示器上:usb未连接
break;
 
/* Following states are used for gState */
typedef enum
{
HOST_IDLE =0,
HOST_DEV_WAIT_FOR_ATTACHMENT,
HOST_DEV_ATTACHED,
HOST_DEV_DISCONNECTED,
HOST_DETECT_DEVICE_SPEED,
HOST_ENUMERATION,
HOST_CLASS_REQUEST,
HOST_INPUT,
HOST_SET_CONFIGURATION,
HOST_CHECK_CLASS,
HOST_CLASS,
HOST_SUSPENDED,
HOST_ABORT_STATE,
}HOST_StateTypeDef;
底层处理过程,从上到下
明显:
空闲状态
驱动等待连接状态
驱动连接上状态
未连接状态
检测驱动速度状态
枚举状态
类请求状态
IN状态状态
设置配置状态
检查类状态
写类
暂停
中止
 
 
 
 

admin

赞同来自:

QQ图片20160725230801.png


QQ图片20160725230858.png

 

血染风采

赞同来自:

STM32CubeIDE配置USB Host,裸机情况下,可以正常识别U盘;使用了FreeRTOS之后,识别不了U盘了,到不了Ready的状态,只能到达Start。STM32CubeMX+MDK5:裸机和FreeRTOS都可以识别U盘。

不知道STM32CubeIDE还需要设置什么?


要回复问题请先登录注册