STC单片机uC/OS-II移植记(11):C51中断处理中的寄存器现场保护与恢复方法
本帖最后由 杨为民 于 2024-3-1 20:15 编辑对于单片机RTOS程序,如笔者前面文章所述,中断这部分程序的编写规范十分重要。用户的RTOS程序通常用C语言编写,因此有必要深入了解RTOS使用的C语言编译器对中断的处理方法。通常对于单片机裸机程序,“main()”函数里面的程序部分称为“后台任务”,中断服务程序部分称为“前台任务”。
中断或者嵌套中断的过程本质上是一个任务切换的过程,从后台任务切换到前台任务或者从前台任务切换到前台任务。中断服务程序包括了完整的任务切换过程:首先保存当前任务的寄存器现场,然后执行前台任务(ISR)代码,最后恢复被中断任务的寄存器现场。本文介绍C51编译器对中断服务程序寄存器现场的处理时使用不同的“using”指令的情况。(1)本文范例来自“STC8H8K64U实验箱-V9.6”范例中的“01.1-用P6口做跑马灯-入门版”和“02-Timer0-Timer1-Timer2-Timer3-Timer4测试程序”。本范例见文后附件。(2)本范例目的是讨论C语言中“using”指令的作用,就将5个定时器的工作频率都设置为50Hz,并且将软件延时函数“delay_ms”改为32位的,这部分程序见下图:
(3)本范例中的5个定时器中断服务程序分别设置了不使用“using”(定时器0)和分别使用“using 0”、“using 1”等,见下图:
(4)下面是这些定时器0和1的中断C语言ISR经过C51编译后的汇编语言:
其中第674到第712行是定时器0的汇编程序,第714到第744行是定时器1的汇编程序。从两者对比来看,除了对AR0-AR7寄存器现场的保存和恢复,两者是一样的。
(5)下面是这些定时器2和3的中断C语言ISR经过C51编译后的汇编语言:
对比前面,可以看到对于定时器1、2、3,它们的差别值在于在保留了PSW后(PUSH PSW),对后面程序使用的寄存器页的设置不同,MOV PSW,#00H -->0页MOV PSW,#08H -->1页MOV PSW,#10H -->2页(6)分析1,不使用“using”关键字与使用“using 0”关键字的差别是,对后者C51编译器产生的ISR汇编语言不会保存和恢复寄存器AR0-AR7现场。(7)分析2,不使用“using”关键字,C51编译器产生的ISR汇编语言会保存和恢复寄存器AR0-AR7现场。使用“using”关键字,C51编译器产生的ISR汇编语言不会保存和恢复寄存器AR0-AR7现场,仅仅是指定下面中断程序使用的寄存器页。
(8)官方依据:下图是Keil的帮助文档,说明了在C语言中使用“using”关键字的方法和效果:
(9)C51采用这个策略的原因是既照顾了一般情况(不使用“using”),C51会自动地保存寄存器现场,又照顾了特殊情况(使用“using”,包括“using 0”),如果要保存恢复该页的寄存器现场,用户自己在C语言中插入汇编语言实现。
(10)在单片机RTOS程序中,中断程序通常是用汇编语言编写,在A51中“USING”的用法与含义与C51中不同,下图是Keil的帮助文档,说明了在A51语言中使用“USING”关键字的方法和效果:
(11)在A51中,“USING”的用途是在后面的汇编程序中,自动地将汇编语言助记符AR0-AR7自动地转换该寄存器页的绝对地址。这个用法在A51汇编语言不限于中断程序,任何地方都可以用和可以反复使用。
并且汇编语言的“USING”语句,不仅在A51中有效,在A251和C51/C251的内嵌汇编语言程序都可以使用(用大写,不限于指定函数函数)。
使用USING指示语句,一个重要得原则就是中断里面调用得函数应该是使用同样得寄存器组
页:
[1]