STM32 usb_prop.c文件分析與usb_core.h一些數(shù)據(jù)定義分析
掃描二維碼
隨時(shí)隨地手機(jī)看文章
usb_prop.c文件可以說(shuō)是一個(gè)蠻重要的文件,因?yàn)閁SB的許多處理函數(shù)都在這里定義。在無(wú)論是在USB的建立階段、數(shù)據(jù)階段還是狀態(tài)階段的一些處理都在這個(gè)文件,USB標(biāo)準(zhǔn)函數(shù)請(qǐng)求的函數(shù)也在這個(gè)文件里。
usb_prop.c一開(kāi)始就是一連串的結(jié)構(gòu)體,如下:
DEVICE Device_Table =
{
EP_NUM, //被使用的端點(diǎn)數(shù)
1 //可以使用的端點(diǎn)數(shù)
};
DEVICE_PROP Device_Property =//注冊(cè)一些CustomHID函數(shù)
{
CustomHID_init,//CustomHID的初始化函數(shù)
CustomHID_Reset,//CustomHID的復(fù)位函數(shù)
CustomHID_Status_In,//CustomHID狀態(tài)輸入函數(shù)
CustomHID_Status_Out,//CustomHID狀態(tài)輸出函數(shù)
CustomHID_Data_Setup,//CustomHID的處理有數(shù)據(jù)階段的特殊類(lèi)請(qǐng)求函數(shù)
CustomHID_NoData_Setup,//CustomHID的處理沒(méi)有數(shù)據(jù)階段特殊類(lèi)請(qǐng)求函數(shù)
CustomHID_Get_Interface_Setting,//CustomHID獲取接口及備用接口設(shè)置(是否可用)
CustomHID_GetDeviceDescriptor,//CustomHID獲取設(shè)備描述符
CustomHID_GetConfigDescriptor,//CustomHID獲取配置描述符
CustomHID_GetStringDescriptor,//CustomHID獲取字符串描述符
0,//當(dāng)前庫(kù)未使用
0x40 /*MAX PACKET SIZE*/ //最大的包長(zhǎng)度為64字節(jié)
};
/*注冊(cè)USB標(biāo)準(zhǔn)請(qǐng)求的實(shí)現(xiàn)函數(shù)*/
USER_STANDARD_REQUESTS User_Standard_Requests =
{
CustomHID_GetConfiguration,//獲取配置請(qǐng)求
CustomHID_SetConfiguration,//設(shè)置配置請(qǐng)求
CustomHID_GetInterface,//獲取接口請(qǐng)求
CustomHID_SetInterface,//設(shè)置接口請(qǐng)求
CustomHID_GetStatus,//獲取狀態(tài)請(qǐng)求
CustomHID_ClearFeature,//清除屬性請(qǐng)求
CustomHID_SetEndPointFeature,//設(shè)置端點(diǎn)屬性請(qǐng)求
CustomHID_SetDeviceFeature,//設(shè)置設(shè)備屬性請(qǐng)求
CustomHID_SetDeviceAddress//設(shè)置設(shè)備地址請(qǐng)求
};
/*注冊(cè)設(shè)備描述符信息*/
ONE_DESCRIPTOR Device_Descriptor =
{
(uint8_t*)CustomHID_DeviceDescriptor, //注冊(cè)設(shè)備描述符數(shù)組
CUSTOMHID_SIZ_DEVICE_DESC //設(shè)備描述符的長(zhǎng)度
};
/*注冊(cè)設(shè)備描述符信息*/
ONE_DESCRIPTOR Config_Descriptor =
{
(uint8_t*)CustomHID_ConfigDescriptor, //注冊(cè)配置描述符數(shù)組
CUSTOMHID_SIZ_CONFIG_DESC //配置描述符的長(zhǎng)度
};
/*注冊(cè)報(bào)告描述符信息*/
ONE_DESCRIPTOR CustomHID_Report_Descriptor =
{
(uint8_t *)CustomHID_ReportDescriptor, //注冊(cè)報(bào)告描述符數(shù)組
CUSTOMHID_SIZ_REPORT_DESC //報(bào)告描述符的長(zhǎng)度
};
/*注冊(cè)HID描述符信息*/
ONE_DESCRIPTOR CustomHID_Descriptor =
{
(uint8_t*)CustomHID_ConfigDescriptor + CUSTOMHID_OFF_HID_DESC, //注冊(cè)HID描述符數(shù)組
CUSTOMHID_SIZ_HID_DESC //HID數(shù)組的長(zhǎng)度
};
/*注冊(cè)字符串描述符,包括語(yǔ)言ID、廠商、產(chǎn)品、序列號(hào)描述符*/
ONE_DESCRIPTOR String_Descriptor[4] =
{
{(uint8_t*)CustomHID_StringLangID, CUSTOMHID_SIZ_STRING_LANGID},//注冊(cè)語(yǔ)言字符串描述符數(shù)組
{(uint8_t*)CustomHID_StringVendor, CUSTOMHID_SIZ_STRING_VENDOR},//注冊(cè)廠商字符串描述符數(shù)組
{(uint8_t*)CustomHID_StringProduct, CUSTOMHID_SIZ_STRING_PRODUCT},//注冊(cè)產(chǎn)品字符串描述符數(shù)組
{(uint8_t*)CustomHID_StringSerial, CUSTOMHID_SIZ_STRING_SERIAL}//注冊(cè)序列號(hào)字符串描述符數(shù)組
};
應(yīng)該看了很明白,這一系列的結(jié)構(gòu)體就是注冊(cè)一些處理函數(shù)。我們一個(gè)個(gè)分析。
先來(lái)說(shuō)下 DEVICE Device_Table這個(gè)結(jié)構(gòu)體,DEVICE這個(gè)結(jié)構(gòu)體類(lèi)型在usb_core.h中定義:
typedef struct _DEVICE
{
uint8_t Total_Endpoint; /*被使用的端點(diǎn)數(shù)*/
uint8_t Total_Configuration;/*還可以用的端點(diǎn)數(shù)*/
}
DEVICE;
這個(gè)結(jié)構(gòu)體類(lèi)型很簡(jiǎn)單,在結(jié)構(gòu)體中定義了已經(jīng)被使用的端點(diǎn)和沒(méi)有被使用的端點(diǎn),把他們兩個(gè)放在一起方便查詢(xún)和管理。
接下去的說(shuō)說(shuō)DEVICE_PROP
Device_Property 這個(gè)類(lèi)型的結(jié)構(gòu)體。這個(gè)結(jié)構(gòu)體的前10個(gè)元素都是函數(shù)指針類(lèi)型的,把一些常用的函數(shù)放在這里,而函數(shù)定義都在該結(jié)構(gòu)體之后定義,有沒(méi)有覺(jué)得像是語(yǔ)文中的關(guān)鍵句,把整個(gè)文件的概要全部濃縮在這個(gè)結(jié)構(gòu)體中了,只要看這個(gè)結(jié)構(gòu)體就可以把整個(gè)文件做什么了解個(gè)七七八八了。這樣的結(jié)構(gòu)使用起來(lái)也非常方便,比如說(shuō)我想要使用CustomHID_init函數(shù),只要寫(xiě)Device_Property.CustomHID_init不就可以了。我們必須學(xué)會(huì)這種方法。
DEVICE_PROP這個(gè)結(jié)構(gòu)體類(lèi)型還是在usb_core.h中定義:
typedef struct _DEVICE_PROP
{
void (*Init)(void); /*初始化設(shè)備*/
void (*Reset)(void); /*復(fù)位該設(shè)備*/
/*在控制傳輸中分三個(gè)過(guò)程:1.建立過(guò)程,2、可選的數(shù)據(jù)過(guò)程,3、狀態(tài)過(guò)程*/
/* Device dependent process after the status stage */
void (*Process_Status_IN)(void);/*狀態(tài)過(guò)程中,處理IN令牌包*/
void (*Process_Status_OUT)(void);/*狀態(tài)過(guò)程中,處理OUT令牌包*/
/*在建立階段的過(guò)程中,會(huì)有很多特殊類(lèi)請(qǐng)求的數(shù)據(jù)階段stage */
/*所有在數(shù)據(jù)階段的特殊類(lèi)請(qǐng)求都在Class_Data_Setup()函數(shù)中處理
Class_Data_Setup() 會(huì)響應(yīng)去檢查所有的特殊類(lèi)請(qǐng)求,同時(shí)根據(jù)請(qǐng)求填充ENDPOINT_INFO結(jié)構(gòu)信息
如果IN令牌包是期望的令牌包,則wLength和wOffset兩個(gè)域會(huì)分別被填充成要發(fā)送的總字節(jié)數(shù)和要開(kāi)始傳輸?shù)奈恢?/p>
如果OUT令牌包是期盼的令牌包,則rLength和rOffser將會(huì)分別被填充成要接收的總字節(jié)數(shù)和要接收數(shù)據(jù)的緩沖區(qū)起始地址
如果請(qǐng)求有效,Class_Data_Setup返回SUCCESS,否則返回UNSUPPORT
注意:
因?yàn)镚ET_CONFIGURATION和GET_INTERFACE兩個(gè)請(qǐng)求跟個(gè)別的類(lèi)聯(lián)系密切,所以他們會(huì)在該函數(shù)中檢查和處理*/
RESULT (*Class_Data_Setup)(uint8_t RequestNo);
/*在建立過(guò)程中,會(huì)有很多特殊類(lèi)請(qǐng)求的無(wú)數(shù)據(jù)階段*/
/*所有的沒(méi)有數(shù)據(jù)階段的特殊請(qǐng)求都在Class_NoData_Setup這個(gè)函數(shù)中處理
Class_NoData_Setup()
會(huì)響應(yīng)去檢查所有特殊類(lèi)請(qǐng)求,并且執(zhí)行請(qǐng)求
注意:
因?yàn)镾ET_CONFIGURATION和SET_INTERFACE這兩個(gè)請(qǐng)求跟個(gè)別的類(lèi)聯(lián)系密切,他們都會(huì)在該函數(shù)中被檢查和處理*/
RESULT (*Class_NoData_Setup)(uint8_t RequestNo);
/*Class_Get_Interface_Setting()
這個(gè)函數(shù)時(shí)在usb_core.c文件中被調(diào)用來(lái)測(cè)試應(yīng)用程序是否支持被選中的接口和備用接口
這個(gè)函數(shù)時(shí)由用戶(hù)寫(xiě)的。如果應(yīng)用程序支持接口和備用接口,則必須返回"SUCCESS",否則,返回"UNSUPPORT"*/
RESULT (*Class_Get_Interface_Setting)(uint8_t Interface, uint8_t AlternateSetting);
uint8_t* (*GetDeviceDescriptor)(uint16_t Length);
uint8_t* (*GetConfigDescriptor)(uint16_t Length);
uint8_t* (*GetStringDescriptor)(uint16_t Length);
/* 這個(gè)字段不是用于當(dāng)前庫(kù)版本。它是只保持兼容以前的版本*/
void* RxEP_buffer;
uint8_t MaxPacketSize;
}DEVICE_PROP;
接下去是USER_STANDARD_REQUESTS User_Standard_Requests這個(gè)結(jié)構(gòu)體,在這個(gè)結(jié)構(gòu)體中主要注冊(cè)了USB標(biāo)準(zhǔn)請(qǐng)求的實(shí)現(xiàn)函數(shù),當(dāng)然這些函數(shù)也實(shí)在該結(jié)構(gòu)體后面定義的。跟上面的DEVICE_PROP
Device_Property結(jié)構(gòu)體類(lèi)似,就不多講了。
USER_STANDARD_REQUESTS 結(jié)構(gòu)體也是在usb_core.h中定義:
typedef struct _USER_STANDARD_REQUESTS
{
void (*User_GetConfiguration)(void); /*獲取配置*/
void (*User_SetConfiguration)(void); /*設(shè)置配置*/
void (*User_GetInterface)(void); /*獲取接口*/
void (*User_SetInterface)(void); /*設(shè)置接口*/
void (*User_GetStatus)(void); /*獲取狀態(tài)*/
void (*User_ClearFeature)(void); /*清除特性*/
void (*User_SetEndPointFeature)(void); /*設(shè)置端點(diǎn)特性*/
void (*User_SetDeviceFeature)(void); /*設(shè)置設(shè)備特性*/
void (*User_SetDeviceAddress)(void); /*設(shè)置設(shè)備地址*/
}
USER_STANDARD_REQUESTS;
像ONE_DESCRIPTOR Device_Descriptor、ONE_DESCRIPTOR Config_Descriptor、ONE_DESCRIPTOR CustomHID_Report_Descriptor、ONE_DESCRIPTOR CustomHID_Descriptor、ONE_DESCRIPTOR String_Descriptor[4]這些結(jié)構(gòu)體都不仔細(xì)講了。貼出各個(gè)結(jié)構(gòu)體的定義,依舊在usb_core.h中:
typedef struct OneDescriptor
{
uint8_t *Descriptor;
uint16_t Descriptor_Size;
}
ONE_DESCRIPTOR, *PONE_DESCRIPTOR;
接下去上面各個(gè)結(jié)構(gòu)體注冊(cè)的函數(shù)貼出來(lái):
/*******************************************************************************
* Function Name : CustomHID_init.
* Description : CustomHID Mouse init routine.初始化
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void CustomHID_init(void)
{
/* Update the serial number string descriptor with the data from the unique
ID*/
Get_SerialNum();//獲取序列號(hào)
pInformation->Current_Configuration = 0;
/* Connect the device */
PowerOn();//上電
/* Perform basic device initialization operations */
USB_SIL_Init();//執(zhí)行基本的初始化操作,比如說(shuō)設(shè)備IP和端點(diǎn)0的初始化
bDeviceState =