<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          談?wù)剶?shù)據(jù)分包以及相關(guān)小技巧

          共 1972字,需瀏覽 4分鐘

           ·

          2022-04-26 07:49


          正文


          大家好,我是bug菌~
          前些天跟大家解釋了如下代碼:

          offset?=?len/64?+?!!(len%64);

          并且跟大家詳細(xì)聊了一下其中的!!操作,然而這段代碼的主要功能還是為了進(jìn)行分包處理,既然是分包自然而然就會想到一種常用的分包處理方法,這也是本文的重點。

          數(shù)據(jù)分包在嵌入式軟件開發(fā)中算是一種非常常見的處理,其主要原因還是硬件上的各種限制,不得已而為之,特別是在通信協(xié)議的定制過程中尤為常見。

          1

          傳輸限制?

          玩過各種通信協(xié)議的朋友都知道,像非常多的通信方式都是以數(shù)據(jù)幀的形式來進(jìn)行傳遞,不同的通信方式因各方面的因素又存在一個最大傳輸字節(jié)數(shù)的限制,考慮到穩(wěn)定性、容錯性等等對單次發(fā)送的數(shù)據(jù)長度進(jìn)行限制,又或者所接收的設(shè)備其內(nèi)存資源有限,不足以接收、處理過長的數(shù)據(jù)包。

          像zigbee這樣的物理層每幀最大只能傳輸127個字節(jié),通過每層不斷的封包到應(yīng)用層后每包才100個字節(jié)。當(dāng)上層用戶協(xié)議的數(shù)據(jù)包過大,無法一次性傳輸,就只能分包或者分組下發(fā),最終接收方組包后解析提取數(shù)據(jù)。

          2

          分包設(shè)計的考慮?

          有些朋友該說了,我就不喜歡搞大包發(fā)送,使用短包,然后通過不同的標(biāo)識進(jìn)行不同數(shù)據(jù)位的定義,簡單很多。

          當(dāng)然長包與短包并沒有本質(zhì)上的區(qū)別,其目的都是傳輸數(shù)據(jù),但在實踐的過程中還是會遇到居多處理上的區(qū)別:

          數(shù)據(jù)的同步性方面:

          比如當(dāng)通信的設(shè)備轉(zhuǎn)速超了,同時報了一個故障碼,如果采用短包上傳,很可能故障碼和轉(zhuǎn)速位于不同的數(shù)據(jù)包中,當(dāng)數(shù)據(jù)包丟包或許是亂序,就會導(dǎo)致當(dāng)接收到故障碼的時候,此時超標(biāo)的轉(zhuǎn)速值已經(jīng)丟失或者延時等,有概率不能準(zhǔn)確獲得故障時的超標(biāo)轉(zhuǎn)速。

          而使用長包,只需要發(fā)送方能夠保證打包的時候同步,那么接收方就可以同步獲得相應(yīng)的數(shù)據(jù)。

          通信協(xié)議設(shè)計自由度方面:

          在設(shè)計協(xié)議的時候,長包會更加的自由,大多數(shù)情況都不需要考慮大數(shù)據(jù)傳輸?shù)?/span>占位問題,甚至在編碼上直接copy結(jié)構(gòu)體發(fā)送也是相當(dāng)方便的。

          3

          計算包數(shù)問題

          既然長包的設(shè)計相對比較方便。那分包處理是少不了的?

          分包還不簡單?

          要發(fā)100個字節(jié)的數(shù)據(jù),每次只能發(fā)15個,那發(fā)送7包就可以了,直接編碼,代碼如下:

          SendPack?=?SendNum?/?PackNum;
          if(SendPack?%?PackNum)SendPack++;


          這算是常規(guī)操作,如果覺得有點難度,還要多敲敲代碼。

          一般用C語言比較久的朋友都想去簡化這種操作,畢竟實現(xiàn)一個簡單的功能需要兩行代碼,強迫癥,忍不了~

          就有了本文開頭的!!處理方式,或者如下處理也是一樣的:

          #include

          #define?PackNum(total,single)??(total/single?+?((total%single)?1:0))
          int?main(void)
          {
          ????printf("packNum:?%d\r\n",PackNum(100,15));
          ????printf("packNum:?%d\r\n",PackNum(150,15));
          ????printf("packNum:?%d\r\n",PackNum(200,15));
          ????printf("packNum:?%d\r\n",PackNum(5,15));
          ????printf("hello?bug?~\r\n");
          ????return?0;
          }

          僅僅只是秀了一下C語言的幾個小技巧罷了,并沒有實質(zhì)性的改善。

          很明顯,本文的重點并不是介紹如上兩種辦法,而是如下更加高效的代碼:

          PackNum?=?(total?+?(singleNum?-?1))/singleNum?;

          對于一些以往沒有使用的朋友或許有點懵,那bug菌這是嘮叨幾句:

          該表達(dá)式主要是利用了取整的特性來達(dá)到+1的目的。

          直接除單包個數(shù),不能整除的情況,結(jié)果都會少1,比如10/6,應(yīng)該是2包,而由于最終除法結(jié)果只能是1。

          所以通過補償(singleNum - 1)后,結(jié)果就分兩種情況:

          1、原本能夠整除的數(shù),補償后無法整除,結(jié)果與之前一致;

          2、原本不能夠整除的數(shù),其余數(shù)必然在【1~(singleNum?- 1)】之間,所以補償以后,其余數(shù)范圍在【singleNum?~(singleNum?+ singleNum?- 2),則其結(jié)果為整除部分+1。

          與我們分包個數(shù)是一致的,相當(dāng)巧妙。

          4

          擴展

          這種方法不僅僅只是用于通信的分組中,把思維進(jìn)一步泛化。

          只要是類似分組的處理都可以使用該算法。

          比如內(nèi)存的分區(qū),flash的設(shè)計上都是一個扇區(qū)一個扇區(qū)的分布。

          現(xiàn)在想分配整數(shù)個扇形區(qū)域用于存儲某些數(shù)據(jù),每一個扇區(qū)512個字節(jié),存儲2000個字節(jié)的數(shù)據(jù),該分配幾個扇區(qū)?

          點擊下面圖片,有星球具體介紹,新用戶有新人優(yōu)惠券,老用戶半價優(yōu)惠,期待大家一起學(xué)習(xí)一起進(jìn)步。


          點擊“閱讀原文”查看更多分享,歡迎點分享、收藏、點贊、在看。


          瀏覽 35
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产成人自拍在线观看 | 婷婷内射精品视频 | 日韩成人免费视频 | 蜜桃人妻系列 | 久久99精品久久久久久草莓 |