当前位置: 首页 > ds >正文

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的基础固件:

/**********************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固件:

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字节:

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:

[  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秒,改动如下:

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         0x1000enum OTA_STEP

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

/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来拉低电平重启,修改代码如下:

--- 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_ALIVEstruct 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);}
+#endifif (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_CNTstruct 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;}
http://www.xdnf.cn/news/15269.html

相关文章:

  • 借助 Wisdom SSH AI 助手,轻松安装 CentOS 8 LNMP 环境
  • 2025前端面试真题以及答案-不断整理中,问题来源于牛客真题
  • CMU15445-2024fall-project1踩坑经历
  • hive/spark sql中unix_timestamp 函数的坑以及时间戳相关的转换
  • 串行数据检测器,检测到011,Y输出1,否则为0.
  • RabbitMQ 之顺序性保障
  • 从零实现一个GPT 【React + Express】--- 【4】实现文生图的功能
  • uniapp-在windows上IOS真机运行(含开发证书申请流程)
  • 重振索尼复古微型电脑——计划以OrangePi CM5 作为主板升级
  • uniapp小程序tabbar跳转拦截与弹窗控制
  • 学习笔记(34):matplotlib绘制图表-房价数据分析与可视化
  • 【数据结构与算法】203.移除链表元素(LeetCode)图文详解
  • 05 唤醒词检测:让语音助手随时待命
  • 平板柔光屏与镜面屏的区别有哪些?技术原理与适用场景全解析
  • Kotlin 常用语法糖完整整理
  • 如何准确查看服务器网络的利用率?
  • 云防火墙有什么用?
  • SoC程序如何使用单例模式运行
  • 企业网络安全的“金字塔”策略:构建全方位防护体系的核心思路
  • OSCP官方靶场-Solstice WP
  • AI驱动的业务系统智能化转型:从静态配置到动态认知的范式革命
  • 【办公类-107-01】20250710视频慢速与视频截图
  • mysql join语句、全表扫描 执行优化与访问冷数据对内存命中率的影响
  • MySQL索引:数据库的超级目录
  • 第35周—————糖尿病预测模型优化探索
  • Android 插件化实现原理详解
  • Apache Dubbo实战:JavaSDK使用
  • 动态物体滤除算法
  • MyBatis-Plus 中使用 Wrapper 自定义 SQL
  • Linux C 文件基本操作