基于Lua脚本语言的嵌入式UART通信的实现
从而在C程序中,只需要调用下面语句即可将该串口发送缓冲区中索引为1的内存区域设置成0x22:
port=(int)lua_tonumber(L,1);//取端口号
index=(int)lua_tonumber(L,2);//取索引
data=(char)lua_tonumber(L,3);//取数据
uart_port_tx_buf[port].data[index]=data;
当在C程序中需对串口发送缓冲区进行设置时,将按如下方法调用该脚本函数:
lua_getglobal(L, "uart_p0_set_txBuf ");
lua_pcall(L, 0, 1, 0);
其中,函数lua_getglobal的参数"uart_p0_set_txBuf"为要调用的脚本函数名,函数lua_pcall的函数原型为:
int (lua_pcall) (
lua_State *L,
int nargs, //调用函数的参数个数
int nresults, //返回的参数个数
int errfunc //错误处理函数号
);
因所调用的脚本函数uart_p0_set_txBuf没有参数,有一个返回值,所以分别将nargs、nresults置为0、1,而错误处理函数暂不使用,故置为0.
对于脚本中的返回值,将在脚本函数调用结束时,置于lua_pcall调用环境所在的虚拟栈的栈顶中,可由C程序根据索引取出。
经以上过程,就完成了对串口发送缓冲区的内容设置,然后就可以通过串口芯片的驱动程序将其发送到外围设备。
在现场应用时,只需根据不同外围设备问询报文的要求来修改脚本中data数组以及p0_send_num变量的内容即可,而不用对装置的C程序进行任何修改。
3.4 通过Lua函数处理接收缓冲区数据
通过Lua和C的交互来对串口接收缓冲区数据的处理方法同发送缓冲区的处理基本相似。
当装置通过串口驱动程序将外围设备发来的数据置入接收缓冲区后,在C函数中调用脚本函数:
lua_getglobal(L, "uart_p0_del_rxBuf");
lua_pushnumber(L, size);
ret=lua_pcall(L, 1, 1, 0);
其中,参数uart_p0_del_rxBuf为脚本中定义的缓冲区数据处理函数名,通过lua_pushnumber将接收数据的大小入栈,从而传给Lua脚本函数,脚本函数的原型如下:
function uart_p0_del_rxBuf(rx_size)
在该函数中,可通过调用注册的C函数get_rx_buf来获取接收缓冲区中的内容:
data[i] = ied.get_rx_buf(port,index)
其中,data为脚本中类似于数组的表类型。port为串口芯片的端口号,index为缓冲区的索引号,在C程序中通过以下语句对脚本返回所取数据值:
port=(int)lua_tonumber(L,1);//取端口号
index=(int)lua_tonumber(L,2);//取索引
data=uart_port_rx_buf[port].data[index];
lua_pushnumber(L, data);//返回值入栈
可以看出,在脚本中也是借助于虚拟栈来获取C程序的返回值。通过以上方法成功获取了串口接收缓存区的内容后,就可根据具体的外围设备在脚本中对其接收数据的正确性进行判断,如果判断结果正确,则调用前面注册的C函数uart_ok_del进行相关业务处理。
ied. uart_ok_del (port)
结语
从本文提供的方案可以看出,从始至终,IED装置的C语言应用程序在Lua虚拟机与外围设备之间,除了报文的透明传输功能外,并不负责具体数据业务的处理,这就使在C程序的设计中完全不需要考虑外围设备所采用的串口通信数据格式,具体的数据内容都可放在脚本文件中进行设置和处理。在现场应用中,就可以达到仅修改Lua脚本文件就能完成IED装置与不同的串口通信外围设备之间的数据交互功能,从而实现对装置串口通信规约的现场可配置化。
- 基于嵌入式系统的USBtoUART通信设计方案(12-16)
- 51单片机UART通信程序(11-30)
- 51单片机UART通信[发送接收数字字母中文,控制LED亮灭](11-20)
- 51单片机UART通信发送接收数字字母中文,控制LED亮灭(11-19)
- MIPS架构下PIC单片机的UART通信(11-22)