freeRTOS與STM32移植源碼分析

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。


 

 



 


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章