衡阳派盒市场营销有限公司

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

如何讓CDC類USB設備批量接收64字節以上數據

茶話MCU ? 來源:茶話MCU ? 作者:茶話MCU ? 2022-10-31 10:54 ? 次閱讀

很多STM32開發者在實現CDC類虛擬串口與PC主機通信過程中,有時會遇到點麻煩而不得其解。那就是當主機端單次發送的數據不超過64字節時,接收正常。一旦發送數據量大于64字節時就接收失敗,總是出現丟包現象,似乎只能接收64字節以內的數據。網上有人干脆建議主機每次發送不要超過64字節,當然,也有人提及要作分包處理但沒具體實現代碼可以參考。

2af41bee-572c-11ed-a3b6-dac502259ad0.png

作為CDC類的USB設備,到底能不能正確接收來自主機64字節以上的批量數據呢?

其實是可以的,只是當我們一次傳輸的數據大于當前端點所支持的最大包長時【這里端點使用BULK傳輸,一般最大包長默認設置為64字節】,USB模塊會做分包傳輸,將一批數據傳輸分成多個處理[或稱事務],即多個transaction來完成,每個Transaction里的數據包傳輸的最大數據量為64字節。

2b16214e-572c-11ed-a3b6-dac502259ad0.png

原理性的東西,這里不多啰嗦了,網上有成堆的介紹資料【當然,或許有點亂】。當我們弄清整個原理后,就可以自行組織接收處理代碼了。下面我利用HAL庫,基于STM32F429芯片演示實現過程,重點在接收處理代碼。我使用STM32F429Discovery開發板,使用HSUSB模塊并令其工作在FSMODE,這樣我們就可以方便地使用片內USBFS PHY。

2b888d4c-572c-11ed-a3b6-dac502259ad0.png

我使用STM32CubeMx工具進行配置,生成基于STM32 HAL庫的工程。使用ST提供的STM32CubeIDE進行編譯調試。有關配置就不截圖了。

另外,我還配置了1個按鍵并開啟相應外部中斷。每發生按鍵事件時,F429USB設備向PC主機發送一段打招呼的字符串,并通過串口助手顯示出來。如下圖所示:

2bcd1674-572c-11ed-a3b6-dac502259ad0.png

我在main.c文件里額外定義了下面幾個變量:

2bfc75f4-572c-11ed-a3b6-dac502259ad0.png

其中,Flag_KeyPressed和Flag_DataReceived分別表示按鍵操作和收到從主機發過來的數據的情況。Rx_buffer【】數組用來存放接收來自主機的全部數據,這里的定義長度為512字節【你具體使用時按需設置】。下圖是Main.c里的主循環代碼截圖:

2c18ee14-572c-11ed-a3b6-dac502259ad0.png

主循環里檢查按鍵標志和收到數據的標志,如有按鍵發生,則向主機發送前面提到的打招呼的字符串;如有收到來自主機的數據,則向主機回送過去。

今天的重點是討論USB設備如何從主機接收64字節以上的數據。基于現有HAL庫,對于USB設備的接收,我們只需關注一個USB中斷接收回調函數,那就是CDC_Receive_HS()函數。該函數在usbd_cdc_if.c文件里。我具體編寫的函數代碼如下面兩幅截圖所示。

2c40952c-572c-11ed-a3b6-dac502259ad0.png

2c7e56e6-572c-11ed-a3b6-dac502259ad0.png

代碼很簡單。 我在庫代碼的基礎上增加了橙色方框內的代碼。基本功能就是,先讀取當前收到的數據長度【SinglePackLength】,分整包和非整包兩種情況鑒別后再處理。若是接收的整包數據,繼續等待接收下一包;若是非整包,視為此次傳輸結束,并設置收到標志Flag_DataReceived為非0值,然后在主循環里將收到的數據回送給主機。

其中,Max_Pack_Size是當前CDC類BULK傳輸端點的最大傳輸包長,這里為64字節。

Num_Rx_Data表示接收到數據個數,Num_Out_Pack表示接收到的數據包個數,Num_Packet跟Num_Out_Pack內容一樣,不過,Num_Packet等于0還表示準備開始新一輪傳輸的接收。這里多定義Num_Out_Pack,一個重要目的是便于調試時查看結果。

基于上面的接收處理代碼,我們來驗證結果:

2cdbacb0-572c-11ed-a3b6-dac502259ad0.png

借助PC端的串口助手向STM32F429 USB設備發送了5個字符,我們通過STM32CubeIDE調試環境可以清晰地從上圖看到設備收到的數據個數為5,數據包個數為1。顯然沒問題。那個Rx_buffer數組是我用來存放接收數據的,若在調試窗口打開,數據較多列表顯示會很長,這里就沒打開了。事實上接收的數據內容也是沒問題的。

下圖是借助PC端的串口助手向STM32F429 USB設備發送了305個字符的接收情況:

2cfe83b6-572c-11ed-a3b6-dac502259ad0.png

顯然,對于305個字符,PC主機端要分成5包才能發送完畢,即4整包【每包64字節】再加1個非完整包。所以USB設備接收結果也正好是5包,即上圖中Num_Out_pack的數據,接收到的數據量為305,即上圖中Num_Rx_Data的數據。同樣,結果OK。

下圖是PC端剛好發送一個完整包64字節數據的USB設備接收情況,也一切正常。

2d42e57e-572c-11ed-a3b6-dac502259ad0.png

也就是說,使用我上面編寫的接收處理代碼,對主機發送的數據的個數不再局限于64字節以內了。當然,具體應用時我們還可以根據主機端單次傳輸數據的大小情況及提取數據的方式適當調整這里的Rx_buffer[]數組大小。【注:上面測試時我臨時關閉了設備端的數據回送功能,是為了避免截圖里的數據混亂,讓人分不清原數據和回顯數據】

有人可能在上面的接收代碼里看到了一個變量Wait_Rx_Dly。剛開始,代碼里是沒有這個變量的。后來我在測試主機發送64字節整包數據時,發現了一個小問題【最終到底算不算問題,或許要視具體應用場景而定,我這里稍作了點處理】。

問題是這樣的:

主機每發送1包64字節數據時,設備端接收沒有問題,但只要主機端每次發送64字節完整數據包過來,不論相隔時間多久,設備端依然接收,且總在前次結果上累加,除非主機端發一個非64字節數據包過來,設備接收就總是視為同一次傳輸。比方像下面截圖所示:

2d76b58e-572c-11ed-a3b6-dac502259ad0.png

上圖就是PC主機端借助串口助手分四次且每次發送64字節數據時USB設備的接收情況。從圖上不難看出,4次數據都匯集在一起了,關鍵還沒完,還在等待后續數據過來。我是希望一次傳輸做一次處理,于是我讓設備每收到一個完整數據包,就重新給定一個延時,比方3~5ms,用變量Wait_Rx_Dly來記錄延時值,在某毫秒定時中斷里對該變量做減1操作。若延時到了還沒有收到數據或延時過程中收到非完整包則視為本次傳輸結束,然后去處理剛才收到的數據。

2d9c6158-572c-11ed-a3b6-dac502259ad0.png

我順便使用了HAL庫里自帶的systick中斷函數來做這個延時管理。當接收處理代碼加上這個延時管理后,就不會出現不同傳輸批次的數據擠在一塊了。問題得以解決。

另外,我上面分享的接收處理代碼也有很好的通用性,并不局限于Bulk傳輸。我們知道,不同傳輸類型的端點的最大包長往往并不一樣,如果使用上面的參考代碼,我們只需調整那個最大包長參數【Max_Pack_Size】,并適當調整Rx_buffer[]數組的大小就可以使用了。數據個數、傳輸包個數這些變量都可以保留使用。

那段接收處理代碼很簡單,看懂了都可以自行組織編寫。順便說下,我使用的STM32F4系列的Cube庫版本為STM32F4xx HALV1.8.1。好,今天的話題就分享到這里,希望幫到有需要的人。祝君好運!

審核編輯:湯梓紅

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • usb
    usb
    +關注

    關注

    60

    文章

    7980

    瀏覽量

    266096
  • STM32
    +關注

    關注

    2272

    文章

    10924

    瀏覽量

    357582
  • CDC
    CDC
    +關注

    關注

    0

    文章

    57

    瀏覽量

    17856

原文標題:如何讓CDC類USB設備批量接收64字節以上數據

文章出處:【微信號:stmcu832,微信公眾號:茶話MCU】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    做STM32f103 USB雙緩存的時候,發送4K數據里面前64字節是0,為什么?

    做STM32f103 USB 雙緩存的時候, 采取ENP3的TXaddr1和TXaddr0的雙緩存ping-pong發送機制,每次上位機接收完4K數據, 4K數據
    發表于 04-28 07:07

    用ESP32發送數據,串口最大接收120字節就進入中斷了,如何才能接收2048字節數據

    請教一個問題,我現在用ESP32發送數據,串口最大接收120字節就進入中斷了,我更改了uart_driver_install中.rxfifo_full_thresh
    發表于 06-20 06:43

    在進行USB CDC開發時,無法發送64整數倍的數據

    ,就是是最多兩包數據。如果需要發送超過127個字節時,又該如何做呢?查看USB協議棧內核代碼,發現每次端點0發送數據時,在發送代碼中固定每次最多可以傳輸
    發表于 03-28 13:30

    如何將配置端點緩沖區的大小配置為64字節

    你好,我在CyPress CY7C68013A高速控制器上工作。如何將配置端點緩沖區的大小配置為64字節(如全速),用于批量傳輸。我的主機還支持USB 2高速,但由于項目的典型性質,我
    發表于 05-09 16:07

    USBUART_PutData()不適用于64字節

    你好!我正在測試USB CDC示例項目,不能讓它發送64字節數據,雖然這等于最大數據包大小,應
    發表于 06-21 11:37

    如何解決傳輸64字節字符串時USB UART出現的問題

    應該發送64字節數據包后發送10數據包長度。在PC的司機會知道該字符串只有在收到這個零長度數據包的接收
    發表于 07-18 14:57

    如何使用Encore II的64字節控制傳輸字節

    我在EnCORE 2中的USB組件控制端點大小只有8字節。在我的應用程序中,我需要傳輸64字節。如何做到這一點?控制端點是一個雙向端點,它使用相同的緩沖器(UBSI接口
    發表于 08-13 09:38

    USB CDC吞吐量問題

    我從論壇上閱讀CDC的所有內容中得知,我的申請應該只是學術性的,并且遲疑不決。我的實時要求是在250毫秒內傳輸115200字節(吞吐量460800字節/秒)。從PIC32到PC。客戶需要他們的PC
    發表于 10-14 15:52

    USB CDC數據損壞:傳輸的32被接收為0

    是:.(!{發送4096字節數據到微告訴微寫數據到閃存}數據被精確地寫入閃存,因此我知道我的閃存可以,但是看起來發送值32(0x20)被接收
    發表于 10-21 14:14

    大于64字節傳輸的USB HID—描述符中要更改什么?

    ,如果需要的話,它將把一個事務分成多個64字節數據包。用這個?我仍然在Microchip應用程序庫的版本2.9的USB堆棧上。謝謝。
    發表于 05-06 13:21

    為什么我在512字節數據緩沖區傳輸數據卻得到1536字節

    我正在使用 STM32L4R5ZI-P 開發板。我已將 USB 配置為僅具有 CDC 設備,其中 APP_TX_DATA_SIZE 為 2048,USBD_MAX_STR_DESC
    發表于 12-19 07:13

    為什么無法從PC接收超過64字節數據

    我正在全速模式下使用經過修改的 CDC USB 設備,但我無法從 PC 接收64 字節
    發表于 01-16 07:22

    rt1052的usb屬于高速usb,hid設備最大不是可以支持到1024字節

    數據一包的大小才8個字節,后面我自己改成64字節,測試收發是可以的,但是我試著改成128字節,最終收發就有問題了 。rt1052的
    發表于 04-17 07:41

    網絡是否允許小于64字節的以太網幀或者報文傳輸?

    同學們在學網絡課程的時候都知道,除巨幀外,常見的以太網幀的長度范圍是64字節到1518字節,并且因為最初總線型半雙工的組網原因,人們制定了CSMA/CD協議,規定了以太網中最短幀為64
    的頭像 發表于 09-05 11:46 ?8383次閱讀
    網絡是否允許小于<b class='flag-5'>64</b><b class='flag-5'>字節</b>的以太網幀或者報文傳輸?

    在進行USB CDC開發時 無法發送64整數倍的數據

    在進行USB CDC開發時 無法發送64整數倍的數據(通信電源技術審稿費用)-在向客戶推STM32F4芯片的時候,客戶反饋使用
    發表于 08-04 17:57 ?18次下載
    在進行<b class='flag-5'>USB</b> <b class='flag-5'>CDC</b><b class='flag-5'>類</b>開發時 無法發送<b class='flag-5'>64</b>整數倍的<b class='flag-5'>數據</b>
    百家乐有人赢过吗| 星河百家乐官网现金网| 皇冠现金网安全吗| 百家乐官网下注法| 包赢百家乐官网的玩法技巧和规则| 百家乐官网平点| 致胜百家乐官网软件| 百家乐官网技巧论坛| 嬴澳门百家乐官网的公式| 百家乐官网波音平台有假吗| 乐天百家乐的玩法技巧和规则 | 扎赉特旗| 缅甸百家乐官网网上投注| 百家乐官网如何投注技巧| 澳门百家乐官网真人版| 百家乐官网机器图片| 新世纪百家乐官网的玩法技巧和规则| 百家乐官网开闲的几率多大| 美国百家乐怎么玩| 百家乐博弈指数| 大发888为什么进不去| 爱拼百家乐| 汝城县| 网上赌百家乐官网被抓应该怎么处理 | 百家乐赌具哪里最好| 神人百家乐赌场| 博必发百家乐的玩法技巧和规则 | 最佳场百家乐的玩法技巧和规则| 大发888我的爱好| 叙永县| 闲和庄百家乐官网娱乐网| 新澳博天上人间娱乐| 百家乐官网牌路分析仪| 做生意门朝山| 闲和庄百家乐的玩法技巧和规则| 凌龙棋牌官方下载| 百家乐官网有不有作弊| 上海百家乐官网的玩法技巧和规则| 15人百家乐桌布| 百家乐怎样玩的| 永利国际娱乐|