9.12 中断(下):中断函数的编写
中断特性
可随时打断正在执行的任务
可在任何地方打断正在执行的任务
中断返回后,CPU不一定重新执行被打断的任务
中断函数
调用时间不固定:中断要自己保护现场
调用地点不固定:无法给中断函数传参
返回地点不固定:中断函数不能有返回值
裸机环境下的中断函数
基本流程
- 保存中断现场
– 状态寄存器、返回地址入栈
– 中断函数中要使用到的寄存器入栈 - 清中断//关中断,保护现场、有些硬件自动清除,重启开启中
断前记得要清除 - 执行中断函数体
- 恢复现场
– 将栈中的寄存器弹出,恢复被中断的现场
– 从栈中弹出PC,被打断的程序继续执行
关键字
ARM编译器:__irq
51编译器:interrupt
命名函数时加入关键字,编译器在编译函数的时候会自动添加保存中断现场和恢复现场的代码
UCOS的中断函数
基本流程
- 保存被打断的任务task1中断现场
– 状态寄存器、返回地址PC压入task1任务栈
– 中断函数中要用到的通用寄存器压入task1任务栈
– 保存 当前的任务栈指针SP// 这一步往往需要手动 - 中断嵌套计数+1
- 执行中断函数体
- 任务调度:查找下一个要运行的任务task2 //调用OS的API
- 恢复现场
– 将task2任务栈中的状态寄存器、栈指针弹出
– 通过中断返回指令,从任务栈中弹出PC,执行任务task2
编写中断函数的基本原则
不能有返回值
不能向ISR传递参数
不调用不可重入函数,如printf
勿调用睡眠函数
速战速决、短小精悍
Linux中断处理框架
Linux中断函数实现
- 返回类型:typedef irqreturn_t (*irq_handler_t)(int, void *);
- 函数形式:irqreturn_t keyboard_isr(int irq, void *dev_id);
- 中断注册:request_irq(unsigned int irq, irq_handler_t handler,
unsigned long flags, const char *name, void *dev)
Linux中断函数的基本原则
处于中断上下文中、禁止任何进程切换
不能调用引起调度的函数:引起睡眠、阻塞,导致调度器介入
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)