




全文预览已结束
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
基于ARM和uClinux多串口通讯的设计与实现 3 王 欣 罗志祥 沈 光 (华中科技大学光电子科学与工程学院 武汉 430074) 摘 要 以ARM7嵌入式处理器S3C44B0X、TI公司的通用异步接收发送设备(UART)芯片TL16C752B为硬件开发 平台,设计基于uClinux嵌入式操作系统的多串口通讯的硬件和驱动的解决方案。 关键词 ARM uClinux 串行设备驱动 嵌入式系统 中图分类号 TP316. 89 1 引言 通用异步接收发送芯片UART产生于上个世 纪70年代,是第一块大规模集成电路。1981年的 推出的I BM PC采用了8250UART芯片与外设进 行数据通信,直到上个世纪末,UART一直是PC中 最主要的串行通信接口。 嵌入式系统的多串口扩展的应用范围很广。 它可以用来做多串口服务器/多串口卡,工业/自动 化现场RS - 485控制,使用CDMA /GPRSMODEM 的无线数据传输,车载信息平台/车载GPS定位系 统,远传自动抄表(AMR)系统,税控POS/银行终 端等金融机具,DSP数据采集和传输系统等。 本文给出了系统的多串口扩展完整硬件和驱 动解决方案。该方案对于多串口扩展应用以及以 Linux/uClinux类的操作系统为基础的驱动开发有 一定的指导意义和参考价值。 2 硬件方案设计 目前嵌入式处理器常见的有ARM、PowerPC、 M IPS、Motorola 68K、ColdFire (冷火)等,但ARM占 据了绝对主流。由于低端市场上ARM7 /9型嵌入 式处理器非常火爆,本文就选用了其中一种流行的 ARM7型处理器S3C44B0X作为硬件开发平台。 因为处理器S3C44B0X不带内存管理单元MMU (无内存分页和地址映射机制,所以不能使用虚拟 内存 ) , 所以选用支持无存储管理单元微处理器的 uClinux操作系统作为软件驱动开发平台。 截止到目前,全球范围内有超过40种UART 芯片可以选择,大多数UART芯片是以计算机总线 转换UART为应用基础的,其管脚、 寄存器基本相 同。这就使得UART芯片有很好的通用性。本文 选用了其中较复杂的通用异步接收发送(UART) 芯片TL16C752B来扩展异步串行通讯口。 2. 1 UART芯片TL16C752B工作原理 图1 TL16C752B功能模块图 1 TL16C752B芯片与UART芯片ST16C2550引 脚兼容,使用外部晶振时有高达3Mbps的波特率, 内置两套UART系统,每套都能独立工作,具有可 选的流控功能等。 TL16C752B具有64字节发送/接收FIFO,收、 发FIFO的触发等级可通过软件编程实现,能减少 对CPU中 断 次 数,提 高 芯 片 收 发 效 率。 TL16C752B芯片功能模块如图1所示。 2. 2 接口电路设计 处理器S3C44B0X 2 与 TL16C752B之间的硬 件连接如图2所示, D0D7通过总线收发芯片 SN74LVC16245A连接CPU数据总线的低8位,是 441 计算机与数字工程 第35卷 3收到本文时间: 2006年9月20日 作者简介:王欣,男,硕士研究生,研究方向:嵌入式系统、 数字图像处理。罗志祥,男,副教授,硕士生导师,研究方 向:宽带光通信,传感器网络。沈光,男,硕士研究生,研究方向:嵌入式系统。 UART的 数 据 输 入 与 输 出 通 道,其 中 SN74LVC16245A是用来延时和增强数据总线驱动 能力;片选CSA、CSB连接Bank4和Bank5的引脚 nCGS4、nGCS5,这两个片选可以确定2个UART端 口的起始地址,分别是0x08000000、0x0a000000。 即高位地址部分已固定,而片内寄存器的地址主要 由地址低3位A0A2确定。只有在片选信号和 地址信号都有效时,才能对片内相应的寄存器进行 正常读写。要注意的是,Bank4和Bank5的控制寄 存器的设置要参考TL16C752B芯片的读写时序。 图2 S3C44B0X与TL16C752B硬件连接图 采用中断方式通知CPU接收到新的字符或字 符已发送,这样可以提高系统的实时性。这里中断 引脚I NTA、I NTB直接连接S3C44B0X的外部中断 引脚EXI NT2EXI NT3。接入TL16C752B的外接 时钟频率最好是使用的波特率的倍数。本文使用 的是11. 0592M的外部时钟,输出的的串口波特率 是115200。TL16C752B内部寄存器的映射表及访 问方法在参考文献1 中可查到。 3 串行设备驱动程序设计 3. 1 uClinux系统内核架构 图3 uClinux内核架构(字符型设备) 设备驱动程序是操作系统内核与机器硬件之 间的接口。它为应用程序屏蔽了硬件的细节。在 应用程序看来,硬件设备只是一个设备文件,应用 程序可以像操作普通文件一样对硬件设备进行操 作。而事实上,对硬件的所有实际操作都是由用户 空间的应用程序调用内核空间的驱动程序来完成 操作的。在uClinux操作系统(本文使用2. 4. 20 版本的内核)中,设备驱动程序大致可以分成三种 类型:字符设备型、 块设备型、 网络接口型。其中字 符型设备,能够像字节流(比如文件)一样被访问。 字符设备驱动程序通常会实现open、close、read和 write等系统调用,如图3所示。 3. 2 串行设备驱动的分析 在uClinux内核中提供了访问串行硬件的设 备,通常叫tty设备 ( tty 是Teletype的简写,也可称 为终端设备 ) , 现在用来表示任何基于字符的数据 终端。uClinux提供了三类tty设备:串行设备(有 的书中干脆称为串口 ) , 控制台,伪终端(pty)。其 中,后两者的命名只是因为从程序员的角度来看, 它们和典型的tty设备(即串行设备)以相似的方 式工作,且它们的驱动程序已经被编写好了,而且 可能也不必为这两类tty驱动程序编写其他的驱动 程序。这使得任何使用tty核心与用户和系统交互 的新驱动程序都可以被看成是串行设备驱动程序。 本文所设计的硬件就是典型的串行设备。下面将 详细介绍tty类设备驱动的层次结构和串行设备驱 动的实现。 3. 2. 1 TTY驱动的层次结构 在uClinux系统中, tty驱动根据它们与设备的 关系,以及在执行流程中的位置,可以分为tty驱动 程序和与上层直接联系的tty驱动接口程序。可以 用图4示意图来表示这种控制关系。各种串行设 备都有自己的tty驱动程序来控制硬件。在tty驱 动程序上层接口中, tty驱动程序的核心紧挨在标 准字符设备驱动层之下,并提供了一系列的功能, 作为接口被终端类型设备使用。内核负责控制通 过tty设备的数据流,并且格式化这些数据。这使 得tty驱动程序把重点放在处理流向或者流出硬件 的数据上,而不必重点考虑使用常规方法与用户空 间的交互。为了控制数据流,有许多不同的线路设 置( line discipline)可虚拟地“ 插入 ” 任何的tty设备 上,这由不同的tty线路设置驱动程序实现。 tty线路设置对于tty驱动程序来说是不透明 的。驱动程序不能直接与线路设置通信,甚至不知 541第35卷(2007)第8期 计算机与数字工程 道它的存在。在某种意义上讲,驱动程序的作用是 将发送给它的数据格式化成硬件能理解的格式,并 从硬件那里接收数据。tty线路设置的作用就是使 用特殊的方法,把从用户或者硬件那里接收的数据 格式化。这种格式化通常使用一些协议来完成转 换,比如PPP或者是蓝牙(Bluetooth) 3。 图4 tty驱动层次结构图 在tty驱动中使用到了一些数据结构,这些数 据结构关联了整个tty驱动的各个层次。如图4和 图5所示,这些数据结构有如下几种。在终端驱动 程序上层接口tty_io. c文件中定义了终端驱动程 序的文件操作结构file_operations实例-用于和用 户空间通讯,这是典型的字符设备的结构,它的每 一个成员函数都将与系统调用的read、write、ioctl 等关联起来。在文件中还定义了tty_struct结构实 例(如图4虚线框所示,它内部包含了下面的三种 结构 ) - 它描述了通用(或高层 ) tty 的属性,主要是 在当tty设备打开的时候, tty核心将当前特定的tty 端口的状态保存在此结构中。在默认线路设置模 块n_tty . c文件和其它文件如ppp协议的线路设置 文件ppp_async. c中,定义了tty_ldisc结构实例 5 -它列出了所有的当前线路设置的入口。在各种 串行设备的tty驱动程序中定义了tty_driver结构 实例(如图4虚线框所示,它内部包含了下面的 ter mios结构 ) - 用来向tty核心注册一个tty驱动 程序。tty_driver结构中还包含所有的回调函数, 它们被tty驱动程序设置,并被tty核心调用。这些 回调函数的实现需要调用到底层硬件控制,对具体 寄存器进行读写,完成串行设备的收发操作。 termios结构(如下所示 ) - 每个tty驱动程序 都包含有这样一个结构实例,结构中的标志集合控 制终端接口的各种特征。用户进程就是通过ter2 mios结构来设置和修改终端属性的。 struct ter mios tcflag_t c_iflag; /3 输入模式标志 3/ tcflag_t c_oflag; /3 输出模式标志 3/ tcflag_t c_cflag; /3 控制模式标志 3/ tcflag_t c_lflag; /3 局部模式标志 3/ cc_t c_line; /3 线路设置 3/ cc_t c_ccNCCS; /3 控制字符 3/ ; 3. 2. 2 数据流 数据处理的可变方式是tty驱动中最重要的一 个特点。在图4中, tty核心从用户那里得到将被 发往tty设备的数据,然后把数据发送给tty线路设 置驱动程序,该驱动程序负责把数据传递给tty驱 动程序。tty驱动程序对数据进行格式化,然后才 能发送给硬件。从tty硬件那里接受的数据将回溯 至tty驱动程序,然后流入tty线路设置驱动程序, 接着是tty核心,最后用户从tty核心那里得到数 据。有时tty驱动程序直接与tty核心通信, tty核 心将数据直接发送给tty驱动程序,但通常是tty线 路设置驱动程序修改在二者之间流动的数据 3 。 在不同的线路设置中,数据的流向和处理方式 是不同的。例如如图5所示,串行设备在默认状态 下和ppp拨号连接建立时的数据处理方式是不同 的,而且数据传入的用户空间(或是传出的用户空 间)也是不同的。图5中描述了串行设备驱动所 涉及的重要模块是如何注册的(注册是为了允许 每个程序块能像内核模块一样被调用 ) , 以及串行 数据是如何在不同的线路设置情况下传输的。其 中实线箭头表示串行设备驱动在默认的线路设置 下的情况下数据在不同的驱动程序文件间的流向, 而点划线箭头描述了串行设备驱动在ppp拨号连 接的线路设置下的情况。 3. 3 串行设备驱动的实现 如前面所述,实现串行设备驱动(即tty驱动 程序 ) , 就是要定义tty_driver结构实例和实现结构 中的回调函数。而在uClinux内核中(如图5所 示 ) , 为了简化并标准化串行设备驱动的编写,又 在tty驱动程序中抽象出了一个串行核心驱动层 serial_core,其中申明了uart_driver结构(用来向串 行核心驱动注册一个串行设备硬件控制驱动 ) , 并 将对串行设备硬件的一组标准控制方法接口(供 tty_driver结构中的回调函数使用)封装在uart_ ops 6 结构中 ,另外在uart_port结构中封装了串行 设备端口的相关参数,还对外提供了注册串行设备 硬件控制驱动的辅助函数。 641 王 欣等:基于ARM和uClinux多串口通讯的设计与实现 第35卷 图5 串行设备驱动模块关联图 由于串行核心驱动serial_core封装的大部分 的通用串行设备的操作,且为串行设备硬件控制驱 动提供了一组实现串行硬件控制的标准接口,这就 大大简化了编写此类串行设备驱动的难度。只需 针对特定的硬件实现这一组方法和对应的中断服 务程序,就基本上实现了串行设备驱动。(如果在 某些情况下不适合使用这套标准接口,也可以不借 助串行核心驱动,而单独编写串行设备驱动。具体 情况请参考Linux/uClinux的串行设备驱动源码。) 因此,实现串行设备硬件控制驱动是本文编写 串行设备驱动的主要目标。本文中所需做的就只 是在串行设备硬件控制驱动程序中对端口进行注 册和实现uart_ops结构中提供的对端口的一组控 制方法及所需的中断服务程序( ISR)。 uart_ops结构是串行核心驱动serial_core和串 行设备硬件控制驱动之间的主要接口。它包含控 制硬件的所有方法。其中重要函数的伪码及说明 如下所示: int( 3startup) ( struct uart_port3port, struct uart_info 3info) 重置串行设备对应端口的FIFO队列; 清除对应端口中断相关的寄存器的值; 检查对应端口线路状态寄存器的值判断UART是否存 在,如果不存在,则立即返回; 抢占对应端口的中断资源,如果中断申请出错,则立即 返回; 初始化对应端口的状态; 使能对应的端口中断并再次重置FIFO队列; 该函数在接收字符时调用并使能端口。 此外,还有void (3shutdown) ( struct uart_port 3port, struct uart_info3 info) 函数,它与startup () 函数操作相反,该函数在关闭端口时调用,并释放 所有的中断资源。 在串行设备硬件控制驱动中还使用了串行核 心驱动提供的一些辅助函数。如在模块初始化函 数中使用了int uart_register_driver( struct uart_driv2 er3 drv) 函数来注册一个串行设备端口;在模块卸 载函数中使用了void uart_unregister_driver( struct uart_driver3 drv) 函数移除串行设备端口。 中断处理是串行设备硬件控制驱动中的重要 部分,当接收FIFO中的字符和发送FIFO中的字 符数到达触发等级的时候都会触发系统中断进行 处理。为了减少中断次数,提高收发效率,在设置 端口参数时,设置接收FIFO至少有8个字符时就 触发中断,设置发送FIFO至少有8个空位时就触 发中断。当注册中断服务程序时,如“request_irq ( port- irq,handler,SA _ I NTERRUPT, “tl16c751buart_int_proc”, info) ;”,驱动将通知内 核该串行设备将使用port - irq对应的中断号 (本文驱动中使用的中断号是22、 23) 。handler指 向的是中断服务函数的地址, SA _ I NTERRUPT说 明注册的是一个快速中断。由于每个UART都分 配了一个中断,且UART收发字符都会产生中断, 因此在中断服务函数中应对两种中断分别进行处 理,这可由中断标示寄存器II R的值来区分。其中 发送中断的操作如图7所示。 为了解决字符型设备的外设处理速度和CPU 的处理速度不匹配问题,往往需要缓冲。一般的 741第35卷(2007)第8期 计算机与数字工程 UART控制器都带有不多于几十个比特的FIFO, 但这远远不够,还需要从主存中开辟缓冲区,具体 大小视情况而定。在tty驱动程序中缓冲区采用的 是一种环形缓冲区,如图6所示。当接收中断到来 后中断服务程序从UART的FIFO中读入接收的字 节,放入接收环形缓冲区的头,然后唤醒处于睡眠 状态的用户读操作。用户读操作将接收缓冲区尾 部的数据传给用户空间。当用户进程想读操作,而 接收缓冲区无数据时,用户读进程睡眠在读等待队 列上,直到UART有新的数据到来,产生新的接收中 断时才被唤醒。当发送中断到来后,中断服务程序 读取发送环形缓冲区尾部的数据发送到UART上, 并唤醒处于睡眠状态的用户写操作。用户写操作把 从用户空间传递来的数据写进发送缓冲区的头。当 用户进程想写操作,而发送缓冲区已满时,用户写进 程睡眠在写等待队列上,直到UART产生新的发送 中断,读走发送缓从区的数据时才被唤醒。 当中断服务函数退出前,应该清除中断。清除 中断有两步:一是清除UART端口的中断请求信 号,只需设置UART的中断使能寄存器关闭中断即 可。二是清除CPU的相应中断请求位,只需对 S3C44B0X的中断挂起寄存器相应位置1即可。 图6 接收/发送缓冲示意图 中断服务程序的伪码如下所示: void tl16c752buart_int_proc ( int irq , void3dev_id , struct pt_regs3 regs) 清除中断请求位; 判断该中断来自哪个UART端口; 读取该端口的中断标示寄存器; if( 端口的tty_struct结构不存在或中断未发生) 退出本程序; s witch(中断标示寄存器 ) case发送中断: 调用中断发送函数; break; case接收中断: case接收超时中断: 调用中断接收函数; break; default: break; 中断发送函数的流程图如图7
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 时间的脚印课件王晶
- 教务主任期中质量分析
- 护理常规培训内容
- 时钟造型基础知识培训课件
- 二零二五版房屋地基下沉修复赔偿合同
- 2025版出轨离婚赔偿金协议书(含法律咨询与执行)
- 二零二五年度房地产开发项目贷款合同范本正规范本
- 旭东化学课件获取
- 二零二五年度动产抵押消费贷款合同编写指南
- 高三试卷:四川省雅安市2024-2025学年高三上学期11月零诊试题数学答案
- 2025年海南省警务辅助人员招聘考试(公共基础知识)历年参考题库含答案详解(5套)
- 城市道路清扫保洁协议
- 2025年医学检验在编考试题库
- 2025年十八项医疗核心制度试题及答案
- 特色食品卖场建设方案(3篇)
- 2025年四川省高考化学试卷真题
- 高考3500词汇表(完整版)
- 《建筑施工安全检查标准》JGJ59-20248
- 1931CIE标准色度三刺激值
- 万玮:《班主任兵法》
- 2MCL458离心式压缩机使用说明书
评论
0/150
提交评论