CMSIS RTX开发之中断优先级(Interrupt priority)

在使用CMSIS RTX这个RTOS时,遇到了如何设计异常的问题。(异常包含中断,为了让搜索引擎更好搜索,本文不区分异常和中断,但是其实异常是中断更为通用的叫法。)

问题有2个:

第一个,如何设置异常优先级。

第二个,进程的优先级和异常优先级要如何匹配。

我们先看第一个问题,如何设置异常优先级。

在使用CMSIS RTX RTOS时,由于RTOS本身会利用Systick,SVC,PendSV这3个异常来完成进程调度之类的任务。而用户在编程开发时,还会用到一些其他中断,GPIO,UART之类。

那么用户要怎么样设置异常的优先级,使得RTOS和用户使用的异常优先级,这两者之间是匹配的。

首先在使用CMSIS RTX RTOS时,由于RTOS的初始化分割成了2个函数,

osKernelInitialize();

osKernelStart();

用户应该调用osKernelStart()函数之前,设置好priority group,什么是priority group?读者请自行查阅Cortex-M3权威指南的第7.2节。

之所以这样,是因为osKernelStart()函数会调用rt_svc_init()函数,初始化Systick,SVC,PendSV这三个异常的优先级。其中SVC的优先级依赖于priority group的值。

rt_svc_init()函数的源码如下:

 1 __inline static void rt_svc_init (void) {
 2 #if !defined(__TARGET_ARCH_6S_M)
 3 U32 sh,prigroup;
 4 #endif
 5 NVIC_SYS_PRI3 |= 0x00FF0000U;
 6 #if defined(__TARGET_ARCH_6S_M)
 7 NVIC_SYS_PRI2 |= (NVIC_SYS_PRI3<<(8+1)) & 0xFC000000U;
 8 #else
 9 sh = 8U - __clz(~((NVIC_SYS_PRI3 << 8) & 0xFF000000U));
10 prigroup = ((NVIC_AIR_CTRL >> 8) & 0x07U);
11 if (prigroup >= sh) {
12 sh = prigroup + 1U;
13 }
14 NVIC_SYS_PRI2 = ((0xFEFFFFFFU << sh) & 0xFF000000U) | (NVIC_SYS_PRI2 & 0x00FFFFFFU);
15 #endif
16 }

如果priority group = 0,那么:

Systick优先级 = 0x0;

PendSV优先级 = 0xFF;

SVC优先级 = 0xFD.

如果priority group = 1,那么:

Systick优先级 = 0x0;

PendSV优先级 = 0xFF;

SVC优先级 = 0xFB.

ARM公司规定了异常优先级供用户设置,寄存器有效位为8bit,其中

参考文献:

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/CIAGECDD.html

http://www.keil.com/support/man/docs/rlarm/rlarm_ar_hints_cortex.htm

http://www.cnblogs.com/gcczhongduan/p/4739096.html

http://www.keil.com/support/man/docs/rlarm/rlarm_ar_svc_func.htm

原文地址:https://www.cnblogs.com/ironx/p/5333926.html