在STM32F1移植UCOSIII-3.03时,发现UCOSIII中并未对中断进行分组,但是bsp_int.c中确有BSP_IntPrioSet(CPU_DATA int_id,CPU_INT08U prio)优先级设置函数,对此有疑问:
按照《Cortex-M3权威指南(中文)》第七章和第八章的说法,需要先进行中断分组,确定抢占优先级和响应优先级的位数,才能生成有效的中断优先级,但是UCOSIII-3.03源码中确实没有中断分组,仅调用BSP_IntPrioSet也是可以设置中断优先级,最终经过调试试验和参考文档,得出以下有效结论:
1.UCOSIII-3.03并未进行中断分组,BSP_IntPrioSet函数可进行优先级设置,相关优先级源码如下:
UCOS优先级设置函数:
void BSP_IntPrioSet (CPU_DATA int_id, CPU_INT08U prio)
{
CPU_SR_ALLOC();
if (int_id < BSP_INT_SRC_NBR) {
CPU_CRITICAL_ENTER();
CPU_IntSrcPrioSet(int_id + 16, prio);
CPU_CRITICAL_EXIT();
}
}
其中调用的底层寄存器
设置的优先级调用了CPU_RevBits汇编函数,再移位清零赋值,最后写入NVIC_IP寄存器设定中断优先级,
void CPU_IntSrcPrioSet (CPU_INT08U pos,
CPU_INT08U prio)
{
CPU_INT08U group;
CPU_INT08U nbr;
CPU_INT08U pos_max;
CPU_INT32U prio_32;
CPU_INT32U temp;
CPU_SR_ALLOC();
prio_32 = CPU_RevBits((CPU_INT08U)prio);
prio = (CPU_INT08U)(prio_32 >> (3 * DEF_OCTET_NBR_BITS));
中间是系统15个系统异常中断的设置
default:
pos_max = CPU_INT_SRC_POS_MAX;
if (pos < pos_max) { /* See Note #3. */
group = (pos - 16) / 4;
nbr = (pos - 16) % 4;
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_PRIO(group);
temp &= ~(DEF_OCTET_MASK << (nbr * DEF_OCTET_NBR_BITS));
temp |= (prio << (nbr * DEF_OCTET_NBR_BITS));
CPU_REG_NVIC_PRIO(group) = temp;
CPU_CRITICAL_EXIT();
}
break;
}
这个CPU_RevBits函数是进行bit翻转的作用
;***************************************************************************************
; CPU_RevBits()
; REVERSE BITS
;
; Description : Reverses the bits in a data value.
;
; Prototypes : CPU_DATA CPU_RevBits(CPU_DATA val);
;
; Argument(s) : val Data value to reverse bits.
;
; Return(s) : Value with all bits in ‘val’ reversed (see Note #1).
;
; Caller(s) : Application.
;
; This function is an INTERNAL CPU module function but MAY be called by application function(s).
;
; Note(s) : (1) The final, reversed data value for ‘val’ is such that :
;
; 'val’s final bit 0 = 'val’s original bit N
; 'val’s final bit 1 = 'val’s original bit (N - 1)
; 'val’s final bit 2 = 'val’s original bit (N - 2)
;
; … …
;
; 'val’s final bit (N - 2) = 'val’s original bit 2
; 'val’s final bit (N - 1) = 'val’s original bit 1
; 'val’s final bit N = 'val’s original bit 0
;********************************************************************************************************
CPU_RevBits
RBIT R0, R0 ; Reverse bits
BX LR
2.UCOSIII-3.03没有进行中断分组,则AIRCR(10:8)默认为0,全程调试可见默认值是0xFA050000,所以按照Group0分组来,再者STM32仅支持16级中断优先级,即每个中断IP的高四位bit7-bit4可用来设置优先级,又是Group0分组4位全是抢占优先级。
3.接下来就是最关键的结论,很多人在调用BSP_IntPrioSet 进行优先级设置时发现,优先级并不是按照0-16优先级依次减弱来的,原因就是UCOSIII-3.03中我们输入的优先级首先经过了CPU_RevBits汇编函数,这个函数的作用是将32bit数据首尾对调,即输入优先级1=0000 0000 0000 00001,首尾对调后就是1000 0000 0000 0000,再经过后面的移位最终写入寄存器的值是1000=0x08,本来想设置优先级1一个仅次于优先级0的高等级,结果变成了8级,这些都是在keil中调试可以看到NVIC相关中断设置结果的,所以UCOSIII-3.03源码中优先级设定对应关系是,优先级0(输入0),优先级1(输入8),优先级2(输入4),优先级3(输入C),依次类推。
最终简单概括:UCOSIII-3.03中断没有分组,但可以进行优先级设置,优先级设置不是按照0-16依次减弱,应该是0,8,4,C…
建议使用时不要移植bsp_int.c函数,直接调用官方misc.c和misc.h先分组,再设置优先级。