侵權投訴

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

strongerHuang ? 2021-09-02 09:24 ? 次閱讀

來源 | 小麥大叔

循環緩沖區是嵌入式軟件工程師在日常開發過程中的關鍵組件。

多年來,互聯網上出現了許多不同的循環緩沖區實現和示例。我非常喜歡這個模塊,可以GitHub上找到這個開源的 CBUF.h 模塊。

地址:https://github.com/barraq/BRBrain/blob/master/firmware/CBUF.h

CBUF.h 模塊使用宏實現循環緩沖區,具體源碼如下所示;

#if !defined( CBUF_H )#define CBUF_H /**《 Include Guard *//* ---- Include Files ---------------------------------------------------- *//* ---- Constants and Types ---------------------------------------------- *//**

* Initializes the circular buffer for use.

*/

#define CBUF_Init( cbuf ) cbuf.m_getIdx = cbuf.m_putIdx = 0/**

* Returns the number of elements which are currently contained in the

* circular buffer.

*/#define CBUF_Len( cbuf ) ((typeof( cbuf.m_putIdx ))(( cbuf.m_putIdx ) - ( cbuf.m_getIdx )))/**

* Appends an element to the end of the circular buffer

*/#define CBUF_Push( cbuf, elem ) (cbuf.m_entry)[ cbuf.m_putIdx++ & (( cbuf##_SIZE ) - 1 )] = (elem)/**

* Retrieves an element from the beginning of the circular buffer

*/#define CBUF_Pop( cbuf ) (cbuf.m_entry)[ cbuf.m_getIdx++ & (( cbuf##_SIZE ) - 1 )]/**

* Retrieves the i‘th element from the beginning of the circular buffer

*/#define CBUF_Get( cbuf, idx ) (cbuf.m_entry)[( cbuf.m_getIdx + idx ) & (( cbuf##_SIZE ) - 1 )]/**

* Retrieves the i’th element from the end of the circular buffer

*/#define CBUF_GetEnd( cbuf, idx ) (cbuf.m_entry)[( cbuf.m_putIdx - idx - 1 ) & (( cbuf##_SIZE ) - 1 )]/**

* Determines if the circular buffer is empty

*/#define CBUF_IsEmpty( cbuf ) ( CBUF_Len( cbuf ) == 0 )/**

* Determines if the circular buffer is full.

*/#define CBUF_IsFull( cbuf ) ( CBUF_Len( cbuf ) == ( cbuf##_SIZE ))/**

* Determines if the circular buffer is currenly overflowed or underflowed.

*/#define CBUF_Error( cbuf ) ( CBUF_Len( cbuf ) 》 cbuf##_SIZE )#if defined( __cplusplus )template 《 class IndexType, unsigned Size, class EntryType 》

class CBUF

{public:

CBUF()

{

m_getIdx = m_putIdx = 0;

}

IndexType Len() const { return m_putIdx - m_getIdx; }

bool IsEmpty() const { return Len() == 0; }

bool IsFull() const { return Len() == Size; }

bool Error() const { return Len() 》 Size; }

void Push( EntryType val )

{

m_entry[ m_putIdx++ & ( Size - 1 )] = val;

}

EntryType Pop()

{

return m_entry[ m_getIdx++ & ( Size - 1 )];

}

private:

volatile IndexType m_getIdx;

volatile IndexType m_putIdx;

EntryType m_entry[ Size ];

};

#endif // __cplusplus/* ---- Variable Externs ------------------------------------------------- *//* ---- Function Prototypes ---------------------------------------------- *//** @} */#endif // CBUF_H

現在一般我不喜歡以這種方式使用宏,但實現已被證明是快速、高效且工作相對良好的,這是很難爭論的。

循環緩沖區的設置非常簡單。首先,需要定義循環緩沖區的大小。這是通過定義宏 myQ_SIZE 來完成的,同時記住緩沖區大小需要是 2 的冪。

然后通過創建一個 myQ 類型的變量來聲明循環緩沖區。例如,如果 myQ_SIZE 定義為 64 字節,則可以定義 UART 的發送和接收緩沖區,如下面的圖 1 所示。

1b3b1556-0b4a-11ec-8fb8-12bb97331649.png

圖 1 – 定義循環緩沖區

在此示例中,myQ 被定義為靜態以限制緩沖區的范圍并聲明為易失性,因為它們在中斷內被修改。定義循環緩沖區只是第一步。為了分配緩沖區,必須將這些變量傳遞給 CBUF_INIT 宏,如下圖 2 所示。

1b476e82-0b4a-11ec-8fb8-12bb97331649.png
圖 2 – 緩沖區初始化

除了這個初始設置之外,緩沖區相當簡單且易于使用。例如,可以使用 CBUF_PUSH 將通過串行接口接收 UART接收的字符推送到循環緩沖區,如圖 3 所示。

1b506712-0b4a-11ec-8fb8-12bb97331649.png

圖 3 – 推入緩沖區

開發人員不僅希望將數據推送到循環緩沖區上,還希望從緩沖區彈出或獲取數據??吹竭@一點的一個簡單示例是需要獲取字符并通過 UART 傳輸的串行發送器。圖 4 中可以看到一個示例傳輸函數。

1b7135fa-0b4a-11ec-8fb8-12bb97331649.png

圖 4 – 從緩沖區彈出數據

在健壯的應用程序中,還應檢查循環緩沖區長度和溢出狀態。CBUF 模塊確實提供了能夠檢查這些重要指標的宏。

要記住的一個重要問題是,如果需要對 CBUF 本身進行任何調試,這是不可能的。無法為宏設置斷點,因此如果出現問題,則需要對模塊進行功能化以逐步執行和調試。

多年來使用這個模塊雖然我沒有發現任何問題。循環緩沖區是在嵌入式系統中與串行設備通信的一個重要方面。

循環緩沖區也很好理解,應該創建它們以便它們可以模塊化并從一個應用程序到下一個應用程序重復使用。

到目前為止,CBUF 模塊已被證明是這樣一個模塊,所以在這里,我強烈推薦一下這個模塊。

免責聲明:本文來源網絡,版權歸原作者所有。如涉及作品版權問題,請與我聯系刪除。

編輯:jq

原文標題:用宏高效實現環形緩沖區

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

收藏 人收藏
分享:

評論

相關推薦

東芝推出TXZ+?族高級系列新款M4G組微控制器

東芝電子元件及存儲裝置株式會社(“東芝”)宣布,已開始量產M4G組中用于高速數據處理的20種新器件。....
的頭像 東芝半導體 發表于 09-09 09:58 ? 262次 閱讀

嵌入式軟件開發怎么編程

嵌入式開發,除了掌握基本的編程語法之外,編程的思想也是很關鍵,下面說兩點編程思想。
的頭像 RTThread物聯網操作系統 發表于 09-03 14:48 ? 1528次 閱讀
嵌入式軟件開發怎么編程

OpenHarmony HDF 驅動框架概述及加載過程分析

OpenHarmony系統 HDF驅動框架概述 OpenAtom OpenHarmony(以下簡稱“....
的頭像 HarmonyOS開發者 發表于 09-03 09:32 ? 154次 閱讀
OpenHarmony HDF 驅動框架概述及加載過程分析

液壓緩沖器的工作原理 怎么使用