Explorar o código

add: airlink,从机fota跑通数据传输,但底层没有更新成功,仅脚本更新成功了,就很奇怪

Wendal Chen hai 11 meses
pai
achega
2e33d15675

+ 14 - 1
components/airlink/binding/luat_lib_airlink.c

@@ -9,6 +9,7 @@
 #include "luat_mcu.h"
 #include <math.h>
 #include "luat_airlink.h"
+#include "luat_airlink_fota.h"
 #include "luat_zbuff.h"
 
 #define LUAT_LOG_TAG "airlink"
@@ -272,7 +273,15 @@ static int l_airlink_config(lua_State *L) {
 static int l_airlink_sfota(lua_State *L) {
     // 直接发指令是不行了, 需要干预airlink task的执行流程
     // bk72xx的flash擦除很慢, 导致spi master需要等很久才能发下一个包
-    return 0;
+    const char* path = luaL_checkstring(L, 1);
+    luat_airlink_fota_t ctx = {0};
+    memcpy(ctx.path, path, strlen(path) + 1);
+    int ret = luat_airlink_fota_init(&ctx);
+    if (ret) {
+        LLOGE("sfota 启动失败!!! %s %d", path, ret);
+    }
+    lua_pushboolean(L, ret == 0);
+    return 1;
 }
 
 static int l_airlink_debug(lua_State *L) {
@@ -296,6 +305,10 @@ static const rotable_Reg_t reg_airlink[] =
 
     // 测试用的fota指令
     { "sfota",         ROREG_FUNC(l_airlink_sfota )},
+    { "sfota_init",    ROREG_FUNC(l_airlink_sfota_init )},
+    { "sfota_done",    ROREG_FUNC(l_airlink_sfota_done )},
+    { "sfota_end",     ROREG_FUNC(l_airlink_sfota_end )},
+    { "sfota_write",   ROREG_FUNC(l_airlink_sfota_write )},
 
     { "debug",         ROREG_FUNC(l_airlink_debug )},
 

+ 1 - 0
components/airlink/include/luat_airlink_fota.h

@@ -5,6 +5,7 @@
 
 typedef struct luat_airlink_fota {
     uint32_t state;
+    size_t total_size;
     char path[64];
     size_t wait_init;
     size_t wait_first_data;

+ 6 - 4
components/airlink/src/exec/luat_airlink_cmd_exec_basic.c

@@ -49,9 +49,11 @@ int luat_airlink_cmd_exec_fota_init(luat_airlink_cmd_t *cmd, void *userdata)
 
 int luat_airlink_cmd_exec_fota_write(luat_airlink_cmd_t *cmd, void *userdata)
 {
-    LLOGD("收到FOTA数据!!!");
+    // LLOGD("收到FOTA数据, len=%ld %02X%02X%02X%02X", cmd->len, cmd->data[0], cmd->data[1], cmd->data[2], cmd->data[3]);
     int ret = luat_fota_write(cmd->data, cmd->len);
-    LLOGD("fota_write ret %d", ret);
+    if (ret) {
+        LLOGD("fota_write ret %d", ret);
+    }
     return 0;
 }
 
@@ -59,7 +61,7 @@ int luat_airlink_cmd_exec_fota_done(luat_airlink_cmd_t *cmd, void *userdata)
 {
     LLOGD("收到FOTA传输完毕指令!!!");
     int ret = luat_fota_done();
-    LLOGD("fota_write ret %d", ret);
+    LLOGD("fota_done ret %d", ret);
     return 0;
 }
 
@@ -67,7 +69,7 @@ int luat_airlink_cmd_exec_fota_end(luat_airlink_cmd_t *cmd, void *userdata)
 {
     LLOGD("收到FOTA传输完毕指令!!!");
     int ret = luat_fota_end(1);
-    LLOGD("fota_write ret %d", ret);
+    LLOGD("fota_end ret %d", ret);
     return 0;
 }
 

+ 85 - 56
components/airlink/src/luat_airlink_fota.c

@@ -8,16 +8,21 @@
 #define LUAT_LOG_TAG "airlink.fota"
 #include "luat_log.h"
 
-luat_airlink_fota_t* g_airlink_fota;
+luat_airlink_fota_t *g_airlink_fota;
 
-int luat_airlink_fota_init(luat_airlink_fota_t* ctx) {
-    if (g_airlink_fota || g_airlink_fota->state != 0) {
+int luat_airlink_fota_init(luat_airlink_fota_t *ctx)
+{
+    LLOGD("执行g_airlink_fota %p %p", g_airlink_fota, ctx);
+    if (g_airlink_fota && g_airlink_fota->state != 0)
+    {
         return -1;
     }
-    if (!g_airlink_fota) {
+    if (!g_airlink_fota)
+    {
         g_airlink_fota = luat_heap_malloc(sizeof(luat_airlink_fota_t));
     }
-    if (g_airlink_fota == NULL) {
+    if (g_airlink_fota == NULL)
+    {
         LLOGE("airlink fota malloc failed");
         return -2;
     }
@@ -26,8 +31,10 @@ int luat_airlink_fota_init(luat_airlink_fota_t* ctx) {
     return 0;
 }
 
-int luat_airlink_fota_stop(void) {
-    if (g_airlink_fota == NULL) {
+int luat_airlink_fota_stop(void)
+{
+    if (g_airlink_fota == NULL)
+    {
         return 0;
     }
     g_airlink_fota->state = 0;
@@ -35,41 +42,48 @@ int luat_airlink_fota_stop(void) {
 }
 
 #define AIRLINK_SFOTA_BUFF_SIZE (1600)
-static uint8_t* s_airlink_fota_txbuff;
-static uint8_t* s_airlink_fota_rxbuff;
-static uint8_t* s_airlink_fota_cmdbuff;
+static uint8_t *s_airlink_fota_txbuff;
+static uint8_t *s_airlink_fota_rxbuff;
+static uint8_t *s_airlink_fota_cmdbuff;
 
-static void pack_and_send(uint16_t cmd_id, uint8_t* data, size_t len) {
+static void pack_and_send(uint16_t cmd_id, uint8_t *data, size_t len)
+{
     // 首先, 打包到txbuff中
-    luat_airlink_cmd_t* cmd = s_airlink_fota_cmdbuff;
+    luat_airlink_cmd_t *cmd = s_airlink_fota_cmdbuff;
     cmd->cmd = cmd_id;
     cmd->len = len;
-    if (len) {
+    if (len)
+    {
         memcpy(cmd->data, data, len);
     }
 
-    luat_airlink_data_pack(data, sizeof(luat_airlink_cmd_t) + len, s_airlink_fota_txbuff);
-
-    airlink_wait_for_slave_ready(1000);
+    luat_airlink_data_pack(cmd, sizeof(luat_airlink_cmd_t) + len, s_airlink_fota_txbuff);
+    // LLOGD("发送sFOTA %d %d", cmd->cmd, cmd->len);
+    airlink_wait_for_slave_ready(5000);
     airlink_transfer_and_exec(s_airlink_fota_txbuff, s_airlink_fota_rxbuff);
 
     memset(s_airlink_fota_txbuff, 0, AIRLINK_SFOTA_BUFF_SIZE);
 }
 
-void airlink_sfota_exec(void) {
+void airlink_sfota_exec(void)
+{
     size_t wait_timeout = 0;
     int ret = 0;
-    LLOGI("开始执行sFOTA");
-    FILE* fd = luat_fs_fopen(g_airlink_fota->path, "rb");
-    if (fd == NULL) {
+    g_airlink_fota->total_size = luat_fs_fsize(g_airlink_fota->path);
+    LLOGI("开始执行sFOTA file size %ld", g_airlink_fota->total_size);
+    FILE *fd = luat_fs_fopen(g_airlink_fota->path, "rb");
+    if (fd == NULL)
+    {
         LLOGE("打开sFOTA文件失败 %s", g_airlink_fota->path);
         goto clean;
     }
-    if (s_airlink_fota_txbuff == NULL) {
+    if (s_airlink_fota_txbuff == NULL)
+    {
         s_airlink_fota_txbuff = luat_heap_opt_malloc(AIRLINK_MEM_TYPE, AIRLINK_SFOTA_BUFF_SIZE);
         s_airlink_fota_rxbuff = luat_heap_opt_malloc(AIRLINK_MEM_TYPE, AIRLINK_SFOTA_BUFF_SIZE);
         s_airlink_fota_cmdbuff = luat_heap_opt_malloc(AIRLINK_MEM_TYPE, AIRLINK_SFOTA_BUFF_SIZE);
-        if (s_airlink_fota_txbuff == NULL || s_airlink_fota_rxbuff == NULL || s_airlink_fota_cmdbuff == NULL) {
+        if (s_airlink_fota_txbuff == NULL || s_airlink_fota_rxbuff == NULL || s_airlink_fota_cmdbuff == NULL)
+        {
             LLOGE("申请sFOTA内存失败");
             goto clean;
         }
@@ -78,51 +92,59 @@ void airlink_sfota_exec(void) {
         memset(s_airlink_fota_cmdbuff, 0, AIRLINK_SFOTA_BUFF_SIZE);
     }
     // 首先, 发送fota_init指令
-    // luat_airlink_send_cmd_simple_nodata(0x04);
     pack_and_send(0x04, NULL, 0);
 
     wait_timeout = 500;
-    if (g_airlink_fota->wait_init > 0) {
+    if (g_airlink_fota->wait_init > 0)
+    {
         wait_timeout = g_airlink_fota->wait_init;
     }
     LLOGI("等待sFOTA初始化 %dms", wait_timeout);
     luat_rtos_task_sleep(wait_timeout);
-    
-    // 开始发送数据
-    ret = luat_fs_fread(s_airlink_fota_rxbuff, 1, 1400, fd);
-    if (ret != 1400) {
-        LLOGE("读取sFOTA文件失败 %d", ret);
-        goto clean;
-    }
-    // 第一个包要等很久的
-    // luat_airlink_send_cmd_simple(0x05, s_airlink_fota_rxbuff, 1400);
-    pack_and_send(0x05, s_airlink_fota_rxbuff, 1400);
-    wait_timeout = 5000;
-    if (g_airlink_fota->wait_first_data) {
-        wait_timeout = g_airlink_fota->wait_first_data;
-    }
-    LLOGI("等待sFOTA第一个包执行完成 %dms", wait_timeout);
-    luat_rtos_task_sleep(wait_timeout);
 
-    // 发送剩余的数据
+    // 开始发送数据
     wait_timeout = 10;
-    if (g_airlink_fota->wait_data) {
+    if (g_airlink_fota->wait_data)
+    {
         wait_timeout = g_airlink_fota->wait_data;
     }
-    while (g_airlink_fota->state) {
-        ret = luat_fs_fread(s_airlink_fota_rxbuff, 1, 1400, fd);
-        if (ret < 1) {
+    size_t sent_size = 0;
+    while (g_airlink_fota->state)
+    {
+        ret = luat_fs_fread(s_airlink_fota_rxbuff, 1, 1024, fd);
+        if (ret < 1)
+        {
             break;
         }
-        if (wait_timeout > 0) {
-            luat_rtos_task_sleep(wait_timeout);
+        sent_size += ret;
+        if (sent_size % (64 * 1024) == 0)
+        {
+            // 每64k打印一次日志
+            LLOGD("sfota sent %ld/%ld head %02X%02X%02X%02X", sent_size, g_airlink_fota->total_size,
+                  s_airlink_fota_rxbuff[0], s_airlink_fota_rxbuff[1], s_airlink_fota_rxbuff[2], s_airlink_fota_rxbuff[3]);
         }
-        // luat_airlink_send_cmd_simple(0x05, s_airlink_fota_rxbuff, ret);
         pack_and_send(0x05, s_airlink_fota_rxbuff, ret);
+        if (sent_size == (5 * 1024))
+        {
+            // 到达5k后, bk的fota实现需要擦除APP分区,耗时比较久, 需要区分
+            if (g_airlink_fota->wait_first_data)
+            {
+                luat_rtos_task_sleep(g_airlink_fota->wait_first_data);
+            }
+            else
+            {
+                luat_rtos_task_sleep(15000);
+            }
+        }
+        else if (wait_timeout > 0)
+        {
+            luat_rtos_task_sleep(wait_timeout);
+        }
     }
     LLOGI("文件数据发送结束, 等待100ms,执行done操作");
     luat_rtos_task_sleep(100);
     luat_fs_fclose(fd);
+    fd = NULL;
 
     // 发送done命令
     // luat_airlink_send_cmd_simple_nodata(0x06);
@@ -136,19 +158,22 @@ void airlink_sfota_exec(void) {
     LLOGI("end发送结束, 等待3000ms, 执行重启操作");
     luat_rtos_task_sleep(3000);
     // luat_airlink_send_cmd_simple_nodata(0x03);
-    if (g_airlink_fota->pwr_gpio) {
+    if (g_airlink_fota->pwr_gpio)
+    {
         LLOGI("使用GPIO复位 %d", g_airlink_fota->pwr_gpio);
         luat_gpio_set(g_airlink_fota->pwr_gpio, 0);
         luat_rtos_task_sleep(50);
         luat_gpio_set(g_airlink_fota->pwr_gpio, 1);
     }
-    else {
+    else
+    {
         LLOGI("使用命令复位");
         pack_and_send(0x03, NULL, 0);
     }
 
-    wait_timeout = 30*1000;
-    if (g_airlink_fota->wait_reboot) {
+    wait_timeout = 30 * 1000;
+    if (g_airlink_fota->wait_reboot)
+    {
         wait_timeout = g_airlink_fota->wait_reboot;
     }
     luat_rtos_task_sleep(wait_timeout);
@@ -156,18 +181,22 @@ void airlink_sfota_exec(void) {
 
 clean:
     g_airlink_fota->state = 0;
-    if (fd) {
+    if (fd)
+    {
         luat_fs_fclose(fd);
     }
-    if (s_airlink_fota_rxbuff) {
+    if (s_airlink_fota_rxbuff)
+    {
         luat_heap_opt_free(AIRLINK_MEM_TYPE, s_airlink_fota_rxbuff);
         s_airlink_fota_rxbuff = NULL;
     }
-    if (s_airlink_fota_txbuff) {
+    if (s_airlink_fota_txbuff)
+    {
         luat_heap_opt_free(AIRLINK_MEM_TYPE, s_airlink_fota_txbuff);
         s_airlink_fota_txbuff = NULL;
     }
-    if (s_airlink_fota_cmdbuff) {
+    if (s_airlink_fota_cmdbuff)
+    {
         luat_heap_opt_free(AIRLINK_MEM_TYPE, s_airlink_fota_cmdbuff);
         s_airlink_fota_cmdbuff = NULL;
     }