前言
本文以STM32F407ZET6 + FreeRTOS V9.0作为演示,其它的Cortex M芯片同样可以参考此文,其他内核和RTOS理论上也支持,本文暂时不做研究。
所以开始阅读本文前,需要一块能运行FreeRTOS的Cortex M芯片,如果没有移植好操作系统,可以参考我的另一篇文章《STM32F103移植FreeRTOS完整过程》
本文打包提供FreeRTOS V9.0源码
,SystemView安装包
,STM32F407ZET6示例工程
,在文章顶部标题下方。
SystemView简介
SystemView是嵌入式系统的实时记录和可视化工具。它揭示了应用程序的真实运行时行为,比调试器提供的系统洞察更深入。这在开发和处理由多线程和中断组成的复杂嵌入式系统时尤为有效。SystemView可确保系统按设计运行,跟踪低效情况,并发现意外的交互和资源冲突。——SEGGER官网
可以查看任务和中断运行的时序图
可以查看任务调度情况
移植源码
官网下载,本文选择的是V3.52版本,如果下载太慢可以在文章顶部标题下方下载。
在工程目录下新建SEGGER目录
,进入SystemView安装目录,准备往SEGGER目录移入源码
将SystemView\Src\SEGGER\
下的所有.c
.h
文件移入SEGGER目录
将SystemView\Src\Config\
下的所有.c
.h
文件移入SEGGER目录
将SystemView\Src\Sample\FreeRTOSV9\
下的所有.c
.h
文件移入SEGGER目录
将SystemView\Src\Sample\FreeRTOSV9\Config\Cortex-M\
下的所有.c
.h
文件移入SEGGER目录
此时SEGGER目录
下的内容如图所示,将此目录文件添加到工程即可
给FreeRTOS打补丁
这里不打补丁一样能监控系统,有知道打补丁作用的大佬可以评论区告诉大家!
这里不打补丁一样能监控系统,有知道打补丁作用的大佬可以评论区告诉大家!
这里不打补丁一样能监控系统,有知道打补丁作用的大佬可以评论区告诉大家!
SystemView\Src\Sample\FreeRTOSV9\Patch\
目录下的FreeRTOSV9_Core.patch
集成了对FreeRTOS的改动,可以通过git apply
命令一键修改
打开文件可以看到工作路径为/libs/FreeRTOS/
打开FreeRTOSv9.0.0
目录,新建libs\FreeRTOS\
文件夹
将FreeRTOSv9.0.0\FreeRTOS\Source\
中所有文件移入其中
将FreeRTOSV9_Core.patch
移入到FreeRTOSv9.0.0
根目录,并执行如下命令即可完成一键打补丁
git apply FreeRTOSV9_Core.patch
修改配置
在FreeRTOSConfig.h
中添加如下宏定义
#define INCLUDE_xTaskGetIdleTaskHandle 1
#define INCLUDE_pxTaskGetStackStart 1
在FreeRTOS.h
中包含如下头文件
#include "SEGGER_SYSVIEW_FreeRTOS.h"
在main.c
中包含如下头文件
#include "SEGGER_SYSVIEW.h"
并在系统调度开始前,调用如下函数
SEGGER_SYSVIEW_Conf();
在SYSTICK中断中添加中断进出记录traceISR_ENTER
和traceISR_EXIT
void xPortSysTickHandler( void )
{
traceISR_ENTER();
vPortRaiseBASEPRI();
{
if( xTaskIncrementTick() != pdFALSE )
{
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
traceISR_EXIT_TO_SCHEDULER();
}
else
{
traceISR_EXIT();
}
}
vPortClearBASEPRIFromISR();
}
其余中断,例如定时器中断、UART中断等,都需要手动加上traceISR_ENTER
和traceISR_EXIT
来记录中断进出,否则不会显示此中断的运行情况
开始运行
代码如下
#include "main.h"
#include "usart.h"
#include "gpio.h"
#include "FreeRTOS.h"
#include "task.h"
#include "SEGGER_SYSVIEW.h"
void SystemClock_Config(void);
static TaskHandle_t task1_handle = NULL;
static TaskHandle_t task2_handle = NULL;
void task1(void *arg)
{
while(1)
{
}
}
void task2(void *arg)
{
while(1)
{
}
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART6_UART_Init();
xTaskCreate(task1, "task1", 1024, NULL, 20, &task1_handle);
xTaskCreate(task2, "task2", 1024, NULL, 20, &task2_handle);
SEGGER_SYSVIEW_Conf();
// 开启调度
vTaskStartScheduler();
while(1);
}
打开SystemView V3.52
,点击开始,选择对应芯片即可
效果如图