主機(jī)環(huán)境:Windows 7 SP1
開(kāi)發(fā)環(huán)境:MDK5.14
目標(biāo)板:STM32F103C8T6
開(kāi)發(fā)庫(kù):STM32F1Cube庫(kù)和STM32_USB_Device_Library
現(xiàn)在來(lái)分析哈USB器件庫(kù)代碼,先來(lái)看usbd_core文件,其頭文件只有一些函數(shù)聲明,沒(méi)啥可說(shuō)的,只有一點(diǎn),之前分析usbd_conf.c文件時(shí)里面USB中斷回調(diào)函數(shù)中調(diào)用的底層接口都是在usbd_core.h文件中聲明的,同樣由用戶實(shí)現(xiàn)的底層接口也是在該文件中聲明的,在usbd_core.c文件中實(shí)現(xiàn),該文件是很重要的一個(gè)文件,因?yàn)樗猩蠈硬僮髯罱K都會(huì)調(diào)用該文件中的API來(lái)實(shí)現(xiàn)。在器件庫(kù)文檔中提到了核心庫(kù)的作用,如下:
第一個(gè)分析的函數(shù)是USB棧的初始化以及重新初始化,如下:
/**
* @brief USBD_Init
* Initializes the device stack and load the class driver
* @param pdev: device instance
* @param pdesc: Descriptor structure address
* @param id: Low level core index
* @retval None
*/
USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, USBD_DescriptorsTypeDef *pdesc, uint8_t id)
{
/* Check whether the USB Host handle is valid */
if(pdev == NULL)
{
USBD_ErrLog("Invalid Device handle");
return USBD_FAIL;
}
/* Unlink previous class*/
if(pdev->pClass != NULL)
{
pdev->pClass = NULL;
}
/* Assign USBD Descriptors */
if(pdesc != NULL)
{
pdev->pDesc = pdesc;
}
/* Set Device initial State */
pdev->dev_state = USBD_STATE_DEFAULT;
pdev->id = id;
/* Initialize low level driver */
USBD_LL_Init(pdev);
return USBD_OK;
}
/**
* @brief USBD_DeInit
* Re-Initialize th device library
* @param pdev: device instance
* @retval status: status
*/
USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev)
{
/* Set Default State */
pdev->dev_state = USBD_STATE_DEFAULT;
/* Free Class Resources */
pdev->pClass->DeInit(pdev, pdev->dev_config);
/* Stop the low level driver */
USBD_LL_Stop(pdev);
/* Initialize low level driver */
USBD_LL_DeInit(pdev);
return USBD_OK;
}
USB初始化函數(shù)很簡(jiǎn)單,將USB句柄的設(shè)備類指針置NULL,同時(shí)將USB的描述符加載上去,將USB設(shè)備狀態(tài)置為默認(rèn)狀態(tài),該函數(shù)里面的id目前不清楚是作何用,最后調(diào)用USB_LL_Init()函數(shù)來(lái)初始化底層驅(qū)動(dòng)。USB器件庫(kù)中USB設(shè)備有四種狀態(tài),定義在usbd_def.h文件中,如下:
/* Device Status */
#define USBD_STATE_DEFAULT 1
#define USBD_STATE_ADDRESSED 2
#define USBD_STATE_CONFIGURED 3
#define USBD_STATE_SUSPENDED 4
默認(rèn)狀態(tài)、地址狀態(tài)、配置狀態(tài)、掛起狀態(tài)。在USB2.0協(xié)議文檔的第9章節(jié)中規(guī)定了USB設(shè)備的6種狀態(tài):連接狀態(tài)、上電狀態(tài)、默認(rèn)狀態(tài)、地址狀態(tài)、配置狀態(tài)、掛起狀態(tài),六者之間的關(guān)系圖如下所示:
在USB庫(kù)中是省略了連接和上電兩個(gè)狀態(tài),剩下四種狀態(tài)的說(shuō)明可以在USB2.0協(xié)議的第九章節(jié)找到,由此可以看出USB2.0協(xié)議中第九章節(jié)有多重要了。在USB分配地址之前其使用默認(rèn)地址,處在默認(rèn)狀態(tài)下的USB設(shè)備不能響應(yīng)正常的請(qǐng)求,當(dāng)USB設(shè)備分配了唯一的地址后即進(jìn)入地址狀態(tài),響應(yīng)正常請(qǐng)求,USB設(shè)備配置完成后進(jìn)入配置狀態(tài),USB設(shè)備在指定時(shí)間長(zhǎng)度內(nèi)沒(méi)有檢測(cè)到總線通信時(shí)會(huì)進(jìn)入掛起狀態(tài),但會(huì)保持任何內(nèi)部狀態(tài),包括地址和配置。在USB重新初始化函數(shù)中,需要釋放類資源,且停止USB底層驅(qū)動(dòng),重新初始化底層驅(qū)動(dòng)。接著是注冊(cè)類函數(shù):
/**
* @brief USBD_RegisterClass
* Link class driver to Device Core.
* @param pDevice : Device Handle
* @param pclass: Class handle
* @retval USBD Status
*/
USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass)
{
USBD_StatusTypeDef status = USBD_OK;
if(pclass != 0)
{
/* link the class to the USB Device handle */
pdev->pClass = pclass;
status = USBD_OK;
}
else
{
USBD_ErrLog("Invalid Class handle");
status = USBD_FAIL;
}
return status;
}
注冊(cè)設(shè)備類函數(shù)也很簡(jiǎn)單,把設(shè)備類指針傳遞給USB設(shè)備句柄即可,通過(guò)指針USB句柄包含了我們所用的所有資源,接著來(lái)看USB的一些基本操作,如下:
/**
* @brief USBD_Start
* Start the USB Device Core.
* @param pdev: Device Handle
* @retval USBD Status
*/
USBD_StatusTypeDef USBD_Start (USBD_HandleTypeDef *pdev)
{
/* Start the low level driver */
USBD_LL_Start(pdev);
return USBD_OK;
}
/**
* @brief USBD_Stop
* Stop the USB Device Core.
* @param pdev: Device Handle
* @retval USBD Status
*/
USBD_StatusTypeDef USBD_Stop (USBD_HandleTypeDef *pdev)
{
/* Free Class Resources */
pdev->pClass->DeInit(pdev, pdev->dev_config);
/* Stop the low level driver */
USBD_LL_Stop(pdev);
return USBD_OK;
}
/**
* @brief USBD_RunTestMode
* Launch test mode process
* @param pdev: device instance
* @retval status
*/
USBD_StatusTypeDef USBD_RunTestMode (USBD_HandleTypeDef *pdev)
{
return USBD_OK;
}
/**
* @brief USBD_SetClassConfig
* Configure device and start the interface
* @param pdev: device instance
* @param cfgidx: configuration index
* @retval status
*/
USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{
USBD_StatusTypeDef ret = USBD_FAIL;
if(pdev->pClass != NULL)
{
/* Set configuration and Start the Class*/
if(pdev->pClass->Init(pdev, cfgidx) == 0)
{
ret = USBD_OK;
}
}
return ret;
}
/**
* @brief USBD_ClrClassConfig
* Clear current configuration
* @param pdev: device instance
* @param cfgidx: configuration index
* @retval status: USBD_StatusTypeDef
*/
USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{
/* Clear configuration and De-initialize the Class process*/
pdev->pClass->DeInit(pdev, cfgidx);
return USBD_OK;
}
/**
* @brief USBD_LL_Reset
* Handle Reset event
* @param pdev: device instance
* @retval status
*/
USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev, USBD_SpeedTypeDef speed)
{
pdev->dev_speed = speed;
return USBD_OK;
}
其中USBD_Start和USBD_Stop跟USBD的初始化類似都是調(diào)用usbd_conf中的底層基本操作,USBD_RunTestMode()函數(shù)為空,表明不支持測(cè)試模式,測(cè)試模式在USB2.0協(xié)議文檔有提及,既然這里不支持就么有去細(xì)研究該功能。另外兩個(gè)函數(shù)USBD_SetClassConfig()、USBD_ClrClassConfig()函數(shù)則是跟USB設(shè)備類相關(guān),這里我們還沒(méi)有分析到USB設(shè)備類中,所以也略過(guò),知道其功能即可。最后有一個(gè)USBD_LL_SetSpeed()函數(shù),USB通信有三種通信速度:低速、全速、高速,STM32F103C8T6支持全速模式,USB速度的定義如下:
/* Following USB Device Speed */
typedef enum
{
USBD_SPEED_HIGH = 0,
USBD_SPEED_FULL = 1,
USBD_SPEED_LOW = 2,
}USBD_SpeedTypeDef;
usbd_core.c中剩下的一些函數(shù)體則是在usbd_conf.cUSB中斷回調(diào)函數(shù)中調(diào)用的USB通信處理的真正實(shí)現(xiàn)者,如下:
/**
* @brief USBD_SetupStage
* Handle the setup stage
* @param pdev: device instance
* @retval status
*/
USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup)
{
USBD_ParseSetupRequest(&pdev->request, psetup);
pdev->ep0_state = USBD_EP0_SETUP;
pdev->ep0_data_len = pdev->request.wLength;
switch (pdev->request.bmRequest & 0x1F)
{
case USB_REQ_RECIPIENT_DEVICE:
USBD_StdDevReq (pdev, &pdev->request);
break;
case USB_REQ_RECIPIENT_INTERFACE:
USBD_StdItfReq(pdev, &pdev->request);
break;
case USB_REQ_RECIPIENT_ENDPOINT:
USBD_StdEPReq(pdev, &pdev->request);
break;
default:
USBD_LL_StallEP(pdev , pdev->request.bmRequest & 0x80);
break;
}
return USBD_OK;
}
/**
* @brief USBD_DataOutStage
* Handle data OUT stage
* @param pdev: device instance
* @param epnum: endpoint index
* @retval status
*/
USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev , uint8_t epnum, uint8_t *pdata)
{
USBD_EndpointTypeDef *pep;
if(epnum == 0)
{
pep = &pdev->ep_out[0];
if ( pdev->ep0_state == USBD_EP0_DATA_OUT)
{
if(pep->rem_length > pep->maxpacket)
{
pep->rem_length -= pep->maxpacket;
USBD_CtlContinueRx (pdev,
pdata,
MIN(pep->rem_length ,pep->maxpacket));
}
else
{
if((pdev->pClass->EP0_RxReady != NULL)&&
(pdev->dev_state == USBD_STATE_CONFIGURED))
{
pdev->pClass->EP0_RxReady(pdev);
}
USBD_CtlSendStatus(pdev);
}
}
}
else if((pdev->pClass->DataOut != NULL)&&
(pdev->dev_state == USBD_STATE_CONFIGURED))
{
pdev->pClass->DataOut(pdev, epnum);
}
return USBD_OK;
}
/**
* @brief USBD_DataInStage
* Handle data in stage
上一篇:STM32 USB學(xué)習(xí)筆記7
下一篇:STM32 USB學(xué)習(xí)筆記5
推薦閱讀
史海拾趣
設(shè)計(jì)資源 培訓(xùn) 開(kāi)發(fā)板 精華推薦
- Microchip 升級(jí)數(shù)字信號(hào)控制器(DSC)產(chǎn)品線 推出PWM 分辨率和 ADC 速度業(yè)界領(lǐng)先的新器件
- 意法半導(dǎo)體STM32MP23x:突破成本限制的工業(yè)AI應(yīng)用核心
- 意法半導(dǎo)體推出用于匹配遠(yuǎn)距離無(wú)線微控制器STM32WL33的集成的匹配濾波芯片
- ESP32開(kāi)發(fā)板連接TFT顯示屏ST7789跳坑記
- 如何讓ESP32支持analogWrite函數(shù)
- LGVL配合FreeType為可變字體設(shè)置字重-ESP32篇
- 使用樹(shù)莓派進(jìn)行 ESP32 Jtag 調(diào)試
- ESP32怎么在SPIFFS里面存儲(chǔ)html,css,js文件,以及網(wǎng)頁(yè)和arduino的通訊
- ESP32 freeRTOS使用測(cè)試
- ARXML 規(guī)則下 ECU 總線通訊與 ADTF 測(cè)試方案
- 日產(chǎn)在歐洲推出第三代e-POWER技術(shù)
- 福特CEO更看好Waymo激光雷達(dá)方案:比特斯拉純視覺(jué)自動(dòng)駕駛路線可靠
- 智元機(jī)器人兩大核心產(chǎn)品啟動(dòng)規(guī)?;a(chǎn)
- 固態(tài)電池2026量產(chǎn)豪賭,真相還是泡沫?
- 100億元!湖北“下注”人形機(jī)器人產(chǎn)業(yè)
- 海外磷酸鐵鋰電池產(chǎn)能從0到1
- 基于多傳感器數(shù)據(jù)的自動(dòng)駕駛仿真確定性驗(yàn)證
- 國(guó)芯科技發(fā)布全球首款48V安全氣囊芯片,引領(lǐng)智能汽車新紀(jì)元
- 亞馬遜全球部署100萬(wàn)臺(tái)機(jī)器人
- 國(guó)產(chǎn)芯5月:曬一曬,初露鋒芒的國(guó)產(chǎn)車規(guī)芯片你知多少?
- 模擬世界的最重要構(gòu)成——信號(hào)鏈與電源
- 【贈(zèng)書(shū)100%有禮】一本書(shū)教你如何開(kāi)發(fā)測(cè)試系統(tǒng),深入了解數(shù)據(jù)采集系統(tǒng)
- 聊聊DSP的那些事兒
- 答題有禮|一起學(xué)習(xí) Mentor PCB 手冊(cè)
- TI嵌入式直播月:深入探究嵌入式產(chǎn)品在工業(yè)和汽車中的新應(yīng)用
- 春暖花開(kāi),我為T(mén)I C2000 LaunchPad“畫(huà)”外圍!
- 有獎(jiǎng)直播|瑞薩電子 Arm MCU 的新能源進(jìn)擊:RA6T2
- 有獎(jiǎng)直播 | 瑞薩新一代視覺(jué) AI MPU 處理器 RZ/V2H:高算力、低功耗、實(shí)時(shí)控制