導言
如上所示,在[[STM32F103_HAL庫+寄存器學習筆記19 - CAN發送中斷+CAN接收中斷+接收所有CAN報文+ringbuffer數據結構]]的基礎上,為CAN發送端也引入了ringbuffer(環形緩沖區)機制。CAN發送有三個發送郵箱,為什么還另外需要ringbuffer?
- 三郵箱限制:STM32F103 的 CAN 控制器只有三個發送郵箱,當應用層在短時間內產生超過3條待發幀時,多余的幀無法立即寫入郵箱,只能被丟棄或阻塞等待(阻塞更可靠,但可能降低響應速度)。
- 突發流量平滑:環形緩沖區可以暫存超出郵箱數的那些幀,在郵箱空閑時再依次發送,避免丟幀。
- 解耦業務與硬件:應用層只需往環形緩沖區寫入數據,不用關心底層郵箱是否空閑,降低了發送接口的耦合度。
總結來說,在CAN發送鏈路中引入ringbuffer,能有效解決上述問題,尤其是郵箱數量限制和突發流量平滑問題。
項目地址:
github:
- HAL庫: https://github.com/q164129345/MCU_Develop/tree/main/stm32f103_hal_library20_Can_Send_Rec_With_RB
- 寄存器方式: https://github.com/q164129345/MCU_Develop/tree/main/stm32f103_ll_library20_Can_Send_Rec_With_RB
gitee(國內): - HAL庫: https://gitee.com/wallace89/MCU_Develop/tree/main/stm32f103_hal_library20_Can_Send_Rec_With_RB
- 寄存器方式: https://gitee.com/wallace89/MCU_Develop/tree/main/stm32f103_ll_library20_Can_Send_Rec_With_RB
使用for循環一口氣發送50條CAN報文
為驗證ringbuffer對“三郵箱限制”和“突發流量平滑”問題的緩解效果。在主循環里調用for循環,一口氣發送50條CAN報文,看看效果!
如上所示:
- 在debug模式里,將對應的全局變量置1,就可以運行對應的測試函數。
測試一口氣發送50條CAN報文,沒有ringbuffer
如圖所示,將全局變量 test 置為1,運行函數 CAN_Test_Send50Frames() 連續發送50條報文。結果顯示,CAN分析儀僅接收到3條報文。原因很簡單,另外47條報文因為發送郵箱擠滿了,所以都溢出了。
測試一口氣發送50條CAN報文,有ringbuffer
如上所示,將全局變量testRB置1,運行函數CAN_Test_Send50Frames_Use_Ringbuffer()
一口氣發送50條報文。接著,CAN分析儀接收到50條報文。實踐證明,ringbuffer作為二級緩存能有效解決突發高流量問題與三個郵箱的局限性問題。
一、代碼(HAL庫)
1.1、myCanDrive.c
1.2、stm32f1xx_it.c
1.3、main.c
1.4、代碼編譯
二、代碼(寄存器方式)
1.1、myCanDrive_reg.c
如上所示,RX Ringbuffer與TX Ringbuffer都是二級緩存。
如上所示,這兩個函數基本跟HAL庫一樣,只是開與關中斷的函數改為寄存器方式直接操作。
如上所示,在CAN發送完成中斷函數USB_HP_CAN1_TX_IRQHandler()
里調用函數CAN_Get_CANMsg_From_RB_To_TXMailBox_IT()
,在中斷里將ringbuffer里的CAN報文放入空閑的發送郵箱。
1.2、main.c
1.3、代碼編譯
1.4、測試
如上所示,測試結果跟HAL庫一樣。