μC/OS—II的嵌入式串口通信模块设计

发布者:TranquilSilence最新更新时间:2006-11-23 来源: CE china关键字:RTOS  Linux  内核 手机看文章 扫描二维码
随时随地手机看文章
在嵌入式应用中,使用RTOS的主要原因是为了提高系统的可靠性,其次是提高开发效率、缩短开发周期。μC/OS-II是一个占先式实时多任务内核,使用对象是嵌入式系统,对源代码适当裁减,很容易移植到8~32位不同框架的微处理器上。但μC/OS-II仅是一个实时内核,它不像其他实时操作系统(如嵌入式Linux)那样提供给用户一些API函数接口。在μC/OS-II实时内核下,对外设的访问接口没有统一完善,有很多工作需要用户自己去完成。串口通信是单片机测控系统的重要组成部分,异步串行口是一个比较简单又很具代表性的中断驱动外设。本文以单片机中的串口为例,介绍μC/OS—II下编写中断服务程序以及外设驅动程序的一般思路。

  1 μC/OS-II的中断处理及51系列单片机中断系统分析

  μC/OS-II中断服务程序(ISR)一般用汇编语言编写。以下是中断服务程序的步骤。

  保存全部CPU寄存器;
  调用OSIntEnter()或OSIntNesting(全局变量)直接加1;
  执行用户代码做中断服务;
  调用0SIntExit();
  恢复所有CPU寄存器;
  执行中断返回指令。

  μC/OS-II提供两个ISR与内核接口函数:OSIntEnter()和OSIntExit()。OSIntEnter()通知μC/OS—II核,中断服务程序开始了。事实上,此函数做的工作是把一个全局变量OSIntNesting加1,此中断嵌套计数器可以确保所有中断处理完成后再做任务调度。另一个接口函数OSIntExit()则通知内核,中断服务已结束。根据相应情况,退回被中断点(可能是一个任务或者是被嵌套的中断服务程序)或由内核作任务调度。

  用户编写的ISR必须被安装到某一位置,以便中断发生后,CPU根据相应的中断号运行准确的服务程序。许多实时操作系统都提供了安装和卸载中断服务程序的API接口函数,但μC/OS—II内核没有提供类似的接口函数,需要用户在对CPU的移植中自己实现。这些接口函数与具体的硬件环境有关,接下来以51单片机下的中断处理对此详细说明。

  51单片机的中断基本过程如下:CPU在每个机器周期的S5P2时刻采样中断标志,而在下一指令周期将对采样的中断进行查询。如果有中断请求,则按照优先级高低的原则进行处理。响应中断时,先置相应的优先级激活触发器于相应位,封锁同级或低级中断,然后根据中断源类别,在硬件控制下,将中断地址压入堆栈,并转向相应的中断向量入口单元。通常在入口单元处放一跳转指令,转向执行中断服务程序.当执行中断返回指令RETI时,把响应中断时所置位的优先级激活触发器清零后,从堆栈中弹出被保护的断点地址,装入程序计数器PC,CPU返回原来被中断处继续执行程序。

  在移植的过程中,采用Keil C51作为编译环境。KeilC5l集成C编译和汇编器。中断子程序用汇编语言编写,放到移植μC/0S—II后的OS_CPU_A.ASM汇编文件中。下面是以串行口中断为例的移植中断服务子程序代码。 

  

  2 串口驱动程序

  笔者已在5l单片机上成功移植了μC/0S-II内核,移植过程在此不再讨论。这里重点分析μC/0S—II内核下串口驱动程序编写。

  由于串行设备存在外设处理速度和CPU速度不匹配的问题,所以需要一个缓冲区.向串口发送数据时,只要把数据写到缓冲区中,然后由串口逐个取出往外发。从串口接收数据时,往往等收到若干个字节后才需要CPU进行处理,所以这些预收的数据可以先存于缓冲区中。实际上,单片机的异步串口中只有两个相互独立、地址相同的接收、发送缓冲寄存器SBUF。在实际应用中,需要从内存中开辟两个缓冲区,分别为接收缓冲区和发送缓冲区。这里把缓冲区定义为环形队列的数据结构。

  μC/OS-II内核提供了信号量作为通信和同步的机制,引入数据接收信号量、数据发送信号量分别对缓冲区两端的操作进行同步。串口的操作模式如下:用户任务想写,但缓冲区满时,在信号量上睡眠,让CPU运行别的任务,待ISR从缓冲区读走数据后唤醒此睡眠的任务;同样,用户任务想读,但缓冲区空时,也可以在信号量上睡眠,待外部设备有数据来了再唤醒。由于μC/OS-II的信号量提供了超时等待机制,串口当然也具有超时读写能力。图1是带缓冲区和信号量的串口接收示意图。数据接收信号量初始化为0,表示在环形缓冲区中无数据。


  接收中断到来后,ISR从UART的接收缓冲器SBUF中读入接收的字节(②),放入接收缓冲区(③),然后通过接收信号量唤醒用户任务端的读操作(④、①)。在整个过程中,可以查询记录缓冲区中当前字节数的变量值,此变量表明接收缓冲区是否已满。UART收到数据并触发了接收中断,但如果此时缓冲区是满的,那么放弃收到的字符。缓冲区的大小应合理设置,降低数据丢失的可能性,又要避免存储空间的浪费。

  图2为带环形缓冲区和超时信号量的串口发送示意图。发送信号量初始值设为发送缓冲区的大小,表示缓冲区已空,并且关闭发送中断。发送数据时,用户任务在信号量上等待(①)。如果发送缓冲区未满,用户任务向发送缓冲区中写入数据(②)。如果写入的是发送缓冲区中的第一个字节,则允许发送中断(②)。然后,发送ISR从发送缓冲区中取出最早写入的字节输出至UART(④),这个操作又触发了下一次的发送中断,如此循环直到发送缓冲区中最后一个字节被取走,重新关闭发送中断。在ISR向UART输出的同时,给信号量发信号(⑤),发送任务据此信号量计数值来了解发送缓冲区中是否有空间。


  3 串口通信模块的设计

  每个串行端口有两个环状队列缓冲区,同时有两个信号量:一个用来指示接收字节,另一个用来指示发送字节。每个环状缓冲区有以下四个要素:
  ◇存储数据(INT8U数组);
  ◇包含环状缓冲区字节数的计数器;
  ◇环状缓冲区中指向将被放置的下一字节的指针;

;
  ◇环状缓冲区中指向被取出的下一字节的指针。

  图3是接收数据软件模块的流程图。SerialGetehar()用来获取接收到的数据,如果缓冲区已空时将任务挂起,接收到字节时,任务将被唤醒,同时从串行口接收字节。SerialPutRxChar()用来将接收的字节放到缓冲区中,如果接收缓冲区已满,则该字节被丢弃。当字节插入到缓冲区中,SerialPutRxChar()通知数据接收信号量,使之将数据己到的消息传达给所有等待的任务。为防止挂起应用任务,可以通过调用SceiallsEmPty()去发现环状队列中是否有字节。


  图4是发送数据模块的流程图。当需要发送数据给串行端口时,SerialPurChar()等待信号量在初始化发送信号量时应该初始为缓冲区的大小。因此,当缓冲区中没有更多空间时,SerialPutChar()就挂起任务,只要UART再次发送字节,挂起任务就将恢复。SerialGctChar()被中断服务程序调用,如果发送缓冲区至少还有一个字节,Seri-a1GetChar()就返回一个从缓冲区发送的字节。如果缓冲区己空,则SerialGetChar()返回Null,这将使调用停止进一步的发送中断,一直到有数据发送为止。


  4 异步串行通信的接口函数

  应用任务可以通过如下的几个函数来控制和访问UART:SerialCfgPort()、SerialGetChar()、SerialInit()、SerialIsEmpty()、SerialIsFull()和SerialPutChar()。

  SerialCfgPort()用于建立串行端口的特征,在为指定端口调用其他服务前,必须先调用该函数,包括确定波特率、比特数、奇偶校验和停止位等。

  SerialGetChar()使应用程序从接收数据的环状title="缓冲区" style="text-decoration:underline;color:blue">缓冲区中取出数据。

  SerialInit()用于初始化整个串口软件模块,且必须在该模块提供的其他任何服务前调用。SeriallInit()将环状缓冲区计数器的字节数清零,并初始化每个环状缓冲区的IN和OUT指针,指向数据存储区的开始处。数据接收信号量初始化为0,表示在环状缓冲区无数据。用传送缓冲区大小初始化数据传送信号量,表示缓冲区已空。

  SerialIsEmpty()允许应用程序确定是否有字节从串口接收进来。本函数允许在无数据时避免将任务挂起。

  SerialIsFull()允许应用程序确定传送环状缓冲区的状态,本函数可以在缓冲区已满时避免将任务挂起。

  SerialPutChar()允许应用程序向一个串行端口发送数据。

  结 语

  该串口通信模块充分利用了实时内核的任务调度功能和信号量机制,系统软件模块化,可读性增强,便于修改和移植,其设计思路和方法可以很好的应用在多种情况下的测控系统中,系统的扩展方便,具有一定的借鉴作用。该串口通信模块已作为某铁路供水远程控制终端的一部分,运行稳定,提高了整个系统的运行效率和实时性。

关键字:RTOS  Linux  内核 引用地址:μC/OS—II的嵌入式串口通信模块设计

上一篇:ARM/DSP双核系统的通信接口设计
下一篇:简要分析I2C总线在多机通信中的应用

推荐阅读最新更新时间:2024-03-30 21:22

风河与飞思卡尔共同推出面向MPC5121e 的Linux解决方案
全球领先的设备软件优化(DSO)厂商风河系统公司(Wind River)与飞思卡尔半导体(Freescale)日前共同推出全新的enablement平台,以满足嵌入式市场不断增长的发展需求。本次推出的联合平台专门针对简化和加速嵌入式计算应用开发而设计,其核心由飞思卡尔的MPC5121e多核处理器和风河的Wind River Linux平台构成。 这一基于MPC5121e的平台通过将飞思卡尔硬件开发工具包与风河面向32位MPC5121e处理器(基于Power Architecture技术)的软件优化产品相捆绑而构建,包括风河商用级Linux或Wind River VxWorks平台(二者任选)、Wind River Workbenc
[新品]
linux下S3C2410的DMA驱动程序开发
网上介绍LINUX下的一般驱动程序开发示例浩如烟海,或是因为简单,关于DMA驱动的介绍却寥寥无几;近期zhaoyang因工作需要,花了几日时间开发了某设备在S3C2410处理器Linux下DMA通信的驱动程序,有感于刚接手时无资料借鉴的茫然,故写点介绍,期待能给有DMA开发任务的网友们一点帮助。 本文将包括如下内容: DMA驱动主要函数功能 驱动中关键技术分析 具体的DMA实例分析 申明:本DMA驱动开发介绍仅适合S3C2410处理器类型,分析源码为韩国MIZI研究中心维护的dma驱动代码: linux/arch/arm/mach-s3c2410/dma.h,linux/arch/arm/mach-s3c2410/dma.
[单片机]
实时操作系统μC/OS-II的改进与应用研究
  传统的嵌入式系统设计大多采用单任务顺序机制,应用程序是一个无限的大循环,所有的事件都按顺序执行,与时间相关性较强的事件靠定时中断来保证,由此带来系统的稳定性、实时性较差;尤其当系统功能较复杂,且对实时性要求较严格时,这种单任务机制的弱点暴露无遗。本文引入的嵌入式操作系统μC/OS-II是一个多任务的实时内核,主要提供任务管理功能。在实时系统中的多个任务,必须决定这些任务的优先级顺序,任务调度算法需要动态为就绪任务的优先级排序。为了满足对实时性要求越来越高的需要,同时避免频繁改变就绪任务的优先级,在分析μC/OS-II源代码的基础上,对其调度算法进行改进。    1 μC/OS-II概述   μC/OS-II是一个完整的,可
[嵌入式]
CE内核十余年后终被弃 手机系统上演丛林法则
    CE内核十余年后终被弃 手机系统上演丛林法则 一开始,先让我们回顾一下这次被微软放弃的WinCE内核。1996年,微软为比笔记本更小的“PDA”(个人事务助理)开发了一款单色版的Windows 95,命名为Compact Edition(精简版),简称Windows CE。这个时候,微软还不怎么会做移动系统——实际上没有哪家会做:在手掌大小的屏幕上还顽固的显示和桌面一样的任务栏和开始菜单。2000年左右,WinCE 3.0 重写了代码,成为一套脱胎换骨的系统,搭载这套系统的机型后来有了一个响亮的名字:Pocket PC。 Windows CE后来在普通的掌上电脑和嵌入式系统领域展开不同的分支,前者变成大家熟悉的Window
[手机便携]
嵌入式系统的以太网接口设计及linux驱动
  以太网概述   以太网(Ethernet)是当今局域网采用的最通用的通信协议标准。在以太网中,所有计算机被连接在一条电缆上,采用带冲突检测的载波侦听多路访问(CSMA/CD)方法,采用竞争机制和总线拓扑结构。基本上,以太网由共享传输媒体,如双绞线电缆或同轴电缆、多端口集线器、网桥或交换机构成。   按照OSI(Open System Interconnection Reference Model,开放式系统互联参考模型)7层参考模型,以太网定义的是物理层(PHY)和数据链路层(对应以太网的MAC层)的标准。   2 嵌入式处理器上扩展以太网接口   以太网接口控制器主要包括MAC乘PHY两部分,如图1所示为嵌入式处理
[嵌入式]
用arm-linux-gcc.4.3.2交叉编译器编译linux-3.0.1内核
1.我这里的内核是forlinx 的FORLINX_linux-3.0.1.tar.gz内核,把这个文件准备好(拷贝到 linux os 的forlinx文件夹下面),这个文件不小117M,用xftp花费了我20秒时间。 2.然后解压缩 命令tar zxf FORLINX_linux-3.0.1.tar.gz, 这里我看出来了已经解压缩成功了 在编译内核之前,我先安装一个工具可能会用到,那就是libncurses5方便使用make menuconfig 命令,执行命令即可:apt-get install libncurses5-dev 下面就是编译内核过程了,之前见别人编译的时间挺长的,我倒要看看需要多少时间。 执行命令
[单片机]
用arm-<font color='red'>linux</font>-gcc.4.3.2交叉编译器编译<font color='red'>linux</font>-3.0.1<font color='red'>内核</font>
arm-linux启动后屏幕不断闪烁
这几天郁闷啦。arm-linux启动后屏幕不断闪烁。记得以前也遇到过这样的问题,却忘了怎么解决的,现在把它记下来,博客在,他就在。 先是,开机后停在屏幕校准界面,十字叉停在那,怎么点都进不去系统。我就把NANDFLASH擦掉,再下载,再烧,结果七整八整,开机就显示个优龙科技,连个校准界面都没有了。接上超级终端后,超级终端上屁都不显示一个。这样想擦写FLASH都没办法了,烦啊。(进入WINDOWS CE还可以) 实在没办法,就把刘老师请来。他就把JP1跳线帽拔掉,从NORFLASH启动,进入了超级终端的界面,然后再把NANDFLASH擦啊写啊的。可是,新的问题又出现了:开机后屏幕闪烁不停,同样进不去系统了。于是乎,进
[单片机]
基于Small RTOS51的肠营养液输液系统
摘要:介绍一种基于Small RTOS51嵌入式操作系统的医疗仪器——智能型肠营养液输液泵。首先介绍系统的功能及硬件组成,然后重点介绍如何利用Small RTOS51来设计系统软件。最后,给出应用Small RTOS51嵌入式操作系统制造的智能型肠营养液输液泵的试验数据。 关键词:Small RTOS51实时操作系统 肠营养液泵 嵌入式操作系统 引言 随着各种电子系统在各个领域中应用的不断深入,对电子系统本身的要求也越来越高,尤其对于控制系统软件设计的可靠性、实时响应等各个方面的性能有了更严格的要求。单片机的程序设计不再是前后台的运行模式,而是采用多任务实时操作系统的设计思想。由于使用嵌入式操作系统,可以将具体应用分解成多
[应用]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
最新工业控制文章
换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved