微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 基于Lua脚本语言的嵌入式UART通信的实现

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

时间:04-05 来源:3721RD 点击:

{"set_tx_buf",set_tx_buf},

  {"get_tx_buf", get_tx_buf},

  {"uart_ok_del", uart_ok_de},

  {NULL, NULL}

  };

  ③ 调用以下函数对C函数库进行注册:luaL_register(L, "ied", uartLib );其中,参数L即为创建虚拟机时的函数返回值(以下同),字符串"ied"为注册到虚拟机中的库名称。第3个参数uartLib即为前面声明的结构数组,对应需要注册的库函数表。

  通过以上步骤,即可完成Lua脚本中需要调用的3个C函数的注册过程,从而就可以在Lua脚本中通过"库名称。库函数"的形式来对其进行调用,如"ied.set_tx_buf(函数参数)"。

  脚本文件本身的加载则相对简单,只需通过如下函数调用即可:

  luaL_dofile(L, "uart_script.lua");

  其中,参数L和以上的函数调用相同,第2个参数则为脚本文件在Flash中的具体存储路径。

  至此,就成功建立了一个Lua与C的交互环境。

  3.2 提取脚本中的串口配置数据

  要正确地进行Lua和C的交互过程,首先必须对Lua和C交互时所采用虚拟栈的作用和操作有比较深入的了解。在Lua和C的交互中,它们彼此之间函数参数以及返回值都将由该栈来负责传递。Lua和C在栈的操作方式上稍有不同,在Lua中采用严格的LIFO方式,而C则还可以通过索引的方式进行。以3个参数为例,参数1首先入栈,参数2、3随后顺次入栈,Lua虚拟栈存储结构及索引对应关系如图3所示。

图3 Lua虚拟栈结构示例图

  如需在C中访问参数1,则既可以通过索引号1进行,也可通过索引号-3进行。其中,正索引按入栈顺序从1依次递增,负索引按出栈顺序从-1依次递减。

  通常情况下,串口的配置主要有以下几项:是否使能、数据位数、停止位数、奇偶校验标志位和波特率。因此,在Lua脚本中,本文采用Lua的表结构对其进行设置,示例如下(本文中斜体代码表示为Lua脚本,以下同):

  uart_p0={

  enable=1,--使能位

  dataBits=8 , --数据位数

  stopBits=1 , --停止位数

  parityBit=2 , --奇偶校验

  baudRate=9600 --波特率

  };

该例表示对UART芯片的P0口进行使能,并且采用8位数据位、1位停止位、偶校验(本文定义parityBit的值取0为无校验,取1为奇校验,取2为偶校验)的帧格式,波特率为9 600 bps.

  在C语言中,要获取表中enable属性字段的值,可采用以下步骤:

  ① 调用接口函数并以表名称作为参数,将该表入栈:

  lua_getglobal(L, "uart_p0");

  ② 调用接口函数将enable属性字段的属性名称入栈:

  lua_pushstring(L, "enable");

  ③ 调用接口函数提取属性值,该操作在C中可看作是一个先出栈再入栈的过程,结果将在②中已入栈的属性名称所在位置填入属性值:

  lua_gettable(L, -2);

  其中,参数"-2"为栈中的索引号。

  ④ 调用接口函数取出栈顶中该属性字段的值,并调用出栈函数,以恢复调用环境:

  p0_enable = (int)lua_tonumber(L, -1);

  lua_pop(L, 1);

  其中,lua_tonumber函数的参数"-1"也为栈中的索引号,该操作将取出栈顶元素的数值,鉴于Lua中的数据都为浮点数,所以需将其强制转换为整型数据。lua_pop中参数"1"为非索引,仅说明从栈顶将1个元素出栈。

  通过以上操作,就可以正确地取出脚本中p0口参数设置表中enable属性字段的值。其他属性字段的提取与其相同。虚拟栈中的内容变化如图4所示。

图4 提取表中属性值时的虚拟栈操作示意图

  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 函数调用时的虚拟栈示例

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top