Răsfoiți Sursa

Merge branch 'master' of https://gitee.com/openLuat/LuatOS

alienwalker 9 luni în urmă
părinte
comite
f95fc0b706

+ 18 - 40
components/fskv/luat_lib_fskv.c

@@ -7,25 +7,9 @@
 @demo    fskv
 @tag     LUAT_USE_FSKV
 @usage
--- 本库的目标是替代fdb库
--- 1. 兼容fdb的函数
--- 2. 使用fdb的flash空间,启用时也会替代fdb库
--- 3. 功能上与EEPROM是类似的
 fskv.init()
 fskv.set("wendal", 1234)
 log.info("fskv", "wendal", fskv.get("wendal"))
-
---[[ 
-fskv与fdb的实现机制导致的差异
-
-                    fskv          fdb
-1. value长度        4096           255
-2. key长度          63             64
-3. 空间利用率(对比)  较低           较高
-4. 读取速度         恒定           脏数据影响速度,非恒定
-5. 写入数据         恒定           脏数据影响速度,非恒定
-6. 均衡擦除         自动           自动
-]]
 */
 
 #include "luat_base.h"
@@ -48,20 +32,14 @@ extern luat_sfd_lfs_t* sfd_lfs;
 #endif
 static int fskv_inited;
 
-// static char fskv_read_buff[LUAT_FSKV_MAX_SIZE];
-
 /**
 初始化kv数据库
 @api fskv.init()
 @return boolean 成功返回true,否则返回false
 @usage
 if fskv.init() then
-    log.info("fdb", "kv数据库初始化成功")
+    log.info("fskv", "kv数据库初始化成功")
 end
-
--- 关于清空fdb库
--- 下载工具是没有提供直接清除fdb数据的途径的, 但有办法解决
--- 写一个main.lua, 执行 fskv.kvdb_init 后 执行 fskv.clear() 即可全清fdb数据.
  */
 static int l_fskvdb_init(lua_State *L) {
     if (fskv_inited == 0) {
@@ -98,10 +76,10 @@ static int l_fskvdb_init(lua_State *L) {
 @usage
 -- 设置数据, 字符串,数值,table,布尔值,均可
 -- 但不可以是nil, function, userdata, task
-log.info("fdb", fskv.set("wendal", "goodgoodstudy"))
-log.info("fdb", fskv.set("upgrade", true))
-log.info("fdb", fskv.set("timer", 1))
-log.info("fdb", fskv.set("bigd", {name="wendal",age=123}))
+log.info("fskv", fskv.set("wendal", "goodgoodstudy"))
+log.info("fskv", fskv.set("upgrade", true))
+log.info("fskv", fskv.set("timer", 1))
+log.info("fskv", fskv.set("bigd", {name="wendal",age=123}))
  */
 static int l_fskv_set(lua_State *L) {
     if (fskv_inited == 0) {
@@ -217,22 +195,22 @@ static int l_fskv_set(lua_State *L) {
 -- 本API在2023.7.26新增,注意与set函数区别
 -- 设置数据, 字符串,数值,table,布尔值,均可
 -- 但不可以是function, userdata, task
-log.info("fdb", fskv.sett("mytable", "wendal", "goodgoodstudy"))
-log.info("fdb", fskv.sett("mytable", "upgrade", true))
-log.info("fdb", fskv.sett("mytable", "timer", 1))
-log.info("fdb", fskv.sett("mytable", "bigd", {name="wendal",age=123}))
+log.info("fskv", fskv.sett("mytable", "wendal", "goodgoodstudy"))
+log.info("fskv", fskv.sett("mytable", "upgrade", true))
+log.info("fskv", fskv.sett("mytable", "timer", 1))
+log.info("fskv", fskv.sett("mytable", "bigd", {name="wendal",age=123}))
 
 -- 下列语句将打印出4个元素的table
-log.info("fdb", fskv.get("mytable"), json.encode(fskv.get("mytable")))
+log.info("fskv", fskv.get("mytable"), json.encode(fskv.get("mytable")))
 -- 注意: 如果key不存在, 或者原本的值不是table类型,将会完全覆盖
 -- 例如下列写法,最终获取到的是table,而非第一行的字符串
-log.info("fdb", fskv.set("mykv", "123"))
-log.info("fdb", fskv.sett("mykv", "age", "123")) -- 保存的将是 {age:"123"}
+log.info("fskv", fskv.set("mykv", "123"))
+log.info("fskv", fskv.sett("mykv", "age", "123")) -- 保存的将是 {age:"123"}
 
 
 -- 如果设置的数据填nil, 代表删除对应的key
-log.info("fdb", fskv.sett("mykv", "name", "wendal"))
-log.info("fdb", fskv.sett("mykv", "name")) -- 相当于删除
+log.info("fskv", fskv.sett("mykv", "name", "wendal"))
+log.info("fskv", fskv.sett("mykv", "name")) -- 相当于删除
 -- 
  */
 static int l_fskv_sett(lua_State *L) {
@@ -301,7 +279,7 @@ static int l_fskv_sett(lua_State *L) {
 @return any 存在则返回数据,否则返回nil
 @usage
 if fskv.init() then
-    log.info("fdb", fskv.get("wendal"))
+    log.info("fskv", fskv.get("wendal"))
 end
 
 -- 若需要"默认值", 对应非bool布尔值, 可以这样写
@@ -391,7 +369,7 @@ static int l_fskv_get(lua_State *L) {
 @string key的名称,必填,不能空字符串
 @return bool 成功返回true,否则返回false
 @usage
-log.info("fdb", fskv.del("wendal"))
+log.info("fskv", fskv.del("wendal"))
  */
 static int l_fskv_del(lua_State *L) {
     if (fskv_inited == 0) {
@@ -440,7 +418,7 @@ if iter then
         if not k then
             break
         end
-        log.info("fdb", k, "value", fskv.kv_get(k))
+        log.info("fskv", k, "value", fskv.kv_get(k))
     end
 end
  */
@@ -493,7 +471,7 @@ static int l_fskv_next(lua_State *L) {
 @return int 总kv键值对数量, 单位个
 @usage
 local used, total,kv_count = fskv.status()
-log.info("fdb", "kv", used,total,kv_count)
+log.info("fskv", "kv", used,total,kv_count)
 */
 static int l_fskv_stat(lua_State *L) {
     size_t using_sz = 0;

+ 1 - 1
components/lcd/luat_lcd.c

@@ -10,7 +10,7 @@
 
 luat_color_t BACK_COLOR = LCD_WHITE, FORE_COLOR = LCD_BLACK;
 
-luat_lcd_conf_t* confs[LUAT_LCD_CONF_COUNT] = {0};
+static luat_lcd_conf_t* confs[LUAT_LCD_CONF_COUNT] = {0};
 
 void luat_lcd_execute_cmds(luat_lcd_conf_t* conf) {
     uint16_t cmd = 0,cmd_len = 0;

+ 242 - 240
components/lvgl/binding/luat_lib_lvgl7.c

@@ -1,240 +1,242 @@
-/*
-@module  lvgl
-@summary LVGL图像库
-@version 1.0
-@date    2021.06.01
-*/
-
-#include "luat_base.h"
-#include "luat_lvgl.h"
-#include "luat_mem.h"
-#include "luat_zbuff.h"
-
-typedef struct luat_lv {
-    lv_disp_t* disp;
-    lv_disp_buf_t disp_buf;
-    int buff_ref;
-    int buff2_ref;
-}luat_lv_t;
-
-static luat_lv_t LV = {0};
-//static lv_disp_drv_t my_disp_drv;
-
-
-/**
-初始化LVGL
-@api lvgl.init(w, h, lcd, buff_size, buff_mode)
-@int 屏幕宽,可选,默认从lcd取
-@int 屏幕高,可选,默认从lcd取
-@userdata lcd指针,可选,lcd初始化后有默认值,预留的多屏入口
-@int 缓冲区大小,默认宽*10, 不含色深.
-@int 缓冲模式,默认0x06, bit0:是否使用lcdbuff bit1:buff1 bit2:buff2 bit3:是否使用lua heap
-@return bool 成功返回true,否则返回false
- */
-int luat_lv_init(lua_State *L);
-
-#ifdef LUAT_USE_LVGL_SDL2
-#include "luat_lcd.h"
-// SDL2 模式
-extern lv_disp_t *lv_sdl_init_display(const char* win_name, int width, int height);
-extern lv_indev_t *lv_sdl_init_input(void);
-#endif
-#if defined(LUAT_EMULATOR_MODE)
-// 模拟器模式
-int luat_lv_init(lua_State *L) {
-    LLOGE("emulator mode init");
-    int w = 480;
-    int h = 320;
-
-    if (lua_isnumber(L, 1) && lua_isnumber(L, 2)) {
-        w = luaL_checkinteger(L, 1);
-        h = luaL_checkinteger(L, 2);
-    }
-
-    extern void emulator_lvgl_init(int w, int h);
-    emulator_lvgl_init(w, h);
-    return 0;
-}
-// #elif defined(LUA_USE_WINDOWS)
-// // win32遗留模式
-// #include <windows.h>
-// extern uint32_t WINDOW_HOR_RES;
-// extern uint32_t WINDOW_VER_RES;
-// int luat_lv_init(lua_State *L) {
-//     if (lua_isnumber(L, 1) && lua_isnumber(L, 2)) {
-//         WINDOW_HOR_RES = luaL_checkinteger(L, 1);
-//         WINDOW_VER_RES = luaL_checkinteger(L, 2);
-//     }
-//     LLOGD("win32 lvgl init %d %d", WINDOW_HOR_RES, WINDOW_VER_RES);
-//     HWND windrv_init(void);
-//     windrv_init();
-//     lua_pushboolean(L, 1);
-//     return 1;
-// }
-
-#elif defined(LUAT_USE_LVGL_INIT_CUSTOM)
-// 自定义模式, 这个由bsp自行实现了
-
-#else
-// 普通MCU模式
-#include "luat_lcd.h"
-
-static luat_lcd_conf_t* lcd_conf;
-static lv_color_t *fbuffer = NULL;
-static lv_color_t *fbuffer2 = NULL;
-
-LUAT_WEAK void luat_lv_disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p) {
-    //-----
-    if (lcd_conf != NULL) {
-        luat_lcd_draw(lcd_conf, area->x1, area->y1, area->x2, area->y2, color_p);
-        if (disp_drv->buffer->flushing_last){
-            if (lcd_conf->buff_ex){
-                lcd_conf->buff_draw = color_p;
-            }
-            luat_lcd_flush(lcd_conf);
-        }
-    }
-    //LLOGD("CALL disp_flush (%d, %d, %d, %d)", area->x1, area->y1, area->x2, area->y2);
-    lv_disp_flush_ready(disp_drv);
-}
-int luat_lv_init(lua_State *L) {
-    int w = 0;
-    int h = 0;
-
-    if (LV.disp != NULL) {
-        lua_pushboolean(L, 0);
-        return 1;
-    }
-
-    if (lua_isnumber(L, 1) && lua_isnumber(L, 2)) {
-        w = luaL_checkinteger(L, 1);
-        h = luaL_checkinteger(L, 2);
-    }
-
-    size_t fbuff_size = 0;
-    uint8_t buffmode = 0;// bit0:是否使用lcdbuff bit1:buff1 bit2:buff2 bit3:是否使用lua heap
-
-    if (lua_isuserdata(L, 3)) {
-        lcd_conf = lua_touserdata(L, 3);
-    }
-    else {
-        lcd_conf = luat_lcd_get_default();
-    }
-    if (lcd_conf == NULL) {
-        #if defined(LUA_USE_LINUX) || defined(LUA_USE_WINDOWS)
-        if (w == 0 || h == 0) {
-            w = 800;
-            h = 640;
-        }
-        #else
-        LLOGE("setup lcd first!!");
-        return 0;
-        #endif
-    }
-
-    if (w == 0 || h == 0) {
-        w = lcd_conf->w;
-        h = lcd_conf->h;
-    }
-
-    if (lua_isinteger(L, 4)) {
-        fbuff_size = luaL_checkinteger(L, 4);
-        if (fbuff_size < w*10)
-            fbuff_size = w * 10;
-    }
-    else {
-        fbuff_size = w * 10;
-    }
-
-    if (lua_isinteger(L, 5)) {
-        buffmode = luaL_checkinteger(L, 5);
-    }else{
-        buffmode = 0x06; //heap申请双buff模式
-    }
-    lcd_conf->lcd_use_lvgl = 1;
-    if (lcd_conf != NULL && lcd_conf->buff != NULL) {
-        // LLOGD("use LCD buff");
-        fbuff_size = w * h;
-        fbuffer = lcd_conf->buff;
-        buffmode = 1;
-        if (lcd_conf->buff_ex){
-            fbuffer2 = lcd_conf->buff_ex;
-        }
-    }
-
-    if (buffmode & 0x08) {
-        //LLOGD("use VM buff");
-        if (buffmode & 0x02) {
-            fbuffer = lua_newuserdata(L, fbuff_size * sizeof(lv_color_t));
-            if (fbuffer == NULL) {
-                LLOGD("not enough memory");
-                return 0;
-            }
-        }
-        if (buffmode & 0x04) {
-            fbuffer2 = lua_newuserdata(L, fbuff_size * sizeof(lv_color_t));
-            if (fbuffer2 == NULL) {
-                LLOGD("not enough memory");
-                return 0;
-            }
-        }
-        // 引用即弹出
-        if (fbuffer2)
-            LV.buff2_ref = luaL_ref(L, LUA_REGISTRYINDEX);
-        LV.buff_ref = luaL_ref(L, LUA_REGISTRYINDEX);
-    }else{
-        //LLOGD("use HEAP buff");
-        if (buffmode & 0x02) {
-            fbuffer = luat_heap_malloc(fbuff_size * sizeof(lv_color_t));
-            if (fbuffer == NULL) {
-                LLOGD("not enough memory");
-                return 0;
-            }
-        }
-        if (buffmode & 0x04) {
-            fbuffer2 = luat_heap_malloc(fbuff_size * sizeof(lv_color_t));
-            if (fbuffer2 == NULL) {
-                luat_heap_free(fbuffer);
-                LLOGD("not enough memory");
-                return 0;
-            }
-        }
-    }
-    
-    LLOGD("w %d h %d fbuff_size %d mode %d fbuffer:%p fbuffer2:%p", w, h, fbuff_size, buffmode, fbuffer, fbuffer2);
-
-    lv_disp_buf_init(&LV.disp_buf, fbuffer, fbuffer2, fbuff_size);
-
-    lv_disp_drv_t my_disp_drv;
-    lv_disp_drv_init(&my_disp_drv);
-
-    my_disp_drv.flush_cb = luat_lv_disp_flush;
-
-    my_disp_drv.hor_res = w;
-    my_disp_drv.ver_res = h;
-    my_disp_drv.buffer = &LV.disp_buf;
-
-#ifdef LUAT_USE_LVGL_SDL2
-    if (lcd_conf == NULL) {
-        LLOGD("use LVGL-SDL2 分辨率 %dx%d", w, h);
-        LV.disp =lv_sdl_init_display("LuatOS", w, h);
-        lv_sdl_init_input();
-        lua_pushboolean(L, LV.disp != NULL ? 1 : 0);
-        return 1;
-    }
-#endif
-    LV.disp = lv_disp_drv_register(&my_disp_drv);
-    if (LV.disp == NULL) {
-        LLOGE("lv_disp_drv_register error");
-    }
-    lua_pushboolean(L, LV.disp != NULL ? 1 : 0);
-#ifdef LUAT_USE_LVGL_SDL2
-    LLOGD("use LVGL-LCD-SDL2 swap %d", LV_COLOR_16_SWAP);
-    lv_sdl_init_input();
-#endif
-#ifdef __LVGL_SLEEP_ENABLE__
-    luat_lvgl_tick_sleep(0);
-#endif
-    return 1;
-}
-#endif
+/*
+@module  lvgl
+@summary LVGL图像库
+@version 1.0
+@date    2021.06.01
+*/
+
+#include "luat_base.h"
+#include "luat_lvgl.h"
+#include "luat_mem.h"
+#include "luat_zbuff.h"
+
+typedef struct luat_lv {
+    lv_disp_t* disp;
+    lv_disp_buf_t disp_buf;
+    int buff_ref;
+    int buff2_ref;
+}luat_lv_t;
+
+static luat_lv_t LV = {0};
+//static lv_disp_drv_t my_disp_drv;
+
+
+/**
+初始化LVGL
+@api lvgl.init(w, h, lcd, buff_size, buff_mode)
+@int 屏幕宽,可选,默认从lcd取
+@int 屏幕高,可选,默认从lcd取
+@userdata lcd指针,可选,lcd初始化后有默认值,预留的多屏入口
+@int 缓冲区大小,默认宽*10, 不含色深.
+@int 缓冲模式,默认0x06, bit0:是否使用lcdbuff bit1:buff1 bit2:buff2 bit3:是否使用lua heap
+@return bool 成功返回true,否则返回false
+ */
+int luat_lv_init(lua_State *L);
+
+#ifdef LUAT_USE_LVGL_SDL2
+#include "luat_lcd.h"
+// SDL2 模式
+extern lv_disp_t *lv_sdl_init_display(const char* win_name, int width, int height);
+extern lv_indev_t *lv_sdl_init_input(void);
+#endif
+#if defined(LUAT_EMULATOR_MODE)
+// 模拟器模式
+int luat_lv_init(lua_State *L) {
+    LLOGE("emulator mode init");
+    int w = 480;
+    int h = 320;
+
+    if (lua_isnumber(L, 1) && lua_isnumber(L, 2)) {
+        w = luaL_checkinteger(L, 1);
+        h = luaL_checkinteger(L, 2);
+    }
+
+    extern void emulator_lvgl_init(int w, int h);
+    emulator_lvgl_init(w, h);
+    return 0;
+}
+// #elif defined(LUA_USE_WINDOWS)
+// // win32遗留模式
+// #include <windows.h>
+// extern uint32_t WINDOW_HOR_RES;
+// extern uint32_t WINDOW_VER_RES;
+// int luat_lv_init(lua_State *L) {
+//     if (lua_isnumber(L, 1) && lua_isnumber(L, 2)) {
+//         WINDOW_HOR_RES = luaL_checkinteger(L, 1);
+//         WINDOW_VER_RES = luaL_checkinteger(L, 2);
+//     }
+//     LLOGD("win32 lvgl init %d %d", WINDOW_HOR_RES, WINDOW_VER_RES);
+//     HWND windrv_init(void);
+//     windrv_init();
+//     lua_pushboolean(L, 1);
+//     return 1;
+// }
+
+#elif defined(LUAT_USE_LVGL_INIT_CUSTOM)
+// 自定义模式, 这个由bsp自行实现了
+
+#else
+// 普通MCU模式
+#include "luat_lcd.h"
+
+static luat_lcd_conf_t* lcd_conf;
+static lv_color_t *fbuffer = NULL;
+static lv_color_t *fbuffer2 = NULL;
+
+LUAT_WEAK void luat_lv_disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p) {
+    //-----
+    if (lcd_conf != NULL) {
+        luat_lcd_draw(lcd_conf, area->x1, area->y1, area->x2, area->y2, color_p);
+        if (disp_drv->buffer->flushing_last){
+            if (lcd_conf->buff_ex){
+                lcd_conf->buff_draw = color_p;
+            }
+            luat_lcd_flush(lcd_conf);
+        }
+    }
+    //LLOGD("CALL disp_flush (%d, %d, %d, %d)", area->x1, area->y1, area->x2, area->y2);
+    lv_disp_flush_ready(disp_drv);
+}
+int luat_lv_init(lua_State *L) {
+    int w = 0;
+    int h = 0;
+
+    if (LV.disp != NULL) {
+        lua_pushboolean(L, 0);
+        return 1;
+    }
+
+    if (lua_isnumber(L, 1) && lua_isnumber(L, 2)) {
+        w = luaL_checkinteger(L, 1);
+        h = luaL_checkinteger(L, 2);
+    }
+
+    size_t fbuff_size = 0;
+    uint8_t buffmode = 0;// bit0:是否使用lcdbuff bit1:buff1 bit2:buff2 bit3:是否使用lua heap
+
+    if (lua_isuserdata(L, 3)) {
+        lcd_conf = lua_touserdata(L, 3);
+    }
+    else {
+        lcd_conf = luat_lcd_get_default();
+    }
+    if (lcd_conf == NULL) {
+        #if defined(LUA_USE_LINUX) || defined(LUA_USE_WINDOWS)
+        if (w == 0 || h == 0) {
+            w = 800;
+            h = 640;
+        }
+        #else
+        LLOGE("setup lcd first!!");
+        return 0;
+        #endif
+    }
+
+    if (w == 0 || h == 0) {
+        w = lcd_conf->w;
+        h = lcd_conf->h;
+    }
+
+    if (lua_isinteger(L, 4)) {
+        fbuff_size = luaL_checkinteger(L, 4);
+        if (fbuff_size < w*10)
+            fbuff_size = w * 10;
+    }
+    else {
+        fbuff_size = w * 10;
+    }
+
+    if (lua_isinteger(L, 5)) {
+        buffmode = luaL_checkinteger(L, 5);
+    }else{
+        buffmode = 0x06; //heap申请双buff模式
+    }
+    if (lcd_conf) {
+        lcd_conf->lcd_use_lvgl = 1;
+    }
+    if (lcd_conf != NULL && lcd_conf->buff != NULL) {
+        // LLOGD("use LCD buff");
+        fbuff_size = w * h;
+        fbuffer = lcd_conf->buff;
+        buffmode = 1;
+        if (lcd_conf->buff_ex){
+            fbuffer2 = lcd_conf->buff_ex;
+        }
+    }
+
+    if (buffmode & 0x08) {
+        //LLOGD("use VM buff");
+        if (buffmode & 0x02) {
+            fbuffer = lua_newuserdata(L, fbuff_size * sizeof(lv_color_t));
+            if (fbuffer == NULL) {
+                LLOGD("not enough memory");
+                return 0;
+            }
+        }
+        if (buffmode & 0x04) {
+            fbuffer2 = lua_newuserdata(L, fbuff_size * sizeof(lv_color_t));
+            if (fbuffer2 == NULL) {
+                LLOGD("not enough memory");
+                return 0;
+            }
+        }
+        // 引用即弹出
+        if (fbuffer2)
+            LV.buff2_ref = luaL_ref(L, LUA_REGISTRYINDEX);
+        LV.buff_ref = luaL_ref(L, LUA_REGISTRYINDEX);
+    }else{
+        //LLOGD("use HEAP buff");
+        if (buffmode & 0x02) {
+            fbuffer = luat_heap_malloc(fbuff_size * sizeof(lv_color_t));
+            if (fbuffer == NULL) {
+                LLOGD("not enough memory");
+                return 0;
+            }
+        }
+        if (buffmode & 0x04) {
+            fbuffer2 = luat_heap_malloc(fbuff_size * sizeof(lv_color_t));
+            if (fbuffer2 == NULL) {
+                luat_heap_free(fbuffer);
+                LLOGD("not enough memory");
+                return 0;
+            }
+        }
+    }
+    
+    LLOGD("w %d h %d fbuff_size %d mode %d fbuffer:%p fbuffer2:%p", w, h, fbuff_size, buffmode, fbuffer, fbuffer2);
+
+    lv_disp_buf_init(&LV.disp_buf, fbuffer, fbuffer2, fbuff_size);
+
+    lv_disp_drv_t my_disp_drv;
+    lv_disp_drv_init(&my_disp_drv);
+
+    my_disp_drv.flush_cb = luat_lv_disp_flush;
+
+    my_disp_drv.hor_res = w;
+    my_disp_drv.ver_res = h;
+    my_disp_drv.buffer = &LV.disp_buf;
+
+#ifdef LUAT_USE_LVGL_SDL2
+    if (lcd_conf == NULL) {
+        LLOGD("use LVGL-SDL2 分辨率 %dx%d", w, h);
+        LV.disp =lv_sdl_init_display("LuatOS", w, h);
+        lv_sdl_init_input();
+        lua_pushboolean(L, LV.disp != NULL ? 1 : 0);
+        return 1;
+    }
+#endif
+    LV.disp = lv_disp_drv_register(&my_disp_drv);
+    if (LV.disp == NULL) {
+        LLOGE("lv_disp_drv_register error");
+    }
+    lua_pushboolean(L, LV.disp != NULL ? 1 : 0);
+#ifdef LUAT_USE_LVGL_SDL2
+    LLOGD("use LVGL-LCD-SDL2 swap %d", LV_COLOR_16_SWAP);
+    lv_sdl_init_input();
+#endif
+#ifdef __LVGL_SLEEP_ENABLE__
+    luat_lvgl_tick_sleep(0);
+#endif
+    return 1;
+}
+#endif

+ 1 - 1
components/lvgl/gen/lv_widgets/luat_lv_table.c

@@ -198,7 +198,7 @@ int luat_lv_table_get_pressed_cell(lua_State *L) {
     uint16_t col = 0;
     lv_res_t ret;
     ret = lv_table_get_pressed_cell(table , &row , &col);
-    if (ret == 0) {
+    if (ret == LV_RES_OK) {
         lua_pushinteger(L, row);
         lua_pushinteger(L, col);
         return 2;

+ 3 - 0
components/lvgl/src/lv_core/lv_indev.c

@@ -123,7 +123,10 @@ void _lv_indev_read_task(lv_task_t * task)
     } while(more_to_read);
 
     /*End of indev processing, so no act indev*/
+    #ifdef __LUATOS__
+    #else
     indev_act     = NULL;
+    #endif
     indev_obj_act = NULL;
 
     LV_LOG_TRACE("indev read task finished");

+ 4 - 2
components/network/httpsrv/inc/luat_httpsrv.h

@@ -11,6 +11,7 @@ typedef struct luat_httpsrv_ctx
     void* userdata;
     uint8_t adapter_id;
     struct netif* netif;
+    struct tcp_pcb* pcb;
 }luat_httpsrv_ctx_t;
 
 
@@ -59,6 +60,7 @@ static const ct_reg_t ct_regs[] = {
     {"bin",     "application/octet-stream"},
 };
 
-
-int luat_httpsrv_stop(int port);
+luat_httpsrv_ctx_t* luat_httpsrv_malloc(int port, int adapter_index);
 int luat_httpsrv_start(luat_httpsrv_ctx_t* ctx);
+int luat_httpsrv_free(luat_httpsrv_ctx_t* ctx);
+int luat_httpsrv_stop(luat_httpsrv_ctx_t* ctx);

+ 55 - 22
components/network/httpsrv/src/luat_httpsrv_lwip.c

@@ -18,10 +18,12 @@
 
 #include "http_parser.h"
 
+#undef LLOGD
+#define LLOGD(...) 
 
 typedef struct client_socket_ctx
 {
-    // int id;
+    int lua_ref_id;
     int code;
     struct http_parser parser;
 
@@ -43,9 +45,6 @@ typedef struct client_socket_ctx
     uint8_t write_done;
 }client_socket_ctx_t;
 
-static struct tcp_pcb* srvpcb;
-static int lua_ref_id;
-
 static int handle_static_file(client_socket_ctx_t *client);
 
 static void client_cleanup(client_socket_ctx_t *client);
@@ -180,7 +179,7 @@ static void client_cleanup(client_socket_ctx_t *client) {
 
 static int luat_client_cb(lua_State* L, void* ptr) {
     client_socket_ctx_t* client = (client_socket_ctx_t*)ptr;
-    lua_geti(L, LUA_REGISTRYINDEX, lua_ref_id);
+    lua_geti(L, LUA_REGISTRYINDEX, client->lua_ref_id);
     if (lua_isnil(L, -1)) {
         client_cleanup(client);
         return 0;
@@ -373,12 +372,12 @@ static void client_err_cb(void *arg, err_t err) {
 }
 
 static err_t srv_accept_cb(void *arg, struct tcp_pcb *newpcb, err_t err) {
-    (void)arg;
     if (err) {
         LLOGD("accpet err %d", err);
         tcp_abort(newpcb);
         return ERR_OK;
     }
+    luat_httpsrv_ctx_t* srvctx = (luat_httpsrv_ctx_t*) arg;
     client_socket_ctx_t* ctx = luat_heap_malloc(sizeof(client_socket_ctx_t));
     if (ctx == NULL) {
         LLOGD("out of memory when malloc client ctx");
@@ -388,6 +387,7 @@ static err_t srv_accept_cb(void *arg, struct tcp_pcb *newpcb, err_t err) {
     tcp_accepted(newpcb);
     memset(ctx, 0, sizeof(client_socket_ctx_t));
     ctx->pcb = newpcb;
+    ctx->lua_ref_id = srvctx->lua_ref_id;
     tcp_arg(newpcb, ctx);
     tcp_recv(newpcb, client_recv_cb);
     tcp_sent(newpcb, client_sent_cb);
@@ -395,37 +395,69 @@ static err_t srv_accept_cb(void *arg, struct tcp_pcb *newpcb, err_t err) {
     return ERR_OK;
 }
 
-int luat_httpsrv_stop(int port) {
-    (void)port;
-    if (srvpcb != NULL) {
-        tcp_close(srvpcb);
-        srvpcb = NULL;
+static void srv_stop_cb(void* arg) {
+    luat_httpsrv_ctx_t* ctx = (luat_httpsrv_ctx_t*)arg;
+    if (ctx == NULL) {
+        return;
+    }
+    if (ctx->pcb) {
+        tcp_abort(ctx->pcb);
+        tcp_close(ctx->pcb);
+        ctx->pcb = NULL;
     }
+    luat_httpsrv_free(ctx);
+}
+int luat_httpsrv_stop(luat_httpsrv_ctx_t* ctx) {
+    tcpip_callback(srv_stop_cb, ctx);
     return 0;
 }
 
-int luat_httpsrv_start(luat_httpsrv_ctx_t* ctx) {
-    if (srvpcb != NULL) {
-        LLOGE("only allow 1 httpsrv");
-        return -10;
-    }
+static void luat_httpsrv_start_cb(luat_httpsrv_ctx_t* ctx) {
     struct tcp_pcb* tcp = tcp_new();
     int ret = 0;
     if (tcp == NULL) {
         LLOGD("out of memory when malloc httpsrv tcp_pcb");
-        return -1;
+        return;
     }
     tcp->flags |= SOF_REUSEADDR;
     ret = tcp_bind(tcp, &ctx->netif->ip_addr, ctx->port);
     if (ret) {
         LLOGD("httpsrv bind port %d ret %d", ctx->port);
-        return -2;
+        return;
+    }
+    ctx->pcb = tcp_listen_with_backlog(tcp, 1);
+    tcp_arg(ctx->pcb, ctx);
+    tcp_accept(ctx->pcb, srv_accept_cb);
+    return;
+}
+
+luat_httpsrv_ctx_t* luat_httpsrv_malloc(int port, int adapter_index) {
+    luat_httpsrv_ctx_t* ctx = luat_heap_malloc(sizeof(luat_httpsrv_ctx_t));
+    if (ctx == NULL) {
+        LLOGD("out of memory when malloc httpsrv ctx");
+        return NULL;
     }
-    lua_ref_id = ctx->lua_ref_id;
-    srvpcb = tcp_listen(tcp);
-    tcp_arg(srvpcb, NULL);
-    tcp_accept(srvpcb, srv_accept_cb);
+    memset(ctx, 0, sizeof(luat_httpsrv_ctx_t));
+    ctx->port = port;
+    ctx->adapter_id = adapter_index;
+    return ctx;
+}
+
+int luat_httpsrv_free(luat_httpsrv_ctx_t* ctx) {
+    if (ctx == NULL) {
+        return 0;
+    }
+    luat_heap_free(ctx);
+    ctx = NULL;
     return 0;
+} 
+
+int luat_httpsrv_start(luat_httpsrv_ctx_t* ctx) {
+    int ret = tcpip_callback(luat_httpsrv_start_cb, ctx);
+    if (ret) {
+        LLOGE("启动失败 %d", ret);
+    }
+    return ret;
 }
 
 // 静态文件的处理
@@ -478,6 +510,7 @@ static int client_send_static_file(client_socket_ctx_t *client, char* path, size
     // 发送body
     FILE*  fd = luat_fs_fopen(path, "rb");
     if (fd == NULL) {
+        tcp_abort(client->pcb);
         tcp_close(client->pcb);
         LLOGE("open %s FAIL!!", path);
         return 1;

+ 65 - 9
components/network/httpsrv/src/luat_lib_httpsrv.c

@@ -17,6 +17,18 @@
 #define LUAT_LOG_TAG "httpsrv"
 #include "luat_log.h"
 
+#define LUAT_HTTPSRV_COUNT 16
+
+typedef struct port_srv
+{
+    uint16_t port;
+    uint8_t adapter;
+    uint8_t status;
+    luat_httpsrv_ctx_t* ctx;
+}port_srv_t;
+
+static port_srv_t srvs[LUAT_HTTPSRV_COUNT];
+
 /*
 启动并监听一个http端口
 @api httpsrv.start(port, func, adapter)
@@ -58,23 +70,48 @@ static int l_httpsrv_start(lua_State *L) {
         LLOGW("httpsrv need callback function!!!");
         return 0;
     }
-    luat_httpsrv_ctx_t ctx = {
-        .port = port
-    };
     uint8_t adapter_index = luaL_optinteger(L, 3, network_get_last_register_adapter());
-    ctx.adapter_id = adapter_index;
     luat_netdrv_t* drv = luat_netdrv_get(adapter_index);
     if (drv == NULL || drv->netif == NULL) {
         LLOGW("该网络还没准备好 %d", adapter_index);
         return 0;
     }
-    ctx.netif = drv->netif;
+    // 检查一下是否有空位
+    for (size_t i = 0; i < LUAT_HTTPSRV_COUNT; i++)
+    {
+        if (srvs[i].port == port && srvs[i].adapter == adapter_index) {
+            LLOGW("httpsrv port %d already in use", port);
+            return 0;
+        }
+    }
+    int index = -1;
+    for (size_t i = 0; i < LUAT_HTTPSRV_COUNT; i++)
+    {
+        if (srvs[i].ctx == NULL) {
+            index = i;
+            break;
+        }
+    }
+    if (index < 0) {
+        LLOGW("httpsrv no free slot, max %d", LUAT_HTTPSRV_COUNT);
+        return 0;
+    }
+
+    luat_httpsrv_ctx_t* ctx = luat_httpsrv_malloc(port, adapter_index);
+    if (ctx == NULL) {
+        return 0;
+    }
+    ctx->netif = drv->netif;
     lua_pushvalue(L, 2);
-    ctx.lua_ref_id = luaL_ref(L, LUA_REGISTRYINDEX);
-    int ret = luat_httpsrv_start(&ctx);
+    ctx->lua_ref_id = luaL_ref(L, LUA_REGISTRYINDEX);
+    int ret = luat_httpsrv_start(ctx);
     if (ret == 0) {
         ipaddr_ntoa_r(&drv->netif->ip_addr, buff,  32);
-        LLOGI("http listen at %s:%d", buff, ctx.port);
+        LLOGI("http listen at %s:%d", buff, ctx->port);
+        srvs[index].port = port;
+        srvs[index].adapter = adapter_index;
+        srvs[index].ctx = ctx;
+        srvs[index].status = 1;
     }
     lua_pushboolean(L, ret == 0 ? 1 : 0);
     return 1;
@@ -88,7 +125,26 @@ static int l_httpsrv_start(lua_State *L) {
 */
 static int l_httpsrv_stop(lua_State *L) {
     int port = luaL_checkinteger(L, 1);
-    luat_httpsrv_stop(port);
+    uint8_t adapter_index = luaL_optinteger(L, 3, network_get_last_register_adapter());
+    for (size_t i = 0; i < LUAT_HTTPSRV_COUNT; i++)
+    {
+        if (srvs[i].port == port && srvs[i].adapter == adapter_index) {
+            if (srvs[i].ctx != NULL) {
+                srvs[i].port = 0;
+                srvs[i].adapter = 0;
+                srvs[i].status = 0;
+
+                if (srvs[i].ctx->lua_ref_id != LUA_NOREF) {
+                    luaL_unref(L, LUA_REGISTRYINDEX, srvs[i].ctx->lua_ref_id);
+                    srvs[i].ctx->lua_ref_id = LUA_NOREF;
+                }
+                luat_httpsrv_stop(srvs[i].ctx);
+                srvs[i].ctx = NULL;
+                lua_pushboolean(L, 1);
+                return 1;
+            }
+        }
+    }
     return 0;
 }
 

+ 1 - 1
components/network/libhttp/luat_lib_http.c

@@ -237,7 +237,7 @@ static int l_http_request(lua_State *L) {
 	}
 	#ifdef LUAT_USE_FOTA
 	if (http_ctrl->timeout < 1000 && http_ctrl->isfota) {
-		http_ctrl->timeout = HTTP_TIMEOUT;
+		http_ctrl->timeout = HTTP_TIMEOUT * 2;
 	}
 	#endif
 	if (http_ctrl->timeout < 1000) {

+ 9 - 4
components/network/netdrv/binding/luat_lib_netdrv.c

@@ -35,9 +35,13 @@
 -- Air8101初始化内部以太网控制器
 netdrv.setup(socket.LWIP_ETH)
 
--- Air8000/Air780EPM初始化CH390H/D作为LAN口, 单一使用.不含WAN.
+-- Air8000/Air780EPM初始化CH390H/D作为LAN/WAN
+-- 支持多个CH390H, 使用不同的CS脚区分不同网口
 netdrv.setup(socket.LWIP_ETH, netdrv.CH390, {spi=0,cs=8})
 netdrv.dhcp(socket.LWIP_ETH, true)
+-- 支持CH390H的中断模式, 能提供响应速度, 但是需要外接中断引脚
+-- 实测对总网速没有帮助, 轻负载时能降低功耗, 让模组能进入低功耗模式
+netdrv.setup(socket.LWIP_ETH, netdrv.CH390, {spi=0,cs=8,irq=20})
 */
 static int l_netdrv_setup(lua_State *L) {
     luat_netdrv_conf_t conf = {0};
@@ -311,14 +315,15 @@ static const rotable_Reg_t reg_netdrv[] =
 
     //@const CH390 number 南京沁恒CH390系列,支持CH390D/CH390H, SPI通信
     { "CH390",          ROREG_INT(1)},
-    { "CH395",          ROREG_INT(2)}, // 考虑兼容Air724UG/Air820UG的老客户
-    { "W5500",          ROREG_INT(3)}, // 考虑兼容Air780EXXX/Air105的老客户
     { "UART",           ROREG_INT(16)}, // UART形式的网卡, 不带MAC, 直接IP包
-    { "SPINET",         ROREG_INT(32)}, // SPI形式的网卡, 可以带MAC, 也可以不带
+    //@const WHALE number 虚拟网卡
     { "WHALE",          ROREG_INT(64)}, // 通用WHALE设备
 
+    //@const CTRL_RESET number 控制类型-复位,当前仅支持CH390H
     { "CTRL_RESET",     ROREG_INT(LUAT_NETDRV_CTRL_RESET)},
+    //@const CTRL_RESET number 请求对网卡硬复位,当前仅支持CH390H
     { "RESET_HARD",     ROREG_INT(0x101)},
+    //@const CTRL_RESET number 请求对网卡硬复位,当前仅支持CH390H
     { "RESET_SOFT",     ROREG_INT(0x102)},
 	{ NULL,             ROREG_INT(0) }
 };

+ 57 - 6
components/network/netdrv/src/ch390h_task.c

@@ -40,10 +40,29 @@ static luat_rtos_queue_t qt;
 static uint64_t warn_vid_pid_tm;
 static uint64_t warn_msg_tm;
 
+static uint32_t s_ch390h_mode; // 0 -- PULL 模式, 1 == IRQ 模式
+
 static int pkg_mem_type = LUAT_HEAP_AUTO;
 
+static int ch390h_irq_cb(void *data, void *args) {
+    uint32_t len = 0;
+    luat_rtos_queue_get_cnt(qt, &len);
+    if (len > 4) {
+        return 0;
+    }
+    pkg_evt_t evt = {
+        .id = 2
+    };
+    luat_rtos_queue_send(qt, &evt, sizeof(pkg_evt_t), 0);
+    return 0;
+}
+
 static int ch390h_bootup(ch390h_t* ch) {
+    if (ch->ulwip.netif != NULL) {
+        return 0;
+    }
     // 初始化SPI设备, 由外部代码初始化, 因为不同bsp的速度不一样, 就不走固定值了
+    luat_gpio_cfg_t gpio_cfg = {0};
 
     // 初始化CS脚
     luat_gpio_t gpio = {0};
@@ -53,7 +72,21 @@ static int ch390h_bootup(ch390h_t* ch) {
     gpio.irq = 1;
     luat_gpio_setup(&gpio);
 
-    // TODO 初始化INT脚
+    // 初始化INT脚
+    if (ch->intpin != 0xff) {
+        luat_gpio_set_default_cfg(&gpio_cfg);
+        gpio_cfg.pin = ch->intpin;
+        gpio_cfg.mode = LUAT_GPIO_IRQ;
+        gpio_cfg.irq_type = LUAT_GPIO_RISING_IRQ;
+        gpio_cfg.pull = 0;
+        gpio_cfg.irq_cb = ch390h_irq_cb;
+        luat_gpio_open(&gpio_cfg);
+        LLOGI("enable irq mode in pin %d", ch->intpin);
+        s_ch390h_mode = 1;
+    }
+    else {
+        // LLOGI("enable pull mode, use pool mode");
+    }
 
     // 初始化dhcp相关资源
     ch->ulwip.netif = ch->netif;
@@ -249,6 +282,9 @@ static int task_loop_one(ch390h_t* ch, luat_ch390h_cstring_t* cs) {
         luat_ch390h_basic_config(ch);
         luat_ch390h_set_phy(ch, 1);
         luat_ch390h_set_rx(ch, 1);
+        if (ch->intpin != 255) {
+            luat_ch390h_write_reg(ch, 0x7F, 1); // 开启接收中断
+        }
         return 0; // 等待下一个周期
     }
     if (check_vid_pid(ch)) {
@@ -318,6 +354,9 @@ static int task_loop_one(ch390h_t* ch, luat_ch390h_cstring_t* cs) {
             luat_ch390h_basic_config(ch);
             luat_ch390h_set_phy(ch, 1);
             luat_ch390h_set_rx(ch, 1);
+            if (ch->intpin != 255) {
+                luat_ch390h_write_reg(ch, 0x7F, 1); // 开启接收中断
+            }
             return 0;
         }
         if (len > 0) {
@@ -346,6 +385,10 @@ static int task_loop_one(ch390h_t* ch, luat_ch390h_cstring_t* cs) {
     else {
         // LLOGD("没有数据待读取");
     }
+
+    if (ch->intpin != 255) {
+        luat_ch390h_write_reg(ch, 0x7E, 0x3F); // 清除中断
+    }
     
     // 这一轮处理完成了
     // 如果rx有数据, 那就不要等待, 立即开始下一轮
@@ -365,7 +408,6 @@ static int task_loop(ch390h_t *ch, luat_ch390h_cstring_t* cs) {
         }
     }
     if (ret) {
-        pkg_evt_t evt = {0};
         luat_rtos_queue_send(qt, &evt, sizeof(pkg_evt_t), 0);
     }
     return ret;
@@ -376,6 +418,7 @@ static int task_wait_msg(uint32_t timeout) {
     ch390h_t *ch = NULL;
     pkg_evt_t evt = {0};
     int ret = luat_rtos_queue_recv(qt, &evt, sizeof(pkg_evt_t), timeout);
+    // LLOGD("evt id %d ret %d timeout %d", evt.id, ret, timeout);
     if (ret == 0 && evt.id == 1) {
         // 收到消息了
         ch = (ch390h_t *)evt.ch;
@@ -390,6 +433,9 @@ static int task_wait_msg(uint32_t timeout) {
         return 1; // 拿到消息, 那队列里可能还有消息, 马上执行下一轮操作
     }
     else {
+        // if (evt.id == 2) {
+        //     LLOGD("CH390中断触发");
+        // }
         ret = task_loop(NULL, NULL);
     }
     return ret;
@@ -404,14 +450,19 @@ static void ch390_task_main(void* args) {
         if (count % 10 == 0) {
             luat_wdt_feed();
         }
-        if (count > 256) {
+        if (count > 1024) {
             if (ret) {
-                // LLOGD("强制休眠20ms");
-                // luat_rtos_task_sleep(20);
+                LLOGD("强制休眠20ms");
+                luat_rtos_task_sleep(20);
             }
             count = 0;
         }
-        ret = task_wait_msg(5);
+        if (s_ch390h_mode == 0) {
+            ret = task_wait_msg(5);
+        }
+        else {
+            ret = task_wait_msg(1000);
+        }
     }
 }
 

+ 11 - 0
components/network/netdrv/src/luat_netdrv.c

@@ -179,12 +179,23 @@ uint16_t alg_tcpudphdr_chksum(uint32_t src_addr, uint32_t dst_addr, uint8_t prot
 
 void luat_netdrv_netif_input(void* args) {
     netdrv_pkg_msg_t* ptr = (netdrv_pkg_msg_t*)args;
+    if (ptr == NULL) {
+        return;
+    }
+    if (ptr->len == 0) {
+        LLOGE("什么情况,ptr->len == 0?!");
+        return;
+    }
     struct pbuf* p = pbuf_alloc(PBUF_TRANSPORT, ptr->len, PBUF_RAM);
     if (p == NULL) {
         LLOGD("分配pbuf失败!!! %d", ptr->len);
         luat_heap_free(ptr);
         return;
     }
+    if (p->tot_len != ptr->len) {
+        LLOGE("p->tot_len != ptr->len %d %d", p->tot_len, ptr->len);
+        return;
+    }
     pbuf_take(p, ptr->buff, ptr->len);
     // luat_airlink_hexdump("收到IP数据,注入到netif", ptr->buff, ptr->len);
     int ret = ptr->netif->input(p, ptr->netif);

+ 1 - 1
components/wlan/luat_lib_wlan.c

@@ -289,7 +289,7 @@ log.info("wlan mac", wlan.getMac())
 static int l_wlan_get_mac(lua_State* L){
     uint8_t tmp[6] = {0};
     char tmpbuff[16] = {0};
-    #if defined(LUAT_USE_NETDRV) && !defined(CONFIG_SOC_BK7258)
+    #if defined(LUAT_USE_NETDRV) && !defined(CONFIG_SOC_BK7258) && !defined(CONFIG_SOC_BK7236)
     int id = luaL_optinteger(L, 1, 0);
     if (id == 0) {
         id = NW_ADAPTER_INDEX_LWIP_WIFI_STA;

+ 10 - 1
demo/airlink/air8000_wifi_eth/main.lua

@@ -84,7 +84,7 @@ function eth_wan()
         0,--CPHA
         0,--CPOL
         8,--数据宽度
-        25600000--,--波特率
+        51200000--,--波特率
     )
     log.info("main", "open spi",result)
     if result ~= 0 then--返回值为0,表示打开成功
@@ -94,6 +94,15 @@ function eth_wan()
 
     netdrv.setup(socket.LWIP_ETH, netdrv.CH390, {spi=1,cs=12})
     netdrv.dhcp(socket.LWIP_ETH, true)
+
+    while 1 do
+        local ip = netdrv.ipv4(socket.LWIP_ETH)
+        if ip and ip ~= "0.0.0.0" then
+            break
+        end
+        sys.wait(100)
+    end
+    iperf.server(socket.LWIP_ETH)
 end
 
 sys.taskInit(function()

+ 1 - 1
lua/src/lobject.c

@@ -436,7 +436,7 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
         goto top2str;
       }
       case 'I': {  /* a 'lua_Integer' */
-#if (defined __PRINT_ALIGNED_32BIT__) && (defined LUAT_CONF_VM_64bit)
+#if (defined __PRINT_ALIGNED_32BIT__) && (defined LUAT_CONF_VM_64bit) && !(defined __BK72XX__)
         // 针对EC618的va_arg取double出错的临时解决方案
         // 直接调用 va_arg(argp, double) 会返回0
         // 可能与某个gcc参数有关