通用隊列管理模塊設(shè)計 —— 簡潔高效的嵌入式數(shù)據(jù)調(diào)度核心
在嵌入式系統(tǒng)中,任務(wù)之間常常需要通過一種結(jié)構(gòu)化方式傳遞消息或數(shù)據(jù),例如傳感器采集值上傳、串口數(shù)據(jù)解析、指令調(diào)度、事件響應(yīng)等。在這些場景下,“隊列(Queue)”是一種非常經(jīng)典且高效的數(shù)據(jù)組織形式。
通用隊列模塊以結(jié)構(gòu)體數(shù)組為核心,結(jié)合固定內(nèi)存與循環(huán)索引,實現(xiàn)了一個輕量、穩(wěn)定、適配性強的隊列管理器。該模塊適合用于裸機或 RTOS 系統(tǒng),是構(gòu)建通信緩沖、消息隊列、任務(wù)分發(fā)機制的基礎(chǔ)組件。
核心結(jié)構(gòu)與概念隊列管理器 queue_t
隊列通過 queue_t 結(jié)構(gòu)體進行管理,內(nèi)部維護以下成員:
base:隊列內(nèi)存起始地址;
size:隊列最大容量(元素個數(shù));
element_size:每個元素的字節(jié)數(shù);
front、rear:隊頭與隊尾索引,用于控制循環(huán)進出。
隊列結(jié)構(gòu)采用 循環(huán)數(shù)組,即環(huán)形緩沖的方式,避免頻繁移動內(nèi)存,入隊出隊僅需更新索引。
功能概覽
接口函數(shù) | 功能描述 |
queue_create | 創(chuàng)建并初始化隊列 |
queue_is_empty | 判斷隊列是否為空 |
queue_is_full | 判斷隊列是否已滿 |
queue_put | 入隊(添加元素) |
queue_get | 出隊(移除元素) |
queue_peek | 預(yù)讀取隊頭元素,不出隊 |
queue_del | 刪除隊頭元素,不讀取 |
queue_size | 獲取當(dāng)前隊列長度 |
queue_clr | 清空隊列 |
一、模塊功能概述
本隊列模塊支持以下基礎(chǔ)能力:
隊列的初始化與創(chuàng)建;
判斷隊列空滿狀態(tài);
元素入隊與出隊;
隊列長度查詢;
隊列內(nèi)容預(yù)讀?。ú怀鲫牐?/span>
隊列清空;
隊尾元素刪除。
該隊列采用循環(huán)數(shù)組結(jié)構(gòu),不依賴動態(tài)內(nèi)存分配,適合資源受限的嵌入式環(huán)境使用。支持自定義元素類型,通過配置元素大小與容器地址實現(xiàn)通用性管理。
二、使用方式簡述
使用者在使用該模塊時需自行提供以下參數(shù):
數(shù)據(jù)緩沖區(qū)指針;
緩沖區(qū)容量(元素個數(shù));
單個元素的大?。ㄗ止?jié));
隊列管理結(jié)構(gòu)體實例。
通過調(diào)用創(chuàng)建函數(shù)對隊列進行初始化后,即可使用相關(guān)接口進行操作,如入隊出隊等。
三、接口功能說明1. 創(chuàng)建隊列
通過 queue_create 函數(shù)傳入結(jié)構(gòu)體、容器地址、容器容量、元素大小,即可完成隊列初始化。
2. 狀態(tài)判斷
提供 queue_is_empty 和 queue_is_full 接口判斷當(dāng)前隊列狀態(tài),便于進行邊界處理。
3. 元素操作
使用 queue_put 向隊列尾部寫入一個元素;
使用 queue_get 從隊列頭部讀取一個元素并出隊;
使用 queue_peek 可在不出隊的情況下獲取隊頭元素地址;
使用 queue_del 可直接丟棄隊頭元素(刪除而不讀?。?;
使用 queue_clr 可清空整個隊列內(nèi)容;
使用 queue_size 可獲取當(dāng)前隊列中元素數(shù)量。
1. 串口接收命令緩存
串口中斷接收到數(shù)據(jù)幀后,將幀內(nèi)容通過 queue_put 入隊,主循環(huán)中調(diào)用 queue_get 提取完整指令進行解析,避免數(shù)據(jù)丟失或阻塞。
typedef struct {
uint8_t data[8];
} uart_cmd_t;uart_cmd_t cmd_buf[16];queue_t cmd_queue;
queue_create(&cmd_queue, cmd_buf, 16, sizeof(uart_cmd_t));
2. 多任務(wù)消息傳遞(RTOS環(huán)境)
任務(wù) A 收集數(shù)據(jù)并通過 queue_put 入隊,任務(wù) B 輪詢或通過事件驅(qū)動使用 queue_get 獲取消息,完成跨任務(wù)通信。
3. 簡易任務(wù)調(diào)度器
使用 queue_t 管理一個“函數(shù)指針 + 參數(shù)”結(jié)構(gòu)體列表,即可構(gòu)建輕量的調(diào)度任務(wù)表,實現(xiàn)軟中斷調(diào)度或定時任務(wù)執(zhí)行。
通用隊列管理模塊,是構(gòu)建嵌入式通信、緩存和調(diào)度功能的堅實基礎(chǔ)。通過靈活封裝與高效實現(xiàn),該模塊能夠幫助開發(fā)者快速構(gòu)建穩(wěn)定的數(shù)據(jù)流通路。在系統(tǒng)架構(gòu)設(shè)計中,清晰的數(shù)據(jù)組織方式往往是高質(zhì)量代碼的關(guān)鍵,隊列,正是連接數(shù)據(jù)與邏輯的橋梁。
開源代碼:
#include "queue.h"#include <stddef.h>#include <string.h>/* @brief 創(chuàng)建一個隊列
* @param[in] q - 隊列管理器
* @param[in] base - 隊列容器基地址
* @param[in] size - 隊列容器可容納元素個數(shù)
* @param[in] element_size - 隊列元素大小(sizeof(type))
* @return true - 創(chuàng)建成功, false - 創(chuàng)建失敗
*/bool queue_create(queue_t *q, void *base, int size, int element_size)
{ if (q == NULL || base == NULL || size== 0 || element_size == 0) return false;
q->base = base;
q->size = size;
q->element_size = element_size;
q->front = q->rear = 0; return true;
}/* @brief 判斷隊列是否為空
* @return true - 隊列為空, false - 隊列非空
*/bool queue_is_empty(queue_t *q)
{ return q->front == q->rear;
}/* @brief 判斷隊列是否滿
* @return true - 隊列非滿, false - 隊列未滿
*/bool queue_is_full(queue_t *q)
{ return (q->rear + 1) % q->size == q->front;
}/* @brief 入隊(添加元素至隊尾)
* @param[in] element - 隊列元素
* @return true - 成功入隊, false - 隊列滿
*/bool queue_put(queue_t *q, void *element)
{ if (queue_is_full(q)) return false;
memcpy((unsigned char *)q->base + q->rear * q->element_size, element,
q->element_size);
q->rear = (q->rear + 1) % q->size; return true;
}/* @brief 出隊(移除隊首元素)
* @param[in] element - 指向隊首元素的地址
* @return true - 成功出隊, false - 隊列為空
*/bool queue_get(queue_t *q, void *element)
{ if (queue_is_empty(q)) return false;
memcpy(element, (unsigned char *)q->base + q->front * q->element_size,
q->element_size);
q->front = (q->front + 1) % q->size; return true;
}/* @brief 獲取隊首元素地址(預(yù)讀取)
* @param[in] element - 指向隊首元素的地址
* @return true - 獲取成功, false - 獲取失敗隊列為空
*/bool queue_peek(queue_t *q, void **element)
{ if (queue_is_empty(q)) return false;
*element = (void *)((unsigned char *)q->base + q->front *
q->element_size); return true;
}/* @brief 刪除隊尾元素
* @return true - 成功移除, false - 隊列為空,
*/bool queue_del(queue_t *q)
{ if (queue_is_empty(q)) return false;
q->front = (q->front + 1) % q->size; return true;
}/* @brief 獲取隊列元素個數(shù)
* @return 隊列元素個數(shù)
*/int queue_size(queue_t *q)
{ return (q->rear + q->size - q->front ) % q->size;
}/* @brief 清空隊列
* @return none
*/void queue_clr(queue_t *q)
{
q->front = q->rear = 0;
}
評論