1、configUSE_PREEMPTION
爲 1 時使用搶佔式調度器,爲 0 時使用協程。如果使用搶佔式調度器的話內核會在每個時
鍾節拍中斷中進行任務切換,當使用協程的話會在如下地方進行任務切換:
● 一個任務調用了函數 taskYIELD()。
● 一個任務調用了可以使任務進入阻塞態的 API 函數。
● 應用程序明確定義了在中斷中執行上下文切換。
2、configUSE_TIME_SLICING
默認情況下, FreeRTOS 使用搶佔式調度器,這意味着調度器永遠都在執行已經就緒了的最
高優先級任務,優先級相同的任務在時鐘節拍中斷中進行切換,當宏 configUSE_TIME_SLICING
爲 0 的 時 候 不會 在 時鐘 節 拍 中 斷 中 執 行 相 同優 先 級 任 務 的 任 務 切 換, 默 認 情 況 下 宏
configUSE_TIME_SLICING 爲 1。
3、中斷控制器
Cotex-M3 的 NVIC 最多支持 240 個 IRQ(中斷請求)、1 個不可屏蔽中斷(NMI)、1 個 Systick(滴
答定時器)定時器中斷和多個系統異常。Cortex-M 處理器有多個用於管理中斷和異常的可編程寄存器, 這些寄存器大多數都在
NVIC 和系統控制塊(SCB)中。
在core_cm3.h中:
/*******************************************************************************
* Register Abstraction
******************************************************************************/
/** @addtogroup CMSIS_CM3_core_register CMSIS CM3 Core Register
@{
*/
/** @addtogroup CMSIS_CM3_NVIC CMSIS CM3 NVIC
memory mapped structure for Nested Vectored Interrupt Controller (NVIC)
@{
*/
typedef struct
{
__IO uint32_t ISER[8]; /*!< Offset: 0x000 Interrupt Set Enable Register */
uint32_t RESERVED0[24];
__IO uint32_t ICER[8]; /*!< Offset: 0x080 Interrupt Clear Enable Register */
uint32_t RSERVED1[24];
__IO uint32_t ISPR[8]; /*!< Offset: 0x100 Interrupt Set Pending Register */
uint32_t RESERVED2[24];
__IO uint32_t ICPR[8]; /*!< Offset: 0x180 Interrupt Clear Pending Register */
uint32_t RESERVED3[24];
__IO uint32_t IABR[8]; /*!< Offset: 0x200 Interrupt Active bit Register */
uint32_t RESERVED4[56];
__IO uint8_t IP[240]; /*!< Offset: 0x300 Interrupt Priority Register (8Bit wide) */
uint32_t RESERVED5[644];
__O uint32_t STIR; /*!< Offset: 0xE00 Software Trigger Interrupt Register */
} NVIC_Type;
/*@}*/ /* end of group CMSIS_CM3_NVIC */
/** @addtogroup CMSIS_CM3_SCB CMSIS CM3 SCB
memory mapped structure for System Control Block (SCB)
@{
*/
typedef struct
{
__I uint32_t CPUID; /*!< Offset: 0x00 CPU ID Base Register */
__IO uint32_t ICSR; /*!< Offset: 0x04 Interrupt Control State Register */
__IO uint32_t VTOR; /*!< Offset: 0x08 Vector Table Offset Register */
__IO uint32_t AIRCR; /*!< Offset: 0x0C Application Interrupt / Reset Control Register */
__IO uint32_t SCR; /*!< Offset: 0x10 System Control Register */
__IO uint32_t CCR; /*!< Offset: 0x14 Configuration Control Register */
__IO uint8_t SHP[12]; /*!< Offset: 0x18 System Handlers Priority Registers (4-7, 8-11, 12-15) */
__IO uint32_t SHCSR; /*!< Offset: 0x24 System Handler Control and State Register */
__IO uint32_t CFSR; /*!< Offset: 0x28 Configurable Fault Status Register */
__IO uint32_t HFSR; /*!< Offset: 0x2C Hard Fault Status Register */
__IO uint32_t DFSR; /*!< Offset: 0x30 Debug Fault Status Register */
__IO uint32_t MMFAR; /*!< Offset: 0x34 Mem Manage Address Register */
__IO uint32_t BFAR; /*!< Offset: 0x38 Bus Fault Address Register */
__IO uint32_t AFSR; /*!< Offset: 0x3C Auxiliary Fault Status Register */
__I uint32_t PFR[2]; /*!< Offset: 0x40 Processor Feature Register */
__I uint32_t DFR; /*!< Offset: 0x48 Debug Feature Register */
__I uint32_t ADR; /*!< Offset: 0x4C Auxiliary Feature Register */
__I uint32_t MMFR[4]; /*!< Offset: 0x50 Memory Model Feature Register */
__I uint32_t ISAR[5]; /*!< Offset: 0x60 ISA Feature Register */
} SCB_Type;
NVIC 和 SCB 都位於系統控制空間(SCS)內。
/* Memory mapping of Cortex-M3 Hardware */
#define SCS_BASE (0xE000E000) /*!< System Control Space Base Address */
#define ITM_BASE (0xE0000000) /*!< ITM Base Address */
#define CoreDebug_BASE (0xE000EDF0) /*!< Core Debug Base Address */
#define SysTick_BASE (SCS_BASE + 0x0010) /*!< SysTick Base Address */
#define NVIC_BASE (SCS_BASE + 0x0100) /*!< NVIC Base Address */
#define SCB_BASE (SCS_BASE + 0x0D00) /*!< System Control Block Base Address */
其基地址爲0xE000E000,NVIC地址以及SCB地址如上圖。
4、優先級分組
cortex-m處理器有 三個固定優先級和256個可編程優先級,最多支持128個搶佔等級,這個是ARM公司爲這類處理器設計的,但是實際上很多芯片廠商會根據需要精簡設置。比如STM就只有16級優先級(0~0xF,由芯片廠商決定)。
在SBC_Type中有一個叫應用程序中斷和復位控制寄存器AIRCR的32位寄存器,其中第3~10爲總共8位表示中斷優先級分組。其表示方法如下:
其中MSB的4位表示搶佔優先級,LSB的4位爲子優先級。因爲STM公司用了4位表示優先級分組,因此最多能表示5組,在misc.h中有如下定義:
/**
* @}
*/
/** @defgroup Preemption_Priority_Group
* @{
*/
#define NVIC_PriorityGroup_0 ((uint32_t)0x700) /*!< 0 bits for pre-emption priority
4 bits for subpriority */
#define NVIC_PriorityGroup_1 ((uint32_t)0x600) /*!< 1 bits for pre-emption priority
3 bits for subpriority */
#define NVIC_PriorityGroup_2 ((uint32_t)0x500) /*!< 2 bits for pre-emption priority
2 bits for subpriority */
#define NVIC_PriorityGroup_3 ((uint32_t)0x400) /*!< 3 bits for pre-emption priority
1 bits for subpriority */
#define NVIC_PriorityGroup_4 ((uint32_t)0x300) /*!< 4 bits for pre-emption priority
0 bits for subpriority */
在移植freeRTOS時候選擇分組4,支持4位16種搶佔優先級,沒有子優先級,這樣用起來也簡單。
note: cortex-m 優先級編號越低,優先級越高!復位,NMI,HardFault優先級最高,爲負數。
5、中斷屏蔽特殊寄存器
許多應用需要屏蔽所有中斷以執行一些對時序要求嚴格的任務,PRIMASK用於禁止除了NMI和HardFault外的所有異常和中斷,而FAULTMASK可以連HardFault中斷也屏蔽,這2個寄存器都太粗暴了,直接關閉了大部分的中斷(USOS中就是通過控制這2寄存器做臨界區代碼保護),然而在freeRTOS中是通過BASEPRI寄存器,通過寫入BASEPRI的值來屏蔽掉所有優先級號大於等於這個值的中斷,比如要屏蔽優先級高於等於優先級號爲4的所有中斷,MOV R0,#0X04 MSR BASEPRI ,R0 即可。需要取消屏蔽中斷時: MOV R0 , #0 MSR BASEPRI, R0 。
6、 configPRIO_BITS
定義MCU使用多少位設置優先級,STM32使用4位。
7、configLIBRARY_LOWEST_INTERRUPT_PRIORITY
STM32 優先級使用了 4 位,而且 STM32 配置的使用組 4,也就是 4 位都是搶佔優先級。 因此優先級數就是 16 個,最低優先級那就是 15。 所以此宏就是 15。