本帖最后由 lzh12a3nf 于 2023-9-14 18:23 编辑
#申请原创#@21小跑堂
1、前言
最近在学习FreeRTOS操作系统,刚好收到了极海的APM32F411开发板,于是整理一份APM32F411关于FreeRTOS源码移植、验证及过问题的思考记录,供大家参考学习。话不多说,接下来将讲解FreeRTOS的移植。
2、FreeRTOS移植 2.1、源码下载 第一步,首先到FreeRTOS官网下载对应的代码包。官网地址:www.freertos.org。打开后进行如下图对应操作即可下载FreeRTOS官网源代码。
点击右上方的DownloadFreeRTOS,根据个人的需求,可以分别下载不同的源码包。本文应用到的版本号为:FreeRTOSv202212.01。 第二步,将下载好的FreeRTOS源码包安装到Middleware文件夹下。如下图所示。
第三步,将所需要的文件添加到工程中。如下图所示。 接下来将对上面的移植文件进行简单的讲解。如下表格所示。 所处目录:...\Middlewares\FreeRTOS\FreeRTOSv202212.01\FreeRTOS\Source | | | | 实现协程(任务调度机制)功能。该文件包含协程任务的创建、调度和切换等相关函数。 | | 实现事件组的功能,用于多任务之间的事件同步和通信。它提供了一组位操作函数,用于设置、清除和等待事件位。 | | 实现了链表数据结构。常用于任务列表,挂起列表等数据结构的管理。 | | 实现了队列的功能。队列是一种用于任务间消息传递的机制。常用于创建队列、发送消息、接收消息等操作。 | | 实现流缓冲区的功能。流缓冲区是一种用于高效数据交换的机制,适用于传感器数据、通信数据等的传输。 | | 实现任务的功能,包括任务的创建、调度、切换、挂起等。 | | 实现了定时器(用于特定的事件间隔内执行任务)的功能,常用于创建定时器、启动定时器、停止定时器等操作。 |
所处目录: ...\Middlewares\FreeRTOS\FreeRTOSv202212.01\FreeRTOS\Source\portable\RVDS\ARM_CM4F | | | | 负责初始化和配置处理器、中断、任务切换以及其他与硬件相关的功能。 |
所处目录:...\Middlewares\FreeRTOS\FreeRTOSv202212.01\FreeRTOS\Source\portable\MemMang | | | | 实现内存管理,管理可用的内存。常用于动态分配和释放任务堆栈和其他资源。 |
第四步,.c文件添加完成后,对应添加.h头文件路径。如下图所示。
第五步,添加完成后。会出现如下图所示报错。 内容为找不到FreeRTOSConfig.h文件,其文件的功能是配置FreeRTOS内核的各种参数和选项。这个文件可以在...\Middlewares\FreeRTOS\FreeRTOSv202212.01\FreeRTOS\Demo路径下找到开发板芯片对应型号的文件,也可以自行创建配置。
其中,同时对FreeRTOSConfig.h文件进行内容进行简介,”INCLUDE”,用于配置FreeRTOS中可选的API函数,如”INCLUDE_vTaskDelay”用于启动或禁止任务延时功能;”config”,用于完成FreeRTOS的功能配置和裁剪,如”configUSE_TIMER”用于启用或禁止软件定时器功能;其他配置选项:用于调整和定制FreeRTOS内核的行为和特性。如”configTICK_RATE_HZ”用于配置内核的系统时钟频率。
第六步,配置好FreeConfig.h文件后,还有一个报错的信息。如下图所示。
报错内容显示,只有当选项配置为启动硬件浮点数支持时,才会支持此选项。如下图,在配置工程Target处将Floating Point Hardware处选择Single Precision,即可解决问题。 解决完报错信息后,便可以编写一个任务调度函数来进行检查。
3. APM32F411 FreeRTOS移植验证例程关键函数参数讲解及思考 3.1 关键函数讲解 PvTaskCode | 指向任务的人口函数,任务执行且***不会退出C函数(即:无线循环) | | | | 任务堆栈,每一个任务都有自己唯一的堆栈,当任务创建时由内核分配。如空闲任务堆栈的大小configMINIMAL_STACK_SIZE在FreeRTOS中被定义被130字节。 | | 传递给任务函数的值。这个任务函数接受类型为(void*)。 | | 定义任务执行的优先级。可以分配0(最低)到(configMAX_PRIORITIES-1),在FreeRTOS中,configMAX_PRIORITIES被定义为5。 | | 任务句柄,指向任务的唯一标识符的指针,保存任务控制块的首地址。当任务创建成功后,会返回此任务的任务句柄,可以用其来控制和管理任务。 |
xTaskCreateSchduler() 启动FreeRTOS调度程序运行。启动调度前,main函数将执行;启动调度后,只有中断和任务才会执行。启动任务调度后,最高任务优先级优先初始化并运行。
3.2 问题思考 当在编写验证函数时,当看到任务句柄这个参数时,我脑海中的第一反应,不就是个钩子函数么,但是当我在认真细看及研究后,发现自己的第一感觉是错误的,发现它是一个二级指针,接下来将对任务句柄参数的研究进行一个简单记录,大家可以一起参考学习。接下来,我们将一起看看任务句柄参数在FreeRTOS中的定义。
如上,任务句柄参数,用于传递创建的任务句柄,同时查看TaskHandle_t函数指针的指向发现,任务句柄包含创建任务时的状态信息,我们也可以理解为任务的ID。同时,结合下方的验证函数可以引出一个概念,二级指针。下面将对其中内容进行探究。 在C语言中,指针用于存储内存的地址。二级指针的本质则是指向指针的指针。它能存储另一个指针的地址。假设存在一个变量,用*可以定义指针变量,用&可以获取它的地址。当想要获取指针所指向的指针时(即解引用),在一级指针处加*,在二级指针处加**,以此类推即可。具体情况如下代码。 通过上面代码,它们的关系可以如下表格来进行表示。当我们设置一个变量a为6时,通过&a来获取当前变量a的地址,然后通过建立int的指针变量b来存储a的地址,并且通过&b来获取自身的地址,*b来解引用得到变量a地址中的数据,以此类推。同时,可以通过下面表格进行理解。 然后,我们来看FreeRTOS中xTaskCreate()创建任务函数中的任务句柄参数,通过一段模拟函数来类比这个工作过程,如下代码。
如上,在创建任务函数进行时,我们想要创建不同任务并保存,这时需要改变改变传入参数的内容,同时需要改变传入参数的地址。并且,可以通过解引用来修改其指向的内容。即,得到了TCB的首地址,便可知道这个任务的所有信息。
4. APM32F411 FreeRTOS移植验证例程关键函数 void vTaskLed2Toggle(void *pvParameters)
{
while(1)
{
/** Toggle LED2 */
APM_MINI_LEDToggle(LED2);
/** Task blocking time Delay */
vTaskDelay(500);
}
}
void vTaskLed3Toggle(void *pvParameters)
{
while(1)
{
/** Toggle LED2 */
APM_MINI_LEDToggle(LED3);
/** Task blocking time Delay */
vTaskDelay(500);
}
}
void vTaskUsartTest(void *pvParameters)
{
staticfloat num=0.00;
printf("welcomto test FreeRTOS in APM32F4xx\r\n");
while(1)
{
num+=0.01f;
printf("num的值是:%.4f\r\n",num);
vTaskDelay(1000);
}
}
static voidUserTaskCreate(void)
{
xTaskCreate(vTaskLed2Toggle,
"TaskLed2Toggle",
128,
NULL,
2,
&xHandleTaskLed2Toggle);
xTaskCreate(vTaskLed3Toggle,
"TaskLed3Toggle",
128,
NULL,
3,
&xHandleTaskLed3Toggle);
xTaskCreate(vTaskUsartTest,
"TaskUsartTest",
128,
NULL,
4,
&xHandleTaskUsartTest);
}
以上便是所有内容,欢迎大家在评论区讨论一起学习,谢谢!
|