位置:51电子网 » 技术资料 » 嵌入式系统

μC/OS—II下中断服务程序和外设驱动的开发

发布时间:2008/5/27 0:00:00 访问次数:408

  在嵌入式应用中,使用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汇编文件中。下面是以串行口中断为例的移植中断服务子程序代码。
csegat0023h ;串口中断响应入口地址
ljmpserialisr;转移到串口中断子程序入口地址
rseg?pr?seriallsr?os_cpu_a
serialisr:
usingo
clr ea ;先关中断,以防中断嵌套
pushall ;已定义的压栈宏,用于将
;cpu寄存器的值压入堆栈
lcall_?osintenter ;监视中断嵌套
lcall_?serial ;串口中断服务程序
lcall_?osintexlt
setbea
popall;已定义的出栈宏,将cpu寄存器的值出栈
reti

2 串口驱动程序

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

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

μc/os-ii内核提供了信号量作为通信和同步的机制,引入数据接收信号量、数据发送信号量分别对缓冲区两端的操作进行同步。串口的操作模式如下:用户任务想写,但缓冲区满时,在信号量上睡眠,让cpu运行别的任务,待isr从缓冲区读走数据后唤醒此睡眠的任务;同样,用户任务想读,但缓冲区空时,也可以在信号量上睡眠,待外部设备有数据来了再唤醒。由于μc/os-ii的信号量提供了超时等待机制,串口当然也具有超时读写能力。

数据接收信号量初始化为0,表示在环形缓冲区中无数据。

接收中断到来后,isr从uart的接收缓冲器sbuf中读入接收的字节(②),放入接收缓冲区(③),然后通过接收信号量唤醒用户任务端

  在嵌入式应用中,使用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汇编文件中。下面是以串行口中断为例的移植中断服务子程序代码。
csegat0023h ;串口中断响应入口地址
ljmpserialisr;转移到串口中断子程序入口地址
rseg?pr?seriallsr?os_cpu_a
serialisr:
usingo
clr ea ;先关中断,以防中断嵌套
pushall ;已定义的压栈宏,用于将
;cpu寄存器的值压入堆栈
lcall_?osintenter ;监视中断嵌套
lcall_?serial ;串口中断服务程序
lcall_?osintexlt
setbea
popall;已定义的出栈宏,将cpu寄存器的值出栈
reti

2 串口驱动程序

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

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

μc/os-ii内核提供了信号量作为通信和同步的机制,引入数据接收信号量、数据发送信号量分别对缓冲区两端的操作进行同步。串口的操作模式如下:用户任务想写,但缓冲区满时,在信号量上睡眠,让cpu运行别的任务,待isr从缓冲区读走数据后唤醒此睡眠的任务;同样,用户任务想读,但缓冲区空时,也可以在信号量上睡眠,待外部设备有数据来了再唤醒。由于μc/os-ii的信号量提供了超时等待机制,串口当然也具有超时读写能力。

数据接收信号量初始化为0,表示在环形缓冲区中无数据。

接收中断到来后,isr从uart的接收缓冲器sbuf中读入接收的字节(②),放入接收缓冲区(③),然后通过接收信号量唤醒用户任务端

相关IC型号

热门点击

 

推荐技术资料

DFRobot—玩的就是
    如果说新车间的特点是“灵动”,FQPF12N60C那么... [详细]
版权所有:51dzw.COM
深圳服务热线:13751165337  13692101218
粤ICP备09112631号-6(miitbeian.gov.cn)
公网安备44030402000607
深圳市碧威特网络技术有限公司
付款方式


 复制成功!