Ver Fonte

change: airlink,优化传输性能

1. crc16算法改为modbus的模式,使用独立的crc16函数
2. 通知队列改成独立queue,不受1024个元素的限制
3. 暂停使用rdy的中断事件,实际改成的轮询模式
Wendal Chen há 1 ano atrás
pai
commit
d472fab220

+ 40 - 0
components/airlink/binding/luat_lib_airlink.c

@@ -13,6 +13,8 @@
 #define LUAT_LOG_TAG "airlink"
 #include "luat_log.h"
 
+extern airlink_statistic_t g_airlink_statistic;
+
 static int l_airlink_init(lua_State *L) {
     LLOGD("初始化AirLink");
     luat_airlink_init();
@@ -47,12 +49,50 @@ static int l_airlink_stop(lua_State *L) {
     return 0;
 }
 
+static int l_airlink_test(lua_State *L) {
+    int count = luaL_checkinteger(L, 1);
+    luat_airlink_cmd_t* cmd = luat_heap_opt_malloc(AIRLINK_MEM_TYPE, sizeof(luat_airlink_cmd_t) + 128);
+    cmd->cmd = 0x21;
+    cmd->len = 128;
+    if (count > 0) {
+        // 发送次数
+        LLOGD("测试AirLink发送%d次", count);
+        for (size_t i = 0; i < count; i++)
+        {
+            luat_airlink_send2slave(cmd);
+        }
+        
+    }
+    luat_heap_opt_free(AIRLINK_MEM_TYPE, cmd);
+    return 0;
+}
+
+static void print_stat(const char* tag, airlink_statistic_part_t* part) {
+    LLOGD("统计信息 %s %lld %lld %lld %lld", tag, part->total, part->ok, part->err, part->drop);
+}
+
+static int l_airlink_statistics(lua_State *L) {
+    airlink_statistic_t tmp;
+    memcpy(&tmp, &g_airlink_statistic, sizeof(airlink_statistic_t));
+    print_stat("发送总包", &tmp.tx_pkg);
+    // print_stat("接收总包", &tmp.rx_pkg);
+    // print_stat("发送IP", &tmp.tx_ip);
+    // print_stat("接收IP", &tmp.rx_ip);
+    print_stat("等待从机", &tmp.wait_rdy);
+    print_stat("Task超时事件", &tmp.event_timeout);
+    print_stat("Task新数据事件", &tmp.event_new_data);
+    print_stat("Task从机通知事件", &tmp.event_rdy_irq);
+    return 0;
+}
+
 #include "rotable2.h"
 static const rotable_Reg_t reg_airlink[] =
 {
     { "init" ,         ROREG_FUNC(l_airlink_init )},
     { "start" ,        ROREG_FUNC(l_airlink_start )},
     { "stop" ,         ROREG_FUNC(l_airlink_stop )},
+    { "test",          ROREG_FUNC(l_airlink_test )},
+    { "statistics",    ROREG_FUNC(l_airlink_statistics )},
 	{ NULL,            ROREG_INT(0) }
 };
 

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

@@ -30,6 +30,27 @@ typedef struct airlink_link_data {
     uint8_t data[0];
 }airlink_link_data_t;
 
+typedef struct airlink_statistic_part {
+    uint64_t total;
+    uint64_t ok;
+    uint64_t err;
+    uint64_t drop;
+}airlink_statistic_part_t;
+
+typedef struct airlink_statistic {
+    // 传输统计信息
+    airlink_statistic_part_t rx_pkg;
+    airlink_statistic_part_t tx_pkg;
+    airlink_statistic_part_t wait_rdy;
+    airlink_statistic_part_t rx_ip;
+    airlink_statistic_part_t tx_ip;
+
+    // Task等待事件
+    airlink_statistic_part_t event_timeout;
+    airlink_statistic_part_t event_rdy_irq;
+    airlink_statistic_part_t event_new_data;
+}airlink_statistic_t;
+
 int luat_airlink_init(void);
 int luat_airlink_start(int id);
 int luat_airlink_stop(int id);
@@ -73,6 +94,8 @@ int luat_airlink_cmd_recv_simple(airlink_queue_item_t* cmd);
 
 int luat_airlink_queue_send_ippkg(uint8_t adapter_id, uint8_t* data, size_t len);
 
+void luat_airlink_send2slave(luat_airlink_cmd_t* cmd);
+
 void luat_airlink_print_mac_pkg(uint8_t* buff, uint16_t len);
 void luat_airlink_hexdump(const char* tag, uint8_t* buff, uint16_t len);
 

+ 5 - 0
components/airlink/src/exec/luat_airlink_cmd_exec_basic.c

@@ -14,6 +14,11 @@
 #define LUAT_LOG_TAG "airlink"
 #include "luat_log.h"
 
+int luat_airlink_cmd_exec_nop(luat_airlink_cmd_t *cmd, void *userdata)
+{
+    return 0;
+}
+
 int luat_airlink_cmd_exec_ping(luat_airlink_cmd_t *cmd, void *userdata)
 {
     LLOGD("收到ping指令,返回pong");

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

@@ -25,6 +25,7 @@ extern int luat_airlink_start_slave(void);
 extern int luat_airlink_start_master(void);
 luat_airlink_newdata_notify_cb g_airlink_newdata_notify_cb;
 luat_airlink_spi_conf_t g_airlink_spi_conf;
+airlink_statistic_t g_airlink_statistic;
 
 int luat_airlink_init(void)
 {
@@ -295,3 +296,21 @@ void luat_airlink_cmd_free(luat_airlink_cmd_t* cmd) {
         luat_heap_opt_free(AIRLINK_MEM_TYPE, cmd);
     }
 }
+
+
+void luat_airlink_send2slave(luat_airlink_cmd_t* cmd) {
+    airlink_queue_item_t item = {0};
+    int ret = 0;
+    item.len = cmd->len + sizeof(luat_airlink_cmd_t);
+    item.cmd = luat_airlink_cmd_new(cmd->cmd, cmd->len);
+    if (item.cmd == NULL) {
+        LLOGD("luat_airlink_send2slave 内存不足, 丢弃掉");
+        return;
+    }
+    ret = luat_airlink_queue_send(LUAT_AIRLINK_QUEUE_CMD, &item);
+    if (ret != 0) {
+        LLOGD("luat_airlink_send2slave 发送消息失败 长度 %d ret %d", cmd->len, ret);
+        luat_airlink_cmd_free(item.cmd);
+        return;
+    }
+}

+ 2 - 0
components/airlink/src/luat_airlink_cmds.c

@@ -26,6 +26,7 @@ CMD_DEFINE(fota_write);
 CMD_DEFINE(fota_done);
 CMD_DEFINE(dev_info);
 CMD_DEFINE(sdata);
+CMD_DEFINE(nop);
 
 // MAC和IP包指令, 0x100开始
 CMD_DEFINE(ip_pkg);
@@ -80,5 +81,6 @@ const luat_airlink_cmd_reg_t airlink_cmds[] = {
     CMD_REG(0x301, gpio_set),
 #endif
 
+    CMD_REG(0x21, nop),
     {0, NULL}
 };

+ 4 - 2
components/airlink/src/luat_airlink_linkdata.c

@@ -41,7 +41,8 @@ airlink_link_data_t* luat_airlink_data_unpack(uint8_t *buff, size_t len)
             if (tlen > 0 && tlen + 4 + i + 4 <= len)
             {
                 // 计算crc16
-                crc16_data = luat_crc16(buff + i + 4 + 4, tlen + 8, 0xFFFF, 0x1021, 0);
+                // crc16_data = luat_crc16(buff + i + 4 + 4, tlen + 8, 0xFFFF, 0x1021, 0);
+                crc16_data = luat_crc16_modbus(&buff[i + 4 + 4], tlen + 8);
                 if (crc16_data == crc16)
                 {
                     return link;
@@ -79,5 +80,6 @@ void luat_airlink_data_pack(uint8_t *buff, size_t len, uint8_t *dst)
         g_airlink_link_data_cb(data);
     }
     
-    data->crc16 = luat_crc16(&data->pkgid, len + 8, 0xFFFF, 0x1021, 0);
+    // data->crc16 = luat_crc16(&data->pkgid, len + 8, 0xFFFF, 0x1021, 0);
+    data->crc16 = luat_crc16_modbus(&data->pkgid, len + 8);
 }

+ 40 - 14
components/airlink/src/task/luat_airlink_spi_master_task.c

@@ -33,6 +33,8 @@
 
 #endif
 
+extern airlink_statistic_t g_airlink_statistic;
+
 static uint8_t start;
 // static uint8_t slave_rdy;
 static uint8_t thread_rdy;
@@ -42,29 +44,25 @@ static uint8_t basic_info[256];
 
 static uint32_t is_waiting_queue = 0;
 
-static int gpio_boot_irq(void *data, void* args)
-{
-	if (thread_rdy) {
-        luat_rtos_event_send(spi_task_handle, 1, 2, 3, 4, 100);
-    }
-	return 0;
-}
+static luat_rtos_queue_t evt_queue;
 
 static int slave_rdy_irq(void *data, void* args) {
     if (is_waiting_queue) {
         // LLOGD("新消息通知, 通知spi线程进行下一次传输!!");
         is_waiting_queue = 0;
-        luat_rtos_event_send(spi_task_handle, 2, 2, 3, 4, 100);
+        // luat_rtos_event_send(spi_task_handle, 2, 2, 3, 4, 100);
     }
     return 0;
 }
 
 static void on_newdata_notify(void) {
-    if (is_waiting_queue) {
-        is_waiting_queue = 0;
+    // if (is_waiting_queue) {
+        // is_waiting_queue = 0;
         // LLOGD("新消息通知, 通知spi线程进行下一次传输!!");
-        luat_rtos_event_send(spi_task_handle, 3, 2, 3, 4, 100);
-    }
+        // luat_rtos_event_send(spi_task_handle, 3, 2, 3, 4, 0);
+    // }
+    luat_event_t evt = {.id=3};
+    luat_rtos_queue_send(evt_queue, &evt, sizeof(evt), 0);
 }
 
 static void spi_gpio_setup(void) {
@@ -126,8 +124,24 @@ static void spi_master_task(void *param)
         event.id = 0;
         item.len = 0;
         is_waiting_queue = 1;
-        luat_rtos_event_recv(spi_task_handle, 0, &event, NULL, 5);
+        // luat_rtos_event_recv(spi_task_handle, 0, &event, NULL, 5);
+        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 & 0x1) == 0) {
             luat_airlink_cmd_recv_simple(&item);
         }
@@ -149,6 +163,7 @@ static void spi_master_task(void *param)
         {
             tmpval = luat_gpio_get(TEST_RDY_PIN);
             if (tmpval == 1) {
+                g_airlink_statistic.wait_rdy.total ++;
                 tnow = luat_mcu_tick64_ms();
                 if (tnow - warn_slave_no_ready > 100) {
                     warn_slave_no_ready = tnow;
@@ -160,18 +175,28 @@ static void spi_master_task(void *param)
             // LLOGD("从机已就绪!! %s %s", __DATE__, __TIME__);
             break;
         }
-        
+        g_airlink_statistic.tx_pkg.total ++;
         luat_spi_transfer(TEST_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("接收到数据不正确, 丢弃");
         }
+
+        // for (size_t i = 0; i < 5; i++) {
+        //     tmpval = luat_gpio_get(TEST_RDY_PIN);
+        //     if (tmpval == 0) {
+        //         break;
+        //     }
+        //     luat_rtos_task_sleep(1);
+        // }
         
         memset(rxbuff, 0, TEST_BUFF_SIZE);
         // luat_rtos_task_sleep(300);
@@ -186,5 +211,6 @@ void luat_airlink_start_master(void)
         LLOGE("SPI主机任务已经启动过了!!!");
         return;
     }
+    luat_rtos_queue_create(&evt_queue, 2048, sizeof(luat_event_t));
     luat_rtos_task_create(&spi_task_handle, 4 * 1024, 95, "spi", spi_master_task, NULL, 0);
 }