【STM32】FreeRTOS中断配置
00. 目錄
文章目錄
- 00. 目錄
- 01. 概述
- 02. 中斷管理
- 03. 優(yōu)先級分組
- 04. 優(yōu)先級設(shè)置
- 05. 特殊寄存器
- 06. FreeRTOS中斷配置宏
- 07. FreeRTOS開關(guān)中斷
- 08. 附錄
- 09. 參考
01. 概述
中斷是微控制器一個很常見的特性,中斷由硬件產(chǎn)生,當中斷產(chǎn)生以后CPU就會中斷當前的流程轉(zhuǎn)而去處理中斷服務,Cortex-M內(nèi)核的MCU提供了一個用于中斷管理的嵌套向量中斷控制器(NVIC)。
Cortex-M3和M4的NVIC最多支持240個IRQ中斷請求,1個不可屏蔽中斷NMI、1個Systick滴答定時器中斷和多個異常。
02. 中斷管理
Cortex-M處理器有多個用于管理中斷和異常的可編程寄存器,這些寄存器大多數(shù)都在NVIC和系統(tǒng)控制塊SCB中,CMSIS將這些寄存器定義為結(jié)構(gòu)體。以STM32F407為例,打開core_cm4.h,有以下兩個結(jié)構(gòu)體。
NVIC_Type類型
/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).*/ typedef struct {__IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */uint32_t RESERVED0[24];__IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */uint32_t RSERVED1[24];__IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */uint32_t RESERVED2[24];__IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */uint32_t RESERVED3[24];__IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */uint32_t RESERVED4[56];__IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */uint32_t RESERVED5[644];__O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ } NVIC_Type;SCB_Type類型
/** \brief Structure type to access the System Control Block (SCB).*/ typedef struct {__I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */__IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */__IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */__IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */__IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */__IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */__IO uint8_t SHP[12]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */__IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */__IO uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */__IO uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */__IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */__IO uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */__IO uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */__IO uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */__I uint32_t PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */__I uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */__I uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */__I uint32_t MMFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */__I uint32_t ISAR[5]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */uint32_t RESERVED0[5];__IO uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ } SCB_Type;NVIC和SCB都位于系統(tǒng)控制空間SCS內(nèi),SCS的地址從0xe000e000開始,scb和NVIC的地址也在core_cm4.h中有定義
/* Memory mapping of Cortex-M4 Hardware */ #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */#define SCnSCB ((SCnSCB_Type*)SCS_BASE) /*!< System control Register not in SCB */ #define SCB ((SCB_Type*)SCB_BASE) /*!< SCB configuration struct */ #define NVIC ((NVIC_Type*)NVIC_BASE) /*!< NVIC configuration struct */03. 優(yōu)先級分組
當多個中斷來臨的時候處理器應該響應哪一個中斷是由中斷的優(yōu)先級決定的,高優(yōu)先級的中斷(優(yōu)先級編號小)肯定是首先得到響應,而且高優(yōu)先級的中斷可以搶占低優(yōu)先級的中斷,這個就是中斷嵌套。Cortex-M處理器的有些中斷是具有固定的優(yōu)先級的,比如復位、NMI、HardFault,這些中斷的優(yōu)先級都是負數(shù),優(yōu)先級也是最高的。
Cortex-M處理器有是三個固定優(yōu)先級和256個可編程的優(yōu)先級,最多有128個搶占等級,但是實際的優(yōu)先級數(shù)量是有芯片廠商來決定的。但是絕大多數(shù)的芯片都會精簡設(shè)計的,導致實際上支持的優(yōu)先級會更少,如8級、16級、32級等等。比如stm32就只有16級優(yōu)先級。在設(shè)計芯片的時候會裁掉表達優(yōu)先級的幾個低端有效位,以減少優(yōu)先級數(shù),所以不管用多少位來表示優(yōu)先級,都是MSB對齊的。下圖都是用三位來表示優(yōu)先級。
優(yōu)先級配置寄存器是位寬的,為什么只有128個搶占等級?8位不應該是256個搶占等級嗎?為了是搶占機能變得更可控,cortex-M處理器還把256個優(yōu)先級按位分為高低兩段:搶占優(yōu)先級(分組優(yōu)先級)和亞優(yōu)先級(子優(yōu)先級),NVIC中有一個寄存器是“應用程序中斷及復位控制寄存器(AIRCR)”,AIRCR寄存器里面有個位段名為“優(yōu)先級組”。
STM32使用了4位,因此最多有5組優(yōu)先級分組設(shè)置,在msic.h中有定義:
/** @defgroup MISC_Preemption_Priority_Group * @{*/#define NVIC_PriorityGroup_0 ((uint32_t)0x700) /*!< 0 bits for pre-emption priority4 bits for subpriority */ #define NVIC_PriorityGroup_1 ((uint32_t)0x600) /*!< 1 bits for pre-emption priority3 bits for subpriority */ #define NVIC_PriorityGroup_2 ((uint32_t)0x500) /*!< 2 bits for pre-emption priority2 bits for subpriority */ #define NVIC_PriorityGroup_3 ((uint32_t)0x400) /*!< 3 bits for pre-emption priority1 bits for subpriority */ #define NVIC_PriorityGroup_4 ((uint32_t)0x300) /*!< 4 bits for pre-emption priority0 bits for subpriority */#define IS_NVIC_PRIORITY_GROUP(GROUP) (((GROUP) == NVIC_PriorityGroup_0) || \((GROUP) == NVIC_PriorityGroup_1) || \((GROUP) == NVIC_PriorityGroup_2) || \((GROUP) == NVIC_PriorityGroup_3) || \((GROUP) == NVIC_PriorityGroup_4))04. 優(yōu)先級設(shè)置
每個外部中斷都有一個對應的優(yōu)先級寄存器,每個寄存器占8位,因此最大寬度是8位,但是最小為3位。4個相鄰的優(yōu)先級寄存器拼成1個32位寄存器。如前所述,根據(jù)優(yōu)先級組的設(shè)置,優(yōu)先級又可以分為高低兩個位段,分別是搶占優(yōu)先級和亞優(yōu)先級。STM32我們已經(jīng)設(shè)置位組4,所以就只有搶占優(yōu)先級了。優(yōu)先級就餐器都可以按字節(jié)訪問,當然也可以按半字、字來訪問,有意義的優(yōu)先級寄存器數(shù)目由芯片廠商來實現(xiàn)。
05. 特殊寄存器
5.1 PRIMASK和FAULTMASK寄存器
5.2 BASEPRI寄存器
06. FreeRTOS中斷配置宏
6.1 configPRIO_BITS
此宏用來設(shè)置MCU使用幾位優(yōu)先級,STM32使用的是4位,因此該宏為4。
#define configPRIO_BITS 4 /* 15 priority levels */6.2 configLIBRARY_LOWEST_INTERRUPT_PRIORITY
/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0xf該宏用來設(shè)置最低優(yōu)先級,STM32優(yōu)先級使用了4位,而且STM32配置的使用組4,也就是4位都是搶占優(yōu)先級。因此優(yōu)先級數(shù)數(shù)就是16個,最低優(yōu)先級就是15。所以該值為15。不同的MCU,此值不同,具體是多少要看所使用的MCU的架構(gòu)。
6.3 configKERNEL_INTERRUPT_PRIORITY
/* Interrupt priorities used by the kernel port layer itself. These are generic to all Cortex-M ports, and do not rely on any particular library functions. */ #define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )該宏用來設(shè)置內(nèi)核中斷優(yōu)先級。
6.4 configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY
/* The highest interrupt priority that can be used by any interrupt service routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER PRIORITY THAN THIS! (higher priorities are lower numeric values. */ #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5此宏用來設(shè)置FreeRTOS系統(tǒng)可管理的最大優(yōu)先級,就是我們之前講解的BASEPRI寄存器說的那個閾值優(yōu)先級,這個可以自由設(shè)置,我們這里設(shè)置為5.也就是高于5的優(yōu)先級(優(yōu)先級小于5)不歸FreeRTOS管理。
6.5 configMAX_SYSCALL_INTERRUPT_PRIORITY
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ #define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )此宏設(shè)置好以后,低于此優(yōu)先級的中斷可以安全的調(diào)用FreeRTOS的API函數(shù),高于此優(yōu)先級的中斷FreeRTOS是不能禁止的。中斷服務函數(shù)也不能調(diào)用FreeRTOS的API函數(shù)。
07. FreeRTOS開關(guān)中斷
FreeRTOS開關(guān)中斷函數(shù)為portDISABLE_INTERRUPTS()和portENABLE_INTERRUPTS(),這兩個函數(shù)在portmacro.h文件中有定義。
#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI()#define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 )可以看出開關(guān)中斷實際上是通過函數(shù)vPortSetBASEPRI( 0 )和vPortRaiseBASEPRI()來實現(xiàn)的,這兩個函數(shù)如下:
static portFORCE_INLINE void vPortRaiseBASEPRI( void ){uint32_t ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY;__asm{/* Set BASEPRI to the max syscall priority to effect a critical* section. */ /* *INDENT-OFF* */msr basepri, ulNewBASEPRIdsbisb /* *INDENT-ON* */}}static portFORCE_INLINE void vPortSetBASEPRI( uint32_t ulBASEPRI ){__asm{/* Barrier instructions are not used as this function is only used to* lower the BASEPRI value. */ /* *INDENT-OFF* */msr basepri, ulBASEPRI /* *INDENT-ON* */}}08. 附錄
8.1 【STM32】STM32系列教程匯總
網(wǎng)址:【STM32】STM32系列教程匯總
09. 參考
《FreeRTOS Reference Manual》
《Using the FreeRTOS Real Time Kernel -A Practical Guide》
《The Definitive Guide to ARM Cortex-M3 and Cortex-M4 Processors,3rd Edition》
總結(jié)
以上是生活随笔為你收集整理的【STM32】FreeRTOS中断配置的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【STM32】FreeRTOS系统配置
- 下一篇: 【STM32】FreeRTOS临界区