日本a√视频在线,久久青青亚洲国产,亚洲一区欧美二区,免费g片在线观看网站

        <style id="k3y6c"><u id="k3y6c"></u></style>
        <s id="k3y6c"></s>
        <mark id="k3y6c"></mark>
          
          

          <mark id="k3y6c"></mark>

          "); //-->

          博客專欄

          EEPW首頁 > 博客 > 分享一個(gè)OTA升級(jí)相關(guān)的應(yīng)用實(shí)踐!(1)

          分享一個(gè)OTA升級(jí)相關(guān)的應(yīng)用實(shí)踐?。?)

          發(fā)布人:魚鷹談單片機(jī) 時(shí)間:2023-04-23 來源:工程師 發(fā)布文章

          大家好,我是雜燴君。

          本次與大家分享一個(gè)ota升級(jí)相關(guān)的應(yīng)用實(shí)踐。

          應(yīng)用場景

          某項(xiàng)目中,有三塊控制板協(xié)同工作,WiFi模塊掛在其中一塊板上:

          圖片


          其中,三塊板子都有升級(jí)的需求。即board1需要從云端下載各板子的升級(jí)文件之后通過串口分發(fā)給另外兩塊板子。

          思路及一些縮減代碼

          作為board1的開發(fā)者,除了處理好給board2、board3分包分發(fā)升級(jí)文件之外,還需要處理好整個(gè)升級(jí)過程的可視化反饋,即需要在手機(jī)APP上顯示出當(dāng)前的升級(jí)進(jìn)度。

          為了顯示這個(gè)升級(jí)進(jìn)度,可能需要考慮如下情況:

          1、下載升級(jí)包的過程與傳輸升級(jí)包(以下我稱為安裝)的進(jìn)度需不需要分開?

          這里我們選擇分開,即手機(jī)APP觸發(fā)升級(jí),下載過程,手機(jī)APP顯示下載進(jìn)度,下載進(jìn)度走完100之后,顯示安裝進(jìn)度。

          圖片圖片

          一方面比較方便地能看出當(dāng)前處于升級(jí)的那個(gè)過程,對(duì)于研發(fā)而言可以方便定位分析問題,對(duì)于用戶體驗(yàn)上也不會(huì)給用戶增加更多的使用成本。

          此處,下載升級(jí)包的過程其實(shí)不受我們控制的,這一塊阿里的SDK已經(jīng)給我們做好,但有些云平臺(tái)的設(shè)備SDK可能沒有沒有做這個(gè)固件下載的過程,可能只提供了固件所在文件服務(wù)器的http鏈接,需要我們自行進(jìn)行下載,固件下載過程可參照這篇文章:C語言實(shí)現(xiàn)http下載器(附代碼)

          我們要處理的其實(shí)就是下載完升級(jí)包之后的事情,如解壓升級(jí)包、安裝。

          2、每次升級(jí)可能不是升級(jí)所有的板子,如何處理?

          啟動(dòng)安裝的時(shí)候,通過比對(duì)各板子升級(jí)文件的md5值與本地保存的md5值確認(rèn)是否是新的固件,并且通過這個(gè)比對(duì)我們就知道了當(dāng)前升級(jí)包中的需要升級(jí)哪些板子。

          三塊板子組合的升級(jí)情況全部列舉如下:

          左右滑動(dòng)查看全部代碼>>>

          // OTA升級(jí)情況
          #define DEV_NON_SELECTED      0   // 設(shè)備沒有被選中
          #define BOARD1_DEV_SELECTED   1   // board1設(shè)備被選中
          #define BOARD2_DEV_SELECTED   2   // board2設(shè)備被選中
          #define BOARD3_DEV_SELECTED   4   // board3設(shè)備被選中
          typedef enum _ota_update_case
          {
              UPDATE_SELECTED_NULL         = -1,                                                              // 初始值
              UPDATE_NON_DEV               = 0,                                                               // 沒有設(shè)備要升級(jí)
              UPDATE_BOARD1_DEV            = BOARD1_DEV_SELECTED,                                             // 只升級(jí)board1設(shè)備
              UPDATE_BOARD2_DEV            = BOARD2_DEV_SELECTED,                                             // 只升級(jí)board2設(shè)備
              UPDATE_BOARD3_DEV            = BOARD3_DEV_SELECTED,                                             // 只升級(jí)board3設(shè)備
              UPDATE_BOARD1_AND_BOARD2_DEV = BOARD1_DEV_SELECTED + BOARD2_DEV_SELECTED,                       // 升級(jí)board1與board2設(shè)備
              UPDATE_BOARD1_AND_BOARD3_DEV = BOARD1_DEV_SELECTED + BOARD3_DEV_SELECTED,                       // 升級(jí)board1與board3設(shè)備
              UPDATE_BOARD2_AND_BOARD3_DEV = BOARD2_DEV_SELECTED + BOARD3_DEV_SELECTED,                       // 升級(jí)board2與board3設(shè)備
              UPDATE_ALL_DEV               = BOARD1_DEV_SELECTED + BOARD2_DEV_SELECTED + BOARD3_DEV_SELECTED, // 升級(jí)所有設(shè)備
          }ota_update_case_e;

          獲取當(dāng)前升級(jí)包屬于哪一種升級(jí)情況:

          左右滑動(dòng)查看全部代碼>>>

          // 獲取升級(jí)情況
          static ota_update_case_e get_ota_update_case(void)
          {
              md5sum_t calc_board1_img_md5 = {0};
              md5sum_t calc_board2_img_md5 = {0};
              md5sum_t calc_board3_img_md5 = {0};
              ota_update_case_e ota_update_case = UPDATE_SELECTED_NULL;
              ota_update_case_e board1_update_case = UPDATE_SELECTED_NULL;
              ota_update_case_e board2_update_case = UPDATE_SELECTED_NULL;
              ota_update_case_e board3_update_case = UPDATE_SELECTED_NULL;

              // 讀取升級(jí)文件md5參數(shù)表
              bzero(&s_flash_ota_file_md5_list, sizeof(s_flash_ota_file_md5_list));
              read_ota_md5_list_from_file(&s_flash_ota_file_md5_list, sizeof(s_flash_ota_file_md5_list)); 

              // 計(jì)算各升級(jí)文件的md5值
              calc_file_md5(OTA_BOARD1_DEV_IMG_FILE, &calc_board1_img_md5);
              calc_file_md5(OTA_BOARD2_DEV_IMG_FILE, &calc_board2_img_md5);
              calc_file_md5(OTA_BOARD3_DEV_IMG_FILE, &calc_board3_img_md5);

              // 檢測是否選中board1設(shè)備
              if (0 == access(OTA_BOARD1_DEV_IMG_FILE, F_OK) && 
                  FALSE == check_md5_equal(&calc_board1_img_md5, &s_flash_ota_file_md5_list[OTA_IMG_INDEX_BOARD1_DEV]))
              {
                  LOG_D("BOARD1_DEV_SELECTED");
                  board1_update_case = BOARD1_DEV_SELECTED;
              }
              else
              {
                  LOG_D("board1 install file not exist or unchanged, not install");
                  board1_update_case = DEV_NON_SELECTED;
              }

              // 檢測是否選中board2設(shè)備
              if (0 == access(OTA_BOARD2_DEV_IMG_FILE, F_OK) && 
                  FALSE == check_md5_equal(&calc_board2_img_md5, &s_flash_ota_file_md5_list[OTA_IMG_INDEX_BOARD2_DEV]))
              {
                  LOG_D("BOARD2_DEV_SELECTED");
                  board2_update_case = BOARD2_DEV_SELECTED;
              }
              else
              {
                  LOG_D("board2 install file not exist or unchanged, not install");
                  board2_update_case = DEV_NON_SELECTED;
              }

              // 檢測是否選中board3設(shè)備
              if (0 == access(OTA_BOARD3_DEV_IMG_FILE, F_OK) && 
                  FALSE == check_md5_equal(&calc_board3_img_md5, &s_flash_ota_file_md5_list[OTA_IMG_INDEX_BOARD3_DEV]))
              {
                  LOG_D("BOARD3_DEV_SELECTED");
                  board3_update_case = BOARD3_DEV_SELECTED;
              }
              else
              {
                  LOG_D("board3 install file not exist or unchanged, not install");
                  board3_update_case = DEV_NON_SELECTED;
              }

              // 升級(jí)的情況
              ota_update_case = board1_update_case + board2_update_case + board3_update_case;
              LOG_D("ota_update_case = %d", ota_update_case);

              return ota_update_case;
          }
          3、各種不同升級(jí)包情況,如何處理?

          因?yàn)閃iFi掛在board1上,所以整個(gè)升級(jí)過程,如果board1需要升級(jí)的話,board1需要放在最后升級(jí),因?yàn)閎oard1升級(jí)的過程中會(huì)與手機(jī)APP斷連。

          三塊板的固件安裝:

          static void start_board1_ota_install(void);
          static void start_board2_ota_install(void)
          static void start_board3_ota_install(void);
          • start_board1_ota_install為安裝board1固件的過程。安裝board1固件的過程很簡單,可以看做一次板子重啟,升級(jí)安裝命令如:
          #define OTA_BOARD1_DEV_IMG_FILE   OTA_FIREWARE_EXTRACT_FILE_PATH "board1_update.img"         // board1固件
          #define SHELL_CMD_START_BOARD1_DEV_OTA_INSTALL    "updateEngine --image_url=" OTA_BOARD1_DEV_IMG_FILE " --misc=update --savepath=" OTA_BOARD1_DEV_IMG_FILE " --reboot"
          • start_board2_ota_install為安裝board2固件的過程。安裝board2固件的過程即board1往board2發(fā)送board2固件的過程,整個(gè)過程通過數(shù)據(jù)傳輸量占總數(shù)據(jù)量的大小可表明安裝進(jìn)度。
          • start_board3_ota_install安裝board3固件的過程,安裝board3固件的過程即board1往board3發(fā)送board3固件的過程,整個(gè)過程通過數(shù)據(jù)傳輸量占總數(shù)據(jù)量的大小可表明安裝進(jìn)度。


          *博客內(nèi)容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀點(diǎn),如有侵權(quán)請(qǐng)聯(lián)系工作人員刪除。



          關(guān)鍵詞: 單片機(jī)

          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉