南昌网站备案,wordpress正版主题,做外国的网站卖东西,wordpress前台在线编辑器一、前言 如果能看到这个教程的话#xff0c;说明大家已经学习嵌入式有一段时间了。还记得嵌入式在大多数时候指的是什么吗#xff1f;是的#xff0c;我们所说的学习嵌入式大部分时候都是在学习嵌入式操作系统。从简单的一些任务状态机再到复杂一些的RTOS#xff0c;再到最…一、前言 如果能看到这个教程的话说明大家已经学习嵌入式有一段时间了。还记得嵌入式在大多数时候指的是什么吗是的我们所说的学习嵌入式大部分时候都是在学习嵌入式操作系统。从简单的一些任务状态机再到复杂一些的RTOS再到最复杂的Linux这些都属于嵌入式操作系统的一种只是简单与复杂的区别。在之前我们开发STM32时采用的都是裸机开发所以对实时系统并没有什么概念接触RTOS会接触到一种新的编程方式。当然因为RTOS已经引入了系统的概念了所以代码看起来与调试起来也更加抽象。但就现在而言实时操作系统仍然是许多公司要求嵌入式工程师必会的技能之一。所以如果你准备好了就让我们一起来移植RTOS吧
二、在开始之前 因为已经涉及到嵌入式系统了所以还请学习这篇教程的小伙伴有一定的STM32基础我始终不推荐纯小白直接接触RTOS。在这篇教程中我会教大家如何下载RTOS的代码固件包如何将RTOS移植到对应的单片机中以及如何解决一些常见的问题。当然你也可以下载我下面给的资料资料中会包含本次会用到的RTOS源码包和我已经移植好的工程
RTOS移植资料https://pan.baidu.com/s/1YbfUm1LUSomslaGWqJ-g4w?pwdclxm 提取码clxm
三、芯片的选择 因为RTOS是一个嵌入式操作系统RTOS强调的是代码的实时性比起裸机开发它并不能提高芯片的性能相反它是一个消耗芯片性能的软件。在运行了RTOS以后我们芯片的资源就被占用了一部分这也会让我们的可编程范围变小了。既然是这样那为什么我们还需要嵌入式操作系统呢当然是为了实时性呀裸机在开发时代码始终顺序执行这也导致了我们有的步骤要等很久才会执行到在某些特定的情况下就可能出现问题。如果使用实时操作系统它会合理分配每一个任务的执行时间保证我们每一个任务都执行一段时间不会有任务长期阻塞程序。当然我们这次的重点并不是RTOS的原理如果想要了解RTOS详细原理与系统性的学习的话还是建议大家去看一些视频教程。这里话又说回来因为RTOS会消耗一部分的性能所以有的芯片可能无法运行RTOS这里我会使用STM32F407ZGT6进行RTOS的移植演示我并不推荐大家使用STM32F103C6T6单片机这款单片机在移植RTOS时可能会出现你无法解决的错误。在移植RTOS时尽量选择RAM与ROM都比较大的芯片。这样代码在编译时也不容易报错。
四、RTOS系统固件包的下载 RTOS的虽说是一个操作系统但是本质上还是代码构成的在这里面我们仍然可以看到.c .h文件。所以移植RTOS简单来说就是将对应的C语言代码在STM32中运行起来。所以我们现在需要下载RTOS的固件包这里我们直接在浏览器中搜索“FreeRTOS”: 我们可以看到这里搜索出来的第一个网站就是FreeRTOS的官网了 当然如果你没有找到FreeRTOS的官网的话也可以点击下方的链接前往
FreeRTOS官网FreeRTOS™ - FreeRTOS™
进入FreeRTOS的官网以后就可以看到以下页面了 如果你这里不是中文的可以点击右上角这里切换语言 接着我们点击网页中的“下载” 点击了下载以后弹出的窗口中会让我们选择要下载的版本 这里我推荐大家使用2022或者2020的版本这些版本经过了几年的迭代已经非常稳定了。如果你是小白的话建议下载和我一样的版本以保证文件的统一。
我们选择好版本以后直接点击“Download”: 随后浏览器就会弹出下载了 我们将其下载到我们能找到的地方 如果你这里无法打开RTOS的官网或者是无法下载RTOS的固件包那么你就可以打开我给的资料中的RTOS固件包文件夹这里有我已经下载好的固件包 下面我们再将下载的压缩包解压得到以下文件夹 至此我们RTOS系统的固件包就已经下载完成了。
五、RTOS的移植 当我们准备好了RTOS系统的固件包以后就可以开始移植了这里我们移植RTOS系统是在原本的工程之上所以首先就要保证我们有一个对应芯片的对应工程模板。我这里使用的是STM32F407ZGT6芯片所以准备的也是STM32F407ZGT6的工程如图 我们进入工程这里需要我们的工程编译没有错误 下面我们直接写一个LED的代码证明我们的硬件没有问题,这个地方的点灯代码很简单就不多说了我的LED在PA12口上并且为高电平点亮 将程序编译下载到芯片后就可以看到LED已经亮起了证明我们的硬件方面没有问题 下面我们就要在这个原本的工程上移植RTOS。
首先需要在工程的主目录下新建一个RTOS的文件夹用来存放RTOS的相关文件 我们进入这个RTOS的文件夹然后新建三个文件夹分别是“inc”“src”“port”: 这里的inc文件夹用来存放RTOS的头文件和配置文件src用来存放RTOS的源文件port用来存放RTOS的内存管理文件。
我们现在去RTOS固件包解压出来的文件夹中复制文件我们进入解压后的文件夹就可以看到以下文件夹和文件 这里我们再进入“FreeRTOSv202212.01”文件夹下的“FreeRTOS”文件夹可以看到以下文件和文件夹 然后我们再进入“FreeRTOS”文件夹下的“Source”文件夹这里面的文件就是我们要用的了 这里我们首先将“Source”文件夹下的所有.c的文件复制到刚才工程目录中创建的“RTOS\src”文件夹下 这里需要注意的是我们只需要复制.c多余的文件如果被复制过去了删除就行了。
随后我们再把“Source”文件夹下的“include”文件夹下的所有.h的文件复制到“RTOS\inc”文件夹下 这里同样的只要.h文件不能复制别的文件。
随后我们进入“Source”文件夹下的“portable”文件夹看到以下文件夹 这里包含了RTOS的内存管理文件和不同编译器的相关文件。这里我们首先来复制内存管理文件我们进入“portable”文件夹下的“MemMang”文件夹将“heap_4.c”文件复制到工程目录下的“RTOS\port下” 这里的内存管理文件我们一般都用4如果你是小白的话请不要随意修改。
随后我们再打开“portable”文件夹下的“RVDS”文件夹可以看到以下文件夹 这里面对应了RVDS集成编译环境不同的ARM内核的编译规则文件。因为我这里使用的是STM32F407ZGT6单片机所以这里首先肯定要选择M4内核因为STM32F407ZG系列都不附带MPU所以我们这里直接选择“ARM_CM4F”文件夹我们将“RVDS\ARM_CM4F”下的文件复制到工程目录下的“RTOS\port”下 至此我们RTOS的基本文件就已经复制完成了这里我们还需要复制一下配置文件。配置文件被放在了“FreeRTOSv202212.01\FreeRTOS\Demo”目录下进入这个目录我们就能看到非常多的芯片型号这些芯片官方都提供的相关的Demo,我们只需要在对应的芯片Demo中寻找配置文件即可 因为这里我使用的是STM32F407ZGT6的芯片所以我芯片所对应的配置文件就被存放在了“CORTEX_M4F_STM32F407ZG-SK”文件夹下。大家可以根据自己的芯片型号和对应的IDE寻找相关的Demo 这里我们进入“CORTEX_M4F_STM32F407ZG-SK”文件夹文件夹中的“FreeRTOSConfig.h”就是我们需要的配置文件了我们将其复制到工程目录下的“RTOS\inc”下 至此我们RTOS运行所需的所有文件都已经复制完成了我们直接打开工程 接着我们把刚才复制的文件添加的工程中点击菜单栏中的箱子 我们这里新建三个文件夹分别是“RTOS\inc”“RTOS\src”“RTOS\port”: 接着将对应文件夹中的文件添加进来这里一定要对应好不要添加错了 这里要注意的是一定是把对应的所有文件添加进来以后再进行下一步。
我们再在魔术棒中将对应文件夹的路径添加进来这里路径添加很基础就不细讲了 将文件添加进来以后我们点击编译这里的编译肯定会报错的我们慢慢来解决 这里的错误提示我们“configSYSTICK_CLOCK_HZ”这个变量没有定义。这里我们去到配置文件中大概在40行左右可以看到这样一条条件编译 这里是为了判断是否是使用IAR编译器我们这里使用的是keil这条条件编译肯定不会过的。我们将这一条条件编译修改一下改成下面这样
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) 这里修改了条件编译以后就可以兼容keilIAR, GCC编译器了。
我们再次编译出现三个重复定义的错误因为这三个函数在STM32原本的库中已经被定义过了但是在RTOS的库中又被定义了一次。既然我们要使用RTOS那当然也要用RTOS的处理函数这里我们直接将原本的函数注释掉 原本的函数被写在了“stm32f4xx_it.c”中我们分别将其注释掉通过报错我们可以得知这里被重复定义的函数分别是“PendSV_Handler”,“SVC_Handler”“SysTick_Handler” 注释后如图 这里将重复定义的函数注释掉以后我们再次编译我们可以看到这几个函数没有被定义 这里又需要我们修改配置文件了我们同样的打开配置文件我们将配置文件中的如下几项的值改为0
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configCHECK_FOR_STACK_OVERFLOW 0
#define configUSE_MALLOC_FAILED_HOOK 0 修改完配置文件以后我们再次编译 可以看到现在已经没有报错了我们现在就算是移植完成了我们可以写一点代码来试一下首先回到“main.c”,这里我们先在main.c中引入RTOS相关的头文件 #include freertos.h
#include task.h
然后我们创建一个任务函数 void LED(void* age)
{while(1){GPIO_ResetBits(GPIOA,GPIO_Pin_12);vTaskDelay(500);GPIO_SetBits(GPIOA,GPIO_Pin_12);vTaskDelay(500);}
}
这里就是我们的任务函数了控制了LED的亮灭注意任务函数进入以后一定是在一个死循环中任务函数不能返回不然可能引发一些错误。在使用了RTOS以后我们的所以延时都要使用RTOS中的相对延时。
在主函数中我们写引脚的初始化和任务的创建 int main(void)
{TaskHandle_t myTaskHandle_t;GPIO_InitTypeDef GPIO_InitStructure;delay_init(168);RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);GPIO_InitStructure.GPIO_Pin GPIO_Pin_12;GPIO_InitStructure.GPIO_Mode GPIO_Mode_OUT;GPIO_InitStructure.GPIO_OType GPIO_OType_PP;GPIO_InitStructure.GPIO_Speed GPIO_Speed_100MHz;GPIO_Init(GPIOA, GPIO_InitStructure);GPIO_SetBits(GPIOA,GPIO_Pin_12);xTaskCreate(LED,LED,128,NULL,2,myTaskHandle_t);vTaskStartScheduler();while(1){}
} 这里主要解释一下“xTaskCreate”函数。xTaskCreate用于创建RTOS中的任务。这里的第一个参数为任务函数的名称我们这里任务函数名为“LED”所以第一个参数就传入LED第二个参数是任务的名字要求传入字符串格式的我们这里传入一个字符串即可。第三个参数是为任务分配的内存我们这里的任务只是点灯而已所以不用分配太大直接128就已经很充足了。第四个参数是向任务中传入的参数我们这里没有参数要传入直接写NULL第五个参数是任务的优先级因为只有一个任务也不存在谁优先的问题随便写个优先级即可。最后要我们传入一个“TaskHandle_t ”类型的结构体指针我们直接定义一个结构体取它的地址传入即可。
随后我们再使用vTaskStartScheduler函数启动任务调度器。当调度器启动以后STM32就已经被系统接管了。
我们将代码编译下载到开发板中可以看到LED正常闪烁 至此我们的RTOS已经算是移植成功了。当然RTOS的知识还很多能够运用只是第一步。
六、结语 本次我们讲解了如何下载RTOS的固件包以及如何复制RTOS的相关文件以及在遇到错误以后如何解决。内容比较多还是希望大家多吸收一下。那么最后感谢大家的观看