原创 基于ARM7与µClinux 的嵌入式系统多串口设计

2008-2-19 14:59 3656 1 1 分类: 模拟

基于ARM7µClinux 的嵌入式系统多串口设计<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


   


东南大学 国家ASIC工程中心 集成电路学院 江苏 南京 210096


 


摘要针对基于ARM7内核微处理器和 µClinux操作系统的嵌入式系统介绍了利用IMP<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />16C554 芯片对其进行多串口扩展给出了系统设计方案详细阐述了多串口设备驱动程序的设计方法并重点介绍了对IMP16C554 芯片的初始化设


置和基于中断工作模式的扩展串行接口编程


关键词嵌入式系统µClinuxARM多串口。


中图分类号TP271  文献标识码B  文章编号1004-373X200702-094-03


 


Design of the Multiple Serial Ports for Embedded System Based on ARM7 and µClinux


CAO  KAI LING  MING


              (IC Academy National ASIC Engineering CentreSoutheast UniversityNanjing 210096China)


 


Abstract: Multiple serial ports extension with chip INP16C554 is conducted to the embedded system based on ARM7 kernel microprocessor and µClinux OS. Besides method of the system projectthe design procedure of multiple serial ports is depictedas well as hardware setting initialization of IMP16C554 and asynchronous uart port programming on interruption working mode


Keywords:embedded systemµClinuxARMmultiple serial ports   


 


1


嵌入式系统以其性能/成本优势和灵活方便的使用等特点在工业控制通信航空航天军事技术等领域取得了广泛的应用尤其在商业管理和信息家电方面伴随着今天计算机技术和集成电路技术的飞速发展嵌入式系统的应用由于巨大的市场需求得到迅猛的增长


由于处理器速度应用软件规模和系统复杂度的提高嵌入式系统越来越依赖于嵌入式操作系统的支持来管理系统软硬件资源和系统应用µClinux操作系统提供了对没有内存管理单元的微处理器和对实时性要求不高的应用的支持因其稳定的性能良好的可移植性强大的网络功能对硬件的广泛支持以及开源的特点在当今主流嵌入。式操作系统中占有重要的地位SEP3203是东南大学国家ASIC中心设计的一款的16/32RISC微处理器他内嵌ARM7TDMI内核采用0.25µm工艺工作频率75MHz其低功耗高性价比优点和所提供的完整的通用外设接口非常适合小型嵌入式应用的需求


在嵌入式系统中串行通讯接口作为常用的与外部设备的数据通信接口在数据通信方式中占有重要地位如用于连接MODEMhost机通讯串口监控设备可编程逻辑控制器PLC因此一旦需要同时连接多个外部串口设备微处理器原有的串口资源就无法满足应用需求本文介绍对采用ARM7内核的SEP3203进行µClinux嵌入式操作系统设备驱动开发来实现微处理器与外围设备串口连接的扩展


 


2 系统硬件设计


本设计使用IMP16C554 SEP3203 微处理器扩展了4RS485 通信串口构成一个多串口的设备远程监控系统该系统的主要功能是获取多个本地设备的工作数据并发送串口设备控制指令


 


2.1 多串口接口芯片


在本设计中采用的IMP16C554 是具有4个通用异步接收和发送UART接口的串行接口芯片带有4组独立的16字节收发FIFO能同时完成4个通道的收发他还提供一个可编程的波特率发生器发送和接收频率在50Hz1.5MHz之间选择IMP16C554 的片上状态寄存器可提供数据传输过程发生错误的类型状态信息此外IMP16C554 还提供了完整的Modem 控制功能和内部Loop-back 片上自诊断功能


 


2.2 串口扩展电路


硬件设计主要包括微处理器与IMP16C554之间的通信接口问题其中包括他们之间进行联络的应答信号利用总线进行数据传递的一组数据线产生片选信号和串口芯片内部寄存器选择的接口连线


电路连接原理框图如图1所示


在电路设计中利用了SEP3203的外部存储接口模块EMI为串口芯片配置了地址选择空闲的存储体F的位置nCSF 片选信号用于选择串口芯片但是IMP16C554 本身并没有片选输入只有4个串行通道的选择信号(#CSA~#CSD)。所以使用微处理器的地址线A3A4通过nCSF作为片选信号的地址译码电路来选择串口芯片4个串行通道ABCD中的1个或多个通道



2a954878-3b8e-4940-9693-da8d141de314.jpg


同时IMP16C554的数据线D0D7直接与微处理器的数据总线相连进行串口数据的传送片内寄存器选择线A0A2与微处理器的A0A2地址线连接读写信号IOR#IOW 分别连到微处理器的nOEnWE信号端口微处理器的GPIO口接收分别来自4UART的中断请求INTAINTS),以及收发FIFO的就绪信号     (#RXRDY,TXRDT)并按照规定的时序产生前面提到的通道选择读写等信号来同串口芯片进行交互


此外本设计串行通信协议采用RS485 作为接口标准与串行接口芯片的CMOS电平不同因此在串口芯片IMP16C554和串行口之间选用了MAX3485芯片来进行电平的转换


 


3 串口驱动程序设计


31设备驱动程序简介


设备驱动程序在Linux内核中发挥着非常重要的作用他们使得所驱动的硬件设备相对于内核来说变成一个定义良好的内部编程接口同时完全隐藏了硬件设备的工作细节因而使得内核对外部硬件设备的操作就像对一个普通文件进行读写一样


设备文件可以使用同操作普通文件相同的标准的系统调用接口来完成打开/关闭读写、以及I/O控制等操作而设备驱动程序的任务就是实现这些操作的系统调用接口函数


开放源代码的µClinux嵌入式操作系统在内核中提供了串口设备驱动但由于扩展串口设备硬件工作方式的不同需在参考原有串口驱动程序的基础上重新设计多串口设备驱动程序


 


32 设备驱动程序架构


Linux内核的I/O子系统向内核中其他部分提供了一个统一的标准设备接口通过在include/linux/fs.h中提供的file_operations数据结构来完成file_operations数据结构提供了设备驱动函数调用的入口点应用程序对设备进行各项操作就是通过这些入口点调用相应的操作函数例如当应用程序对设备文件执行读操作时内核通过file_operations数据结构查到Read函数的入口地址从而调用Read


多串口设备驱动程序的设计基本可按照Linux字符型设备驱动程序的架构进行设备驱动程序大致可由如下几个部分构成驱动程序的注册与注销设备的打开与释放设备的读写操作设备的控制操作设备的中断处理


Linux操作系统中内核对设备的管理是通过设备号来进行的这可以在设备初始化过程中调用register_chrdev()函数来完成而关闭设备则是通过调用unregister_chrdev()从内核中注销程序同时释放占用的设备号


在多串口设备驱动程序中init_module()函数中用以下语句进行quadserial设备的注册int result="register"_chrdev(GFD_QS_MAJOR,“quadserial”,&qs_fops)


其中GFD_QS_MAJOR即设备主设备号的宏定义名相应地下面的语句在函数cleanup_module()中完成quadserial设备的注销


unregister_chrdev(GFD_QS_MAJOR,“quadserial)


打开和释放设备是通过调用file_operations 结构中的open()=release()函数来进行的open()通常完成的工作是检查设备相关错误进行设备初始化工作通过次设备号识别具体的设备分配和填写放在fileprivate_data中的数据结构release()函数的作用正好相反释放对设备的控制权释放设备数据占用的内存和中断等


设备的读写操作相对简单对于字符设备使用read()write()函数分别进行读写操作同样在file_operations结构注册入口地址中)。在多串口设备驱动程序中,由于微处理器通过数据总线连接多串口芯片来读写数据,所以具体在read()write()函数中使用系统提供的I/O端口读写函数inb(),outb()进行


除了读写操作经常还需要对设备进行某些控制操作如波特率的设置这可以通过file_operations结构中的ioctl ()函数来完成ioctl()的用法与具体的设备密切相关需要根据设备的实际情况分析


使用中断工作方式来响应设备事件时要在设备初始化代码中登记设备中断和编写中断处理函数下面的语句进行quadserial设备中断的登记其中QS_IRQ是多串口设备使用的GPIO口中断号的宏定义名handle_qs_irqn是接收数据中断处理函数名


err = request_irq(QS_IRQnhandle_qs_irqnO,“quadserial”,NULL)


总之多串口设备驱动程序是按照Linux字符型设备驱动架构来进行编写的而具体的设备驱动程序设计的重点主要在硬件的初始化设置和中断处理函数的设计上


 


3.3 多串口初始化


多串口设备的初始化主要涉及多串口芯片的初始化以及微处理器GPIO口工作方式的初始化设置


多串口芯片的初始化工作就是设置其内部寄存器的初始值参数包括串行通信时数据位数停止位数奇偶检验中断方式以及发送和接收的波特率等可分为设置FIFO工作模式和设置异步通信数据格式2方面IMP16C554的寄存器包括接收保持寄存器RHR发送保持寄存器THRFIFO控制寄存器FCR中断使能寄存器IER、中断状态寄存器ISR线形状态寄存器以及设置波特率的DLLDLM 寄存器等可通过地址线A0A2来选择这些片内寄存器可写的),对他们进行设置


IMP16C554FIFO2种工作方式查询方式和中断方式在查询工作方式下占用系统时间过多降低了系统的性能同时微处理器SEP3203提供了18个外部中断源已足够本系统使用因而在本设计中采用中断工作方式这样多串口芯片的4个串口通道都独立地工作在中断方式下保证了系统内部的高速通信同时FIFO中触发级Trugger Level的选择也保证了多串口通道的中断处理不会彼此影响而发生FIFO数据溢出


另外对用到的GPIO口要设定其工作方式比如中断输入或数据输入/输出设定的过程须按硬件文档规定的设置顺序进行


 


34 中断和缓冲区处理


对工作在半双工方式的RS485 串口来说系统采用中断来实现软件流控4个串口独立工作在中断工作方式下采用中断工作方式来实现数据的收发就是当串口接收数据时CPU响应中断并将相应的中断标志置位然后处理相应的中断程序在中断处理程序中在接收数据时将接收FIFO中的数据读入缓冲区而发送数据时将缓冲区数据写入发送FIFO


首先驱动程序在系统初始化串口时使串口的接收使能等待接收数据当有数据被传送过来时就可在数据接收中断处理程序中顺利接收而在系统要发送本地数据时则先使能串口发送然后发送数据


针对硬中断驱动的异步串口数据收发为每个串口建立了两个环行缓冲区TxBuffer[n]RxBuffer[n]来实现上层驱动程序与底层硬件的数据传递环行缓冲区采用先进先出(FIFO)的调度策略两个指针分别指向数据的排头和排尾保证新存入的数据不会覆盖尚未得到处理的数据需要发送数据时上层驱动程序把准备好的数据送入环行缓冲区TxBuffer[n]再由中断处理程序从环行缓冲


TxBuffer[n]取出并发送而当中断处理程序接收到串口送来的数据时将其存入接收环行缓冲区RxBuffer[n]上层驱动程序就可以从该环行缓冲区取出数据了环形缓冲区操作所使用的控制块结构如下


struct bufferblock{


   int b_start


   int b_end


   int count


   char * buf


}


其中count域表示当前缓冲区内的现有数据长度b_start表示数据排头即从当前环形缓冲区中读取数据的指针位置b_end表示数据排尾即往当前环形缓冲区中存放数据的指针位置buf指针指向缓冲区的首地址


上层程序对缓冲区进行读写的程序代码示例如下


static char * get_from_rxbuffer(int num){


int temp_start = RxBuffer[num].b_start /* 保存初始缓冲区数据头标志 */


if(RxBuffer[num].count==0)return /* 如果缓冲区为空则退出 */


RxBuffer[num].count――;   /* 缓冲区数据计数减1 */


if(RxBuffer[num].b_start+1==BUFFER_LENGTH)Rxbuffer[nem].b_start==0/* 数据头标志回到缓冲区首地址 */


   else


RxBuffer[num].b_start ++;    /* 数据头标志递增 */


return (RxBuffer[nem].buftemp_start)


/* 返回原来数据头标志处的数据地址 */


}


static int put_in_txbuffer(int numchar data){


if(TxBuffer[num].count==BUFFER_LENGTH)returnENOBUFS


/* 如果缓冲区满则退出 */


*(TxBuffer[num].bufTxBuffer[num].b_end)data


/* 将写入的数据放到数据尾标志处 */


 if(TxBuffer[num].b_end+1==BUFFER_LENGTH)TxBuffer[num].b_end0


/* 数据尾标志回到缓冲区首地址 */


   else


  TxBuffer[num].b_end++;          /* 数据尾标志递增 */


  TxBuffer[num].count++;          /* 缓冲区数据计数加1 */


   return 0


 }


 


4 多串口驱动模块的加载


Linux系统可以采用的动态和静态2种驱动程序模块加载方式,µClinux只支持静态的驱动程序加载方式也就是将驱动程序直接加入到内核中再重新编译内核


整个多串口设备驱动程序编译过程包括将驱动程序添加到µClinux 内核源文件字符设备驱动程序目录µClinuxdist/linux2.4.x/driver/char/修改该目录下的Makefile文件添加编译该设备语句修改该目录下的Config.in文件,添加在编译时的设备选定提示菜单选项$µClinux-dist/vendor/GFD/Garfield/makefile文件中为扩展的4个串口添加设备节点ttyS2ttyS5最后是按顺序使用编译命令生成包含多串口设备驱动的内核二进制文件具体设备驱动模块加载和编译命令的使用方法此处不再赘述至此模块加载和内核编译过程结束可将编译生成的内核二进制文件通过调试工具下载到系统硬件上调试运行


5


本设计通过采用通用的IMP16C554串口扩展芯片为基于ARM7内核芯片SEP3203µClinux操作系统的嵌入式系统进行了串口扩展从而实现了嵌入式系统同多个外部设备的串口通信使系统能够进行多个设备的数据采集完成设备监控任务


 


参考文献


[1] Alessandro Rubini.Linux设备驱动程序[M].3.北京:中国电力出版社2006


[2] Garfield SEP3203移动终端应用处理器用户手册[S].东南大学国家专用集成电路系统工程技术研究中心200406


[3] IMP16C553 quad UART data commucications[EB/OL]. http://www.impweb.com


[4] 杜春雷.ARM体系结构与编程[M].北京:清华大学出版社,2003.


[5] 刘峥嵘张智超许振山.嵌入式Linux开发详解[M].北京机械工业出版社,2005


 


作者简介      1973年出生硕士研究生主要研究方向为嵌入式系统设计与应用


    1972年出生讲师主要研究领域为嵌入式实时操作系统及相关平台


 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
1
关闭 站长推荐上一条 /3 下一条