AIC8800M40低功耗wifi在ARM-LINUX开发板上做OTA的调试经验

ARM-LINUX开发板通过SDIO 接口和AIC8800M40低功耗WIFI/BT芯片连接,然后整个WIFI协议栈都是跑在AIC8800M40芯片上面,所以就不需要LINUX的WIFI驱动和CFG80211协议栈,当然AIC8800M40的固件就需要能够OTA升级了,看了下SDK提供的文档,OTA升级可以通过HOST_OTA和HTTP_OTA,这里我记录一下HOST OTA方式的调试经验:

FLASH分区

首先看一下整个FLASH的分区,bootloader有20KB,当前工作区(包含image_info和cur_image),备份分区(可以删除),OTA升级分区(image_header + upg_image)

从上图可以看到升级分区的烧写地址是0x08156000,当前工作区代码运行的地址为0x08006000。升级分区LZMA压缩代码段地址为0x08157000;

1:制作包含bootloader的基础固件:

powershell 复制代码
/**********************LZMA OTA BUILD********************/
./build_fhostif_wifi_case.sh -j8
cd ../target_test/
./build_lzma_bootloader.sh -j8
cd ../../../docs/Tool/OTA-Tool/bootloader_lzma
cp ../../../../build/basic-aic8800m40/bootloader.bin source/bootloader.bin
cp ../../../../build/host-wifi-aic8800m40/host_wb_aic8800m40.bin source/host_wb.bin
python ota_bin_generator.py

2:制作升级的OTA固件:

powershell 复制代码
cp ../../../../build/host-wifi-aic8800m40/host_wb_aic8800m40.bin source/host_wb_upg.bin
python image_pack_ota.py 0x8157000 v0.1.3 //注意这里的0x8157000是LZMA升级固件的地址,v0.1.3是版本号

下面列举一下在调试过程中碰到的问题:

问题1:

通过在linux host上发送升级命令:custom_msg vnet0 13 /app/host_wb_upg_lzma.bin,然后通过串口查看wifi芯片的打印,发现wifi芯片直接栈溢出死机了:

解决方案:加大Hostif task线程栈的深度,从原来的384字节翻一倍到768字节:

c 复制代码
index e3711b6..cc4497c 100644
--- a/aic8800-sdk/applications/fhostifwifi/src/fhostif_example.c
+++ b/aic8800-sdk/applications/fhostifwifi/src/fhostif_example.c
@@ -834,7 +834,7 @@ int fhost_application_init(void)
     }

     if (rtos_task_create(hostif_task, "Hostif task", APP_HOSTIF_TASK,
-                         384, NULL, TASK_PRIORITY_HOSTIF, NULL)) {
+                         768, NULL, TASK_PRIORITY_HOSTIF, NULL)) {
         return 3;
     }
     if (rtos_task_create(hostif_rxdata_task, "Hostif rxdata", APP_HOSTIF_RX_TASK,

问题2:

在Linux主机上第一次发送custom_msg vnet0 13 /app/host_wb_upg_lzma.bin命令升级不成功,需要发送第二次才能成功,查看了一下linux主机dmesg log:

clike 复制代码
[  163.003209] rwnx_do_ioctl cmd 35314
[  163.003216] IOCTL PRIVATE+2
[  163.003219] AICWFDBG(LOGTRACE)       >>> mcu_cust_msg()
[  163.003223] mcu_cust_msg: Devipc custom msg "13 /app/host_wb_upg_lzma.bin" on vnet0
[  163.003230] APP_CMD_HOST_OTA
[  163.003234] load_file: /app/host_wb_upg_lzma.bin
[  163.003248] bin-file size: 521727 Byte
[  163.003256] aicwf_sdio_bus_txmsg 1056
[  165.057479] error: aicwf mcu-ota confirm timeout
[  166.171683] MCU-OTA: flash erase OK.

这里发现错误打印:aicwf mcu-ota confirm timeout,通过查看代码发现是主机等待wifi芯片擦除flash 2秒超时了,估计擦除时间比较长,需要3秒多,干脆把超时时间调整为8秒,改动如下:

c 复制代码
index f270e77..97b62c7 100644
--- a/aic8800-sdk/wifi/LinuxDriver/aic8800_netdrv/aicwf_custom_utils.h
+++ b/aic8800-sdk/wifi/LinuxDriver/aic8800_netdrv/aicwf_custom_utils.h
@@ -13,7 +13,7 @@
 #include "rwnx_main.h"


-#define MCU_OTA_TIMEOUT         2000
+#define MCU_OTA_TIMEOUT         8000
 #define IMAGE_INFO_SIZE         0x1000

 enum OTA_STEP

改动之后,OTA成功升级,Log打印如下:

clike 复制代码
/app # dmesg -c
[  515.323602] rwnx_do_ioctl cmd 35314
[  515.323608] IOCTL PRIVATE+2
[  515.323611] AICWFDBG(LOGTRACE)       >>> mcu_cust_msg()
[  515.323615] mcu_cust_msg: Devipc custom msg "13 /app/host_wb_upg_lzma.bin" on vnet0
[  515.323622] APP_CMD_HOST_OTA
[  515.323626] load_file: /app/host_wb_upg_lzma.bin
[  515.323639] bin-file size: 521727 Byte
[  515.323647] aicwf_sdio_bus_txmsg 1056
[  518.523923] MCU-OTA: flash erase OK.
[  518.523958] aicwf_sdio_bus_txmsg 1056
[  518.526858] aicwf_sdio_bus_txmsg 1056
[  518.529762] aicwf_sdio_bus_txmsg 1056
[  520.033543] MCU-OTA: finish LZMA-OTA...

问题三

升级成功后,重启linux系统,发现SDIO WIFI识别不成功,查看一下WIFI芯片的串口打印:

发现wifi芯片重启后,bootloader首先会检测升级分区的版本号,如果有新的版本,则会把升级分区的image搬运到当前的image工作区,这个过程比较耗时;虽然我们linux kernel的SDIO设备检测扫描会延迟3秒,但bootloader搬运的时间加上WIFI系统启动时间远远大于3秒,就会造成SDIO扫描检测不成功。

解决方案:WIFI固件升级后,直接让WIFI芯片重启,而不是等到主控芯片的WIFI ENABLE GPIO来拉低电平重启,修改代码如下:

c 复制代码
--- a/aic8800-sdk/wifi/hostif/fhostif_cmd.c
+++ b/aic8800-sdk/wifi/hostif/fhostif_cmd.c
@@ -51,7 +51,7 @@

 #define HOSTIF_KEEP_ALIVE 0
 #define HOST_CNTRL_DHCP   0
-#define HOST_OTA_REBOOT   0
+#define HOST_OTA_REBOOT   1

 #if HOSTIF_KEEP_ALIVE
 struct custom_msg_keep_alive
@@ -1135,17 +1135,17 @@ static int custom_msg_start_ap_handler(uint16_t const host_type,

     set_hostif_wlan_status(HOSTIF_ST_IDLE);
     dbg("HOSTIF_ST: IDLE\n");
-
+#if 1
     // If sta is CONN or ap is START, close it first.
     if (WLAN_CONNECTED == wlan_get_connect_status()) {
         msg.id = WIFI_STA_DISCONNECT;
         wifi_msg_write(&msg);
     }
+#endif
     if (wlan_get_softap_status()) {
         msg.id = WIFI_AP_STOP;
         wifi_msg_write(&msg);
     }
-
     uint8_t *pssid = rtos_malloc(SSID_LEN);
     if (pssid == NULL) {
         dbg("alloc buff fail.\n");
@@ -1470,6 +1470,7 @@ static int custom_msg_host_ota_handler(uint16_t const host_type,
         } else {
             flash_cache_invalid_range((void *)UPGRADE_START_ADDR, 0x1000 + a4k);
             cfm->status = OTA_STEP_FLASH_ERASE_OK;
+            dbg("OTA-Step0: flash erase addr=0x%x, len=0x%x\n", UPGRADE_START_ADDR ,0x1000 + a4k);
         }

     } else if(OTA_STEP_FR_PKG_WRITE == req->ota_step) {
@@ -1478,6 +1479,7 @@ static int custom_msg_host_ota_handler(uint16_t const host_type,
             dbg("OTA_Step1: write pkg at 0x%x fail. Please restart OTA.\r\n", req->ota_msg.ota_pkg_info.flash_addr);
             cfm->status = OTA_STEP_FR_PKG_WRITE_ERR;
         } else {
+            dbg("OTA_Step1: write pkg at 0x%x ,size 0x%x \r\n", req->ota_msg.ota_pkg_info.flash_addr, req->ota_msg.ota_pkg_info.flash_size);
             cfm->status = OTA_STEP_FR_PKG_WRITE_OK;
         }

@@ -1493,6 +1495,7 @@ static int custom_msg_host_ota_handler(uint16_t const host_type,
             flash_cache_invalid_range((void *)UPGRADE_IMAGE_ADDR,
                             (req->ota_msg.ota_pkg_info.flash_addr - UPGRADE_IMAGE_ADDR) + req->ota_msg.ota_pkg_info.flash_size);
             cfm->status = OTA_STEP_LT_PKG_WRITE_OK;
+            dbg("OTA_Step2: recv last pkg and write OK, UPGRADE_IMAGE_ADDR = 0x%x.\r\n", UPGRADE_IMAGE_ADDR);
         }

     }
@@ -1516,7 +1519,7 @@ static int custom_msg_host_ota_handler(uint16_t const host_type,

             // Use OTA-Tool to build OTA.bin, its version is "v0.1.0".
             // Updated version is necessary and newer (than "v0.1.0") when build newer bin!
-            char *version = "v0.1.1";  // strlen(version) <= VER_BYTE_CNT
+            char *version = "v0.1.2";  // strlen(version) <= VER_BYTE_CNT
             struct image_info *curr_info = (void *)CURRENT_INFO_ADDR;
             dbg("OTA_Step3: new-version is %s, curr-version is %s\n", version, curr_info->version);
             if (strcmp((const char *)curr_info->version, version) >= 0) {
@@ -1561,8 +1564,17 @@ static int custom_msg_host_ota_handler(uint16_t const host_type,
                     dbg("OTA_Step3: erease upg_image header fail.\n");
                 }
             } else {
-                dbg("OTA_Step3: LZMA OTA finish...\n");
+                dbg("OTA_Step3: LZMA OTA finish....\n");
                 cfm->status = OTA_STEP_LZMA_CRC_CHECK_OK;
+                e2a_msg_send(host_type, cfm);
+   #if HOST_OTA_REBOOT
+                int ret = rtos_timer_start(reboot_timer, 1000, false);
+                if (ret)
+                    dbg("start reboot_timer failed: %d\n", ret);
+    #endif
+                return KE_MSG_CONSUMED;
+
+
             }
         }
     }
@@ -1574,12 +1586,6 @@ static int custom_msg_host_ota_handler(uint16_t const host_type,
     e2a_msg_send(host_type, cfm);
     #endif /* PLF_OTA */

-    #if HOST_OTA_REBOOT
-    int ret = rtos_timer_start(reboot_timer, 1000, false);
-    if (ret)
-        dbg("start reboot_timer failed: %d\n", ret);
-    #endif
-
     return KE_MSG_CONSUMED;
 }
相关推荐
deeper_wind5 小时前
k8s-容器化部署论坛和商城服务(小白的“升级打怪”成长之路)
linux·运维·容器·kubernetes
勇往直前plus5 小时前
VMware centos磁盘容量扩容教程
linux·运维·centos
政安晨6 小时前
Ubuntu 服务器无法 ping 通网站域名的问题解决备忘 ——通常与网络配置有关(DNS解析)
linux·运维·服务器·ubuntu·ping·esp32编译服务器·dns域名解析
路溪非溪8 小时前
嵌入式Linux驱动开发杂项总结
linux·运维·驱动开发
Neolock8 小时前
Linux应急响应一般思路(三)
linux·web安全·应急响应
被遗忘的旋律.9 小时前
Linux驱动开发笔记(七)——并发与竞争(上)——原子操作
linux·驱动开发·笔记
轻松Ai享生活9 小时前
minidump vs core dump
linux
轻松Ai享生活10 小时前
详细的 Linux 常用文件系统介绍
linux
张童瑶11 小时前
Linux 离线安装lrzsz(rz、sz上传下载小插件)
linux·运维·centos
十五年专注C++开发11 小时前
通信中间件 Fast DDS(二) :详细介绍
linux·c++·windows·中间件·fastdds