视频一区二区中文字幕,91精品久久久久,国产精品久久久,天天狠天天透天干天天怕∴

智宇物聯(lián) 專注于提供高穩(wěn)定、高速率的三網(wǎng)物聯(lián)網(wǎng)卡

婁底物聯(lián)網(wǎng)設(shè)備的固件遠(yuǎn)程升級方案以及軟件代碼

  • 作者:智宇物聯(lián)
  • 發(fā)表時(shí)間:2022年10月13日
  • 來源:智宇物聯(lián)

作為通用的物聯(lián)網(wǎng)設(shè)備,由于用戶需求各不相同,不少用戶有一些個(gè)性化的定制要求;

設(shè)備所對接的傳感器協(xié)議也多種多樣,比如Modbus讀寫參數(shù)的數(shù)據(jù)類型,某些物理量需要特殊的數(shù)據(jù)類型;

甚至可能還存在意想不到的bug。

因此,遠(yuǎn)程升級的功能對于設(shè)備來說必不可少。

遠(yuǎn)程固件升級需要解決以下問題:

1)設(shè)備的遠(yuǎn)程訪問

當(dāng)設(shè)備被安裝于局域網(wǎng)內(nèi)部時(shí),位于遠(yuǎn)程的固件升級軟件工具無法穿透路由器訪問設(shè)備。

2)固件的分包以及傳送

由于設(shè)備的處理器資源有限,無法移植開源的http、FTP等協(xié)議棧,無法通過http、FTP等協(xié)議從服務(wù)器上下載固件,而需要自己實(shí)現(xiàn)代碼,采用TCP協(xié)議進(jìn)行固件包的發(fā)送;

而且對于幾十k甚至上百k的固件,需要將固件拆成幾百個(gè)字節(jié)的數(shù)據(jù)包,逐一發(fā)給設(shè)備;

4)固件的有效性檢驗(yàn)

固件在傳輸過程中,難免會出現(xiàn)錯(cuò)誤。

比如WiFi模塊,或者是ethernet模塊將數(shù)據(jù)通過uart轉(zhuǎn)發(fā)給處理器時(shí),如果有干擾、數(shù)據(jù)可能被破壞;

或者是處理器太忙,來不及接收數(shù)據(jù),導(dǎo)致固件包丟失數(shù)據(jù);

如果不對固件進(jìn)行有效性檢驗(yàn),將被破壞的固件升級進(jìn)控制器,會導(dǎo)致設(shè)備變磚而無法使用;

5)bootloader程序

bootloader程序需要下載固件的有效性檢驗(yàn),程序的擦除、固件數(shù)據(jù)從備份區(qū)到程序區(qū)的搬移。

6)處理器的固件升級軟件實(shí)現(xiàn)

軟件需要實(shí)現(xiàn)數(shù)據(jù)包接收,固件有效性驗(yàn)證、存儲,數(shù)據(jù)應(yīng)答等。

遠(yuǎn)程固件升級系統(tǒng)架構(gòu)

物聯(lián)網(wǎng)設(shè)備的固件遠(yuǎn)程升級方案以及軟件代碼

遠(yuǎn)程固件升級系統(tǒng)架構(gòu)

設(shè)備作為TCP客戶端連接到云服務(wù)器上的TCP服務(wù)端,定時(shí)發(fā)送心跳,維護(hù)連接,從而實(shí)現(xiàn)TCP的長鏈接。

在PC電腦上開發(fā)遠(yuǎn)程升級工具,作為TCP客戶端與云服務(wù)器上的TCP服務(wù)器建立連接;

當(dāng)需要遠(yuǎn)程升級時(shí),通過PC工具向云服務(wù)器發(fā)送消息,所發(fā)消息中包括了遠(yuǎn)程設(shè)備的設(shè)備編號,以及PC工具的設(shè)備編號;

服務(wù)器收到消息之后,根據(jù)消息中的目標(biāo)設(shè)備編號,從其維護(hù)的長鏈接中找到與該編號對應(yīng)的鏈接,通過該鏈接向設(shè)備轉(zhuǎn)發(fā)該消息;

設(shè)備收到消息之后,對消息中的固件包進(jìn)行有效性驗(yàn)證,如果有效,則寫入到固件暫存區(qū),并回復(fù)成功,否則回復(fù)失敗。

一些設(shè)計(jì)要點(diǎn)

處理器的存儲空間安排:

以STM32F103RCT6為例,該處理器有256KByte的FLASH空間;

4KByte的空間用于bootloader程序。

52KByte用于存儲用戶數(shù)據(jù);

剩余的FLASH空間一半作為程序存儲區(qū),一半作為固件暫存區(qū),程序必須小于100KByte。

固件的生成與分包

在Keil中,將程序的memory的起始地址設(shè)置為0x8001000,大小設(shè)置為0x19000。

同時(shí),設(shè)置運(yùn)行fromelf.exe,使得編譯程序時(shí)自動(dòng)生成用于固件升級的bin文件。

物聯(lián)網(wǎng)設(shè)備的固件遠(yuǎn)程升級方案以及軟件代碼

Keil設(shè)置

通過delphi將生成出來的bin文件讀入,并采用下述代碼進(jìn)行發(fā)包,加上協(xié)議頭以及CRC32的校驗(yàn)值。

pkgs := stream.Size div perpage;
  rem := stream.Size mod perpage;
  addr := 0;
  if(rem > 0) then
  begin
    pkgs := pkgs + 1;
  end;
  strcrc := '';
  for i:= 0 to (pkgs - 1) do
  begin
       curlen := perpage;
       if((i + 1) * perpage > bytecount) then
       begin
          curlen := bytecount - (i * perpage);
       end;
       payload :=  inttohex(i* perpage, 8)+inttohex(curlen, 8);      //
       stream.Position := i * perpage;
       k := 0;
       tmpstr := '';
       for j:= 0 to (curlen - 1) do
       begin
        stream.Read(val, 1);
        if((k and 1) = 0)  then
        begin
          tmpstr := inttohex(val, 2);
        end
        else
        begin
          tmpstr := inttohex(val, 2) + tmpstr;
        end;
        inc(k);
        if((k and 1) = 0)  then
        begin
          payload := payload + tmpstr;
        end;
       end;
       tempcrc :=  crc(payload);
       payload := tempcrc +payload;
       payload := inttohex((2 + 4 + 4 + perpage) * i, 8) + payload;
       payload := '01'+payload;
       strcrc := strcrc + tempcrc;
       payload := payload + crc(payload);;
       str := header+'&msgid='+inttostr(msgid)+'&length='+inttostr(1 + 2 + 4 + 4 + 4 + 2+ curlen)+'&cmd='+payload;
       inc(msgid);
       strcommands.Add(str);
  end;

固件的有效性驗(yàn)證以及升級的可靠性保證

整個(gè)固件包根據(jù)處理器的資源拆分為500個(gè)byte一個(gè)數(shù)據(jù)包;

每一個(gè)數(shù)據(jù)包都計(jì)算CRC32的數(shù)值并加入數(shù)據(jù)包中;

所以CRC32的數(shù)值再計(jì)算一遍CRC32數(shù)值并放入開始升級的命令之中;

控制器收到固件之后,重新計(jì)算500個(gè)byte的CRC32的計(jì)算值并與收到的CRC32值進(jìn)行比對,只有兩者相等時(shí)才存入暫存區(qū);

當(dāng)收到所有數(shù)據(jù)包時(shí),從暫存區(qū)中按包讀出固件,計(jì)算CRC32值與同時(shí)存儲的CRC32值比對,同時(shí)計(jì)算所有CRC32數(shù)值的CRC32數(shù)值,與開始升級的命令中所攜帶的數(shù)值比對。

只有所有CRC32的數(shù)值都相同的情況下,應(yīng)用程序才將升級程序的標(biāo)志位寫入到FLASH中,并重啟處理器進(jìn)入bootloader程序。

bootloader程序從FLASH中讀取到升級程序的標(biāo)志,則從暫存區(qū)中按包讀取數(shù)據(jù),進(jìn)行同樣的CRC32的驗(yàn)證過程,確保無誤的情況下,將暫存區(qū)中的固件搬移到程序區(qū)。

全部程序搬移完之后,再逐個(gè)字節(jié)比較暫存區(qū)以及程序區(qū)的內(nèi)容。

比對時(shí),再檢驗(yàn)CRC32是否正確。

只有CRC32數(shù)值正確并且與程序區(qū)的數(shù)據(jù)都相等的情況下,才清空升級程序的標(biāo)志,完成升級過程。

升級程序的步驟及代碼

步驟1:PC工具發(fā)送清空暫存區(qū)的命令,將暫存區(qū)的內(nèi)存都擦寫成0xff。

步驟2:PC工具發(fā)送寫固件數(shù)據(jù)包的命令,處理器收到之后,進(jìn)行有效性驗(yàn)證,并寫入暫存區(qū),重復(fù)該過程,完成整個(gè)固件的發(fā)送。

步驟3:PC工具發(fā)送開始升級的命令,處理器收到之后,再進(jìn)行一次有效性驗(yàn)證,并重啟,進(jìn)入bootloader程序。

步驟4:bootloader程序進(jìn)行有效性驗(yàn)證之后,將暫存區(qū)的固件搬移至程序區(qū),完成升級;

代碼如下:

U32 data, value, dataB;
U8 res = FALSE;
U8 flag;
U16 pointer;
U16 len;

U8 *ins = lins + AP_ID_HEX_BYTE;

if(fnCRC16_Check(lins, llen)){
  len = 0;
  if(llen >= AP_ID_HEX_BYTE){
    len = llen - AP_ID_HEX_BYTE;
  }
  if(inscode == FM_OPERATECODE_START){
    if(fmups.m_uchState == FM_STATE_IDLE){
      if(len == (1 + 4 + FM_STARTCODE_LEN + 2 )){

        if(fnFM_IsStartStopValid(&ins[1 + 4])){
          data = (U32)ins[1] << 24;	
          data |= (U32)ins[2] << 16;
          data |= (U32)ins[3] << 8;
          data |= (U32)ins[4];
          if(data < FLASH_ROM_SIZE_FIRMWARE){
            fmups.m_uchState = FM_STATE_INIT;
            fmups.m_ulLen = data;
            fmups.m_uiTimer = FM_STATE_TIME;
            res = TRUE;
          }
        }
      }
    }
  }
  else if(inscode == FM_OPERATECODE_DOWNLOAD){

    if(fmups.m_uchState == FM_STATE_DOWNLOAD){

      if((len > (1 + 4 + 2 + 4 + 4 + 2))
         && (len <= (1 + 4 + 2 + 4 + 4 + 2 + FM_DOWNLOAD_EVERYMSG))){

        data = (U32)ins[1] << 24;	
        data |= (U32)ins[2] << 16;
        data |= (U32)ins[3] << 8;
        data |= (U32)ins[4];

        value = (U32)ins[7] << 24;	
        value |= (U32)ins[8] << 16;
        value |= (U32)ins[9] << 8;
        value |= (U32)ins[10];

        dataB = (U32)ins[11] << 24;	
        dataB |= (U32)ins[12] << 16;
        dataB |= (U32)ins[13] << 8;
        dataB |= (U32)ins[14];

        flag = TRUE;
        if(value != fmups.m_uchPointer){
          flag = FALSE;
          if((value + dataB) == fmups.m_uchPointer){
            res = TRUE;
          }
        }
        if(data >= (FLASH_ROM_SIZE_FIRMWARE - (FM_DOWNLOAD_EVERYMSG + 4+ 4 + 2))){
          flag = FALSE;
        }
        if(dataB > FM_DOWNLOAD_EVERYMSG){
          flag = FALSE;
        }
        if((fmups.m_uchPointer + dataB) > fmups.m_ulLen){
          flag = FALSE;
        }
        if(flag){
          if(value == fmups.m_uchPointer){
            res = fnFL_WriteBytesAndCheck(data + FLASH_ROM_ADDR_FIRMWARE, (2 + 4 + 4 + dataB), &ins[5]);
            if(res){
              fmups.m_uchPointer += dataB;
            }
          }else{
            res = TRUE;
          }
        }
      }
    }
  }
  else if(inscode == FM_OPERATECODE_STOP){
    if(len == (1 + 2 + 2 + FM_STARTCODE_LEN)){
      if(fnFM_IsStartStopValid(&ins[3])){
        if(fmups.m_uchState == FM_STATE_COMPLETE){
          if(fnFM_Check(ins[1], ins[2])){
            res = fnFM_ProCon(ins[1], ins[2]);
            if(res){
              fmups.m_uchReStartTimer = 10;
            }
          }

        }
      }
    }
  }
  else if(inscode == FM_OPERATECODE_RESET){
    if(len == (1 + 2 + FM_STARTCODE_LEN)){
      if(fnFM_IsStartStopValid(&ins[1])){
        res = TRUE;
        fmups.m_uchState = FM_STATE_IDLE;
        fmups.m_uiTimer = 0;
      }
    }
  }
}
ack[0] = inscode | 0x80;
ack[1] = res;
ack[2] = 0 ;
pointer = 3;
return(pointer);
物聯(lián)網(wǎng)設(shè)備的固件遠(yuǎn)程升級方案以及軟件代碼

最新資訊
最熱資訊
视频一区二区中文字幕,91精品久久久久,国产精品久久久,天天狠天天透天干天天怕∴
<ul id="i4ug0"></ul>
  • <ul id="i4ug0"></ul>
    <ul id="i4ug0"></ul> <ul id="i4ug0"><sup id="i4ug0"></sup></ul><ul id="i4ug0"></ul>
  • 久久久伊人欧美| 亚洲视频在线观看| 久久久久九九九| 影音先锋日韩有码| 国产欧美日韩在线播放| 久久久精品午夜少妇| 91久久极品少妇xxxxⅹ软件| 亚洲黄色精品| 欧美伊人久久久久久久久影院 | 久久久久久久91| 午夜激情综合网| 国产精品mm| 欧美精品成人| 亚洲欧美亚洲| 亚洲高清免费| 黄色欧美成人| 欧美无乱码久久久免费午夜一区| 久久综合九色综合久99| 一本色道久久综合狠狠躁篇的优点 | 99这里有精品| 国产精品亚洲综合一区在线观看| 日韩午夜在线观看视频| 亚洲大胆av| 国产精品久久久久久亚洲调教 | 亚洲国产精品国自产拍av秋霞| 国产在线观看精品一区二区三区| 国产一区二区三区四区| 欧美日韩一卡二卡| 欧美影院一区| 日韩视频二区| 日韩一区二区免费高清| 国产有码一区二区| 国产在线麻豆精品观看| 欧美视频中文一区二区三区在线观看| 欧美日韩国产综合网| 国产精品视频久久一区| 老司机免费视频久久| 中文在线资源观看网站视频免费不卡| 国精品一区二区| 国产欧美日韩一区| 欧美日韩国产免费| 国产精品jvid在线观看蜜臀| 久久综合电影| 国产日本欧美一区二区三区在线| 亚洲欧美日韩视频一区| 亚洲精品久久久久久久久久久久久 | 国产欧美视频一区二区三区| 国语精品中文字幕| 亚洲国产高清一区| 国产三区精品| 影音先锋日韩精品| 国产亚洲精品bt天堂精选| 国产真实乱偷精品视频免| 国产精品99一区| 国产区日韩欧美| 午夜精品成人在线视频| 亚洲一区二区三区三| 在线不卡中文字幕| 91久久久亚洲精品| 尤物yw午夜国产精品视频明星| 亚洲国产二区| 曰本成人黄色| 日韩一级精品视频在线观看| 在线看视频不卡| 欧美高清视频| 欧美激情第六页| 久久精品国产一区二区电影| 久热国产精品| 久久在线免费| 欧美日韩亚洲高清一区二区| 欧美国产综合视频| 国产精品社区| 国产精品入口福利| 在线精品观看| 在线观看日韩国产| 一区二区国产精品| 久久久精品日韩欧美| 久久成人精品电影| 欧美激情一区二区三区成人| 欧美成人高清| 国产精品视频在线观看| 国产精品护士白丝一区av| 精品动漫3d一区二区三区| 黄色成人在线网址| 一区二区日韩| 久久综合中文字幕| 美女日韩在线中文字幕| 国产精品第13页| 国产精品视频久久| 亚洲日本无吗高清不卡| 日韩香蕉视频| 久久综合精品一区| 国产精品视频xxx| 国产视频久久网| 一本大道久久a久久综合婷婷| 夜夜嗨av一区二区三区网站四季av | 欧美日韩精品二区| 国产精品va在线播放| 在线观看日韩av| 国产日产高清欧美一区二区三区| 亚洲自拍另类| 欧美电影资源| 欧美日韩一区二区三| 一区二区三区中文在线观看| 欧美电影免费| 久久精品国产99| 国产精品啊啊啊| 国产欧美在线视频| 日韩手机在线导航| 久久免费视频一区| 欧美成人a视频| 韩国自拍一区| 日韩视频一区二区三区| 久久人人97超碰人人澡爱香蕉| 亚洲欧洲综合另类| 国产偷自视频区视频一区二区| 一本色道久久综合狠狠躁篇的优点| 久久婷婷影院| 欧美日韩国产在线| 亚洲国产精品一区在线观看不卡| 日韩午夜av| 欧美成人精品激情在线观看| 国产在线播放一区二区三区| 久久精品在线视频| 亚洲欧美在线一区二区| 欧美日本一道本在线视频| 国产精品理论片在线观看| 日韩一区二区精品| 欧美黄色网络| 国产欧美精品日韩| 亚洲男人天堂2024| 欧美四级剧情无删版影片| 国产一区二区三区的电影| 欧美亚洲一级片| 国产精品午夜春色av| 亚洲福利一区| 麻豆精品视频在线观看| 黄色亚洲网站| 久久人人爽人人爽| 欧美视频一区二区| 一区二区日韩免费看| 欧美精品一二三| 国产亚洲精品美女| 欧美亚洲一区二区在线观看| 国产精品久久中文| 亚洲黑丝在线| 欧美精品激情在线观看| 亚洲乱码精品一二三四区日韩在线| 欧美福利网址| 韩日成人在线| 久久资源在线| 亚洲国产99| 欧美大学生性色视频| 国产一区二区高清| 久久精品视频免费播放| 国产一区二区三区四区三区四| 亚洲最新色图| 国产精品老牛| 欧美中文日韩| 激情欧美丁香| 免费观看成人鲁鲁鲁鲁鲁视频| 国产精品国产三级国产aⅴ入口| 亚洲视频在线免费观看| 国产精品美女久久久久av超清| 亚洲人成77777在线观看网| 欧美激情精品久久久久久免费印度 | 老司机成人在线视频| 欧美丝袜第一区| 国产偷久久久精品专区| 99国内精品久久| 国产精品毛片a∨一区二区三区|国| 亚洲一区尤物| 国产亚洲欧美一区| 久久综合五月| 国产亚洲亚洲| 欧美mv日韩mv国产网站| 欧美激情一区二区三区成人| 欧美激情一区二区三区四区| 99精品国产一区二区青青牛奶| 欧美日韩综合| 亚洲蜜桃精久久久久久久| 国产精品h在线观看| 欧美一区二区视频在线观看| 国产一区二区三区四区在线观看| 快射av在线播放一区| 国模精品一区二区三区色天香 | 久久琪琪电影院| 国产日韩综合| 欧美成人精品在线观看| 一本色道久久88综合日韩精品 | 久久夜色精品| 国产主播喷水一区二区| 欧美黑人一区二区三区| 亚洲一区二区三区色| 国产一区二区三区丝袜| 欧美理论电影在线观看| 亚洲精品国产欧美| 国产精品区一区二区三| 久久久久久综合| 亚洲美女在线看|