你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。
chrome
firefox
safari
ie8及以上
ST
官网
STM32
中文官网
ST
全球论坛
登录/注册
首页
技术问答
话题
资源
创客秀
视频
标签
每日签到
STM32团队2
论坛吐槽优化专区
升级测试
stm32cube中freertos的优先级设置问题
[复制链接]
电小龙
提问时间:2016-12-13 21:10 /
阅读主题, 点击返回1楼
赞
0
收藏
3
评论
11
分享
发布时间:2016-12-13 21:10
请先
登录
后回复
11个回答
电小龙
回答时间:2018-8-11 13:31:35
a0a.1 32b0c
绝版森哥 发表于 2018-8-10 09:41
我也遇到楼主这样的问题,楼主最后怎么解决的?
这个是CUBE自定义的,不用CUBE定义的也行。
赞
0
评论
回复
支持
反对
watershade
回答时间:2019-3-31 18:19:32
a0a.1 32b0c
本帖最后由 watershade 于 2019-3-31 18:43 编辑
这个问题已经过去很久了。但我还是写一下答案吧。有机会自己写一篇。
在cmsis-rtos v1中是通过下面这个函数来转化优先级的:
/* Convert from CMSIS type osPriority to FreeRTOS priority number */
static unsigned portBASE_TYPE makeFreeRtosPriority (osPriority priority)
{
unsigned portBASE_TYPE fpriority = tskIDLE_PRIORITY;
if (priority != osPriorityError) {
fpriority += (priority - osPriorityIdle);
}
return fpriority;
}
复制代码
翻译一下就是在freeRTOS中的优先级
fpriority =
tskIDLE_PRIORITY +
priority -
osPriorityIdle
priority的值是什么呐?在cmsis.os.c中有一段代码:
typedef enum {
osPriorityIdle = -3, ///< priority: idle (lowest)
osPriorityLow = -2, ///< priority: low
osPriorityBelowNormal = -1, ///< priority: below normal
osPriorityNormal = 0, ///< priority: normal (default)
osPriorityAboveNormal = +1, ///< priority: above normal
osPriorityHigh = +2, ///< priority: high
osPriorityRealtime = +3, ///< priority: realtime (highest)
osPriorityError = 0x84 ///< system cannot determine priority or thread has illegal priority
} osPriority;
复制代码
可以看出osPriorityNormal是0,可以看作一个基准。对于osPriorityNormal来说在freeRTOS的优先级是tskIDLE_PRIORITY - osPriorityIdle
那么在task.h中规定了它的值。比如stm32cubemx生成的f0的工程中默认取值是:
/**
* Defines the priority used by the idle task. This must not be modified.
*
* \ingroup TaskUtils
*/
#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
):
__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if ((int32_t)(IRQn) < 0)
{
SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
}
else
{
NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
}
}
复制代码
其中
#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL)
复制代码
这是core_cm4.h的代码(其中
__NVIC_PRIO_BITS的宏定义是4
):
__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if ((int32_t)(IRQn) < 0)
{
SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
}
else
{
NVIC->IP[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
}
}
复制代码
m0的处理非常复杂,基本上最终的优先级是中断号和可配置中断的组合计算。
m4的简单一点,可以看出对于优先级不小于0的中断来说就是将优先级前移4位。
另外在F0的工程中发现没有configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY和configLIBRARY_LOWEST_INTERRUPT_PRIORITY的定义。在cubemx的配置中应该是无效的(但后者可以影响mx自动设置一些中断的优先级。还是要设置。):
具体情况看能否找到官方文档再说。
赞
0
评论
回复
支持
反对
1
2
/ 2 页
所属标签
相似问题
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
微信公众号
手机版
快速回复
返回顶部
返回列表
这个是CUBE自定义的,不用CUBE定义的也行。
这个问题已经过去很久了。但我还是写一下答案吧。有机会自己写一篇。
在cmsis-rtos v1中是通过下面这个函数来转化优先级的:
那么在task.h中规定了它的值。比如stm32cubemx生成的f0的工程中默认取值是:
对于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):
这是core_cm4.h的代码(其中__NVIC_PRIO_BITS的宏定义是4):
m4的简单一点,可以看出对于优先级不小于0的中断来说就是将优先级前移4位。
另外在F0的工程中发现没有configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY和configLIBRARY_LOWEST_INTERRUPT_PRIORITY的定义。在cubemx的配置中应该是无效的(但后者可以影响mx自动设置一些中断的优先级。还是要设置。):
具体情况看能否找到官方文档再说。