(作者:LL 出处:http://blog.csdn.net/tcpipstack , 欢迎转载,也请保留这段声明。谢谢!)
先看一个实例,在EK-LM3S8962平台上实现的,见下图所示:
对于EK-LM3S8962平台,主要是TI的芯片LM3S8962芯片,ARM Cortex-M3内核,256KB FLASH,64KB SRAM,总之资源来说是非常好小的,但是却可以运行eLua虚拟机,如下所示:
那是怎么回事呢?且听细细分解。
说到eLua,首先要了解Lua语言:
LuaLua 是一个小巧的脚本语言。是巴西里约热内卢天主教大学(Pontifical Catholic University of Rio de Janeiro)里的一个研究小组,由Roberto Ierusalimschy、Waldemar Celes 和 Luiz Henrique de Figueiredo所组成并于1993年开发。
Lua语言设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。
Lua由标准C编写而成,几乎在所有操作系统和平台上都可以编译,运行。
Lua并没有提供强大的库,这是由它的定位决定的。所以Lua不适合作为开发独立应用程序的语言。
Lua脚本可以很容易的被C/C++代码调用,也可以反过来调用C/C++的函数,这使得Lua在应用程序中可以被广泛应用。不仅仅作为扩展脚本,也可以作为普通的配置文件,代替XML,Ini等文件格式,并且更容易理解和维护。
一个完整的Lua解释器不过200k,在目前所有脚本引擎中,Lua的速度是最快的。这一切都决定了Lua是作为嵌入式脚本的最佳选择。
以上资料来自百度百科: http://baike.baidu.com/view/416116.htm
定时器/计数器(TC)
ARM7系列芯片中定时器/计数器模块一般包括三个相同的16位定时器/计数器通道,每个通道可独立编程,通道通过驱动一个可编程内部中断信号来产生处理器中断。
工作时钟源
TC由电源管理控制器(PMC)驱动,使用定时器模块之前必须首先配置PMC模块以使能TC时钟。TC通过一条中断线与高级中断控制器(AIC)相连,若是在定时器处理模块添加中断处理程序,则处理中断之前需对AIC进行编程,然后再对TC模块进行配置。
TC的三个通道相互独立,但操作相同。每个通道有一个16位的寄存器,寄存器值在所选时钟的每个正沿处自增,当计数器的值增加为0xFFFF进而变成0x0000时,产生溢出,此时状态寄存器(TC_SR)中的COVFS位置位。
定时器/计数器的时钟选择方面,每个通道可独立选择内部或外部的时钟作为计数器时钟源。对于时钟源的选择可通过TC通道模式寄存器的TCCLKS位实现。另外,对于所选时钟信号的工作方式,可以通过TC_CMR寄存器的CLKI位来实现反转,即使用时钟负沿进行计数。当使用外部时钟作为计数器时钟源时,需要保证外部时钟电平的持续时间长于主机时钟周期。
工作模式及触发形式
TC的每个通道有两种工作模式可供选择:捕获模式及波形模式。工作模式的选择通过TC通道模式寄存器的WAVE位设定。两种工作模式下有三种较为通用的触发器,触发器的作用是复位计数器并启动计数器时钟。触发器类别如下:
一、软件触发器:每个通道均有一个软件触发器。通过设置TC_CCR中的SWTRG位使能。
二、SYNC:每个通道均有一个SYNC同步信号。当此信号使能时,该信号所触发的作用与软件触发器效果类似,通过控制TC_BCR使能所有通道的SYNC信号。
三、RC比较触发器:每个通道均执行RC,若TC_CMR中的CPCTRG置位,则当计数器的值与RC值相等时产生触发信号。
以下对两种工作模式做简单介绍:
捕获工作模式:通过清零TC_CMR(通道模式寄存器)的WAVE参数可进入此工作模式。捕获工作模式下TC通道可作为测量用。此时待测试信号的脉冲时间、频率、周期占空比等可通过TC通道进行测量。
波形工作模式:通过设置TC_CMR寄存器的WAVE参数可进入此工作模式。波形工作模式下,TC通道产生一个或两个相同频率的可独立编程占空比的PWM信号,或产生不同类型的单发射或重复脉冲。根据TC_CMR中的WAVSEL参数的不同,TC_CV产生不同的动作。如,WAVSEL=00时,TC_CV的值从0增加到0xFFFF,一旦到达0XFFFF,TC_CV值即被复位并重新增加且继续循环。外部事件或软件触发亦可复位TC_CV的值。
示例程序
通过RC比较寄存器来设置定时计数,其程序代码如下:
void init_tc0(void)
{
AT91C_BASE_PMC -> PMC_PCER = 1 << AT91C_ID_TC0; // Enable peripheral clock
AT91C_BASE_TC0 -> TC_CMR =AT91C_TC_CLKS_TIMER_DIV5_CLOCK|AT91C_TC_CPCTRG; //RC Compare trigger
AT91C_BASE_TC0-> TC_RC = 4680; //100ms
AT91F_TC_InterruptEnable(AT91C_BASE_TC0, AT91C_TC_CPCS); //RC compare lead to interrupt pTc->TC_IER = flag;
AT91F_AIC_ConfigureIt(AT91C_BASE_AIC,AT91C_ID_TC0,1\
,AT91C_AIC_SRCTYPE_POSITIVE_EDGE,(void(*)())TC_handler); //Configure and enable interrupt on RC compare
AT91F_AIC_EnableIt(AT91C_BASE_AIC,AT91C_ID_TC0);
AT91C_BASE_TC0-> TC_CCR = ((AT91C_TC_CLKEN)|(AT91C_TC_SWTRG)); //Start Timer
}
void TC_handler(void) __irq
{
unsigned int u32TCSR;
u32TCSR= AT91C_BASE_TC0->TC_SR; // Clearstatus bit to acknowledge interrupt Clearall status by read
u32TCSR= u32TCSR; //Suppress warning <<variable "u32TCSR" was set but neverused>>
u32TCtime++;
if(u32TCtime>= 4) //1=100ms
{
u32TCtime=0;
//此处可添加处理函数
}
AT91F_AIC_AcknowledgeIt(AT91C_BASE_AIC);
}
最基本的那个例子,也就是官网上的那个demo,我就不说了...
1、demo地址:http://weavesky.com/2010/02/19/mina-article-2/
但是我们实际项目中,肯定比不是如此的传输一两个数据的,我们需要传对象...老样子在此上传demo的源代码
此例子参考了himi的博文,博文地址:http://www.himigame.com/category/apache-mina
2、依赖的包:
mina-core-2.0.7.jar
slf4j-api-1.7.2.jar
slf4j-jdk14-1.7.2.jar
slf4j-log4j12-1.7.2.jar
3、客户端和服务端目录结构图:
一、Server
1、MinaServer
package com.potter; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.charset.Charset; import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder; import org.apache.mina.filter.codec.ProtocolCodecFilter; import org.apache.mina.transport.socket.SocketAcceptor; import org.apache.mina.transport.socket.nio.NioSocketAcceptor; public class MinaServer { private static final int bindPort=8899; public static void main(String[] args){ SocketAcceptor acceptor = new NioSocketAcceptor(); DefaultIoFilterChainBuilder chain = acceptor.getFilterChain(); ProtocolCodecFilter filter= new ProtocolCodecFilter(new HCoderFactory(Charset.forName("UTF-8"))); //添加编码过滤器 处理乱码问题、编码问题 chain.addLast("objectFilter",filter); //设置核心消息业务处理器 acceptor.setHandler(new MinaServerHanlder()); try { // 绑定端口 acceptor.bind(new InetSocketAddress(bindPort)); } catch (IOException e) { System.out.println("Mina Server start for error!"+bindPort); e.printStackTrace(); } System.out.println("Mina Server run done! on port:"+bindPort); } }
2、MinaServerHanlder
package com.potter; import org.apache.mina.core.service.IoHandlerAdapter; import org.apache.mina.core.session.IoSession; public class MinaServerHanlder extends IoHandlerAdapter { private int count = 0; public void sessionCreated(IoSession session) { System.out.println("新客户端连接"); } @Override public void sessionOpened(IoSession session) throws Exception { // TODO Auto-generated method stub count++; System.out.println("第 " + count + " 个 client 登陆!address: : " + session.getRemoteAddress()); } @Override public void sessionClosed(IoSession session) throws Exception { // TODO Auto-generated method stub session.close(); System.out.println("I'm Client && I closed!"); } @Override public void messageReceived(IoSession session, Object message) throws Exception { // TODO Auto-generated method stub PlayerAccount_Entity ho = (PlayerAccount_Entity) message; System.out.println("Client message="+ho.getId()+ho.getName()+ho.getEmailAdress()+ho.getSex()); // session.write(ho); } }
3、HCoderFactory
package com.potter; import java.nio.charset.Charset; import org.apache.mina.core.session.IoSession; import org.apache.mina.filter.codec.ProtocolCodecFactory; import org.apache.mina.filter.codec.ProtocolDecoder; import org.apache.mina.filter.codec.ProtocolEncoder; public class HCoderFactory implements ProtocolCodecFactory { private final HEncoder encoder; private final HDecoder decoder; public HCoderFactory() { this(Charset.defaultCharset()); } public HCoderFactory(Charset charSet) { this.encoder = new HEncoder(charSet); this.decoder = new HDecoder(charSet); } @Override public ProtocolDecoder getDecoder(IoSession arg0) throws Exception { // TODO Auto-generated method stub return decoder; } @Override public ProtocolEncoder getEncoder(IoSession arg0) throws Exception { // TODO Auto-generated method stub return encoder; } }
4、HEncoder
package com.potter; import java.nio.charset.Charset; import java.nio.charset.CharsetEncoder; import org.apache.mina.core.buffer.IoBuffer; import org.apache.mina.core.session.IoSession; import org.apache.mina.filter.codec.ProtocolEncoder; import org.apache.mina.filter.codec.ProtocolEncoderOutput; public class HEncoder implements ProtocolEncoder{ private final Charset charset; public HEncoder(Charset charset) { this.charset = charset; } @Override public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception { CharsetEncoder ce = charset.newEncoder(); PlayerAccount_Entity paEntity = (PlayerAccount_Entity) message; IoBuffer buffer = IoBuffer.allocate(100).setAutoExpand(true); buffer.putInt(paEntity.getId()); buffer.putString(paEntity.getName(), ce); buffer.putString(paEntity.getEmailAdress(), ce); buffer.putInt(paEntity.getSex()); buffer.flip(); out.write(buffer); } @Override public void dispose(IoSession session) throws Exception { // TODO Auto-generated method stub } }
5、HDecoder
package com.potter; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import org.apache.mina.core.buffer.IoBuffer; import org.apache.mina.core.session.IoSession; import org.apache.mina.filter.codec.CumulativeProtocolDecoder; import org.apache.mina.filter.codec.ProtocolDecoderOutput; public class HDecoder extends CumulativeProtocolDecoder { private final Charset charset; public HDecoder(Charset charset) { this.charset = charset; } @Override protected boolean doDecode(IoSession arg0, IoBuffer message, ProtocolDecoderOutput arg2) throws Exception { CharsetDecoder cd = charset.newDecoder(); int id=0; if(message.remaining()>=4){ id=message.getInt(); } String name = message.getString(cd); String emailAdress=message.getString(cd); int sex=0; if(message.remaining()>=4){ sex=message.getInt(); } PlayerAccount_Entity paEntity = new PlayerAccount_Entity(id,name,emailAdress,sex); arg2.write(paEntity); return true; } }
6、PlayerAccount_Entity
package com.potter; public class PlayerAccount_Entity{ private int id; private String name; private String emailAdress; private int sex;// 0=man 1=woman public PlayerAccount_Entity(int id,String name,String emailAdress,int sex){ this.id=id; this.name=name; this.emailAdress=emailAdress; this.sex=sex; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmailAdress() { return emailAdress; } public void setEmailAdress(String emailAdress) { this.emailAdress = emailAdress; } public int getSex() { return sex; } public void setSex(int sex) { this.sex = sex; } }
二、Client
1、MinaClient
package com.potter; import java.net.InetSocketAddress; import java.nio.charset.Charset; import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder; import org.apache.mina.core.future.ConnectFuture; import org.apache.mina.filter.codec.ProtocolCodecFilter; import org.apache.mina.transport.socket.nio.NioSocketConnector; public class MinaClient { private static final int bindPort=8899; public static void main(String[] args){ // 创建一个socket连接 NioSocketConnector connector=new NioSocketConnector(); // 获取过滤器链 DefaultIoFilterChainBuilder chain=connector.getFilterChain(); ProtocolCodecFilter filter= new ProtocolCodecFilter(new HCoderFactory(Charset.forName("UTF-8"))); // 添加编码过滤器 处理乱码、编码问题 chain.addLast("objectFilter",filter); // 消息核心处理器 connector.setHandler(new MinaClientHanlder()); // 设置链接超时时间 connector.setConnectTimeoutCheckInterval(30); // 连接服务器,知道端口、地址 ConnectFuture cf = connector.connect(new InetSocketAddress("localhost",bindPort)); // 等待连接创建完成 cf.awaitUninterruptibly(); cf.getSession().getCloseFuture().awaitUninterruptibly(); connector.dispose(); } }
2、MinaClientHanlder
package com.potter; import org.apache.mina.core.service.IoHandlerAdapter; import org.apache.mina.core.session.IoSession; public class MinaClientHanlder extends IoHandlerAdapter{ public void sessionOpened(IoSession session) throws Exception { PlayerAccount_Entity ho = new PlayerAccount_Entity(10,"Potter","potter@qq.com",0); session.write(ho); } @Override public void messageReceived(IoSession session, Object message) throws Exception { PlayerAccount_Entity ho = (PlayerAccount_Entity) message; System.out.println("Server Say:name:" + ho.getName()); } @Override public void sessionClosed(IoSession session) throws Exception { // TODO Auto-generated method stub session.close(); } }
好了,共同的就不穿了....