高效的、省內(nèi)存的、任意格式的隊(duì)列
關(guān)注「嵌入式大雜燴」,選擇「星標(biāo)公眾號(hào)」一起進(jìn)步!
在資源緊張的MCU中一般會(huì)這樣做,使用隊(duì)列主要涉及到3個(gè)函數(shù):入隊(duì)列、出隊(duì)列以及隊(duì)列當(dāng)前大小 :
1//入隊(duì)列
2uint8_t?QueueIn(uint8_t?uByte);??
3
4//出隊(duì)列
5uint8_t?QueueOut(void);
6
7//當(dāng)前隊(duì)列大小
8uint8_t?QueueSize(void);
指定通信協(xié)議,非常的簡(jiǎn)潔,不需要考慮丟包和重發(fā)機(jī)制。數(shù)據(jù)格式定義如下 :
1數(shù)據(jù)長(zhǎng)度1? ?數(shù)據(jù)區(qū)1? ?...?數(shù)據(jù)長(zhǎng)度N? ?數(shù)據(jù)區(qū)N
2
3byte1???|??byte2?~?byteX?|?...?|byteY?|?byte(Y 1)?~?byteZ
參考偽代碼:
1/*********************************************
2?*?隊(duì)列數(shù)據(jù)包定義
3?********************************************/
4typedef?struct?_tag_pack
5{
6????uint8_t?len;
7????uint8_t?dataBuff[MAX_DATA_LEN];
8}QueuePack;
9
10/*********************************************
11?*?Function:?SendPack
12?*?Description:用于發(fā)送數(shù)據(jù)包的打包入隊(duì)過(guò)程
13?*?Author:?bug菌
14?********************************************/
15uint8_t?SendPack(QueuePack?*?pQueuePack)
16{
17????uint8_t?Cnt?=?0;
18
19????//進(jìn)入臨界區(qū)--對(duì)于多任務(wù)系統(tǒng)
20????if(QueueIn(pQueuePack->len))
21????{
22????????return?false;?//queue?overflow
23????}
24
25????for(Cnt?=?0;Cnt?len;Cnt )
26????{
27????????if(QueueIn(pQueuePack->dataBuff[Cnt]))
28????????{
29????????????return?false;?//queue?overflow
30????????}
31????}
32????//出臨界區(qū)--對(duì)于多任務(wù)系統(tǒng)
33????return?return;?//queue?success
34}
35/*********************************************
36?*?Function:?RevPack
37?*?Description:由于接受隊(duì)列數(shù)據(jù)包解析過(guò)程
38?*?Author:?bug菌
39?********************************************/
40uint8_t?RevPack(QueuePack?*?pQueuePack)
41{
42????uint8_t?Cnt?=?0;
43
44????//進(jìn)入臨界區(qū)--對(duì)于多任務(wù)系統(tǒng)
45????if(QueueSize()?return?false;
46????????pQueuePack->len?=?QueueOut();
47
48????for(Cnt?=?0;Cnt?len;Cnt )
49????{
50????????if(QueueSize()?return?false;?//queue?empty
51????????pQueuePack->dataBuff[Cnt]?=?QueueOut();
52????}
53????//出臨界區(qū)--對(duì)于多任務(wù)系統(tǒng)
54????return?return;?//queue?success
55}
這樣我們就可以發(fā)送不同格式的數(shù)據(jù)包,并且在接收端進(jìn)行解析獲得最終的數(shù)據(jù)區(qū)。接受到數(shù)據(jù)區(qū)域以后,比如數(shù)據(jù)區(qū)的第一個(gè)字節(jié)表示數(shù)據(jù)包類型,接受端即可識(shí)別對(duì)應(yīng)的數(shù)據(jù)類型來(lái)使用~其實(shí)還有很多軟件上的處理都是類比的處理辦法,一旦你把它們統(tǒng)一起來(lái)就非常容易了~
最后再小提一下臨界區(qū)的事,對(duì)于多任務(wù)系統(tǒng),由于不同任務(wù)的出入隊(duì)需要對(duì)打包過(guò)程進(jìn)行互斥,這樣每個(gè)包才具有完整性~最后?? ?如果覺得本文不錯(cuò)的話,一定要記得跟bug菌點(diǎn)個(gè)贊再走哦~
往期干貨:往期推薦
實(shí)用 | 10分鐘教你搭建一個(gè)嵌入式web服務(wù)器RT-Thread和Freertos的區(qū)別?程序如何運(yùn)行?編譯、鏈接、裝入?串口通信 | 簡(jiǎn)單明了的基礎(chǔ)知識(shí)一種無(wú)OS的MCU實(shí)用軟件框架