From efa3abb9a6b98c9400d7436595563300668f567e Mon Sep 17 00:00:00 2001 From: Lizongdi <1210855344@qq.com> Date: Fri, 6 Nov 2026 15:54:50 +0800 Subject: [PATCH] =?UTF-8?q?lua=E3=80=90=E5=BE=85=E9=AA=8C=E8=AF=81?= =?UTF-8?q?=E3=80=91=E5=A2=9E=E5=8A=A0=E4=B8=B2=E5=8F=A3=E7=BB=88=E7=AB=AF?= =?UTF-8?q?=E8=87=AA=E8=BA=AB=E5=8F=A5=E6=9F=84=EF=BC=8C=E6=96=B9=E4=BE=BF?= =?UTF-8?q?ymoden=E6=94=B6=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bspMCU/My_print.c | 9 +++++++++ bspMCU/bsp_uart.c | 16 +++++++++------- bspMCU/l_stm32.c | 2 ++ bspMCU/l_uart.c | 32 ++++++++++++++++++++++++++++++++ lua/lua.c | 6 ++++++ 5 files changed, 58 insertions(+), 7 deletions(-) diff --git a/bspMCU/My_print.c b/bspMCU/My_print.c index 54cfc88..b071c42 100644 --- a/bspMCU/My_print.c +++ b/bspMCU/My_print.c @@ -30,6 +30,15 @@ volatile uint8_t g_flow_control_paused = 0; TComCtrl *g_ptUartCtrl; +/** + * @brief 控制台串口句柄 getter (供 lua CON() 绑定) + * @note 借用语义: 调用方(lua GC)不得 Close, 控制台生命周期归 Myprint + */ +WEAK TComCtrl *Myprint_GetCtrl(void) +{ + return g_ptUartCtrl; +} + int USART_Send(char *_pBuffer, uint32_t _iSize) { HAL_GPIO_WritePin(RS485_2_DIR_GPIO_Port, RS485_2_DIR_Pin,GPIO_PIN_SET); diff --git a/bspMCU/bsp_uart.c b/bspMCU/bsp_uart.c index 79dce8c..861e041 100644 --- a/bspMCU/bsp_uart.c +++ b/bspMCU/bsp_uart.c @@ -12,15 +12,15 @@ extern DMA_HandleTypeDef hdma_uart7_rx; #ifdef CONFIG_UART_IT_IDLEDMA static TUartTab g_ptUartTab[] = { - {&hlpuart1, &hdma_usart2_rx, 0}, - {&huart1, &hdma_usart1_rx, 0}, - {&huart2, &hdma_usart2_rx, 0}, + {&hlpuart1, NULL, 0}, + {&huart1, NULL, 0}, + {&huart2, NULL, 0}, {&huart3, &hdma_usart3_rx, 0}, #ifdef IOC_100PIN - {&huart4, &hdma_uart4_rx, 0}, - {&huart5, &hdma_uart5_rx, 0}, - {&huart6, &hdma_usart6_rx, 0}, - {&huart7, &hdma_uart7_rx, 0} + {&huart4, NULL, 0}, + {&huart5, NULL, 0}, + {&huart6, NULL, 0}, + {&huart7, NULL, 0} #endif }; #else @@ -159,6 +159,7 @@ void UART_RX_IRQHandler(TComCtrl *_ptComCtrl) #endif } +#ifndef CONFIG_UART_IT_IDLEDMA void UART_RX_ERRORHandler(TComCtrl *_ptComCtrl) { TUartUserData *ptUartUserData = (TUartUserData *)_ptComCtrl->m_pUserData; @@ -177,5 +178,6 @@ void UART_RX_ERRORHandler(TComCtrl *_ptComCtrl) /* 重新启动中断接收 */ HAL_UART_Receive_IT(ptUartUserData->m_uart, &ptUartUserData->m_temp, 1); } +#endif #endif diff --git a/bspMCU/l_stm32.c b/bspMCU/l_stm32.c index df46307..2da8339 100644 --- a/bspMCU/l_stm32.c +++ b/bspMCU/l_stm32.c @@ -767,6 +767,8 @@ int luaopen_stm32(lua_State *L) lua_call(L, 0, 1); lua_getfield(L, -1, "new"); lua_setfield(L, -3, "COM"); + lua_getfield(L, -1, "console"); + lua_setfield(L, -3, "CON"); lua_pop(L, 1); #endif diff --git a/bspMCU/l_uart.c b/bspMCU/l_uart.c index 6c2748c..4bb0773 100644 --- a/bspMCU/l_uart.c +++ b/bspMCU/l_uart.c @@ -165,6 +165,35 @@ static int l_com_sy(lua_State *L) return 1; } +// 构造函数: CON() — 控制台串口句柄 (借用语义) +// MCU(USE_PRINT) 上 lua 终端自身的收发(printf/fgetc)都走 g_ptUartCtrl, +// CON() 把它包成 COMMT 句柄, 便可在控制台 REPL 直接对控制台串口 ymodem: +// c:ry('.') -- 接收上位机发来的文件到当前目录 +// c:sy('f.bin') -- 把本地文件发给上位机 +// 借用句柄 GC 不关闭 (m_iOwned=0), 控制台生命周期归 Myprint; +// 无控制台句柄的平台(如 Linux 桌面构建)返回 nil +static int l_con_new(lua_State *L) +{ +#if defined(USE_PRINT) + extern TComCtrl *Myprint_GetCtrl(void); + TComCtrl *ptCtrl = Myprint_GetCtrl(); + if (NULL == ptCtrl) + { + lua_print("CON: console port not ready\n"); + lua_pushnil(L); + return 1; + } + stm32_com_t *u = (stm32_com_t *)lua_newuserdata(L, sizeof(stm32_com_t)); + u->m_ptComCtrl = ptCtrl; + luaL_getmetatable(L, "stm32.COMMT"); + lua_setmetatable(L, -2); + return 1; +#else + lua_pushnil(L); + return 1; +#endif +} + // 模块注册 int luaopen_stm32_com(lua_State *L) { @@ -199,6 +228,9 @@ int luaopen_stm32_com(lua_State *L) lua_pushcfunction(L, l_com_new); lua_setfield(L, -2, "new"); + lua_pushcfunction(L, l_con_new); + lua_setfield(L, -2, "console"); + return 1; } diff --git a/lua/lua.c b/lua/lua.c index 2222d40..fc46869 100644 --- a/lua/lua.c +++ b/lua/lua.c @@ -727,6 +727,12 @@ int lua_init(lua_output _lua_print) luaopen_stm32(L); #endif luaopen_default(L); + + /* 预创建控制台串口句柄全局 c (见 lacmd.c CON()): + * MCU 上控制台串口即 lua 终端自身, 开机直接 c:ry('.') / c:sy('f') 做 ymodem; + * 无控制台句柄的平台 CON() 返回 nil, c 为 nil, 无副作用 */ + (void)luaL_dostring(L, "if st.CON then c = st.CON() end"); + lua_print("Lua REPL V5.4\nType 'exit' or Ctrl+D to quit.\n\n"); lua_print("%s", incomplete ? CONT_PROMPT : PROMPT); return 0;