欢迎光临散文网 会员登陆 & 注册

FreeRTOS移植,国产stm32BASEPRI寄存器中断优先级屏蔽问题

2023-07-10 13:58 作者:我有钱途  | 我要投稿

FreeRTOS移植比较简单(比LVGL简单多了,lvgl移植总是报错各种东西)使用Demo里的f103Keil工程中的FreeRTOSconfig.h,不再赘述。移植后创建任务,在打开调度器,xPortStartScheduler()中调用prvStartFirstTask()后进入HardFault。结合网上资料经过排查,默认的config.h中的优先级设置(就f103keilDemo里的那个)没有问题,刚创建了一个任务也不会出现栈溢出(经测试config里的全局数组大小也不会超过c8t6的ram,不是内存溢出问题),最后看别人视频发现还要在config.h中添加两句话:

#define     xPortPendSVHandler         PendSV_Handler

#define     vPortSVCHandler              SVC_Handler

然后把stm32f10x_it.c中的void SVC_Handler(void)和void PendSV_Handler(void)去掉,即可正常使用。原因是FreeROTS实现了这两个Handler,但是名字是xPortPendSVHandler和vPortSVCHandler,和startup.s中的DCD PendSV_Handler、DCD SVC_Handler名字对不上,所以用宏定义对它们改名,使其和start.s中的名字一致,才能对接。下图为没有对接PendSV中断和SVC中断导致进入HardFault的函数。

prvStartFirstTask

第二个问题,FreeRTOS为了实现对数据的独立访问,会关闭调度器和中断(或者只关闭调度器),关中断使用portDISABLE_INTERRUPTS()宏,即vPortRaiseBASEPRI()函数。原理是向BASEPRI寄存器写入一个数,大于等于这个数的优先级(更低优先级)都会被屏蔽。可以参考正点原子讲解FreeRTOS中断的视频。正点原子f103例程中有一个实验:设定屏蔽优先级为5,将两个定时器的中断优先级设置为4和5,调用函数写BasePri寄存器关中断后,定时器5的中断被关闭了,定时器4的中断不受影响,验证了这个机制。

FreeRTOS关中断的方法

然而在使用国产32验证时遇到了极其逆天的问题,调用函数屏蔽优先级为5和以上的中断后,优先级为4的中断居然也被屏蔽了,效果和屏蔽等级为4相同。经过验证,发现国产32对于写入BASEPRI寄存器的高四位,会将最后一位按照0处理。比如优先级为5,写入0X50,即01010000,等同于01000000,0X40!优先级为9,写入0x90,即10010000,等同于10000000,0X80!非常奇怪!

我是直接改了一下正点原子的定时器初始化里的几句话(因为c8t6没有TIM5,用TIM4代替),如果正点原子代码没问题,那这个现象就和预料中不一样,只能是国产32的问题了。国产32之前还遇到过个别定时器个别引脚无法输出PWM波的问题。

调用函数写basepri寄存器屏蔽中断,屏蔽等级为5,却把优先级为4、5两个定时中断都屏蔽了!
这是正确的现象

帮大伙踩踩坑,又是国产32的坑

FreeRTOS移植,国产stm32BASEPRI寄存器中断优先级屏蔽问题的评论 (共 条)

分享到微博请遵守国家法律