RTOS的移植的坑-STM32F103RCT6

个人RTOS的移植的坑-STM32F103RCT6篇

本篇中简单描述RTOS移植的过程,重点在于记录移植过程中出现的调度失败问题。

移植之前的准备

在移植之前,我准备了基于STM32F103RCT6的标准库项目以及在FreeRTOS官网上下载的项目包。

标准库项目为RCT6的1.44寸LCD的例程项目。

之前跟着韦东山老师进行项目的移植,他的方法为对demo项目进行直接裁剪。这种方法比较简单,但是对我们理解RTOS运行所需文件可能比较困难。
于是决定在现有项目上直接移植RTOS所需的文件。

第一步:移植RTOS所需要的文件

在下载完解压后得到\FreeRTOSv202212.01文件。

我们需要的文件如下:

目录\FreeRTOS\Source\:

croutine.c 、 event_groups.c 、 list.c、 queue.c、 stream_buffer.c、 tasks.c、 timers.c

目录\FreeRTOS\Source\include\:其中包含的头文件均可以移植

目录\FreeRTOSv202212.01\FreeRTOS\Source\portable\:

该目录下的MemMang文件(内存管理文件)以及RVDS文件(包含port配置)

FreeRTOSconfig.h文件,这个文件是对系统进行设置的文件

移动到我们的标准库项目中,除了FreeRTOSconfig.h文件我们放在项目的USER目录下,其他的可以新建一个RTOS的文件夹。

第二步: 在keil5中将这些文件添加到项目中

首先是对工作空间的设置,将RTOS移植的c文件添加到我们的工作空间。

接着点击魔法棒,在C/C++栏目将RTOS的使用到的头文件所在目录都添加到目录列表中,我们的编译器在编译时回去这些文件夹中找到头文件。

第三步:对报错信息进行修复

报错信息基本上可以分为几类:

1. 未定义的函数使用

我们使用CTRL+F来检索该未定义的函数,部分函数在RTOS中是要由用户自己来编写的。
为了保证项目的简洁,在RTOS中,我们检索函数在定义时需要的宏定义,将宏定义关闭。(因为RTOS项目我之前进行过修改,全新的好像不需要)

2. 数据类型未定义

这类问题一般是库与库之间对变量类型的定义问题,如它使用到了u8,u16这种。修复也很简单,可以在头文件中进行定义,或者直接调用定义过的头文件。

systick延时
还需要注意的一点就是,裸机中我们常常使用systick来作为延时函数,在rtos中我们不能随便对它进行修改。
所以我在移植的时候把delay.c的延时全部改成了软件delay先。

第四步:创建任务进行测试

配置完成以后,就可以创建任务来进行调试了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
TaskHandle_t xHandleTask1;
TaskHandle_t xHandleTask2;

void Task1(void* parm)
{
while(1)
{
LED = ~LED;
vTaskDelay(100);
}
}


void Task2(void* parm)
{
u16 num = 0;
while(1)
{
LCD_ShowIntNum(0,64,num++,1,BLACK,WHITE,16);
vTaskDelay(100);
}
}

int main(void)
{
LED_Init();//LED初始化
LCD_Init();//LCD初始化
LED = ~LED;
LCD_Fill(0,0,LCD_W,LCD_H,RED);
LCD_ShowPicture(32,0,40,40,gImage_1);
xTaskCreate(Task1, "Task1", 1024, NULL, 1, &xHandleTask1);
xTaskCreate(Task2, "Task2", 1024, NULL, 1, &xHandleTask2);
vTaskStartScheduler();
while(1);
}

首先动态创建两个任务,接着开启调度器让任务调度。
发现任务并没有如期进行。

第五步: DEBUG

出现了问题首先要检查是不是漏配了哪一步。

最后发现,可能是systick中断的问题。
在FreeRTOS中SysTick定时器尤为重要,因为它是给FreeRTOS系统提供时钟的。
在FreeRTOS中任务的切换即每个任务运行的时间是由SysTick定时器提供的。
调度不正常就需要去考量一下systick的问题了。

在FreeRTOS中已经提供了SysTick配置的函数vPortSetupTimerInterrupt(),函数在port.c文件中。当调用了开启任务调度函数vTaskStartScheduler()后里面就会调用该函数完成SysTick的配置。

我们也可以通过另一种方式。
在stm32f10x_it.c中,我们对systick中断进行重写。

1
2
3
4
5
6
7
8
9
10
11
12
void SysTick_Handler(void)
{
#if (INCLUDE_xTaskGetSchedulerState == 1 )
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
{
#endif /* INCLUDE_xTaskGetSchedulerState */
xPortSysTickHandler();
#if (INCLUDE_xTaskGetSchedulerState == 1 )
}
#endif /* INCLUDE_xTaskGetSchedulerState */
}

完成后发现调度正常。

接下来就可以美美的进行lvgl的移植咯。


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以邮件至 1186703947@qq.com

💰

×

Help us with donation

相册 动态菜单1