模拟串口

2024-09-12

模拟串口 篇1

嵌入式系统是以应用为中心、计算机技术为基础、软硬件可裁剪、适应应用系统对功能、可靠性、体积功耗严格要求的专用计算机系统。但在嵌入式系统的开发过程中,软件和硬件开发相互牵制,硬件干扰引起的异常严重影响软件的调试和测试,延误开发进度,并且对系统的功耗也难以预测。仿真开发是摆脱困境的一条有效途径,它在硬件原型制造前就完成系统模型验证和运行行为分析,从而提高开发效率。因此,本文将介绍一种嵌入式StrongARM功耗模拟器——EMSIM(Embedded StrongARM Energy Simulator)。EMSIM模拟StrongARM微处理器和需要的外围设备,能够运行Linux以及μC/OS-II等多种嵌入式操作系统,也在模拟系统中为各个部分设置功耗模型,以使能够统计嵌入式系统的功耗[1]464。EMSIM从总体上可分为四个层次:用户接口模块、符号处理模块、目标控制模块、目标模拟模块。其中,目标模拟模块是EMSIM的核心,模拟计算机系统中主要硬件(包括CPU、内存和各种I/O接口)的行为,能够模拟每一条机器指令的执行,对二进制执行文件的代码进行解释、执行,并产生相应的硬件响应等。

串口在嵌入式系统当中是一类重要的数据通信接口,串口通信的优点是开发简单,在传输数据量不大、要求速度不高而传输距离较大的通信场合得到广泛应用。本文将介绍EMSIM对串口的模拟与改进,以及在此基础上串口的测试。

2 EMSIM的总体设计

2.1 EMSIM的功耗统计算法

我们的研究主要使用软件功耗模拟器测量软件代码的功耗,因而在功耗模拟器中针对不同硬件模拟部分采用不同的功耗统计方法。Simumic[2]等人的研究表明当一个嵌入式系统执行一个程序时,系统的功耗可以通过下面的公式得到:

其中:ETsys表示嵌入式系统的总功耗;ETproc表示表示处理器核工作时的处理器功耗;ETidle表示处理器核空闲时的处理器功耗;ETmem表示存储器的功耗;ETuart表示串口UART的功耗;ETperi表示其它外围设备的功耗。

对于ETuart,当串口工作时其功率大约稳定在44mW[2]。通过计算,当时钟频率为206MHz时,串口模块在每个时钟周期内的功耗为0.21nJ(用Euart表示),于是得到ETuart的计算公式:

其中:Nuart_cyc表示串口处在工作状态时的时钟周期总数。

其它外围设备的功耗可以通过计算UART功耗相同的方法得到。

3 EMSIM的UART模拟实现

3.1 UART模拟的总体介绍

模拟串口有多种方式,如完全仿真,即使用一个定时器来接收每一位(BIT),这样能完全仿真串口的行为。EMSIM没有采用完全仿真方式,它模拟串口的功能,首先,根据实际硬件,定义相关寄存器,然后根据寄存器地址的不同,完成串口不同的功能。

EMSIM工作原理:模拟器的核心指令循环获取和执行,整个过程围绕CPU执行指令展开。在执行指令过程中,如果访问地址属于I/O地址空间,则转到I/O模拟模块,由armio.c中的io_read/write_word函数处理,在处理io_read/write_word函数时,如果访问地址属于UART地址空间,则转到UART模拟模块处理。下面详细介绍相关函数。

在I/O模拟模块中包括如下函数:

1)io_reset:完成硬件执行reset后的寄存器状态模拟。对串口的复位由uart_reset函数处理。

2)io_do_cycle:为了模拟外设的执行,在执行指令过程的每一个周期,会执行io_do_cycle函数,完成对时钟、串口输入输出等的处理,并根据条件产生中断信号。当处理串口传输时,执行uart_cycle函数。

3)io_read/write_word:io区域的读/写函数。模拟CPU读/写中断处理,时钟,串口等相关寄存器的硬件操作。当操作串口时,执行uart_read/write_handle函数。

在串口处理文件中包括如下函数:

1)uart_reset:对串口的各寄存器以及环形缓冲区进行复位,并调用uart_init_modem。

2)uart_cycle:当发送环形缓冲未满或接收环形缓冲非空时,置发送寄存器为空或接收数据准备好,并打开接收中断,最后更新中断状态寄存器。对于串口1,若有字符要发送,则调用send函数将字符发送到套接字文件描述符中。

3)uart_read/write_handle:根据地址的不同,对串口各个寄存器进行操作。比如:uart_read_rx;uart_read_ier;uart_write_tx;uart_write_ier;uart_read_lcr;uart_write_mcr等。

4)uart_init_modem和uart_receiver:此两个函数只适用于串口1,uart_init_modem首先调用socket函数创建通信所需的套接字,然后通过connect来连接服务器。uart_receiver调用recv函数获取指定套接字发送的数据,并将数据存放到接收环形缓冲。

3.2 UART模拟实现原理分析

在对串口进行读/写操作之前,应先对其寄存器和环形缓冲区进行复位。当读时,返回串口接收寄存器的值;当写时,将欲发送的字符传送到串口发送寄存器。而串口的接收和发送工作由uart_read_rx和uart_write_tx两个函数来实现。

uart_read_rx模拟串口接收的硬件操作,过程是读取接收环形缓冲中的字符,然后判断接收缓冲的状态,当接收缓冲非空时,使缓冲数加1;否则置UART_LSR为接收数据未准备好,最后将取出的字符返回给用户应用程序。uart_write_tx模拟串口发送的操作,将输出的字符保存到发送环形缓冲,当发送缓冲未满时,也使发送缓冲数加1;否则置UART_LSR为发送寄存器非空,最后若为串口0,则再写入到输出文件流,即在屏幕上显示出来。

操作UART_LCR便可对串口的奇偶校验位,停止位,数据长度进行设置。当UART_LCR的DLAB位置1时,可设置串口的波特率,它由UART_DLM的低7位与UART_DLL的低7位组成;当UART_LCR的DLAB位置0时,就可进行读/写操作。

我们可以将串口1连接到TCP的套接字上。首先,创建用于通信的套接字,并且连接到指定的服务器。当从串口发送时,通过调用uart_write_tx,将欲发送的字符存放到发送环形缓冲,再调用send函数将字符发送到套接字文件描述符中。当从串口接收时,先调用recv函数获取指定套接字发送的字符,再将字符存放到接收环形缓冲,最后调用uart_read_rx读取字符。这一特性使得多台模拟器之间可以相互进行通讯。

4 UART模拟的改进

通过对EMSIM源码的分析,发现此模拟器还不够完善,有四处需要改进的地方。

1)当接收环形缓冲为空或发送环形缓冲满时,仍能进行读/写操作。因此,需将uart_read_rx以及uart_write_tx进行改写,使之实现先判断缓冲区的状态,当接收缓冲非空时,才返回缓冲区的字符;当发送缓冲未满时,将字符保存到发送缓冲,对于串口0,并将字符写入到输出文件流。

2)当进行串口读操作时,不能实现从键盘或文件读入,只能实现两个模拟器之间相互传送数据。为了实现从文件读入,可以在uart_read_rx中增加读文件的操作,把从文件中读取到的字符传送给接收缓冲,再将接收缓冲中的字符返回给用户应用程序。

3)模拟器无接收超时中断机制。因此,应定义UART_TOR寄存器和UART_TOR_TOIE 0x80//超时中断使能,并在串口处理文件中,修改uart_read/write_handle函数,实现对UART_TOR的处理,并在uart_cycle函数中,若接收缓冲非空,还应打开接收超时中断。最后定义UART_TOR读写函数,当接收字符并且缓冲非空时,判断是否超时,若超时,则立即返回;否则返回从接收缓冲取出的字符。

4)统计串口的功耗。由于串口功耗的计算公式为ETuart=Euart*Nuart_cyc,因此需在串口读写函数中,使时钟周期数自加1,并在功耗统计ARMul_do_energy函数中统计串口的功耗。

void ARMul_do_energy(ARMul_State*state,……)

{……

uart_energy=uart_cycle*UART_ENERGY;

state->u_energy+=uart_energy;

……}

EMSIM只模拟了两个串口,对于现在很多开发板,都拥有两个以上串口,除了具有收发功能,还具有Bluetooth transceiver功能,IrDA SIR功能,这是以后研究的重点。

5 UART的实验

通过改进,我们便可像操作实际硬件一样,对串口进行设置或读写。

5.1 UART的设置

改变linux系统中串口的设置,需要存取termios结构,有两种方法可以选择,一种是通过ioctl函数,另一种是符合POSIX1.0的函数tcgetattr()和tcsetattr()方法。在充分理解EMSIM对串口模拟原理之后,也可直接对串口相关寄存器相应位进行操作,来设置其波特率、检验位和停止位等。

struct termios

{tcflag_t c_iflag;/*输入模式标志*/tcflag_t c_oflag;/*输出模式标志*/………}

1)波特率设置

tcgetattr(fd,&Opt);cfsetispeed(&Opt,B19200);cfsetospeed(&Opt,B19200);tcsetattr(fd,TCSANOW,&Opt);

2)检验位和停止位的设置(8位无校验,1停止位模式,8N1)

Opt.c_cflag&=~PARENB;Opt.c_cflag&=~CSTOPB;Opt.c_cflag&=~CSIZE;Opt.c_cflag|=CS8;tcsetattr(fd,TCSANOW,&Opt);

3)设置工作模式

Opt.c_lflag&=~(ICANON|ECHO|ISIG);Opt.c_oflag&=~OPOST;

Opt.c_cc[VMIN]=0;Opt.c_cc[VTIME]=10;tcsetattr(fd,TCSANOW,&Opt);

还有其他设置,在此不作一一列举。

5.2 UART的读写与功耗统计

为了运行模拟器,需要三个软件:1)new-gdb-4.18.tar.gz模拟器源代码;2)linux-2.4.18.tar.gz内核源码;3)ARM交叉编译工具。

在linux操作系统中,驱动程序屏蔽了硬件细节,使用户进程能方便地对设备进行控制操作。在串口的驱动程序中,需定义相关寄存器(注意:应使各寄存器的地址和EMSIM中寄存器的地址一致),驱动注册函数,初始化函数(初始化串口的波特率、校验位等通信参数,串口寄存器)和读写函数,中断服务程序等。驱动程序对不同设备提供了统一的访问接口。

要操作串口,还需编写用户应用程序。首先调用open函数打开该设备,然后调用read/write函数实现串口的读/写,当使用完成后,应当关闭。

当把EMSIM中串口的发送缓冲设为很小时,其先判断缓冲区的状态,若满则输出错误信息,因此较长字符串将不能被输出到串口。

由于EMSIM是一个功耗模拟器,通过运行应用程序,便能得到每个函数的功耗。比如,运行上述程序后,可得如下结果,如表1所示。

还可以得到:total instructions=59049037;total cycles=144810234;total energy=248305223.737864

经过多次实验,每次的功耗会根据所运行的应用程序的不同而不同,但串口的功耗始终稳定在1.8*108nJ,即44mW。

6 结束语

串口设备无论是在工控领域,还是在嵌入式设备领域,应用都非常广泛,而串口编程也就十分重要。本文主要介绍EMSIM对串口的模拟与改进,并且实现了在此基础上串口的简单应用,并统计出功耗。可利用上述方法,以及Linux网络编程想,先由串口采集数据,再通过网口发送出去,实现两机间互相通信。

EMSIM不但是以纯软件实现的嵌入式系统仿真运行环境,能够实现对串口、中断、时钟计数器等的模拟,而且能够获得应用程序和系统软件的任务和函数的功耗。EMSIM的这种特性不仅使其优于其它模拟器,并使嵌入式学习和开发者在没有实际硬件的条件下,也能测出所需的功耗,而这一点是嵌入式开发的关键。

摘要:文章采用开放源码的嵌入式功耗模拟器EMSIM(Embedded StrongARM Energy Simulator)实现对嵌入式硬件系统的模拟。首先论述EMSIM的总体设计,详细阐述EMSIM的UART(Universal Asynchronous Receiver/Transmitter)模拟模块的设计与实现,然后提出UART模拟的改进,最后嵌入式Linux在EMSIM上的成功运行与UART的测试,验证了UART模拟模块的设计实现是正确的。

关键词:EMSIM,嵌入式系统,UART,模拟,功耗

参考文献

[1]TAN T.K,RAGHUNATHAN A,JHA N.K。EMSIM:an energy simulation framework for an embedded operating system[J]。IEEE International Symposium on Circuits and Systems,2002[2]:464-467.

[2]SIMUNIC T,BENINI L,DEMICHELI G.Cycle-accurate simulation of energy consumption in embedded systems[C].//Proceedings of the36th Conference on Design Automation,New Orleans,LA,USA,June21-25,1999.NewYork:ACM Press,1999:867-872.

[3]何婷,王岩.嵌入式Linux设备驱动程序实例详解[J].电脑知识与技术,2007,[22]:1040-1042.

[4]马文辉,李兰友.Linux环境下的串口通信[J].仪器仪表用户,2005,12[01]:39-41.

[5]刘淼.嵌入式系统接口设计与Linux驱动程序开发[M].北京:北京航空航天大学出版社,2006.

上一篇:思想方法与工作方法下一篇:许昌学院