当前位置:首页 > 单片机 > 单片机
[导读] 一.在uc/os操作系统上设计中断函数时所要考虑的一些问题:1 .操作系统本身必须使用一个定时器中断源来作为系统节拍中断,它是操作系统工作的基础。2.只要没有关闭中断,中断服务程序就可以中断任何任务

一.在uc/os操作系统上设计中断函数时所要考虑的一些问题:

1 .操作系统本身必须使用一个定时器中断源来作为系统节拍中断,它是操作系统工作的基础。

2.只要没有关闭中断,中断服务程序就可以中断任何任务的运行,所以将中断服务程序看成比最高优先级(0)级的任务还要高的任务。

3.中断服务程序的功能应该尽量简单,只要将获取的异步事件通信给关联任务即可,后续处理由其关联任务完成。

4.实时操作系统UC/OS移植到ARM7体系的CPU上时,没有对FIQ进行处理,即FIQ是不受操作系统管理的。由于没有操作系统介入,FIQ的ISR无法与关联任务进行通信,所获取的信息不能及时得到关联任务的处理,故只能以原始形式保存在一个缓冲区内,等待以后进行离线处理。

注:由于使用FIQ方式进行采样,其ISR不受操作系统管理,所以只能用使能中断源和关闭中断源来控制FIQ中断过程。

二.在UC/OS操作系统上编写ISR

1.在UC/OS上编写ISR和在裸机上编写ISR时的区别

l进入中断:除了要保护现场外,还需要调用进入中断服务函数,用来通知实时操作系统,使UC/OS操作系统掌握当前中断的嵌套深度

l运行功能代码:除了完成ISR的实质公能的代码外,还要实现与其他任务进行通信的功能。通过这种通信功能使关联任务得到同步信号或数据,从而进入就绪状态。但是,在ISR中不允许调用延迟函数和可能被挂起的系统服务函数。

2.如何在UC/OS操作系统上编写ISR?

在UC/OS中用中断程序由以下几部分组成:

l添加中断句柄

l配置和初始化中断源

l配置向量中断控制器

l编写中断服务函数

1>.中断句柄:

在UC/OS操作系统上编写中断程序,必须在文件IRQ.S的尾部添加中断句柄:

XXX_HandlerHANDLERXXX_Exception

lXXX_Handler是ISR的起始地址,即汇编的起始地址,在初始化化向量控制器时作为中断向量地址使用。其中的XXX可根据具体的中断源名称命名

lHANDLER是句柄关键字,必须大写。

lXXX_Exception:是用C语言编写的功能函数名,该函数用汇编调用。其中的XXX可根据具体的中断源名称命名

Eg:如果要使用UART0作为一个中断源,用来接收数据,则需要在文件IRQ.S的尾部添加一个中断句柄:

Timer0_HandlerHANDLER Timer0_Exception

UART0_HandlerHANDLER UART0_Exception

RTC_HandlerHANDLERRTC_Exception

EINT3_HandlerHANDLEREINT3_Exception

2>.配置和初始化中断源

1>在一个中断源开始之前,需要配置和初始化中断源,使它按预定的方式工作。

还是以UART0为例:

/***********************************************************

*作者:tiger-john

*时间:2011年1月29日

*名称:UART0_Init

*功能:UART0初始化通讯波特率115200,8位数据位,1位停止位,无奇偶校验

*入口参数:bps串口波特率

*出口参数:无

***********************************************************/

voidUART0_Init(uint32 bps)

{

uint16Fdiv;

PINSEL0 = (PINSEL0 & ~(0xf) " 0x05) ;//设置UART0的引脚

U0LCR = 0x83;

Fdiv = (Fpclk>>4)/bps;

U0DLM = Fdiv>>8;

U0DLL = Fdiv%256;

U0LCR = 0x03;

U0FCR = 0x41;//使能FIFO,并设置触发点为4字节

U0IER = 0x01;//允许RBR中断,即接收中断

}

3>.向量中断控制器配置

为了使中断信号和对应的ISR联系起来,还必需对向量中断控制器进行配置。对于通道号为X的中断源XXXX,如果配置中断优先级为Y,则需要在target.c文件中的

VICInit ()函数中添加代码:

//声明中断源XXX的中断服务函数ISR

externvoidXXXX_Handler(void);

//将ISR入口地址填入向量寄存器Y

VICVectAddrY = (uint32)XXXX_Handler;

//向量中断方式,通道号为X

VICVectCntlY = (0x20 | X);

void VICInit(void)

{

extern void IRQ_Handler(void);

extern void Timer0_Handler(void);

extern void UART0_Handler(void);

extern void RTC_Handler(void);

extern void EINT3_Handler(void);

VICIntEnClr = 0xffffffff;

VICDefVectAddr = (uint32)IRQ_Handler;

VICVectAddr0 = (uint32)Timer0_Handler;

VICVectCntl0 = (0x20 | 0x04);

VICIntEnable = 1 << 4;

VICVectAddr1 = (uint32)UART0_Handler;

VICVectCntl1 = (0x20 | 6);

VICVectAddr2 = (uint32)RTC_Handler;

VICVectCntl2 = (0x20 | 13);

VICIntEnable = 1 << 13;

VICVectAddr3 = (uint32)EINT3_Handler;

VICVectCntl3 = (0x20 | 17);

VICIntEnable = 1 << 17;

}

4>.编写中断服务程序程序的功能函数

voidXXXX_Exception(void)

{

OS_ENTER_CRITICAL();//关中断

清除中断源;

通知中断控制器中断结束;

OS_EXIT_CRITICAL();//开中断

用户中断处理代码;

}

注:在UC/OS编写中断服务函数时,清除中断源和清除中断控制器的工作必须放在临界代码端中。即在UC/OS中编写中断服务函数时,必须要有OS_ENTER_CRITICAL();和OS_EXIT_CRITICAL()。

3.控制中断源的工作:

在程序运行过程中,可以通过使能中断源和关闭中断源来启动和关闭通道号为X的中断源。

VICIntEnable = 1 << X;//使能中断源X产生中断

VICIntEnClr = 1 << X;//禁止中断源X产生中断

三.设计ISR与关联任务之间的通信方法:

1. ISR的主要功能是响应异步事件,该异步事件将触发一系列操作。ISR设计的基本原则是:尽可能简短。

2.ISR与关联任务的通信方式有两种类型:信号型和数据型。

1>当使用信号量进行通信时,ISR只完成发送信号量的工作,表示事件已经发生,通过信号量的同步功能触发关联任务。

2>当使用数据进行通信时,ISR需要完成对异步事件的信息进行采集工作,然后使用消息邮箱(或消息队列)将数据发送给关联任务,由关联任务完成后续数据处理工作。

3>做项目时常见的三种情况:

?触发ISR的事件不包含数据:不需要对事件进行信息采集。此时,ISR使用信号量与关联任务进行通信。

?触发ISR的事件是包含数据的低频事件:将数据采集的工作放在关联任务中完成,(产生的时刻延迟与采样周期相比可以忽略不计,对采集数据的质量没有影响。此时,ISR使用信号量与关联任务进行通信,从而简化了ISR。

?触发ISR的事件是包含数据的中高频事件:数据采集的工作放在关联任务中完成时,产生的时延与采样周期相比不能忽略不计时,对采样数据的质量有影响。此时,关联任务从消息邮箱中得到消息的数据,并完成后续处理工作。

?触发ISR的事件是包含数据的非周期高频率事件:对于非周期高频事件,其最短事件间隔可能小于一个事件数据处理的耗时,如果使用消息邮箱进行通信,就可能会出现数据丢失现象。此时,数据采集的工作应该在ISR中完成,由ISR使用具有数据缓冲功能的消息队列与关联任务进行通信。关联任务从消息队列中得到消息的数据,并完成后续处理工作。


本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
关闭
关闭