串列埠緩衝區管理分析

2021-07-02 20:46:12 字數 2680 閱讀 3664

一、 概述:

串列埠使用時一般包含兩個緩衝區,即傳送緩衝區和接收緩衝區。傳送資料時,先將資料存在傳送緩衝區,然後通過串列埠傳送;接收資料時,先將接收的資料存在接收緩衝區,然後再進行讀取。

合理恰當的使用緩衝區,不僅可以使不同裝置間正常通訊,而且還有助於節約記憶體,提高效率。

二、緩衝區分配管理:

方法一:

通過記憶體池實現

1、資料結構:

struct _chn_pool_mgr

;引數含義:struct _chn_pool_mgr:記憶體池的資料型別

buffer:緩衝區,大小為buf_sz  192

free_bitmap:標誌位。

注意:緩衝區又分為若干塊,每塊大小blk_sz

free_bitmap標誌緩衝區塊中的空閒塊和被使用塊,1表示空閒,0表示被使用

注:陰影部分表示存放著資料

free_bitmap初始化為(1

<< (sizeof(chn_pool_mgr.buffer) / blk_sz)) -1即(1 << (2^10/2^6)) -1,即二進位制數11111...11111b,共16個1,緩衝區塊全部空閒

alloc_a_slot()函式分配緩衝區塊:檢測free_bitmap值,將空閒的緩衝區塊標號較小的塊分配,返回分配的緩衝區塊的標號

free_bitmap值

分配的緩衝區塊標號

alloc_a_slot()返回值

1111...111111

1111...111100

1111...110010

1111...000100

//不是太明白????

struct _chn_slot

;引數含義:struct _chn_slot:記錄緩衝區讀寫狀態的結構體

tx:記錄緩衝區塊標號和資料的寫入位置(具體存放如圖所示)

rx:記錄緩衝區塊標號和資料的讀取位置(具體存放如圖所示)

data_cnt:記錄緩衝區中未讀取的資料量

data_max:向緩衝區中寫入資料時,緩衝區中允許存在的最大資料量

tx,rx資料含義:

2,例項分析

1)向緩衝區中寫資料:

向緩衝區中寫資料,每次寫90個位元組,寫兩次。

初始狀態:

假設struct _chn_slot結構體中各引數均為初始狀態:tx = rx = invalid_ptr,即(invalid_blk_no << blk_no_shift),data_cnt為0,data_max為uart_max_len

記憶體池的狀態如下:

寫資料:

alloc_a_slot()分配緩衝區塊:

檢測free_bitmap,分配緩衝區塊標號為2的塊;

tx記錄緩衝區塊標號及寫入資料位置(0x80);

緩衝區塊最後乙個位元組置為invalid_blk_no;

變為如下狀態:

寫入90個資料:

由於90 > blk_sz-1(乙個塊存放資料的最大位元組數),所以再次呼叫alloc_a_slot()分配緩衝區塊

檢測free_bitmap,分配緩衝區塊標號為4的塊;

tx記錄緩衝區塊標號及寫入資料位置(0x100);

緩衝區塊最後乙個位元組置為invalid_blk_no;

此外,還要使標號為2的塊的最後乙個位元組記錄下一塊的標號(4),最後將剩餘的資料寫入,tx記錄資料位置(0x11b)

寫入完成後,各引數狀態如下:

第二次寫入資料:

與上面類似,根據tx記錄的緩衝區塊標號及資料位置繼續向後寫。

最終變為如下狀態:

3)從緩衝區中讀資料

從緩衝區中讀資料,每次讀40個,讀完為止。

假設此時緩衝區狀態,及各引數如下:

data_cnt為180

此時開始讀取資料,rx記錄緩衝區標號及資料位置,成功讀取40個資料後變為:

繼續讀取,data_cnt變為0,讀取結束。

小結:由以上分析可知,使用記憶體池的方法,通過檢測free_bitmap可使緩衝區被多個任務共同使用,節約空間。

方法二:

利用迴圈佇列實現

1、資料型別:

struct _chn_slot

;引數含義:

tx:記錄緩衝區寫入位置

rx:記錄緩衝區讀取位置

buf:緩衝區

2、方法實現:

每存入乙個位元組,tx後移一位,每取走乙個位元組,rx後移一位

當tx移至緩衝區結尾時,若緩衝區頭部已讀取,則tx會繼續在頭部存放資料,如下:

當(rx + 1) % buffer_len == tx時,緩衝區存滿

三、兩種方法的比較:

比較內容

方法一方法二(迴圈佇列式)

使用緩衝區的任務數

允許多工

只能單任務

空間利用率高低

緩衝區的使用順序

優先使用低位址處的緩衝區塊

由低位址到高位址迴圈使用

不能存放資料的位元組數

緩衝區塊數

1b程式設計複雜度

略微複雜

簡單方法一最大的好處在於可同時被多個任務共同使用,互不影響,有助於節約記憶體;而且每次分配空間時,會優先使用低位址處的空閒塊,資料集中,有利於減少記憶體池的占用;某一任務釋放的空間可被另一任務使用,提高了利用率,但程式設計略微複雜。

迴圈佇列式程式設計簡單,容易理解,特別適合單任務的使用,但緩衝區的利用率不是很高,且無法多工使用。

cout緩衝區管理

下面的程式是在vector中找元素,找到返回1,否則返回0 同時求出其相對位移vector difference type dif.include include include include using namespace std bool search vector iterator beg,...

UDP寫緩衝區(傳送緩衝區)分析

最近,碰到udp是否有寫緩衝區的疑問,對於應用,如下圖linux手冊中有設定udp傳送緩衝區相關屬性,也明確提到了send buffer的概念 那這是否意味著udp是有傳送緩衝區的嗎?我們再看一下 unix network programming 書中所述,這本書的作者權威性我就不多說了吧,在國內高...

輸出緩衝區的管理

每個 io 物件管理乙個緩衝區,用於儲存程式讀寫的資料。如有下面語句 os please enter a value 系統將字串字面值儲存在與流 os 關聯的緩衝區中。下面幾種情況將導致緩衝區的內容被重新整理,即寫入到真實的輸出裝置或者檔案 1 程式正常結束。作為 main 返回工作的一部分,將清空...