ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

理解STM32的NVIC_PriorityGroupConfig函数

2022-01-21 12:34:58  阅读:353  来源: 互联网

标签:PriorityGroupConfig NVIC AIRCR 优先级 assert STM32 PriorityGroup GROUP


该函数的作用

用于设置NVIC优先级分组,分配抢占优先级响应优先级各自所占的比例。

 

优先级的基本定义

  • 在 Cortex-M3(CM3)中,优先级对于异常来说很关键的,它会影响一个异常是否能被响应,以及何时可以响应。
  • 优先级的数值越小,则优先级越高
  • CM3 支持中断嵌套,使得高优先级异常会抢占(preempt)低优先级异常。
  • 有 3 个系统异常:复位,NMI 以及硬 fault,它们有固定的优先级,并且它们的优先级号是负数,从而高于所有其它异常。
  • CM3 支持 3 个固定的高优先级和多达 256 级的可编程优先级,并且支持 128级抢占,但是绝大多数芯片在设计时会裁掉表达优先级的几个低端有效位,以达到减少优先级数的目的。

 

 

为什么要设置抢占优先级和响应优先级

为了使抢占机能变得更可控,CM3把 256 级优先级按位分成高低两段,即抢占优先级和亚优先级。     函数代码理解
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
{
  /* Check the parameters */
  assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup));
  
  /* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */
  SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
}

 

在这个函数中,我们需要选择NVIC分组类型作为参数进入该函数,该参数在misc.h文件中有定义

可见共有4bit用于设置优先级分组,而不同的分组类型决定抢占优先级和响应优先级各自所占的bit比例。如果各占2bit,那么抢占优先级和响应优先级就各有2²=4的优先级值。

 

看回到函数第一行代码

assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup));

 

该函数用于判断用户输入的参数是否有错。在misc.h文件中有一个带参宏定义。

#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))

如果参数正确则会返回true值。我们再看到以下代码

#ifdef  USE_FULL_ASSERT

/**
  * @brief  The assert_param macro is used for function's parameters check.
  * @param  expr: If expr is false, it calls assert_failed function which reports 
  *         the name of the source file and the source line number of the call 
  *         that failed. If expr is true, it returns no value.
  * @retval None
  */
  #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
/* Exported functions ------------------------------------------------------- */
  void assert_failed(uint8_t* file, uint32_t line);
#else
  #define assert_param(expr) ((void)0)
#endif /* USE_FULL_ASSERT */

#endif /* __STM32F10x_CONF_H */

可以看到当定义USE_FULL_ASSERT时,当此前函数返回的值为true,则函数不执行任何操作,如果返回的值为false,则assert_failed()会报告错误文件和错误行。但在代码中能够发现assert_failed()仅仅是个框架,因此需要开发者自己编写。

通常USE_FULL_ASSERT是没有被定义的,那么该函数往往不会执行任何操作。

 

看到原函数第二行代码

SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;

 

首先是执行了一次或运算,在头文件中有给出AIRCR_VECTKEY_MASK的值

#define AIRCR_VECTKEY_MASK    ((uint32_t)0x05FA0000)

该函数用于配置AIRCR寄存器(应用程序中断及复位控制寄存器)。根据规定,任何对该寄存器的写操作都要把0x05FA写入31:16位段,否则该操作会被忽略。

同时我们也可以看到共有3bit用于配置优先级分组,具体值在头文件中宏定义的NVIC优先级分组给出。

 

其中SCB只是个结构体,在core_cm3.h中给出,里面定义了一些寄存器的数据类型。

 

最终加上访问钥匙后,我们把值写入AIRCR寄存器,完成优先级分组的配置。

 

参考资料

Cortex-M3权威指南(中文)

标签:PriorityGroupConfig,NVIC,AIRCR,优先级,assert,STM32,PriorityGroup,GROUP
来源: https://www.cnblogs.com/icysamon/p/15829763.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有