中断服务子程序

中断是嵌入式系统中重要的组成部分,这导致了很多编译开发商提供一种扩展—让标准C支持中断。

具代表事实是,产生了一个新的关键字 __interrupt。

下面的代码就使用了__interrupt关键字去定义了一个中断服务子程序(ISR),请评论一下这段代码的。

__interrupt double compute_area (double radius) 
{
    double area = PI * radius * radius;
    printf("\nArea = %f", area);
    return area;
}

这个函数有太多的错误了,以至让人不知从何说起了:

1)  ISR 不能返回一个值。如果你不懂这个,那么你不会被雇用的。

2)  ISR 不能传递参数。如果你没有看到这一点,你被雇用的机会等同第一项。

3)  在许多的处理器/编译器中,浮点一般都是不可重入的。有些处理器/编译器需要让额处的寄存器入栈,有些处理器/编译器就是不允许在ISR中做浮点运算。

此外,ISR应该是短而有效率的,在ISR中做浮点运算是不明智的。

4) 与第三点一脉相承,printf经常有重入和性能上的问题。如果你丢掉了第三和第四点,我不会太为难你的。不用说,如果你能得到后两点,那么你的被雇用前景越来越光明了。

不能在中断服务程序中执行类似操作的原因是运算时间太长,不能在中段中作复杂的工作,你可以在中断服务程序中置一个标志位.然后在主程序中查询此位,判断是否执行计算子程序.当然这样做会在中断产生与实际的中断响应之间产生一定的延迟,如果你的系统对时间不太敏感还好,如果非常敏感可以考虑采用rtos。否则。。。多加几句对中断标志位的判断语句。。。。

在主程序中监测是否被置位来决定子程序是否执行.可能存在以下问题,就是,中断返回后要执行几个耗时比较长的子程序才能执行判断标志位的语句,这样,可能会有太长的时间间隔.如果你在几个耗时比较长的子程序之间加上一句判断语句,就会减小中断产生与中断响应之
间的时间延迟.

中断活动的全过程大致为:

1、中断请求:中断事件一旦发生或者中断条件一旦构成,中断源提交“申请报告”,与请求CPU暂时放下目前的工作而转为中断源作为专项服务

2、中断屏蔽:虽然中断源提交了“申请报告”,但是,是否得到CPU的响应,还要取决于“申请报告”是否能够通过2道或者3道“关卡”(中断屏蔽)送达CPU(相应的中断屏蔽位等于1,为关卡放行;反之相应的中断屏蔽位等于0,为关卡禁止通行);

3、中断响应:如果一路放行,则CPU响应中断后,将被打断的工作断点记录下来(把断点地址保护到堆栈),挂起“不再受理其他申请报告牌”(清除全局中断标志位GIE=0),跳转到中断服务子程序

4、保护现场:在处理新任务时可能破坏原有的工作现场,所以需要对工作现场和工作环境进行适当保护;

5、调查中断源:检查“申请报告”是由哪个中断源提交的,以便作出有针对性的服务;

6、中断处理:开始对查明的中断源进行有针对性的中断服务;

7、清除标志:在处理完毕相应的任务之后,需要进行撤消登记(清除中断标志),以避免造成重复响应;

8、恢复现场:恢复前面曾经被保护起来的工作现场,以便继续执行被中断的工作;

9、中断返回:将被打断的工作断点找回来(从堆栈中恢复断点地址),并摘下“不再受理其他申请报告牌”(GIE=1),继续执行原先被打断的工作。

中断服务子程序

时间: 2024-10-14 00:52:40

中断服务子程序的相关文章

嵌入式中断服务函数的一些特点

中断是嵌入式系统中重要的组成部分,但是在标准C中不包含中断.许多编译开发商在标准C上增加了对中断的支持,提供新的关键字用于标示中断服务程序 (ISR),类似于__interrupt.#program interrupt等.当一个函数被定义为ISR的时候,编译器会自动为该函数增加中断服务程序所需要的中断现场入栈和出栈代码. 中断服务程序需要满足如下要求: (1)不能返回值: (2)不能向ISR传递参数: (3) ISR应该尽可能的短小精悍: (4) printf(char * lpFormatSt

request_irq() | 注册中断服务

一.中断注册方法 在linux内核中用于申请中断的函数是request_irq(),函数原型在Kernel/irq/manage.c中定义: int request_irq(unsigned int irq, irq_handler_t handler,                         unsigned long irqflags, const char *devname, void *dev_id) irq是要申请的硬件中断号. handler是向系统注册的中断处理函数,是一个

一种根据不同阶级注册不同的中断服务函数的写法

一.注册一个硬件中断服务函数irq_handler,作为硬件中断产生后,实际中断服务函数的总入口. void intc_setup_irq(vector, priority, irq_handler) 二.中断服务函数irq_handler入口,根据不同的条件调用不同分支 void irq_handler(void) { get isr val switch(val) { case condition_1: call_service(condition_1) case condition_2:

UCOS iii 钩子函数 中断服务函数 临界区 延时函数

钩子函数 功能: 扩展任务功能,被其他任务调用  算是消息机制 1.OSIdleTaskHook(),空闲任务调用这个函数,可以用来让CPU进入低功耗模式 2.OSInitHook(), 系统初始化函数OSInit()调用此函数. 3.OSStatTaskHook(),统计任务每秒中都会调用这个函数,此函数允许你向统计任务中添加自己的应用函数. 4.OSTaskCreateHook(),任务创建的钩子函数. 5.OSTaskDelHook(), 任务删除的钩子函数. 6.OSTaskReturn

中断服务函数的编写要求

中断是嵌入式系统中重要的组成部分,但是在标准C中不包含中断.许多编译开发商在标准C上增加了对中断的支持,提供新的关键字用于标示中断服务程序 (ISR),类似于__interrupt.#program interrupt等.当一个函数被定义为ISR的时候,编译器会自动为该函数增加中断服务程序所需要的中断现场入栈和出栈代码 例: _interrupt double compute_area(double radius) { double area=PI*radius*radius; printf("

freeertos中关于PendSV中断服务函数的解析

__asm void xPortPendSVHandler( void ) { extern uxCriticalNesting; extern pxCurrentTCB; extern vTaskSwitchContext; PRESERVE8 //栈的8字节对齐 mrs r0, psp //读取当前psp进程指针,存入r0 isb /* 获取当前任务控制块 */ ldr r3, =pxCurrentTCB //把当前任务控制块的指针给r3 ldr r2, [r3] //把r3地址中的值给r2

nginx平滑升级(不中断服务升级可执行文件)

1.将新版本nginx编译安装到旧版本的nginx路径中(注意备份) 2.发送USR2指令:kill -USR2 [nginx主进程] kill -USR2 `cat /usr/local/nginx/logs/nginx.pid` 3.将旧版本nginx主进程nginx.pid重命名为nginx.pid.oldbin,然后从容关闭旧的nginx 子进程,再关闭旧的ningx主进程 cd /usr/local/nginx/logs/ mv nginx.pid nginx.pid.oldbin k

STM32_中断

为什么要用中断? 常用的现实生活中的例子是,如果你正在看电视,门铃响了你该咋整? 这里门铃响了就是一个中断(interrupt),我们放下电视去开门就是一个中断服务子程序(ISP) STM32的中断介绍 Cortex-M3 内核支持 256 个中断,包括 16 个内核中断和 240 个外部中断: STM32F10x 有 84 个中断通道,包括 16 个内核中断和 68 个可屏蔽中断,也就是只用了 Cortex-M3 中断的一部分: 中断可以分配优先级,有的是固定死的,有的可以自定义. 中断会分配

TI C66x DSP 系统events及其应用 - 5.10(中断控制寄存器)

C66x DSP执行中断的简要流程: 1.使能了全局中断和子中断,如果硬件检测到中断发生,那么CPU就要跳转. 2.软件把CPU内部的A,B类寄存器的值等推入堆栈保存,把当前PC寄存器的值放入IRP/NRP寄存器中以备中断返回能找到当前被打断的位置. 3.CPU的PC指针读出中断向量表的地址,也就是把"ISTP寄存器的ISTB值+子中断向量偏移量"装入PC寄存器,这样就执行跳转. 4.在中断向量表里一般有就用跳转指令,这样就可以跳转到我们用C语言编写的中断服务子程序中.由于我们在一般的