在使用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
