Просмотр исходного кода

update:完善ymodem接收文件的结尾处理
add:ymodem接收文件的demo

alienwalker 2 лет назад
Родитель
Сommit
41dcd49849
3 измененных файлов с 90 добавлено и 7 удалено
  1. 12 3
      components/ymodem/luat_lib_ymodem.c
  2. 14 4
      components/ymodem/luat_ymodem.c
  3. 64 0
      demo/ymodem/main.lua

+ 12 - 3
components/ymodem/luat_lib_ymodem.c

@@ -72,14 +72,15 @@ static int l_ymodem_create(lua_State *L){
 ymodem接收文件数据并保存
 @api ymodem.receive(handler, data)
 @userdata ymodem处理句柄
-@zbuff or string输入的数据
+@zbuff/string 输入的数据
 @return boolean 成功true,失败false
 @return int ack值,需要通过串口/网络等途径返回发送方
-@return int flag值,需要通过串口/网络等途径返回发送方
+@return int flag值,需要通过串口/网络等途径返回发送方,如果有ack值则不发送flag
 @return boolean, 一个文件接收完成true,传输中false
 @return boolean, 整个传输完成true 否则false
 @usage
 -- 注意, 数据来源不限, 通常是uart.read得到data
+no_error,ack,flag,file_done,all_done = ymodem.receive(handler, data)
 */
 
 static int l_ymodem_receive(lua_State *L){
@@ -109,12 +110,20 @@ static int l_ymodem_receive(lua_State *L){
 		result = luat_ymodem_receive(handler->ctrl, (uint8_t*)data, len, &ack, &flag, &file_ok, &all_done);
 		lua_pushboolean(L, !result);
 		lua_pushinteger(L, ack);
-		lua_pushinteger(L, flag);
+		if (flag)
+		{
+			lua_pushinteger(L, flag);
+		}
+		else
+		{
+			lua_pushnil(L);
+		}
 		lua_pushboolean(L, file_ok);
 		lua_pushboolean(L, all_done);
 	}
 	else
 	{
+		LLOGE("%x,%x", handler, handler->ctrl);
 		lua_pushboolean(L, 0);
 		lua_pushnil(L);
 		lua_pushnil(L);

+ 14 - 4
components/ymodem/luat_ymodem.c

@@ -132,6 +132,7 @@ int luat_ymodem_receive(void *handler, uint8_t *data, uint32_t len, uint8_t *ack
 					if (!ctrl->packet_data[XMODEM_DATA_POS])
 					{
 						luat_ymodem_reset(handler);
+						*flag = 0;
 						*ack = XMODEM_ACK;
 						*all_done = 1;
 						return 0;
@@ -279,11 +280,20 @@ YMODEM_DATA_CHECK:
 		}
 		break;
 	case 2:
-		ctrl->state++;
-		ctrl->data_pos = 0;
-		*ack = XMODEM_NAK;
+		if (data[0] == XMODEM_EOT)
+		{
+			ctrl->state++;
+			ctrl->data_pos = 0;
+			*flag = 0;
+			*ack = XMODEM_NAK;
+			if (ctrl->fd) luat_fs_fclose(ctrl->fd);
+			ctrl->fd = NULL;
+		}
+		else
+		{
+			goto DATA_RECIEVE_ERROR;
+		}
 		return 0;
-
 	case 3:
 		if (data[0] == XMODEM_EOT)
 		{

+ 64 - 0
demo/ymodem/main.lua

@@ -0,0 +1,64 @@
+-- LuaTools需要PROJECT和VERSION这两个信息
+PROJECT = "uart_ymodem"
+VERSION = "1.0.0"
+log.style(1)
+log.info("main", PROJECT, VERSION)
+
+-- 引入必要的库文件(lua编写), 内部库不需要require
+sys = require("sys")
+
+if wdt then
+    --添加硬狗防止程序卡死,在支持的设备上启用这个功能
+    wdt.init(9000)--初始化watchdog设置为9s
+    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
+end
+
+local uartid = 1 -- 根据实际设备选取不同的uartid
+
+--初始化
+local result = uart.setup(
+    uartid,--串口id
+    115200,--波特率
+    8,--数据位
+    1--停止位
+)
+local ymodem_running = false
+
+local rxbuff = zbuff.create(1024 + 32)
+local ymodem_handler = ymodem.create("/","save.bin")
+local function ymodem_to()
+    if not ymodem_running then
+        uart.write(uartid, "C")
+        ymodem.reset(ymodem_handler)
+    end
+end
+
+
+sys.timerLoopStart(ymodem_to,500)
+
+local function ymodem_rx(id,len)
+    uart.rx(id,rxbuff)
+    log.info(rxbuff:used())
+    local result,ack,flag,file_done,all_done = ymodem.receive(ymodem_handler,rxbuff)
+    ymodem_running = result
+    log.info(ymodem_running,ack,flag,file_done,all_done)
+    rxbuff:del()
+    if result then
+        rxbuff:copy(0, ack,flag)
+        uart.tx(id, rxbuff)
+    end
+    if all_done then
+        ymodem_running = false  --再次开始接收
+    end
+    rxbuff:del()
+end
+uart.on(uartid, "receive", ymodem_rx)
+
+uart.on(uartid, "sent", function(id)
+    log.info("uart", "sent", id)
+end)
+
+-- 用户代码已结束---------------------------------------------
+-- 结尾总是这一句
+sys.run()
+-- sys.run()之后后面不要加任何语句!!!!!