你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

stm32cube中freertos的优先级设置问题

[复制链接]
电小龙 提问时间:2016-12-13 21:10 /
在用stm32cube中freertos,在配置界面里设置为12级任务优先级,但是在cube中配置每个任务优先级时还是只能选择7种优先级,分别是:osPriorityIdle,osPriorityLow,osPriorityBelowNormal,osPriorityNormal,osPriorityAboveNormal,osPriorityHigh,osPriorityRealtime 。这是为什么呢?下面有我的两张截图供大家看看。
1.jpg
2.jpg
收藏 4 评论11 发布时间:2016-12-13 21:10

举报

11个回答
assssdz 回答时间:2016-12-13 22:00:25
jackten 回答时间:2016-12-13 22:09:36
过来学习                        
adlu 回答时间:2016-12-14 09:15:07
可能是Cube在优先级上进行了精简,只支持7个优先级。下图是cmsis_os.h中对优先级的定义:

QQ截图20161214091305.jpg

评分

参与人数 1ST金币 +2 收起 理由
zero99 + 2

查看全部评分

斜阳 回答时间:2016-12-14 09:18:29
帮顶            
jackten 回答时间:2016-12-14 09:25:31
顶一个               
电小龙 回答时间:2016-12-14 11:42:36
adlu 发表于 2016-12-14 09:15
可能是Cube在优先级上进行了精简,只支持7个优先级。下图是cmsis_os.h中对优先级的定义:

那如果我的任务比较多呢?我改怎么设置呢,就算不在cube里面改变,可以在keil中自己定义一个优先级大于3的等级吗?
adlu 回答时间:2016-12-14 12:11:32
电小龙 发表于 2016-12-14 11:42
那如果我的任务比较多呢?我改怎么设置呢,就算不在cube里面改变,可以在keil中自己定义一个优先级大于3 ...

这个不是很清楚。只能通过实验验证了。但是最好还是不要改。
电小龙 回答时间:2016-12-14 12:40:44
adlu 发表于 2016-12-14 12:11
这个不是很清楚。只能通过实验验证了。但是最好还是不要改。

想问问stm32cube设计的人有没有添加这个功能
绝版森哥 回答时间:2018-8-10 09:41:24
我也遇到楼主这样的问题,楼主最后怎么解决的?
电小龙 回答时间:2018-8-11 13:31:35
绝版森哥 发表于 2018-8-10 09:41
我也遇到楼主这样的问题,楼主最后怎么解决的?

这个是CUBE自定义的,不用CUBE定义的也行。
watershade 回答时间:2019-3-31 18:19:32
本帖最后由 watershade 于 2019-3-31 18:43 编辑

这个问题已经过去很久了。但我还是写一下答案吧。有机会自己写一篇。
在cmsis-rtos v1中是通过下面这个函数来转化优先级的:
  1. /* Convert from CMSIS type osPriority to FreeRTOS priority number */
  2. static unsigned portBASE_TYPE makeFreeRtosPriority (osPriority priority)
  3. {
  4.   unsigned portBASE_TYPE fpriority = tskIDLE_PRIORITY;
  5.   
  6.   if (priority != osPriorityError) {
  7.     fpriority += (priority - osPriorityIdle);
  8.   }
  9.   
  10.   return fpriority;
  11. }
复制代码
翻译一下就是在freeRTOS中的优先级fpriority = tskIDLE_PRIORITY + priority - osPriorityIdlepriority的值是什么呐?在cmsis.os.c中有一段代码:
  1. typedef enum  {
  2.   osPriorityIdle          = -3,          ///< priority: idle (lowest)
  3.   osPriorityLow           = -2,          ///< priority: low
  4.   osPriorityBelowNormal   = -1,          ///< priority: below normal
  5.   osPriorityNormal        =  0,          ///< priority: normal (default)
  6.   osPriorityAboveNormal   = +1,          ///< priority: above normal
  7.   osPriorityHigh          = +2,          ///< priority: high
  8.   osPriorityRealtime      = +3,          ///< priority: realtime (highest)
  9.   osPriorityError         =  0x84        ///< system cannot determine priority or thread has illegal priority
  10. } osPriority;
复制代码
可以看出osPriorityNormal是0,可以看作一个基准。对于osPriorityNormal来说在freeRTOS的优先级是tskIDLE_PRIORITY - osPriorityIdle
那么在task.h中规定了它的值。比如stm32cubemx生成的f0的工程中默认取值是:
  1. /**
  2. * Defines the priority used by the idle task.  This must not be modified.
  3. *
  4. * \ingroup TaskUtils
  5. */
  6. #define tskIDLE_PRIORITY                        ( ( UBaseType_t ) 0U )
复制代码
而osPriorityIdle在上面的取值是-3.所以可以看到实际上真正的几种实际上是osPriorityIdle(因为tskIDLE_PRIORITY + osPriorityIdle - osPriorityIdle = tskIDLE_PRIORITY)。
对于osPriorityNormal来说。这个取值在freeRTOS中的优先级是:tskIDLE_PRIORITY+3
osPriorityIdle的优先级就是tskIDLE_PRIORITY 这样保证了freeRTOS和cmsis-RTOS的idle优先级的一致。
这一点在优先级较多的时候还行。但对于CM0那种可设置优先级只有4个的任务来说,害死人。(这一点还没有查看代码中有没有保险措施,但如果不加保护,优先级就会乱套。)


但freeRTOS的优先级还不是在真正的优先级。这部分可以查看一下其他人关于freeRTOS的描述。


下面是深入篇。如果你在调试的时候发现显示的优先级和自己设置的不同,不要奇怪。比如keil上面显示的是内核优先级。具体计算可以看下面说明。
另外对于M0内核和M3/M4内核的STM32产品内核优先级的计算是不同的。M0的内核优先级是8位中的高2位可配置。而M3和M4是高4位可配置。

这是core_cm0.h的代码(其中__NVIC_PRIO_BITS的宏定义是2):
  1. __STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
  2. {
  3.   if ((int32_t)(IRQn) < 0)
  4.   {
  5.     SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
  6.        (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
  7.   }
  8.   else
  9.   {
  10.     NVIC->IP[_IP_IDX(IRQn)]  = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)]  & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
  11.        (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
  12.   }
  13. }
复制代码
其中
  1. #define _BIT_SHIFT(IRQn)         (  ((((uint32_t)(int32_t)(IRQn))         )      &  0x03UL) * 8UL)
复制代码


这是core_cm4.h的代码(其中__NVIC_PRIO_BITS的宏定义是4):
  1. __STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
  2. {
  3.   if ((int32_t)(IRQn) < 0)
  4.   {
  5.     SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
  6.   }
  7.   else
  8.   {
  9.     NVIC->IP[((uint32_t)(int32_t)IRQn)]               = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
  10.   }
  11. }
复制代码
m0的处理非常复杂,基本上最终的优先级是中断号和可配置中断的组合计算。
m4的简单一点,可以看出对于优先级不小于0的中断来说就是将优先级前移4位。

另外在F0的工程中发现没有configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY和configLIBRARY_LOWEST_INTERRUPT_PRIORITY的定义。在cubemx的配置中应该是无效的(但后者可以影响mx自动设置一些中断的优先级。还是要设置。):
F0问题.jpg
具体情况看能否找到官方文档再说。

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版