在学习FreeRTOS的时候,就了解到Keil有一个RTX操作系统,听说其配合Keil 的Event Recorder调试非常好用。它的中断延迟很低,关键还和FreeRTOS一样,免费的。
在网上找了一些资料之后,大都是直接使用Keil进行添加,于是结合官方资料和网上的资料,尝试在使用STM32CubeMX生成的工程中添加RXT操作系统。
STM32CubeMX的配置和平时没有什么不同,主要有两个需要注意的地方,一个是Timebase Source的配置,这个是HAL库的基础时钟,默认是SysTick,但是操作系统默认使用这个时钟,所以需要将HAL库的基础时钟换为TIMER,这里我选择TIM2.
然后是时钟树的配置,注意先选择外部高速时钟,设置频率,然后设置HCLK就会自动配置所有时钟。
第二点需要注意的就是,点击NVIC配置,点击Code generation选择,将SVC, PendSV和SysTick这三个中断的Generate IRQ handler选项去掉,因为Keil的RTX系统要用到这三个中断。
配置完成之后,就可以生成代码。接下来就是Keil需要配置的部分。
生成工程之后,点击 Manage Run-Time Environment 按钮,进行RTX和Event Recorder的配置。
完成之后需要对RTX进行一个配置,展开右侧的CMSIS,双击,RTX_Config.h,点击下面的Configuration Wizard按钮,给操作系统分配内存,在这里我一共分配了32*1024 一共32KB的内存。其它的默认即可。
完成以上部分之后,还需要添加一些代码,来对RTX进行初始化,首先是添加头文件。
然后就是添加RTX的初始化函数,其中Thread_Init()为创建线程的函数,需要用户自己编写。其它函数看名字应该都知道是干嘛的。
#ifdef RTE_Compiler_EventRecorder
EventRecorderInitialize(EventRecordAll, 1);
#endif
SystemCoreClockUpdate();
osKernelInitialize();
Thread_Init();
osKernelStart();
这个文件是我们自己手动编写,我在此处使用的是CMSIS-RTOS C API v2 。
例程中一共创建了两个线程,分别是Thread1和Thread2.其中,Thread1的名字为Thread1,优先级为osPriorityLow3(比osPriorityLow4低),给它分配了256*4个Byte的堆栈。Thread2同理。
在两个线程中,首先添加了printf函数,打印任务运行情况,然后在while中添加了Event Recorder的时间测量函数,HAL库的延时函数(基于TIM2),这个延时不会被RTOS打断,以及RTOS的延时函数,会引起调度。
完成之后,编译,进行Debug,查看运行结果。
编译完成之后就可以进行测试,我使用的是DAP下载器,注意将Trace的时钟改为168,也就是系统系统内核时钟。
然后依次打开 Debug (printf)Viewer窗口。
Event Statistics窗口
以及RTX RTOS窗口。
最后点击RUN开始运行。
进入Debug模式后,打开Debug (printf) Viewer 窗口,然后运行程序,可以看到,两个线程均已运行,而且由于Thread2的优先级高,所以它优先执行。
然后就是Event Recorder调试组件,可以看到,在Event Recorder中,可以看到很多系统信息,包括系统的内存使用情况,每个任务的栈使用情况、优先级、运行状态、Flag等等,可以说调试起来非常方便。
再看看Event Recorder的时间测量,可以看到Event Recorder在传输数据过程中出现了一些错误,但是其时间测量还是比较准的。
Thread1的时间测量从开始到停止理论上一共消耗220ms,实测平均值221.58ms。
Thread2的时间测量从开始到停止理论上一共消耗110ms,实测平均值110.81ms。
Thread1的运行时间理论上为20ms,实测平均值23.738ms,阻塞理论上200ms,实测平均值201ms。
Thread2的运行时间理论上为10ms,实测平均值10.735ms,阻塞理论上100ms,实测平均值101.59ms。
CSDN
自建的gits。
每天早上9点到晚上23点59分开
STM32CubeMX版本
测试所用单片机为STM32F407ZGT6,固件包为1.25.0
Keil版本为V5.29.0.0