IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> FreeRTOS & Cortex-M中断管理 -> 正文阅读

[嵌入式]FreeRTOS & Cortex-M中断管理

FreeRTOS & Cortex-M中断管理

Cortex-M 中断

Cortex-M 外中断

??Cortex-M内核提供了一个用于中断管理的 硬件单元 :NVIC(嵌套向量中断控制器).
Cortex-M3 和 M4的NVIC最多支持240个IRQ(中断请求)、1个不可屏蔽中断(NMI)、1个滴答定时器中断(Systick)和多个系统异常中断(编号1-15)。
??以CM4为例,我们找到随便一个STM32F4的项目打开它的core_cm4.h。一般路径为CMISIS/Include

/**
  \ingroup    CMSIS_core_register
  \defgroup   CMSIS_core_base     Core Definitions
  \brief      Definitions for base addresses, unions, and structures.
  @{
 */
/* Memory mapping of Core Hardware */
#define SCS_BASE            (0xE000E000UL)                            /*!< System Control Space Base Address */
#define ITM_BASE            (0xE0000000UL)                            /*!< ITM Base Address */
#define DWT_BASE            (0xE0001000UL)                            /*!< DWT Base Address */
#define TPI_BASE            (0xE0040000UL)                            /*!< TPI Base Address */
#define CoreDebug_BASE      (0xE000EDF0UL)                            /*!< Core Debug Base Address */
#define SysTick_BASE        (SCS_BASE +  0x0010UL)                    /*!< SysTick 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 SysTick             ((SysTick_Type   *)     SysTick_BASE  )   /*!< SysTick configuration struct */
#define NVIC                ((NVIC_Type      *)     NVIC_BASE     )   /*!< NVIC configuration struct */
#define ITM                 ((ITM_Type       *)     ITM_BASE      )   /*!< ITM configuration struct */
#define DWT                 ((DWT_Type       *)     DWT_BASE      )   /*!< DWT configuration struct */
#define TPI                 ((TPI_Type       *)     TPI_BASE      )   /*!< TPI configuration struct */
#define CoreDebug           ((CoreDebug_Type *)     CoreDebug_BASE)   /*!< Core Debug configuration struct */

这里的宏定义主要看 NVICSCS_BASE
NVIC的地址就是 SCS_BASE的地址偏移0x0100UL
NVIC_BASE 就是 xE000_E100

#define NVIC                ((NVIC_Type      *)     NVIC_BASE     )   /*!< NVIC configuration struct */

这一行就是在 NVIC_BASE 的基础上定义了一个结构体NVIC_Type来方便对NVIC内部寄存器的访问。

NVIC_Type结构体的定义如下:

/**
 \brief      Type definitions for the NVIC Registers
  \brief  Structure type to access the Nested Vectored Interrupt Controller (NVIC).
 */
typedef struct
{
  __IOM uint32_t ISER[8U];               /*!< Offset: 0x000 (R/W)  Interrupt Set Enable Register */
        uint32_t RESERVED0[24U];
  __IOM uint32_t ICER[8U];               /*!< Offset: 0x080 (R/W)  Interrupt Clear Enable Register */
        uint32_t RSERVED1[24U];
  __IOM uint32_t ISPR[8U];               /*!< Offset: 0x100 (R/W)  Interrupt Set Pending Register */
        uint32_t RESERVED2[24U];
  __IOM uint32_t ICPR[8U];               /*!< Offset: 0x180 (R/W)  Interrupt Clear Pending Register */
        uint32_t RESERVED3[24U];
  __IOM uint32_t IABR[8U];               /*!< Offset: 0x200 (R/W)  Interrupt Active bit Register */
        uint32_t RESERVED4[56U];
  __IOM uint8_t  IP[240U];               /*!< Offset: 0x300 (R/W)  Interrupt Priority Register (8Bit wide) */
        uint32_t RESERVED5[644U];
  __OM  uint32_t STIR;                   /*!< Offset: 0xE00 ( /W)  Software Trigger Interrupt Register */
}  NVIC_Type;
__IOM uint32_t ISER[8U];               /*!< Offset: 0x000 (R/W)  Interrupt Set Enable Register */

??每一个ISER都是一个uint32_t 的数据,也就是说ISER一共有[0-7] 8个,这个是干什么的呢,参考CM3权威指南

可以看到:

CM3 中可以有 240 对使能位/除能位,每个中断拥有一对。这 240 个对子分布在 8 对 32 位寄存器中(最后一对没有用完)。欲使能一个中断,你需要写 1 到对应 SETENA 的位中;欲除能一个中断,你需要写 1 到对应的 CLRENA 位中;如果往它们中写 0,不会有任何效果。

ISER : Interrupt Set Enable Register 就是其缩写。怎么验证说的是对的呢?我们可以简单计算一下他的兄弟ICER地址。

ICER= ISER_BASE + RESERVED0[24] +ISER[8]=xE000_E100 + 32 * 24/8 + 32 * 8/8 = xE000_E100 + x80UL = 0xE000_E180

??对照权威指南(如下图)就是 ICER 寄存器开始的地址,对应上边代码段的 ICER 的偏移量0x80都正好符合。所以总的来说这个结构体里面定义的都是一类一类的关于中断的寄存器。
请添加图片描述
??特别提示,这对这些外部中断,其对应优先级由IP这个寄存器来配置。下文会详细解释怎么配置。

??以上都是关于240个外中断的定义下面来看一下系统中断的定义。

Cortex-M 系统中断

请添加图片描述
以上每一个配置寄存器同样都是8位,针对PendSV、SysTick访问时都按字访问,即从0XE000_ED20开始访问。

Cortex-M 中断优先级分组

既然知道了这些终端由些寄存器控制,现在来讨论一下如何配置这些寄存器。

我们以STM32F4为例子,来看一下它是如何实现中断优先级分组的。

/**
  * @brief  Sets the priority grouping field (preemption priority and subpriority)
  *         using the required unlock sequence.
  * @param  PriorityGroup The priority grouping bits length. 
  *         This parameter can be one of the following values:
  *         @arg NVIC_PRIORITYGROUP_0: 0 bits for preemption priority
  *                                    4 bits for subpriority
  *         @arg NVIC_PRIORITYGROUP_1: 1 bits for preemption priority
  *                                    3 bits for subpriority
  *         @arg NVIC_PRIORITYGROUP_2: 2 bits for preemption priority
  *                                    2 bits for subpriority
  *         @arg NVIC_PRIORITYGROUP_3: 3 bits for preemption priority
  *                                    1 bits for subpriority
  *         @arg NVIC_PRIORITYGROUP_4: 4 bits for preemption priority
  *                                    0 bits for subpriority
  * @note   When the NVIC_PriorityGroup_0 is selected, IRQ preemption is no more possible. 
  *         The pending IRQ priority will be managed only by the subpriority. 
  * @retval None
  */
void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
{
  /* Check the parameters */
  assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
  
  /* Set the PRIGROUP[10:8] bits according to the PriorityGroup parameter value */
  NVIC_SetPriorityGrouping(PriorityGroup);
}

从上面NVIC_SetPriorityGrouping中跳转到下面函数 :

__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
{
  uint32_t reg_value;
  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);             /* only values 0..7 are used          */

  reg_value  =  SCB->AIRCR;                                                   /* read old register configuration    */
  reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change               */
  reg_value  =  (reg_value                                   |
                ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
                (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos)  );              /* Insert write key and priority group */
  SCB->AIRCR =  reg_value;
}

其操作的正是SCB->AIRCR寄存器。来看一下AIRCR寄存器(下图地址错误)。
请添加图片描述
??通过设置[10:8] 这三个位来实现优先级分组, 结合Cortex-M系统中断中的图,每一个优先级配置寄存器都是8位,将这8位分为8种情况,当然这样分组不仅仅针对系统异常,同样对所有可配置中断的异常都适用,分组情况见下图。
请添加图片描述
??打个比方将[10:8]这三个位设置成0x110,就是6,那所有可编程的中断优先级配置寄存器 -->IP 都必须按照抢占优先级占一个位[7:7],亚优先级占7个位[6:0]来设置优先级。

Freertos 中断

Freertos 中断配置

Freertos 中断配置的信息都存放于freertos/include/FreeRTOSConfig.h

/* Cortex-M specific definitions. */
#ifdef __NVIC_PRIO_BITS
	/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
	#define configPRIO_BITS       		__NVIC_PRIO_BITS
#else
	#define configPRIO_BITS       		4        /* 15 priority levels */
#endif

/* The lowest interrupt priority that can be used in a call to a "set priority"
function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY			0xf

/* 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

/* Interrupt priorities used by the kernel port layer itself.  These are
 *
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) )
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 	( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )

??首先看最上边一行定义__NVIC_PRIO_BITS,这个并没有定义,所以跳转到定义configPRIO_BITS这里,因为样例使用的是STM32F4,对于STM32F4优先级配置寄存器 IP 只有高四位被用于使用,也就是说configPRIO_BITS应该被设定成 4

接下来看最下面两行的宏定义

* /*Interrupt priorities used by the kernel port layer itself.  These are 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) )

??这个宏定义是根据configLIBRARY_LOWEST_INTERRUPT_PRIORITY宏定义来确定的(在上面),configLIBRARY_LOWEST_INTERRUPT_PRIORITY宏设定了最小的内核抢占优先级,这里设定的是0xf也就是15,再给任务设定优先级大小的时候,最低可以设置到15(优先级数字越大优先级越小)。

/* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 	( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )

??configMAX_SYSCALL_INTERRUPT_PRIORITY这个宏定义的是FreeRTOS内核控制的最大优先级,将此宏设定成5,则有[4:0]优先级不归内核控制,即无法屏蔽这些中断,在这些优先级高的中断中也不能安全的调用FreeRTOS的API。

移植配置FreeRTOS的时候将这个几个宏定义依次进行修改即可。

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-10-03 17:14:14  更:2021-10-03 17:14:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 5:48:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码