前些天跟大家解釋了如下代碼:
offset=len/64+!!(len%64);
并且跟大家詳細(xì)聊了一下其中的!!操作,然而這段代碼的主要功能還是為了進(jìn)行分包處理,既然是分包自然而然就會(huì)想到一種常用的分包處理方法,這也是本文的重點(diǎn)。
數(shù)據(jù)分包在嵌入式軟件開(kāi)發(fā)中算是一種非常常見(jiàn)的處理,其主要原因還是硬件上的各種限制,不得已而為之,特別是在通信協(xié)議的定制過(guò)程中尤為常見(jiàn)。
1
傳輸限制
玩過(guò)各種通信協(xié)議的朋友都知道,像非常多的通信方式都是以數(shù)據(jù)幀的形式來(lái)進(jìn)行傳遞,不同的通信方式因各方面的因素又存在一個(gè)最大傳輸字節(jié)數(shù)的限制,考慮到穩(wěn)定性、容錯(cuò)性等等對(duì)單次發(fā)送的數(shù)據(jù)長(zhǎng)度進(jìn)行限制,又或者所接收的設(shè)備其內(nèi)存資源有限,不足以接收、處理過(guò)長(zhǎng)的數(shù)據(jù)包。
像zigbee這樣的物理層每幀最大只能傳輸127個(gè)字節(jié),通過(guò)每層不斷的封包到應(yīng)用層后每包才100個(gè)字節(jié)。當(dāng)上層用戶協(xié)議的數(shù)據(jù)包過(guò)大,無(wú)法一次性傳輸,就只能分包或者分組下發(fā),最終接收方組包后解析提取數(shù)據(jù)。
2
分包設(shè)計(jì)的考慮
有些朋友該說(shuō)了,我就不喜歡搞大包發(fā)送,使用短包,然后通過(guò)不同的標(biāo)識(shí)進(jìn)行不同數(shù)據(jù)位的定義,簡(jiǎn)單很多。
當(dāng)然長(zhǎng)包與短包并沒(méi)有本質(zhì)上的區(qū)別,其目的都是傳輸數(shù)據(jù),但在實(shí)踐的過(guò)程中還是會(huì)遇到居多處理上的區(qū)別:
數(shù)據(jù)的同步性方面:
比如當(dāng)通信的設(shè)備轉(zhuǎn)速超了,同時(shí)報(bào)了一個(gè)故障碼,如果采用短包上傳,很可能故障碼和轉(zhuǎn)速位于不同的數(shù)據(jù)包中,當(dāng)數(shù)據(jù)包丟包或許是亂序,就會(huì)導(dǎo)致當(dāng)接收到故障碼的時(shí)候,此時(shí)超標(biāo)的轉(zhuǎn)速值已經(jīng)丟失或者延時(shí)等,有概率不能準(zhǔn)確獲得故障時(shí)的超標(biāo)轉(zhuǎn)速。
而使用長(zhǎng)包,只需要發(fā)送方能夠保證打包的時(shí)候同步,那么接收方就可以同步獲得相應(yīng)的數(shù)據(jù)。
通信協(xié)議設(shè)計(jì)自由度方面:
在設(shè)計(jì)協(xié)議的時(shí)候,長(zhǎng)包會(huì)更加的自由,大多數(shù)情況都不需要考慮大數(shù)據(jù)傳輸?shù)?/span>占位問(wèn)題,甚至在編碼上直接copy結(jié)構(gòu)體發(fā)送也是相當(dāng)方便的。
3
計(jì)算包數(shù)問(wèn)題
既然長(zhǎng)包的設(shè)計(jì)相對(duì)比較方便。那分包處理是少不了的?
分包還不簡(jiǎn)單?
要發(fā)100個(gè)字節(jié)的數(shù)據(jù),每次只能發(fā)15個(gè),那發(fā)送7包就可以了,直接編碼,代碼如下:
SendPack=SendNum/PackNum;
if(SendPack%PackNum)SendPack++;
這算是常規(guī)操作,如果覺(jué)得有點(diǎn)難度,還要多敲敲代碼。
一般用C語(yǔ)言比較久的朋友都想去簡(jiǎn)化這種操作,畢竟實(shí)現(xiàn)一個(gè)簡(jiǎn)單的功能需要兩行代碼,強(qiáng)迫癥,忍不了~
就有了本文開(kāi)頭的!!處理方式,或者如下處理也是一樣的:
#include
僅僅只是秀了一下C語(yǔ)言的幾個(gè)小技巧罷了,并沒(méi)有實(shí)質(zhì)性的改善。
很明顯,本文的重點(diǎn)并不是介紹如上兩種辦法,而是如下更加高效的代碼:
PackNum=(total+(singleNum-1))/singleNum;
對(duì)于一些以往沒(méi)有使用的朋友或許有點(diǎn)懵,那bug菌這是嘮叨幾句:
該表達(dá)式主要是利用了取整的特性來(lái)達(dá)到+1的目的。
直接除單包個(gè)數(shù),不能整除的情況,結(jié)果都會(huì)少1,比如10/6,應(yīng)該是2包,而由于最終除法結(jié)果只能是1。
所以通過(guò)補(bǔ)償(singleNum - 1)后,結(jié)果就分兩種情況:
1、原本能夠整除的數(shù),補(bǔ)償后無(wú)法整除,結(jié)果與之前一致;
2、原本不能夠整除的數(shù),其余數(shù)必然在【1~(singleNum- 1)】之間,所以補(bǔ)償以后,其余數(shù)范圍在【singleNum~(singleNum+ singleNum- 2)】,則其結(jié)果為整除部分+1。
與我們分包個(gè)數(shù)是一致的,相當(dāng)巧妙。
4
擴(kuò)展
這種方法不僅僅只是用于通信的分組中,把思維進(jìn)一步泛化。
只要是類(lèi)似分組的處理都可以使用該算法。
比如內(nèi)存的分區(qū),flash的設(shè)計(jì)上都是一個(gè)扇區(qū)一個(gè)扇區(qū)的分布。
現(xiàn)在想分配整數(shù)個(gè)扇形區(qū)域用于存儲(chǔ)某些數(shù)據(jù),每一個(gè)扇區(qū)512個(gè)字節(jié),存儲(chǔ)2000個(gè)字節(jié)的數(shù)據(jù),該分配幾個(gè)扇區(qū)?
我相信你已經(jīng)有答案了~
審核編輯 :李倩
-
嵌入式
+關(guān)注
關(guān)注
5094文章
19178瀏覽量
307732 -
ZigBee
+關(guān)注
關(guān)注
158文章
2271瀏覽量
243360 -
C語(yǔ)言
+關(guān)注
關(guān)注
180文章
7614瀏覽量
137739
原文標(biāo)題:嵌入式數(shù)據(jù)分包以及相關(guān)技巧
文章出處:【微信號(hào):嵌入式情報(bào)局,微信公眾號(hào):嵌入式情報(bào)局】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
嵌入式主板的概述與發(fā)展
![<b class='flag-5'>嵌入式</b>主板的概述與發(fā)展](https://file1.elecfans.com/web2/M00/EB/A1/wKgZomZe5fWAXs4EAABHp9zbA6E074.png)
新手怎么學(xué)嵌入式?
什么是嵌入式?一文讀懂嵌入式主板
嵌入式主板是什么意思?嵌入式主板全面解析
嵌入式常用數(shù)據(jù)結(jié)構(gòu)有哪些
嵌入式系統(tǒng)是什么?
嵌入式開(kāi)發(fā)前景怎么樣?
![<b class='flag-5'>嵌入式</b>開(kāi)發(fā)前景怎么樣?](https://file.elecfans.com/web2/M00/4C/70/pYYBAGKv0omAZ5SxAABZOwjQSKM935.png)
如何提升嵌入式編程能力?
嵌入式系統(tǒng)軟硬件基礎(chǔ)知識(shí)大全
嵌入式系統(tǒng)的外設(shè)器件選擇
![<b class='flag-5'>嵌入式</b>系統(tǒng)的外設(shè)器件選擇](https://file1.elecfans.com/web2/M00/D4/03/wKgaomYkbU2AfzuwAAASqtl4vhI345.jpg)
嵌入式主板,你了解多少?
嵌入式fpga是什么意思
fpga是嵌入式嗎
嵌入式軟件設(shè)計(jì)的原則分享
![<b class='flag-5'>嵌入式</b>軟件設(shè)計(jì)的原則分享](https://file1.elecfans.com/web2/M00/C1/D3/wKgaomXarJuAfAYZAAAk4c2b2Lg596.png)
評(píng)論