Browse Source

update: airlink,分拆头文件,整理sfota代码

Wendal Chen 9 months ago
parent
commit
02234c621f

+ 12 - 0
components/airlink/include/luat_airlink.h

@@ -77,6 +77,10 @@ void luat_airlink_task_start(void);
 void luat_airlink_print_buff(const char* tag, uint8_t* buff, size_t len);
 void luat_airlink_on_data_recv(uint8_t *data, size_t len);
 
+void airlink_wait_for_slave_ready(size_t timeout_ms);
+void airlink_transfer_and_exec(uint8_t *txbuff, uint8_t *rxbuff);
+void airlink_wait_and_prepare_data(uint8_t *txbuff);
+
 typedef void (*luat_airlink_newdata_notify_cb)(void);
 
 typedef int (*luat_airlink_cmd_exec)(luat_airlink_cmd_t* cmd, void* userdata);
@@ -120,6 +124,9 @@ typedef struct luat_airlink_dev_wifi_info {
     uint8_t bt_mac[6];
     uint8_t sta_state;
     uint8_t ap_state;
+    uint8_t reverted[32]; // 预留的空位
+    uint8_t version[4];
+    uint8_t fw_type[2];
 }luat_airlink_dev_wifi_info_t;
 
 typedef struct luat_airlink_dev_cat_info {
@@ -130,6 +137,9 @@ typedef struct luat_airlink_dev_cat_info {
     uint8_t imei[16];
     uint8_t iccid[20];
     uint8_t imsi[16];
+    uint8_t reverted[32]; // 预留的空位
+    uint8_t version[4];
+    uint8_t fw_type[2];
 }luat_airlink_dev_wifi_cat_t;
 
 typedef struct luat_airlink_dev_info
@@ -164,6 +174,8 @@ uint64_t luat_airlink_get_next_cmd_id(void);
 luat_airlink_cmd_t* luat_airlink_cmd_new(uint16_t cmd, uint16_t data_len);
 
 void luat_airlink_cmd_free(luat_airlink_cmd_t* cmd);
+int luat_airlink_send_cmd_simple_nodata(uint16_t cmd_id);
+int luat_airlink_send_cmd_simple(uint16_t cmd_id, uint8_t* data, uint16_t len);
 
 enum {
     LUAT_AIRLINK_CONF_SPI_ID = 0x100,

+ 15 - 0
components/airlink/include/luat_airlink_drv_gpio.h

@@ -0,0 +1,15 @@
+#ifndef LUAT_AIRLINK_DRV_GPIO_H
+#define LUAT_AIRLINK_DRV_GPIO_H
+
+
+#ifndef LUAT_AIRLINK_H
+#error "include luat_airlink.h first"
+#endif
+
+// GPIO 操作, 临时放这里
+#include "luat_gpio.h"
+int luat_airlink_drv_gpio_setup(luat_gpio_t* gpio);
+int luat_airlink_drv_gpio_set(int pin, int level);
+int luat_airlink_drv_gpio_open(luat_gpio_cfg_t* gpio);
+
+#endif

+ 17 - 0
components/airlink/include/luat_airlink_drv_uart.h

@@ -0,0 +1,17 @@
+#ifndef LUAT_AIRLINK_DRV_UART_H
+#define LUAT_AIRLINK_DRV_UART_H
+
+
+#ifndef LUAT_AIRLINK_H
+#error "include luat_airlink.h first"
+#endif
+
+// uart参数
+#include "luat_uart.h"
+int luat_airlink_drv_uart_setup(luat_uart_t* uart);
+int luat_airlink_drv_uart_write(int uart_id, void* data, size_t length);
+int luat_airlink_drv_uart_read(int uart_id, void* buffer, size_t length);
+int luat_airlink_drv_uart_close(int uart_id);
+
+
+#endif

+ 56 - 0
components/airlink/include/luat_airlink_drv_wlan.h

@@ -0,0 +1,56 @@
+#ifndef LUAT_AIRLINK_DRV_WLAN_H
+#define LUAT_AIRLINK_DRV_WLAN_H
+
+#ifndef LUAT_AIRLINK_H
+#error "include luat_airlink.h first"
+#endif
+
+// WLAN, 也就是wifi
+#include "luat_wlan.h"
+int luat_airlink_drv_wlan_init(luat_wlan_config_t *conf);
+
+int luat_airlink_drv_wlan_mode(luat_wlan_config_t *conf);
+
+int luat_airlink_drv_wlan_ready(void);
+
+int luat_airlink_drv_wlan_connect(luat_wlan_conninfo_t* info);
+
+int luat_airlink_drv_wlan_disconnect(void);
+
+int luat_airlink_drv_wlan_scan(void);
+
+int luat_airlink_drv_wlan_scan_get_result(luat_wlan_scan_result_t *results, size_t ap_limit);
+
+int luat_airlink_drv_wlan_set_station_ip(luat_wlan_station_info_t *info);
+
+int luat_airlink_drv_wlan_smartconfig_start(int tp);
+
+int luat_airlink_drv_wlan_smartconfig_stop(void);
+
+// 数据类
+int luat_airlink_drv_wlan_get_mac(int id, char* mac);
+int luat_airlink_drv_wlan_set_mac(int id, const char* mac);
+
+int luat_airlink_drv_wlan_get_ip(int type, char* data);
+
+const char* luat_airlink_drv_wlan_get_hostname(int id);
+
+int luat_airlink_drv_wlan_set_hostname(int id, const char* hostname);
+
+// 设置和获取省电模式
+int luat_airlink_drv_wlan_set_ps(int mode);
+
+int luat_airlink_drv_wlan_get_ps(void);
+
+int luat_airlink_drv_wlan_get_ap_bssid(char* buff);
+
+int luat_airlink_drv_wlan_get_ap_rssi(void);
+
+int luat_airlink_drv_wlan_get_ap_gateway(char* buff);
+
+
+// AP类
+int luat_airlink_drv_wlan_ap_start(luat_wlan_apinfo_t *apinfo);
+int luat_airlink_drv_wlan_ap_stop(void);
+
+#endif

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

@@ -0,0 +1,23 @@
+#ifndef LUAT_AIRLINK_FOTA_H
+#define LUAT_AIRLINK_FOTA_H
+#include "luat_base.h"
+#include "luat_fs.h"
+
+typedef struct luat_airlink_fota {
+    uint32_t state;
+    char path[64];
+    size_t wait_init;
+    size_t wait_first_data;
+    size_t wait_data;
+    size_t wait_done;
+    size_t wait_reboot;
+    uint8_t pwr_gpio;
+}luat_airlink_fota_t;
+
+int luat_airlink_fota_init(luat_airlink_fota_t* ctx);
+int luat_airlink_fota_stop(void);
+
+extern luat_airlink_fota_t* g_airlink_fota;
+
+#endif
+

+ 19 - 0
components/airlink/src/luat_airlink.c

@@ -350,3 +350,22 @@ int luat_airlink_ready(void) {
     }
     return 0;
 }
+
+int luat_airlink_send_cmd_simple_nodata(uint16_t cmd_id) {
+    luat_airlink_cmd_t* cmd = luat_airlink_cmd_new(cmd_id, 8);
+    uint64_t pkgid = luat_airlink_get_next_cmd_id();
+    memcpy(cmd->data, &pkgid, 8);
+    luat_airlink_send2slave(cmd);
+    luat_heap_opt_free(AIRLINK_MEM_TYPE, cmd);
+    return 0;
+}
+
+int luat_airlink_send_cmd_simple(uint16_t cmd_id, uint8_t* data, uint16_t len) {
+    luat_airlink_cmd_t* cmd = luat_heap_opt_malloc(AIRLINK_MEM_TYPE, sizeof(luat_airlink_cmd_t) + len);
+    cmd->cmd = cmd_id;
+    cmd->len = len;
+    memcpy(cmd->data, data, len);
+    luat_airlink_send2slave(cmd);
+    luat_heap_opt_free(AIRLINK_MEM_TYPE, cmd);
+    return 0;
+}

+ 175 - 0
components/airlink/src/luat_airlink_fota.c

@@ -0,0 +1,175 @@
+#include "luat_base.h"
+#include "luat_airlink.h"
+#include "luat_airlink_fota.h"
+#include "luat_fs.h"
+#include "luat_mem.h"
+#include "luat_rtos.h"
+
+#define LUAT_LOG_TAG "airlink.fota"
+#include "luat_log.h"
+
+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) {
+        return -1;
+    }
+    if (!g_airlink_fota) {
+        g_airlink_fota = luat_heap_malloc(sizeof(luat_airlink_fota_t));
+    }
+    if (g_airlink_fota == NULL) {
+        LLOGE("airlink fota malloc failed");
+        return -2;
+    }
+    memcpy(g_airlink_fota, ctx, sizeof(luat_airlink_fota_t));
+    g_airlink_fota->state = 1;
+    return 0;
+}
+
+int luat_airlink_fota_stop(void) {
+    if (g_airlink_fota == NULL) {
+        return 0;
+    }
+    g_airlink_fota->state = 0;
+    return 0;
+}
+
+#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 void pack_and_send(uint16_t cmd_id, uint8_t* data, size_t len) {
+    // 首先, 打包到txbuff中
+    luat_airlink_cmd_t* cmd = s_airlink_fota_cmdbuff;
+    cmd->cmd = cmd_id;
+    cmd->len = 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);
+    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) {
+    size_t wait_timeout = 0;
+    int ret = 0;
+    LLOGI("开始执行sFOTA");
+    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) {
+        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) {
+            LLOGE("申请sFOTA内存失败");
+            goto clean;
+        }
+        memset(s_airlink_fota_txbuff, 0, AIRLINK_SFOTA_BUFF_SIZE);
+        memset(s_airlink_fota_rxbuff, 0, AIRLINK_SFOTA_BUFF_SIZE);
+        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) {
+        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) {
+        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) {
+            break;
+        }
+        if (wait_timeout > 0) {
+            luat_rtos_task_sleep(wait_timeout);
+        }
+        // luat_airlink_send_cmd_simple(0x05, s_airlink_fota_rxbuff, ret);
+        pack_and_send(0x05, s_airlink_fota_rxbuff, ret);
+    }
+    LLOGI("文件数据发送结束, 等待100ms,执行done操作");
+    luat_rtos_task_sleep(100);
+    luat_fs_fclose(fd);
+
+    // 发送done命令
+    // luat_airlink_send_cmd_simple_nodata(0x06);
+    pack_and_send(0x06, NULL, 0);
+    luat_rtos_task_sleep(500);
+    LLOGI("done发送结束, 等待100ms, 执行end操作");
+    luat_rtos_task_sleep(100);
+    // luat_airlink_send_cmd_simple_nodata(0x07);
+    pack_and_send(0x07, NULL, 0);
+
+    LLOGI("end发送结束, 等待3000ms, 执行重启操作");
+    luat_rtos_task_sleep(3000);
+    // luat_airlink_send_cmd_simple_nodata(0x03);
+    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 {
+        LLOGI("使用命令复位");
+        pack_and_send(0x03, NULL, 0);
+    }
+
+    wait_timeout = 30*1000;
+    if (g_airlink_fota->wait_reboot) {
+        wait_timeout = g_airlink_fota->wait_reboot;
+    }
+    luat_rtos_task_sleep(wait_timeout);
+    LLOGI("FOTA执行完毕");
+
+clean:
+    g_airlink_fota->state = 0;
+    if (fd) {
+        luat_fs_fclose(fd);
+    }
+    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) {
+        luat_heap_opt_free(AIRLINK_MEM_TYPE, s_airlink_fota_txbuff);
+        s_airlink_fota_txbuff = NULL;
+    }
+    if (s_airlink_fota_cmdbuff) {
+        luat_heap_opt_free(AIRLINK_MEM_TYPE, s_airlink_fota_cmdbuff);
+        s_airlink_fota_cmdbuff = NULL;
+    }
+    return;
+}

+ 171 - 123
components/airlink/src/task/luat_airlink_spi_master_task.c

@@ -2,20 +2,22 @@
 #include "luat_spi.h"
 #include "luat_airlink.h"
 
-
 #include "luat_rtos.h"
 #include "luat_debug.h"
 #include "luat_spi.h"
 #include "luat_pm.h"
 #include "luat_gpio.h"
 #include "luat_airlink.h"
+#include "luat_airlink_fota.h"
+
 #include "luat_mem.h"
 #include "luat_mcu.h"
+#include "luat_fs.h"
 
 #define LUAT_LOG_TAG "airlink"
 #include "luat_log.h"
 
-#define MASTER_SPI_ID   g_airlink_spi_conf.spi_id
+#define MASTER_SPI_ID g_airlink_spi_conf.spi_id
 #define TEST_BUFF_SIZE (1600)
 #define TEST_CS_PIN g_airlink_spi_conf.cs_pin
 #define TEST_RDY_PIN g_airlink_spi_conf.rdy_pin
@@ -26,12 +28,12 @@
 #endif
 
 #ifndef __USER_FUNC_IN_RAM__
-#define __USER_FUNC_IN_RAM__ 
+#define __USER_FUNC_IN_RAM__
 #endif
 
 extern airlink_statistic_t g_airlink_statistic;
 
-static uint8_t start;
+// static uint8_t start;
 // static uint8_t slave_rdy;
 static uint8_t thread_rdy;
 static luat_rtos_task_handle spi_task_handle;
@@ -42,32 +44,37 @@ static uint32_t is_waiting_queue = 0;
 
 static luat_rtos_queue_t evt_queue;
 
-__USER_FUNC_IN_RAM__ static int slave_irq_cb(void *data, void* args) {
+__USER_FUNC_IN_RAM__ static int slave_irq_cb(void *data, void *args)
+{
     uint32_t len = 0;
     // if (is_waiting_queue) {
     //     is_waiting_queue = 0;
-        luat_rtos_queue_get_cnt(evt_queue, &len);
-        // luat_rtos_event_send(spi_task_handle, 2, 2, 3, 4, 100);
-        luat_event_t evt = {.id=2};
-        if (len < 24) {
-            luat_rtos_queue_send(evt_queue, &evt, sizeof(evt), 0);
-        }
+    luat_rtos_queue_get_cnt(evt_queue, &len);
+    // luat_rtos_event_send(spi_task_handle, 2, 2, 3, 4, 100);
+    luat_event_t evt = {.id = 2};
+    if (len < 24)
+    {
+        luat_rtos_queue_send(evt_queue, &evt, sizeof(evt), 0);
+    }
     // }
     return 0;
 }
 
-__USER_FUNC_IN_RAM__ static void on_newdata_notify(void) {
+__USER_FUNC_IN_RAM__ static void on_newdata_notify(void)
+{
     // if (is_waiting_queue) {
-        // is_waiting_queue = 0;
-        // LLOGD("新消息通知, 通知spi线程进行下一次传输!!");
-        // luat_rtos_event_send(spi_task_handle, 3, 2, 3, 4, 0);
+    // is_waiting_queue = 0;
+    // LLOGD("新消息通知, 通知spi线程进行下一次传输!!");
+    // luat_rtos_event_send(spi_task_handle, 3, 2, 3, 4, 0);
     // }
-    luat_event_t evt = {.id=3};
+    luat_event_t evt = {.id = 3};
     luat_rtos_queue_send(evt_queue, &evt, sizeof(evt), 0);
 }
 
-static void spi_gpio_setup(void) {
-    if (g_airlink_spi_conf.cs_pin == 0) {
+static void spi_gpio_setup(void)
+{
+    if (g_airlink_spi_conf.cs_pin == 0)
+    {
         // if (g_airlink_spi_conf.spi_id == 0) {
         g_airlink_spi_conf.cs_pin = 8;
         // }
@@ -75,12 +82,14 @@ static void spi_gpio_setup(void) {
         //     g_airlink_spi_conf.cs_pin = 8;
         // }
     }
-    if (g_airlink_spi_conf.rdy_pin == 0) {
+    if (g_airlink_spi_conf.rdy_pin == 0)
+    {
         // if (g_airlink_spi_conf.spi_id == 0) {
         g_airlink_spi_conf.rdy_pin = 22;
         // }
     }
-    if (g_airlink_spi_conf.irq_pin == 0) {
+    if (g_airlink_spi_conf.irq_pin == 0)
+    {
         g_airlink_spi_conf.irq_pin = 255; // 默认禁用irq脚
     }
 
@@ -93,14 +102,13 @@ static void spi_gpio_setup(void) {
         .dataw = 8,
         .bit_dict = 0,
         .master = 1,
-        .mode = 1,             // mode设置为1,全双工
-		.bandrate = 31000000,
-        .cs = 255
-    };
+        .mode = 1, // mode设置为1,全双工
+        .bandrate = 31000000,
+        .cs = 255};
     luat_pm_iovolt_ctrl(0, 3300);
 
     luat_spi_setup(&spi_conf);
-	luat_gpio_cfg_t gpio_cfg = {0};
+    luat_gpio_cfg_t gpio_cfg = {0};
 
     // 从机准备好脚
     luat_gpio_set_default_cfg(&gpio_cfg);
@@ -111,14 +119,15 @@ static void spi_gpio_setup(void) {
     luat_gpio_open(&gpio_cfg);
 
     // CS片选脚
-	luat_gpio_set_default_cfg(&gpio_cfg);
-	gpio_cfg.pin = TEST_CS_PIN;
-	gpio_cfg.mode = LUAT_GPIO_OUTPUT;
-	gpio_cfg.pull = LUAT_GPIO_PULLUP;
+    luat_gpio_set_default_cfg(&gpio_cfg);
+    gpio_cfg.pin = TEST_CS_PIN;
+    gpio_cfg.mode = LUAT_GPIO_OUTPUT;
+    gpio_cfg.pull = LUAT_GPIO_PULLUP;
     gpio_cfg.output_level = 1;
-	luat_gpio_open(&gpio_cfg);
+    luat_gpio_open(&gpio_cfg);
 
-    if (g_airlink_spi_conf.irq_pin != 255) {
+    if (g_airlink_spi_conf.irq_pin != 255)
+    {
         luat_gpio_set_default_cfg(&gpio_cfg);
         gpio_cfg.pin = TEST_RDY_PIN;
         gpio_cfg.mode = LUAT_GPIO_IRQ;
@@ -129,121 +138,160 @@ static void spi_gpio_setup(void) {
     }
 }
 
+static void record_statistic(luat_event_t event)
+{
+    switch (event.id)
+    {
+    case 0:
+        g_airlink_statistic.event_timeout.total++;
+        break;
+    case 2:
+        g_airlink_statistic.event_rdy_irq.total++;
+        break;
+    case 3:
+        g_airlink_statistic.event_new_data.total++;
+        break;
+    default:
+        break;
+    }
+}
+
+static uint8_t *s_txbuff;
+static uint8_t *s_rxbuff;
+static airlink_link_data_t *link = NULL;
+static uint64_t warn_slave_no_ready = 0;
+static uint64_t tnow = 0;
+extern void airlink_sfota_exec();
 
-__USER_FUNC_IN_RAM__ static void spi_master_task(void *param)
+__USER_FUNC_IN_RAM__ void airlink_transfer_and_exec(uint8_t *txbuff, uint8_t *rxbuff)
 {
-    int i;
-    airlink_link_data_t* link = NULL;
+    // 清除link
+    link = NULL;
+
+    g_airlink_statistic.tx_pkg.total++;
+    luat_spi_transfer(MASTER_SPI_ID, (const char *)txbuff, TEST_BUFF_SIZE, (char *)rxbuff, TEST_BUFF_SIZE);
+    luat_gpio_set(TEST_CS_PIN, 1);
+    // luat_airlink_print_buff("RX", rxbuff, 32);
+    // 对接收到的数据进行解析
+    link = luat_airlink_data_unpack(rxbuff, TEST_BUFF_SIZE);
+    if (link)
+    {
+        g_airlink_statistic.tx_pkg.ok++;
+        luat_airlink_on_data_recv(link->data, link->len);
+    }
+    else
+    {
+        g_airlink_statistic.tx_pkg.err++;
+        // LLOGE("接收到数据不正确, 丢弃");
+    }
+}
+
+__USER_FUNC_IN_RAM__ void airlink_wait_for_slave_ready(size_t timeout_ms)
+{
+    luat_gpio_set(TEST_CS_PIN, 0); // 拉低片选, 等待从机就绪
     int tmpval = 0;
+    for (size_t i = 0; i < timeout_ms; i++)
+    {
+        tmpval = luat_gpio_get(TEST_RDY_PIN);
+        if (tmpval == 1)
+        {
+            g_airlink_statistic.wait_rdy.total++;
+            if (g_airlink_debug)
+            {
+                tnow = luat_mcu_tick64_ms();
+                if (tnow - warn_slave_no_ready > 1000)
+                {
+                    warn_slave_no_ready = tnow;
+                    LLOGD("从机未就绪,等1ms");
+                }
+            }
+            luat_rtos_task_sleep(1);
+            continue;
+        }
+        // LLOGD("从机已就绪!! %s %s", __DATE__, __TIME__);
+        break;
+    }
+}
+
+void airlink_wait_and_prepare_data(uint8_t *txbuff)
+{
     luat_event_t event = {0};
     airlink_queue_item_t item = {0};
-	uint8_t* txbuff = luat_heap_opt_malloc(AIRLINK_MEM_TYPE, TEST_BUFF_SIZE);
-    uint8_t* rxbuff = luat_heap_opt_malloc(AIRLINK_MEM_TYPE, TEST_BUFF_SIZE);
+    // 等到消息
+    if (link != NULL && (link->flags.queue_cmd != 0 || link->flags.queue_cmd != 0))
+    {
+        // 立即进行下一轮操作
+        event.id = 2;
+    }
+    else
+    {
+        is_waiting_queue = 1;
+        luat_rtos_queue_recv(evt_queue, &event, sizeof(event), 5);
+        is_waiting_queue = 0;
+    }
+
+    record_statistic(event);
+
+    // LLOGD("事件id %p %d", spi_task_handle, event.id);
+    if (link == NULL || (link->flags.mem_is_high) == 0)
+    {
+        luat_airlink_cmd_recv_simple(&item);
+    }
+    else
+    {
+        LLOGI("从机内存高水位, 停止下发IP数据");
+    }
+    if (item.len > 0 && item.cmd != NULL)
+    {
+        // LLOGD("发送待传输的数据, 塞入SPI的FIFO cmd id %d", item.cmd->cmd);
+        luat_airlink_data_pack(item.cmd, item.len, txbuff);
+        luat_airlink_cmd_free(item.cmd);
+    }
+    else
+    {
+        // LLOGD("填充PING数据");
+        luat_airlink_data_pack(basic_info, sizeof(basic_info), txbuff);
+    }
+}
+
+
+__USER_FUNC_IN_RAM__ static void spi_master_task(void *param)
+{
+    int i;
+    luat_event_t event = {0};
 
     luat_rtos_task_sleep(5); // 等5ms
     spi_gpio_setup();
     thread_rdy = 1;
-    uint64_t warn_slave_no_ready = 0;
-    uint64_t tnow = 0;
     g_airlink_newdata_notify_cb = on_newdata_notify;
     while (1)
     {
-        // 等到消息
-        event.id = 0;
-        item.len = 0;
-        if (link != NULL && (link->flags.queue_cmd != 0 || link->flags.queue_cmd != 0)) {
-            // 立即进行下一轮操作
-            event.id = 2;
-        }
-        else {
-            is_waiting_queue = 1;
-            luat_rtos_queue_recv(evt_queue, &event, sizeof(event), 5);
-            is_waiting_queue = 0;
-        }
-        
-        switch (event.id)
-        {
-        case 0:
-            g_airlink_statistic.event_timeout.total ++;
-            break;
-        case 2:
-            g_airlink_statistic.event_rdy_irq.total ++;
-            break;
-        case 3:
-            g_airlink_statistic.event_new_data.total ++;
-            break;
-        default:
-            break;
-        }
-        // LLOGD("事件id %p %d", spi_task_handle, event.id);
-        if (link == NULL || (link->flags.mem_is_high) == 0) {
-            luat_airlink_cmd_recv_simple(&item);
-        }
-        else {
-            LLOGI("从机内存高水位, 停止下发IP数据");
-        }
-        if (item.len > 0 && item.cmd != NULL) {
-            // LLOGD("发送待传输的数据, 塞入SPI的FIFO cmd id %d", item.cmd->cmd);
-            luat_airlink_data_pack(item.cmd, item.len, txbuff);
-            luat_airlink_cmd_free(item.cmd);
-        }
-        else {
-            // LLOGD("填充PING数据");
-            luat_airlink_data_pack(basic_info, sizeof(basic_info), txbuff);
+        if (g_airlink_fota != NULL && g_airlink_fota->state == 1) {
+            airlink_sfota_exec();
         }
+
+        airlink_wait_and_prepare_data(s_txbuff);
         // slave_rdy = 0;
-        luat_gpio_set(TEST_CS_PIN, 0);
-        for (size_t i = 0; i < 1000; i++)
-        {
-            tmpval = luat_gpio_get(TEST_RDY_PIN);
-            if (tmpval == 1) {
-                g_airlink_statistic.wait_rdy.total ++;
-                if (g_airlink_debug) {
-                    tnow = luat_mcu_tick64_ms();
-                    if (tnow - warn_slave_no_ready > 1000) {
-                        warn_slave_no_ready = tnow;
-                        LLOGD("从机未就绪,等1ms");
-                    }
-                }
-                luat_rtos_task_sleep(1);
-                continue;
-            }
-            // LLOGD("从机已就绪!! %s %s", __DATE__, __TIME__);
-            break;
-        }
+        airlink_wait_for_slave_ready(1000); // 最多等1秒
 
-        // 清除link
-        link = NULL;
-
-        g_airlink_statistic.tx_pkg.total ++;
-        luat_spi_transfer(MASTER_SPI_ID, (const char*)txbuff, TEST_BUFF_SIZE, (char*)rxbuff, TEST_BUFF_SIZE);
-        luat_gpio_set(TEST_CS_PIN, 1);
-        // luat_airlink_print_buff("RX", rxbuff, 32);
-        // 对接收到的数据进行解析
-        link = luat_airlink_data_unpack(rxbuff, TEST_BUFF_SIZE);
-        if (link) {
-            g_airlink_statistic.tx_pkg.ok ++;
-            luat_airlink_on_data_recv(link->data, link->len);
-        }
-        else {
-            g_airlink_statistic.tx_pkg.err ++;
-            // LLOGE("接收到数据不正确, 丢弃");
-        }
-        
-        memset(rxbuff, 0, TEST_BUFF_SIZE);
-        // luat_rtos_task_sleep(300);
-        start = 0;
+        airlink_transfer_and_exec(s_txbuff, s_rxbuff);
+
+        memset(s_rxbuff, 0, TEST_BUFF_SIZE);
+        // start = 0;
     }
 }
 
-
 void luat_airlink_start_master(void)
 {
-    if (spi_task_handle != NULL) {
+    if (spi_task_handle != NULL)
+    {
         LLOGE("SPI主机任务已经启动过了!!!");
         return;
     }
 
-    luat_rtos_queue_create(&evt_queue, 4*1024, sizeof(luat_event_t));
+    s_txbuff = luat_heap_opt_malloc(AIRLINK_MEM_TYPE, TEST_BUFF_SIZE);
+    s_rxbuff = luat_heap_opt_malloc(AIRLINK_MEM_TYPE, TEST_BUFF_SIZE);
+
+    luat_rtos_queue_create(&evt_queue, 4 * 1024, sizeof(luat_event_t));
     luat_rtos_task_create(&spi_task_handle, 4 * 1024, 95, "spi", spi_master_task, NULL, 0);
 }

+ 1 - 0
components/drv/src/luat_drv_gpio.c

@@ -3,6 +3,7 @@
 #include "luat_mem.h"
 #include "luat/drv_gpio.h"
 #include "luat_airlink.h"
+#include "luat_airlink_drv_gpio.h"
 
 #define LUAT_LOG_TAG "drv.gpio"
 #include "luat_log.h"

+ 1 - 0
components/drv/src/luat_drv_uart.c

@@ -4,6 +4,7 @@
 #include "luat/drv_gpio.h"
 #include "luat/drv_uart.h"
 #include "luat_airlink.h"
+#include "luat_airlink_drv_uart.h"
 
 #define LUAT_LOG_TAG "drv.uart"
 #include "luat_log.h"

+ 1 - 0
components/drv/src/luat_drv_wlan.c

@@ -3,6 +3,7 @@
 #include "luat_mem.h"
 #include "luat_wlan.h"
 #include "luat_airlink.h"
+#include "luat_airlink_drv_wlan.h"
 #include "luat/drv_wlan.h"
 #include "luat_network_adapter.h"
 #include "luat_netdrv.h"