[APM32F4] 基于APM32F411 FreeRTOS的移植、验证及思考

[复制链接]
3358|20
 楼主| lzh12a3nf 发表于 2023-9-14 18:23 | 显示全部楼层 |阅读模式
本帖最后由 lzh12a3nf 于 2023-9-14 18:23 编辑

#申请原创#@21小跑堂
1、前言
  最近在学习FreeRTOS操作系统,刚好收到了极海的APM32F411开发板,于是整理一份APM32F411关于FreeRTOS源码移植、验证及过问题的思考记录,供大家参考学习。话不多说,接下来将讲解FreeRTOS的移植。

2、FreeRTOS移植
2.1、源码下载
第一步,首先到FreeRTOS官网下载对应的代码包。官网地址:www.freertos.org。打开后进行如下图对应操作即可下载FreeRTOS官网源代码。
1.png



  点击右上方的DownloadFreeRTOS,根据个人的需求,可以分别下载不同的源码包。本文应用到的版本号为:FreeRTOSv202212.01。
  第二步,将下载好的FreeRTOS源码包安装到Middleware文件夹下。如下图所示。
2.png

  第三步,将所需要的文件添加到工程中。如下图所示。
3.png
  接下来将对上面的移植文件进行简单的讲解。如下表格所示。
  
所处目录:...\Middlewares\FreeRTOS\FreeRTOSv202212.01\FreeRTOS\Source
  
文件名称
描述
courtine.c
实现协程(任务调度机制)功能。该文件包含协程任务的创建、调度和切换等相关函数。
event_groups.c
实现事件组的功能,用于多任务之间的事件同步和通信。它提供了一组位操作函数,用于设置、清除和等待事件位。
list.c
实现了链表数据结构。常用于任务列表,挂起列表等数据结构的管理。
queue.c
实现了队列的功能。队列是一种用于任务间消息传递的机制。常用于创建队列、发送消息、接收消息等操作。
stream_buffer.c
实现流缓冲区的功能。流缓冲区是一种用于高效数据交换的机制,适用于传感器数据、通信数据等的传输。
task.c
实现任务的功能,包括任务的创建、调度、切换、挂起等。
timers.c
实现了定时器(用于特定的事件间隔内执行任务)的功能,常用于创建定时器、启动定时器、停止定时器等操作。

  
所处目录: ...\Middlewares\FreeRTOS\FreeRTOSv202212.01\FreeRTOS\Source\portable\RVDS\ARM_CM4F
  
文件名称
描述
port.c
负责初始化和配置处理器、中断、任务切换以及其他与硬件相关的功能。

  
所处目录:...\Middlewares\FreeRTOS\FreeRTOSv202212.01\FreeRTOS\Source\portable\MemMang
  
文件名称
描述
head4.c
实现内存管理,管理可用的内存。常用于动态分配和释放任务堆栈和其他资源。


  第四步,.c文件添加完成后,对应添加.h头文件路径。如下图所示。
4.png
第五步,添加完成后。会出现如下图所示报错。
5.png
内容为找不到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文件后,还有一个报错的信息。如下图所示。
6.png
报错内容显示,只有当选项配置为启动硬件浮点数支持时,才会支持此选项。如下图,在配置工程Target处将Floating Point Hardware处选择Single Precision,即可解决问题。
7.png
解决完报错信息后,便可以编写一个任务调度函数来进行检查。

3.  APM32F411 FreeRTOS移植验证例程关键函数参数讲解及思考
3.1 关键函数讲解
8.png
  
PvTaskCode
  
指向任务的人口函数,任务执行且***不会退出C函数(即:无线循环)
pcName
任务名字。
usStackDepth
任务堆栈,每一个任务都有自己唯一的堆栈,当任务创建时由内核分配。如空闲任务堆栈的大小configMINIMAL_STACK_SIZE在FreeRTOS中被定义被130字节。
pvParameters
传递给任务函数的值。这个任务函数接受类型为(void*)。
UxPriority
定义任务执行的优先级。可以分配0(最低)到(configMAX_PRIORITIES-1),在FreeRTOS中,configMAX_PRIORITIES被定义为5。
pxCreatedTask
任务句柄,指向任务的唯一标识符的指针,保存任务控制块的首地址。当任务创建成功后,会返回此任务的任务句柄,可以用其来控制和管理任务。

  xTaskCreateSchduler()
  启动FreeRTOS调度程序运行。启动调度前,main函数将执行;启动调度后,只有中断和任务才会执行。启动任务调度后,最高任务优先级优先初始化并运行。

3.2 问题思考
当在编写验证函数时,当看到任务句柄这个参数时,我脑海中的第一反应,不就是个钩子函数么,但是当我在认真细看及研究后,发现自己的第一感觉是错误的,发现它是一个二级指针,接下来将对任务句柄参数的研究进行一个简单记录,大家可以一起参考学习。接下来,我们将一起看看任务句柄参数在FreeRTOS中的定义。
10.png

11.png

12.png
如上,任务句柄参数,用于传递创建的任务句柄,同时查看TaskHandle_t函数指针的指向发现,任务句柄包含创建任务时的状态信息,我们也可以理解为任务的ID。同时,结合下方的验证函数可以引出一个概念,二级指针。下面将对其中内容进行探究。
在C语言中,指针用于存储内存的地址。二级指针的本质则是指向指针的指针。它能存储另一个指针的地址。假设存在一个变量,用*可以定义指针变量,用&可以获取它的地址。当想要获取指针所指向的指针时(即解引用),在一级指针处加*,在二级指针处加**,以此类推即可。具体情况如下代码。
13.png
通过上面代码,它们的关系可以如下表格来进行表示。当我们设置一个变量a为6时,通过&a来获取当前变量a的地址,然后通过建立int的指针变量b来存储a的地址,并且通过&b来获取自身的地址,*b来解引用得到变量a地址中的数据,以此类推。同时,可以通过下面表格进行理解。
  
a
  
b
c
d
6
0x62fe1c
0x62fe10
0x62fe08
0x62fe1c
0x62fe10
0x62fe08
0x62fe00
然后,我们来看FreeRTOS中xTaskCreate()创建任务函数中的任务句柄参数,通过一段模拟函数来类比这个工作过程,如下代码。

14.png
如上,在创建任务函数进行时,我们想要创建不同任务并保存,这时需要改变改变传入参数的内容,同时需要改变传入参数的地址。并且,可以通过解引用来修改其指向的内容。即,得到了TCB的首地址,便可知道这个任务的所有信息。

4. APM32F411 FreeRTOS移植验证例程关键函数
  1. void vTaskLed2Toggle(void *pvParameters)
  2. {
  3.    while(1)
  4.     {
  5.        /** Toggle LED2 */
  6.        APM_MINI_LEDToggle(LED2);
  7.        /** Task blocking time Delay */
  8.        vTaskDelay(500);
  9.     }
  10. }

  11. void vTaskLed3Toggle(void *pvParameters)
  12. {
  13.    while(1)
  14.     {
  15.        /** Toggle LED2 */
  16.        APM_MINI_LEDToggle(LED3);
  17.        /** Task blocking time Delay */
  18.        vTaskDelay(500);
  19.     }
  20. }

  21. void vTaskUsartTest(void *pvParameters)
  22. {
  23.       staticfloat num=0.00;
  24.       printf("welcomto test FreeRTOS in APM32F4xx\r\n");
  25.       while(1)
  26.       {
  27.              num+=0.01f;
  28.              printf("num的值是:%.4f\r\n",num);
  29.              vTaskDelay(1000);
  30.        }
  31. }
  1. static voidUserTaskCreate(void)
  2. {
  3.     xTaskCreate(vTaskLed2Toggle,
  4.                 "TaskLed2Toggle",
  5.                  128,
  6.                  NULL,
  7.                  2,
  8.                  &xHandleTaskLed2Toggle);
  9.     xTaskCreate(vTaskLed3Toggle,
  10.                 "TaskLed3Toggle",
  11.                  128,
  12.                  NULL,
  13.                  3,
  14.                  &xHandleTaskLed3Toggle);
  15.                                          
  16.     xTaskCreate(vTaskUsartTest,
  17.                 "TaskUsartTest",
  18.                 128,
  19.                 NULL,
  20.                 4,
  21.                 &xHandleTaskUsartTest);
  22. }


  以上便是所有内容,欢迎大家在评论区讨论一起学习,谢谢!

      
田舍郎 发表于 2023-9-14 22:35 来自手机 | 显示全部楼层
有实践有总结值得学习
 楼主| lzh12a3nf 发表于 2023-9-14 23:14 | 显示全部楼层
田舍郎 发表于 2023-9-14 22:35
有实践有总结值得学习

vivilyly 发表于 2023-10-5 15:02 | 显示全部楼层
需要从FreeRTOS官方网站或GitHub仓库获取最新版本的FreeRTOS源代码。
maudlu 发表于 2023-10-5 15:26 | 显示全部楼层
将FreeRTOS源代码添加到项目中。确保将FreeRTOS的核心代码和移植层代码包含在项目中。通常,FreeRTOS提供了针对不同微控制器系列的移植文件
timfordlare 发表于 2023-10-5 15:40 | 显示全部楼层
FreeRTOS是一款轻量级的实时操作系统,适用于各种嵌入式系统的开发
beacherblack 发表于 2023-10-5 15:53 | 显示全部楼层
需要参考FreeRTOS的官方文档
vivilyly 发表于 2023-10-5 17:21 | 显示全部楼层
熟悉APM32F411芯片的硬件结构和软件环境。

下载并安装FreeRTOS的移植工具链,例如ARM Cortex-RTOS toolchain。

在移植工具链中设置APM32F411芯片的相关参数,如时钟频率、内存大小等。

编写FreeRTOS应用程序,并使用移植工具链进行编译。

在移植工具链中生成APM32F411芯片的可执行文件,并进行调试和测试。

对移植过程中遇到的问题进行分析和解决,确保FreeRTOS能够正常运行。
wwppd 发表于 2023-10-5 17:36 | 显示全部楼层
编写应用程序代码,创建任务,并使用FreeRTOS提供的API函数进行任务调度和管理。
timfordlare 发表于 2023-10-5 20:23 | 显示全部楼层
基于APM32F411的FreeRTOS移植需要以下步骤:

准备好基础工程,并且编译通过。
拷贝文件。
增加freertos源码到keil工程中。
修改编译问题。
修改SYSTEM文件和systick中断处理函数。
修改main文件,创建freertos任务。
houjiakai 发表于 2023-10-8 14:51 | 显示全部楼层
在工程中添加FreeRTOS配置文件FreeRTOSConfig.h,并根据需要配置FreeRTOS的各项参数。
uiint 发表于 2023-10-8 15:00 | 显示全部楼层
可以完成基于 APM32F411 的 FreeRTOS 移植。在实际操作过程中,可能需要根据具体硬件和应用场景进行适当调整。
claretttt 发表于 2023-10-8 15:08 | 显示全部楼层
在APM32F411上实现FreeRTOS的核心需要编写一些低级代码。这可能包括初始化内存管理,任务切换,中断处理等。对于Cortex-M系列处理器,FreeRTOS已经提供了相应的启动代码。
mnynt121 发表于 2023-10-8 16:01 | 显示全部楼层
freeRTOS是一个非常流行的实时操作系统(RTOS),广泛用于各种嵌入式系统和微控制器
ccook11 发表于 2023-10-8 16:17 | 显示全部楼层
使用FreeRTOS提供的API创建任务,例如xTaskCreate()。每个任务都应该有一个明确的入口点函数,该函数在任务启动时被调用。
mickit 发表于 2023-10-8 16:26 | 显示全部楼层
在工程中添加启动文件startup_apm32f411.s,并根据需要配置启动文件。
kmzuaz 发表于 2023-10-8 16:53 | 显示全部楼层
熟悉APM32F411芯片的硬件特性和寄存器配置。根据芯片的引脚分配和外设配置,初始化系统时钟、中断控制器、GPIO等必要的硬件。
pentruman 发表于 2023-10-8 17:10 | 显示全部楼层
由于FreeRTOS是面向嵌入式系统的操作系统,其API接口可能并不直接适用于APM32F411。因此,你需要编写一些封装函数,将FreeRTOS的API接口转化为适合APM32F411使用的形式。
usysm 发表于 2023-10-8 17:19 | 显示全部楼层
在工程中添加FreeRTOS配置文件FreeRTOSConfig.h,并根据需要配置FreeRTOS的各项参数。
backlugin 发表于 2023-10-8 17:54 | 显示全部楼层
取APM32F411芯片的数据手册和FreeRTOS源码。
在FreeRTOS源码中,找到port.c文件,并根据APM32F4
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

37

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部