新闻中心

EEPW首页>嵌入式系统>设计应用> 基于Lua脚本语言的嵌入式UART通信的实现

基于Lua脚本语言的嵌入式UART通信的实现

作者: 时间:2013-10-15 来源:网络 收藏

  3.3 调用Lua函数设置发送缓冲区

  为通过Lua脚本对串口发送缓冲区进行设置,在脚本中定义了如下函数:

  data ={0x11, 0x22, 0x33, 0x44, 0x55 };

  function uart_p0_set_txBuf()

  local port=0;

  local p0_send_num=5;

  for i=1, p0_send_num do

  ied.set_tx_buf(port,i-1, data[i])

  end

  return p0_send_num

  end

  从脚本内容可以看出,在此采用了一个Lua中的循环结构对发送缓冲区进行设置,并返回设置的数据个数。其中,全局变量data是Lua脚本中的表,类似于数组,在此表示需要设置的缓冲区内容;ied.set_tx_buf()为在3.1节中提到的已注册到虚拟机中的C函数库中的一个函数。其参数port表示端口号,i-1表示缓冲区索引号,data[i]表示具体的数据内容。在应用中需要注意的是,在Lua中,数组索引默认从1开始,而不像C中从0开始。另外,在C中定义set_tx_buf函数时并未设置参数,这主要是因为参数的提取必须借助于虚拟栈才能实现。在脚本中调用时,对其参数将按照从左到右的顺序依次入栈,在C中要取出参数时,按照其在栈中相应的索引号取出即可。在Lua中对每个函数的调用都有一个独立的栈,因此,若以i取2时调用情况为例,在C函数set_tx_buf中看到的栈内容将如图5所示。

图5 函数调用时的虚拟栈示例

  从而在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装置与不同的串口通信外围设备之间的数据交互功能,从而实现对装置串口通信规约的现场可配置化。

linux操作系统文章专题:linux操作系统详解(linux不再难懂)

c语言相关文章:c语言教程


通信相关文章:通信原理


土壤湿度传感器相关文章:土壤湿度传感器原理

上一页 1 2 3 下一页

关键词:Lua脚本语言嵌入式UART通信

评论


相关推荐

技术专区

关闭