基于嵌入式LUA协同程序分析与设计

2010-05-11 03:48:40段鑫陈宇孙伟力
自动化与信息工程 2010年4期
关键词:宿主嵌入式程序

段鑫 陈宇 孙伟力

1 引言

Lua是一种简洁、轻量、可扩展的脚本语言。该语言的设计目的是为了嵌入宿主程序中,从而为应用程序提供灵活的扩展和定制功能。语言采用 clean C编写(所谓 Clean C ,指 ANSI C 和 C++ 共通的一个子集),可移植性强,几乎在所有操作系统和平台上都可以编译和运行,因此也可以运行在目前常见的嵌入式处理器上。通过Lua语言对应用软件的扩展,实现了设备的现场可定制和可扩展能力,为嵌入式产品的应用提供了广阔空间。Lua有内建与操作系统无关的协同模式,在Lua语言中称之为coroutine。对于嵌入式产品的最终用户,其关心的重点在具体应用功能的设计与实现上,采用协同的嵌入式功能扩展程序可以简化开发过程。同时为避免过多的涉及程序设计语言细节,本文在实现协同功能的基础上设计了适合嵌入式产品功能扩展的协同程序实现方法,简化协同编程的实现。

2 协同机制

Coroutine是Lua提供的一种“非对称的协同程序”,即coroutine采用两个函数来控制协同程序的执行,一个用于挂起执行,另一个用于恢复执行。一个非对称协同程序可以看作是从属于它的调用者,二者之间关系非常类似于例程与其调用者之间的关系。只是协同程序不是必须在执行逻辑结束时才返回到调用者,而可以在执行的任何阶段主动挂起并返回调用者,当再次恢复执行时可以从挂起处继续执行。

对于每个协同程序,在创建时都对应一个状态(lua_State)或者称之为线程(thread),状态中保存了协同程序运行的上下文和数据。执行或恢复一个协同程序时,可以简单的理解为从调用者状态切换到了被执行协同程序的状态上,当协同程序显式的挂起自身时,则将当前状态切换回调用者状态。

由于Lua是嵌入式语言,语言本身提供了协同程序的各种操作,同时也提供了由宿主程序操作的API函数库,库中包含了协同程序的创建、恢复以及挂起操作的函数。因此可以通过宿主程序实现协同程序的创建和恢复操作,在lua程序中实现挂起操作,从而将整个协同程序的大部分操作封装在宿主程序中执行,协同程序简化为类似编写普通Lua函数,同时又具备了协同程序的功能。

3 协同操作分析

可以通过Lua本身提供的coroutine协同库实现协同程序状态的完全控制。其中 coroutine.create(f),coroutine.resume(co [, val1, ··])以及 coroutine.yield(…)三个函数用于创建和实现协同。当需要创建一个新的协同程序时,使用 coroutine.create函数 ,coroutine.create的唯一参数是函数,通常为匿名函数。例如:

Co = coroutine.create(

function(a, b)

for i=1,100 do

print(i)

coroutine.yield(a+i, b-i);

end

end

)

函数对于 Lua语言作为第一类值(First Class Value)看待,也就是函数可以存储在变量中,可以通过参数传递给其他函数,还可以作为函数返回值。通过coroutine.create函数,将输入的函数转为参数,创建一个协同函数并赋值到Co变量,此时Co是处于挂起状态的协同函数。

通过在程序中使用 coroutine.resume (co [, val1, ··])函数,恢复协同程序的执行。Coroutine.resume第一个参数为将要恢复执行的协同函数,其次为传入的可变参数。例如执行上例中的协同程序可以通过 caller函数实现。

function caller ()

for i=0, 99 do

c,d,e = coroutine.resume(Co,10, 20)

print(c, d)

end

end

caller迭代的恢复Co执行,每次Co函数会执行一条print(i)语句,然后Co主动挂起自身,并将执行控制权交回 caller。对上例进行扩展,可以创建多个具有不同功能的协同函数,如:Co1、Co2等。caller根据需要每次恢复其中一个协同程序的执行,协同程序在每次执行后都将操作权返回给 caller,由 caller决定下一次执行,从而实现了多个协同程序之间的协同运行。由此可知,对于常规的协同处理,通常需要编写多个协同处理函数,然后为每个协同处理函数创建协同状态,最后在合适的程序中执行或恢复执行该协同函数。

在嵌入式开发中,基础功能一般由宿主程序(应用程序)完成,如:设备驱动、任务调度、设备操作等,扩展功能则通过Lua程序实现,如:设备配置、逻辑处理等。对于具体的嵌入式应用,通常是可以确定扩展功能的种类和执行的条件,扩展功能采用Lua协同程序处理,宿主程序需要提供固定数量的协同程序以及可以由宿主程序决定在何种条件下创建及恢复执行协同程序的能力。

图1 协同层次结构

固定数量的协同程序由宿主程序通过 API预先创建,并赋予唯一的函数名,同时指定参数。宿主程序预先创建所有协同程序的状态(即实现协同程序的创建),也可以根据Lua程序中协同程序的使用情况动态创建状态。宿主程序实现协同程序的参数传递,执行/恢复执行,协同程序死亡(Dead)后的再次执行等操作。

4 程序设计

宿主程序创建了两个与协同处理相关的任务协同执行任务(TaskScriptExec)和协同调度任务(TaskEventGen) 。其中 TaskScriptExec完成 Lua程序加载和协同程序的执行,TaskEventGen实现协同程序之间的调度。协同函数作为普通函数处理时(即函数本身不包含挂起操作),通常执行一次便处于死亡状态,但是协同函数在具体应用中,条件符合时可能需要重复执行,因此 TaskEventGen还具有重新装载协同函数使之可以再次运行的能力。

嵌入式系统提供的预置协同程序均为全局函数,在第一次加载Lua程序时,会将程序中使用到的全局函数注册到全局变量表中,因此全局变量表中可能包含了预置的协同程序。宿主程序通过查询该表判断程序中是否存在相应的预置协同程序,如果存在则通过API函数创建该协同程序的状态,反之则不做处理。

所有预置协同函数的执行都在同一个任务中,宿主程序根据调度结果,从协同队列中获取需要执行的协同函数。当该协同函数执行完或主动挂起后,控制权返回宿主程序,宿主程序会接着从队列中获取下一个协同函数执行。当队列为空时,该任务处于空闲状态。

图2 协同执行流程

协同程序调度处理在适当条件下触发需要执行的协同函数,并将该函数放入协同队列中由协同函数执行任务完成执行操作。

5 实现及结果

通过对NXP公司的LPC2478 ARM7 处理器程序开发,对宿主程序的协同操作进行了实验与测试。32位的处理器在72MHz的工作频率下能够很好的完成lua程序的执行。由于平台不涉及GUI相关的功能,因此在操作系统的选择上优先选择微内核的轻量级实时操作系统,本实现基于uCOSII 3.84版本的操作系统。

宿主程序中预先实现了4个协同程序:

ON_EVENT1(a,b,c), ON_EVENT2(),

ON_EVENT4(), ON_SYSON()

协同程序的创建以及执行操作均由宿主程序完成,执行协同程序的条件通过串口接收字符1~4产生。协同程序的Lua测试代码常用循环语句模拟要执行的任务。类似于如下代码:

function aa()

for i=0,1000 do

print("in event2, i=",i)

coroutine.yield()

end

end

function ON_EVENT2()

local i=0

aa()

print("ON_EVENT2 end!")

end

当单个协同函数执行时,其运行就像执行普通函数,通过不断的挂起和恢复操作直至执行结束,其测试运行结果如图3所示。

当多个协同函数同时运行时,每次协同函数执行一段代码后;当函数主动执行挂起操作后,便会将控制权交给宿主程序,宿主程序会将执行权调度给下一个协同函数,如此反复执行,测试运行结果如图 4所示。图中显示了两个协同函数ON_EVENT1与ON_EVENT2交替执行的情况。

图3 单协同程序执行结果

图4 多协同程序执行结果

6 结束语

本文采用的协同处理方法,使用户在进行嵌入式产品的功能扩展时可以采用协同程序处理,实现了多个协同程序同时在一个任务中协同执行的能力,同时将协同处理的大部分工作在宿主程序中实现,很好的封装了程序设计语言实现细节,简化了应用开发难度,适合于领域内通用嵌入式模块或产品的扩展。

[1] Robert Ierusalimschy. Programming in Lua, 2008.

[2] Ana L´ ucia de Moura. Coroutines in Lua, 2004.

[3] R. Ierusalimschy. Lua 5.1 Reference Manual, 2006.

猜你喜欢
宿主嵌入式程序
病原体与自然宿主和人的生态关系
科学(2020年3期)2020-11-26 08:18:22
龟鳖类不可能是新冠病毒的中间宿主
当代水产(2020年3期)2020-06-15 12:03:02
试论我国未决羁押程序的立法完善
人大建设(2019年12期)2019-05-21 02:55:44
搭建基于Qt的嵌入式开发平台
“程序猿”的生活什么样
英国与欧盟正式启动“离婚”程序程序
环球时报(2017-03-30)2017-03-30 06:44:45
嵌入式软PLC在电镀生产流程控制系统中的应用
电镀与环保(2016年3期)2017-01-20 08:15:32
表现为扁平苔藓样的慢性移植物抗宿主病一例
创卫暗访程序有待改进
中国卫生(2015年3期)2015-11-19 02:53:32
人乳头瘤病毒感染与宿主免疫机制