一直没亲手移植过FreeRTOS,心血来潮移植了下最新版的FreeRTOSv202104.00
过程不赘述,可以参考 https://www.cnblogs.com/iot-dev/p/11681067.html,写的还是非常详细的。
task还是常见的LED1 LED2 闪烁加UART的打印,期间遇到了几个问题,如下
1.程序跑过了 vTaskStartScheduler(); //开启调度,继续往校跑
2.进入HardFault_Handler(这个应该是为#define configTOTAL_HEAP_SIZE 设置的太小)
3.程序卡到 while( uxDeletedTasksWaitingCleanUp > ( UBaseType_t ) 0U )
总结还是应从下面几点入手:
1、三个重要的中断函数SysTick、PendSV_Handler()与SVC_Handler()
这三个函数数在stm32f10x_it.c文件中和FreeRTOS 的port.c文件中都实现了。
一般stm32f10x_it.c文件里的都是空函数当然是不能用的,可以直接使用FreeRTOS 的port.c文件中的这三个函数。
首先是PendSV_Handler()与SVC_Handler()。在stm32f10x_it.c中注释掉PendSV_Handler()与SVC_Handler()这两个函数的函数体,声明不要注释,并在FreeRTOSConfig.h加上下面两句
/****************************************************************
FreeRTOS与中断服务函数有关的配置选项
****************************************************************/
#define xPortPendSVHandler PendSV_Handler
#define vPortSVCHandler SVC_Handler
接着是SysTick,在stm32f10x_it.c文件中增加extern void xPortSysTickHandler(void),原来的函数体内增加代码如下
extern void xPortSysTickHandler(void);
//systick中断服务函数
void SysTick_Handler(void)
{
#if (INCLUDE_xTaskGetSchedulerState == 1 )
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
{
#endif /* INCLUDE_xTaskGetSchedulerState */
xPortSysTickHandler();
#if (INCLUDE_xTaskGetSchedulerState == 1 )
}
#endif /* INCLUDE_xTaskGetSchedulerState */
}
注:有些网上的文章写增加#define xPortSysTickHandler SysTick_Handler,直接加到FreeRTOSConfig.h肯定会报错,因为stm32f10x_it.c文件中和FreeRTOS 的port.c的SysTick_Handler冲突了,如果注释掉stm32f10x_it.c中的SysTick_Handler虽然不报错了,但也是FreeRTOS也是跑不起来的。原因如下图,在startup_stm32f10x_md.s中同样会用到这个函数,这是一个很重要的函数,我们需要在stm32f10x_it.c文件中实现STM32平台上的SysTick_Handler()函数
2.#define configTOTAL_HEAP_SIZE 不能设置的太小,任务栈的大小设置不合理
本人尝试下面这个,设置的大小倒影响不大,只要大于0就可以,但他关系到configTOTAL_HEAP_SIZE 设置的大小
#define configMINIMAL_STACK_SIZE
本人创建了三个任务如下
static void AppTaskCreate(void);/* 用于创建任务 */
static void LED1_Task(void* pvParameters);/* LED1_Task任务实现 */
static void LED2_Task(void* pvParameters);/* LED2_Task任务实现 */