在usbh_core.c中有一个函数USBH_Process(),这个函数很重要,main()函数每循环一次,它就执行一次,

它处理所有USB内核状态的变化,

typedef enum { 

HOST_IDLE =0, 

HOST_DEV_ATTACHED, 

HOST_DEV_DISCONNECTED,  

HOST_DETECT_DEVICE_SPEED, 

HOST_ENUMERATION, 

HOST_CLASS_REQUEST,  

HOST_CLASS, 

HOST_CTRL_XFER, 

HOST_USR_INPUT, 

HOST_SUSPENDED, 

HOST_ERROR_STATE  

}HOST_State;


根据这个当前状态(phost->gState)处于以上哪个状态的不同,做出不同的处理过程。其中最重要的要属这两个状态:HOST_ENUMERATION,,HOST_CLASS。
HOST_ENUMERATION状态,不言而喻,这就是大名鼎鼎的枚举状态,经过空闲,连接状态后面就要对设备进行枚举了,枚举过程其实也是对状态机的处理过程,用

的是这个USBH_HandleEnum(pdev , phost)函数,也在在usbh_core.c中,因为枚举过程也是USB过程的核心过程。枚举过程根据时间先后顺序依次经过 

typedef enum { 

ENUM_IDLE = 0, 

ENUM_GET_FULL_DEV_DESC, 

ENUM_SET_ADDR, 

ENUM_GET_CFG_DESC, 

ENUM_GET_FULL_CFG_DESC, 

ENUM_GET_MFC_STRING_DESC, 

ENUM_GET_PRODUCT_STRING_DESC, 

ENUM_GET_SERIALNUM_STRING_DESC, 

ENUM_SET_CONFIGURATION, 

ENUM_DEV_CONFIGURED 

} ENUM_State;


以上几个过程,如果都得到正确的处理,且返回值也为OK的话,枚举过程结束,此时已经获得了USB设备的基本信息。比如:设备描述符,配置描述符等等。下一

步就该加载设备驱动了,根据枚举过程获得到的设备类型和ID号,比如大容量存储设备,HID,VIDIO等,选择不同的设备驱动加载,并初始化。这一步是在USBH_Process()处

理函数在的HOST_USR_INPUT状态下执行的。正确执行后进入下一个状态HOST_CLASS_REQUEST,
在这个HOST_CLASS_REQUEST状态,主要是初始化设备驱动类的状态机(host class state machine),为一步做准备。
下面就到了另一个重要的处理函数,status = phost->class_cb->Machine(pdev, phost);其实这个函数最终会调用USBH_MSC_Handle(),这个函数在

usbh_msc_core.c中,usbh_msc_core.c顾名思义,这就是USB主机端mass storage类的驱动程序,核心文件,
USBH_MSC_Handle()函数根据当前所处的状态,作出相应的处理。

typedef enum 

{ 

USBH_MSC_BOT_INIT_STATE = 0,  

USBH_MSC_BOT_RESET,  

USBH_MSC_GET_MAX_LUN,  

USBH_MSC_TEST_UNIT_READY,  

USBH_MSC_READ_CAPACITY10, 

USBH_MSC_MODE_SENSE6, 

USBH_MSC_REQUEST_SENSE,  

USBH_MSC_BOT_USB_TRANSFERS,  

USBH_MSC_DEFAULT_APPLI_STATE,  

USBH_MSC_CTRL_ERROR_STATE, 

USBH_MSC_UNRECOVERED_STATE 

}

MSCState; 

USBH_MSC_DEFAULT_APPLI_STATE, 这个状态就是我们编写的应用程序将要执行的状态。最为不爽的是,连STM提供的上层应用程序也是按状态机的方式编写的。 

USBH_USR_MSC_Application(),就是STM提供的应用程序,在usbh_usr.c中,分为4个状态: 

#define USH_USR_FS_INIT 0 

#define USH_USR_FS_READLIST 1 

#define USH_USR_FS_WRITEFILE 2 

#define USH_USR_FS_DRAW 3


如果我要编写我自己的应用程序的话,应该就是修改这个函数吧,