精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

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

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

3天內不再提示

分享一個嵌入式通用FIFO環形緩沖區實現庫

strongerHuang ? 來源:Mculover666 ? 2024-10-23 16:20 ? 次閱讀

轉自| Mculover666

今天給大家分享一個開源的嵌入式通用FIFO環形緩沖區實現庫:ringbuff 地址:

https://github.com/MaJerle/ringbuff

1. 關于ringbuff

開源項目ringbuff ,是一款通用FIFO環形緩沖區實現的開源庫,作者MaJerle,遵循 MIT 開源許可協議。

目前 ringbuff 的特點有:

使用C99語法編寫,并且沒有平臺相關代碼;

沒有動態內存分配;

使用更優的內存復制而不是循環從內存讀取數據/向內存寫入數據;

2. 移植ringbuff

2.1. 移植思路

在移植過程中主要參考兩個資料:項目的readme文檔和demo工程。

對于這些開源項目,其實移植起來也就兩步:

① 添加源碼到裸機工程中;

② 實現需要的接口即可;

2.2. 準備裸機工程

本文中我使用的是小熊派IoT開發套件,主控芯片STM32L431RCT6:

c81da2cc-9074-11ef-a511-92fbcf53809c.png

移植之前需要準備一份裸機工程,我使用STM32CubeMX生成,需要初始化以下配置:

配置一個串口,中斷方式接收數據,查詢方式發送數據;

printf重定向;

2.3. 添加ringbuff 到工程中

① 復制 ringbuff 源碼到工程中:

c85233c0-9074-11ef-a511-92fbcf53809c.png

② 在keil中添加 ringbuff 組件的源碼文件:

c86925c6-9074-11ef-a511-92fbcf53809c.png

③ 添加 ringbuff 的頭文件路徑:

c878e1e6-9074-11ef-a511-92fbcf53809c.png

2.4. 配置ringbuff

ringbuff中默認volatile關鍵詞沒有定義,需要手動配置一下,在ringbuff.h中:

c89419e8-9074-11ef-a511-92fbcf53809c.png

至此,ringbuff移植修改完成,可以愉快的使用ringbuff啦~

3. 使用ringbuff

3.1. 為什么使用ringbuff

緩沖區一般用于解決設備接收數據的速度和設備處理速度不匹配的情況下,防止丟包,通俗的來說就是:收到數據先存進緩沖區,等到CPU來處理的時候一次性取出處理。

緩沖區有兩種形式,一種是數組,一種就是本文所介紹的環形緩沖區ringbuff。

相較于數組,環形緩沖區對整段內存的利用達到最大,并且使用非常方便,如下:

① 寫入的時候不用手動維護下標,直接寫入即可(由緩沖區的實現維護);

② 讀取的時候不用判斷從哪里讀,直接讀取即可(有緩沖區的實現維護)

本文設計的一個簡單的不定長串口協議如下:

c8a75a26-9074-11ef-a511-92fbcf53809c.png

數據類型:比如0x3F表示這是通道1的數據,0x4E表示通道2的數據;

數據長度:表示后面跟著有效數據的長度;

有效數據:有效字節數;

校驗數據:省略;

接下來演示如何用環形緩沖區做到不丟包解析。

3.2. 計算緩沖區大小

假定數據每200ms處理一次,而數據10ms接收一次,每次接收的數據包長度為7個字節。

要想做到不丟包,就需要將200ms內接收到的所有數據包都存進緩沖區,所以緩沖區大小至少為:200/10*7 = 140 個字節。

保險起見,可以將緩沖區適當的擴大一下,設置為150個字節。

3.3. 初始化緩沖區

使用時包含頭文件:

#include"ringbuff/ringbuff.h"

接著初始化緩沖區:

uint8_tringbuff_init(RINGBUFF_VOLATILEringbuff_t*buff,void*buffdata,size_tsize);

該 API 用來初始化一個ringbuff句柄(指向ringbuff結構體的指針),其中傳入的參數分別為:

buff:ringbuff句柄;

buffdata:緩沖區地址;

size:緩沖區大小;

首先創建一個緩沖區句柄,開辟一塊緩沖區:

/*Privateusercode---------------------------------------------------------*/
/*USERCODEBEGIN0*/
//用于串口接收
uint8_trecv_data=0;

//用于存儲從緩沖區讀取出的數據
uint8_tread_data=0;

//用于串口1的ringbuff句柄
ringbuff_tusart1_ringbuff;

//開辟一塊內存用于緩沖區
#defineUSART1_BUFFDATA_SIZE150
uint8_tusart1_buffdata[USART1_BUFFDATA_SIZE];

/*USERCODEEND0*/

然后在main函數中初始化ringbuff:

/*USERCODEBEGIN2*/
printf("ringbuffPortByMculover666
");

//初始化ringbuff句柄
if(1!=ringbuff_init(&usart1_ringbuff,(uint8_t*)usart1_buffdata,USART1_BUFFDATA_SIZE))
{
printf("usart1ringbuffinitfail.
");
}

//使能串口中斷接收
HAL_UART_Receive_IT(&huart1,(uint8_t*)&recv_data,1);

/*USERCODEEND2*/

3.4. 數據接收

接收到一個字節數據后,話不多說,直接往緩沖區扔:

/*USERCODEBEGIN4*/
/*中斷回調函數*/
voidHAL_UART_RxCpltCallback(UART_HandleTypeDef*huart)
{
/*判斷是哪個串口觸發的中斷*/
if(huart->Instance==USART1)
{
/*將接收到的數據寫入緩沖區*/
ringbuff_write(&usart1_ringbuff,&recv_data,1);
//重新使能串口接收中斷
HAL_UART_Receive_IT(huart,(uint8_t*)&recv_data,1);
}
}
/*USERCODEEND4*/

3.5. 數據處理

數據處理在while(1)中進行,每隔200ms將緩沖區數據全部讀出進行處理:

/*USERCODEBEGINWHILE*/
while(1)
{
/*USERCODEENDWHILE*/


/*USERCODEBEGIN3*/
while((len=ringbuff_read(&usart1_ringbuff,(uint8_t*)&read_data,sizeof(read_data)))>0)
{
/*捕獲起始標志*/
if(read_data==0x3F)
{
//讀取數據字節數,最大支持0xFF
if((len=ringbuff_read(&usart1_ringbuff,(uint8_t*)&read_data,sizeof(read_data)))>0)
{
data_len=read_data;
printf("yourdatahas%dbyte(s):
	",data_len);
}

//提取data_len個數據
for(i=0;i0)
{
printf("[0x%02x]",read_data);
}
}
printf("over
");
}
}
HAL_Delay(200);

}
/*USERCODEEND3*/

編譯下載測試,實驗結果如下,可以做到不丟包解析:

c8c4dc2c-9074-11ef-a511-92fbcf53809c.png

3.6. 丟包測試

經過3.2節的計算,不丟包的最小緩沖區大小是140個字節,接下里我們將緩沖區大小修改為100個字節,測試一下是否產生丟包:

//開辟一塊內存用于緩沖區
#defineUSART1_BUFFDATA_SIZE100//會發生丟包
//#defineUSART1_BUFFDATA_SIZE150//10ms接收7byte的協議包時不丟包
uint8_tusart1_buffdata[USART1_BUFFDATA_SIZE];

再次編譯下載,查看串口輸出:

c8db1294-9074-11ef-a511-92fbcf53809c.png

4. 設計思想解讀

關于環形緩沖區背后的設計實現,請閱讀這篇文章,寫的非常棒:

STM32進階之串口環形緩沖區實現

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

    關注

    0

    文章

    33

    瀏覽量

    9093
  • 嵌入式
    +關注

    關注

    5068

    文章

    19014

    瀏覽量

    303229
  • fifo
    +關注

    關注

    3

    文章

    387

    瀏覽量

    43547
  • 串口
    +關注

    關注

    14

    文章

    1543

    瀏覽量

    76185
  • 開源
    +關注

    關注

    3

    文章

    3245

    瀏覽量

    42396

原文標題:分享一個嵌入式通用FIFO環形緩沖區實現庫

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

收藏 人收藏

    評論

    相關推薦

    基于C語言實現環形緩沖區/循環隊列

    這里分享自己用純C實現環形緩沖區
    的頭像 發表于 04-11 10:39 ?3145次閱讀
    基于C語言<b class='flag-5'>實現</b><b class='flag-5'>環形</b><b class='flag-5'>緩沖區</b>/循環隊列

    基于宏高效實現環形緩沖區教程

    來源 | 小麥大叔 循環緩沖區嵌入式軟件工程師在日常開發過程中的關鍵組件。 多年來,互聯網上出現了許多不同的循環緩沖區實現和示例。我非常喜歡這個模塊,可以GitHub上找到這個開源的
    的頭像 發表于 09-02 09:24 ?6707次閱讀
    基于宏高效<b class='flag-5'>實現</b><b class='flag-5'>環形</b><b class='flag-5'>緩沖區</b>教程

    STM32進階之串口環形緩沖區實現

    完了數據,‘0’地址空間的數據進行釋放掉,列隊頭指向下一個可以處理數據的地址‘1’。從而實現整個環形緩沖區的數據讀寫。看圖,隊列頭就是指向已經存儲的數據,并且這個數據是待處理的。下
    發表于 06-08 14:03

    STM32串口環形緩沖區實現

    是列隊頭的數據,處理完了數據,‘0’地址空間的數據進行釋放掉,列隊頭指向下一個可以處理數據的地址‘1’。從而實現整個環形緩沖區的數據讀寫。看圖,隊列頭就是指向已經存儲的數據,并且這個數
    發表于 10-16 11:40

    環形緩沖區的設計分享!

    以下內容轉自網絡,感謝網友:玩笑joker 環形緩沖區嵌入式系統中十分重要的種數據結構,比如在
    發表于 10-28 23:29

    環形緩沖區簡介

    程序中,經常使用環形緩沖器作為數據結構來存放通信中發送和接收的數據。環形緩沖區先進先出的循
    發表于 08-17 06:56

    請問怎么實現串口環形緩沖區FIFO

    請問怎么實現串口環形緩沖區FIFO
    發表于 12-06 07:23

    環形緩沖區讀寫操作的分析與實現

    環形緩沖區嵌入式系統中種重要的常用數據結構。在多任務環境下實現時,如果有多個讀寫任務,般需
    發表于 04-15 11:35 ?40次下載

    環形緩沖區實現原理

    在通信程序中,經常使用環形緩沖區作為數據結構來存放通信中發送和接收的數據。環形緩沖區先進先
    的頭像 發表于 03-22 10:03 ?7494次閱讀
    <b class='flag-5'>環形</b><b class='flag-5'>緩沖區</b>的<b class='flag-5'>實現</b>原理

    緩沖區是啥意思 STM32串口數據接收之環形緩沖區

    緩沖區顧名思義是緩沖數據用的。實現緩沖區最簡單的辦法時,定義多個數組,接收包數據到數組A,就把接收數據的地址換成數組B,每個數據有
    的頭像 發表于 07-22 15:33 ?1.1w次閱讀

    STM32串口數據接收 --環形緩沖區

    程序中,經常使用環形緩沖器作為數據結構來存放通信中發送和接收的數據。環形緩沖區先進先出的循
    發表于 12-28 19:24 ?30次下載
    STM32串口數據接收 --<b class='flag-5'>環形</b><b class='flag-5'>緩沖區</b>

    環形緩沖區實現思路

    單片機程序開發般都會用到UART串口通信,通過通信來實現上位機和單片機程序的數據交互。通信中為了實現正常的收發,般都會有對應的發送和接收緩存來暫存通信數據。這里使用
    的頭像 發表于 01-17 15:07 ?1583次閱讀

    STM32進階之串口環形緩沖區實現

    STM32進階之串口環形緩沖區實現
    的頭像 發表于 09-19 09:20 ?2137次閱讀
    STM32進階之串口<b class='flag-5'>環形</b><b class='flag-5'>緩沖區</b><b class='flag-5'>實現</b>

    C++環形緩沖區設計與實現

    的存儲空間。環形緩沖區的特點是其終點和起點是相連的,形成環狀結構。這種數據結構在處理流數據和實現數據緩存等場景中具有廣泛的應用。
    的頭像 發表于 11-09 11:21 ?1854次閱讀
    C++<b class='flag-5'>環形</b><b class='flag-5'>緩沖區</b>設計與<b class='flag-5'>實現</b>

    嵌入式環形隊列與消息隊列的實現原理

    嵌入式環形隊列,也稱為環形緩沖區或循環隊列,是種先進先出(FIFO)的數據結構,用于在固定大小
    的頭像 發表于 09-02 15:29 ?337次閱讀