STM32系列单片机标准库移植FreeRTOS V10.4.6详解

news/2024/6/3 18:30:53 标签: 单片机, stm32, 嵌入式硬件

  文中所用到的资料下载地址 https://download.csdn.net/download/qq_20222919/87370679

  最近看正点原子新录制了手把手教你学FreeRTOS的视频教程,看了一下教程发现视频里面讲的是使用HAL移植 FreeRTOS V10.4.6 版本,以前的标准库移植的是FreeRTOS V9.0 版本。而自己平时写代码使用的都是标准库,就想着能不能把FreeRTOS V10.4.6 版移植到标准库中去。
  为了移植简单,直接下载正点原子的代码在上面修改。实现思路为,下载一个标准库函数的FreeRTOS V9.0版的程序,然后在下载一个HAL库函数的FreeRTOS V10.4.6 版的程序,然后将HAL库函数中FreeRTOS 相关代码直接拷贝到标准库函数中替换FreeRTOS相关代码。

准备资料

  首先去正点原子网站上下载源码,下载mini开发板和战舰开发板的资料。

在这里插入图片描述

  mini开发板里面有标准库函数的FreeRTOS代码,战舰开发板里面有HAL库函数的FreeRTOS代码。

  下载mini开发板资料,在mini开发板中找到扩展程序,在里面打开FreeRTOS例程,复制第一个程序到桌面。

在这里插入图片描述
在这里插入图片描述

  将文件夹重命名为FreeRTOS_demo

在这里插入图片描述

  随便打开一个FreeRTOS相关的文件,可以看到这个FreeRTOS的版本为V9.0

在这里插入图片描述

  下载战舰开发板资料,在战舰开发板中找到扩展程序,在里面打开FreeRTOS例程,一会要用到这些程序里面FreeRTOS相关代码。

在这里插入图片描述

  随便打开一个FreeRTOS相关的文件,可以看到这个FreeRTOS的版本为V10.4.6

在这里插入图片描述

开始移植

删除main函数中无用代码

  准备工作已经完成了,下面开始移植。打开桌面上FreeRTOS_demo工程。

在这里插入图片描述

  编译工程,确保工程文件的正确,接下来删除main文件中和FreeRTOS相关的代码和头文件。
  删除前代码如下:

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "FreeRTOS.h"
#include "task.h"
/************************************************
 ALIENTEK Mini STM32F103开发板 FreeRTOS实验2-1
 FreeRTOS移植实验-库函数版本
 技术支持:www.openedv.com
 淘宝店铺:http://eboard.taobao.com 
 关注微信公众平台微信号:"正点原子",免费获取STM32资料。
 广州市星翼电子科技有限公司  
 作者:正点原子 @ALIENTEK
************************************************/

//任务优先级
#define START_TASK_PRIO		1
//任务堆栈大小	
#define START_STK_SIZE 		128  
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);

//任务优先级
#define LED0_TASK_PRIO		2
//任务堆栈大小	
#define LED0_STK_SIZE 		50  
//任务句柄
TaskHandle_t LED0Task_Handler;
//任务函数
void led0_task(void *pvParameters);

//任务优先级
#define LED1_TASK_PRIO		3
//任务堆栈大小	
#define LED1_STK_SIZE 		50  
//任务句柄
TaskHandle_t LED1Task_Handler;
//任务函数
void led1_task(void *pvParameters);

int main(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4	 	 
	delay_init();	    				//延时函数初始化	  
	uart_init(115200);					//初始化串口
	LED_Init();		  					//初始化LED
	
	 
	//创建开始任务
    xTaskCreate((TaskFunction_t )start_task,            //任务函数
                (const char*    )"start_task",          //任务名称
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //任务句柄              
    vTaskStartScheduler();          //开启任务调度
}

//开始任务任务函数
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //进入临界区
    //创建LED0任务
    xTaskCreate((TaskFunction_t )led0_task,     	
                (const char*    )"led0_task",   	
                (uint16_t       )LED0_STK_SIZE, 
                (void*          )NULL,				
                (UBaseType_t    )LED0_TASK_PRIO,	
                (TaskHandle_t*  )&LED0Task_Handler);   
    //创建LED1任务
    xTaskCreate((TaskFunction_t )led1_task,     
                (const char*    )"led1_task",   
                (uint16_t       )LED1_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )LED1_TASK_PRIO,
                (TaskHandle_t*  )&LED1Task_Handler);         
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
}

//LED0任务函数 
void led0_task(void *pvParameters)
{
    while(1)
    {
        LED0=~LED0;
        vTaskDelay(500);
    }
}   

//LED1任务函数
void led1_task(void *pvParameters)
{
    while(1)
    {
        LED1=0;
        vTaskDelay(200);
        LED1=1;
        vTaskDelay(800);
    }
}


  删除后代码如下:

#include "led.h"
#include "delay.h"
#include "sys.h"
/************************************************
 ALIENTEK Mini STM32F103开发板 FreeRTOS实验2-1
 FreeRTOS移植实验-库函数版本
 技术支持:www.openedv.com
 淘宝店铺:http://eboard.taobao.com 
 关注微信公众平台微信号:"正点原子",免费获取STM32资料。
 广州市星翼电子科技有限公司  
 作者:正点原子 @ALIENTEK
************************************************/
int main(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4	 	 
	delay_init();	    				//延时函数初始化	  
	LED_Init();		  					//初始化LED
}

  再次编译工程,确保代码没有错误。

在这里插入图片描述

替换FreeRTOS文件

  接下来替换FreeRTOS相关文件。将FreeRTOS_demo工程中FreeRTOS文件夹中的所有文件全部删除。

在这里插入图片描述

  删除FreeRTOS V9.0 所有文件

在这里插入图片描述

  接下来打开战舰资料中的FreeRTOS例程。文件目录为:【正点原子】战舰STM32F103开发板V4 资料盘(A盘)\4,程序源码\3,扩展例程\2,FreeRTOS例程\FreeRTOS实验例程2 FreeRTOS移植实验\Middlewares\FreeRTOS

请添加图片描述

  打开FreeRTOS这个文件夹,将里面所有的文件复制到FreeRTOS_demo工程中FreeRTOS文件夹中。

在这里插入图片描述

复制初始化和配置文件

  接下来将 战舰STM32F103开发板V4 资料盘(A盘)\4,程序源码\3,扩展例程\2,FreeRTOS例程\FreeRTOS实验例程2 FreeRTOS移植实验\User 文件夹中freertos_demo.c、freertos_demo.h、FreeRTOSConfig.h 这三个文件复制到 FreeRTOS_demo这个工程的USER文件夹中。

在这里插入图片描述

修改代码

  打开 FreeRTOS_demo工程,可以看到此时FreeRTOS的版本已经成功替换为 V10.4.6版本了。

在这里插入图片描述
  将freertos_demo.c文件添加到USER文件夹中

在这里插入图片描述

  在main函数中添加 freertos_demo.h头文件,在初始化代码中添加freertos_demo();函数。

在这里插入图片描述

调试编译工程

  将工程文件全部编译,此时工程里面出现了好多错误。

在这里插入图片描述

  双击错误提示,跳转到代码中。

在这里插入图片描述

  这里主要是头文件的路径错误,将sys.h 和 usart.h前面的路径删除掉,再次编译。

在这里插入图片描述

  此时编译错误减少了,但是还有一个led.h的路径错误。双击错误提示,跳转到文件中。

在这里插入图片描述

  这个freertos_demo.c文件中是FreeRTOS任务相关的代码,正点原子的示例中用到了液晶屏和LED灯,在这里删除液晶屏相关代码,只保留LED灯相关代码。同时要修改LED头文件路径。

在这里插入图片描述

  删除文件中LCD相关的代码

在这里插入图片描述

  修改LED相关代码,修改后代码如下:

#include "freertos_demo.h"
#include "usart.h"
#include "led.h"

/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"

/******************************************************************************************************/
/*FreeRTOS配置*/

/* START_TASK 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define START_TASK_PRIO 1                   /* 任务优先级 */
#define START_STK_SIZE  128                 /* 任务堆栈大小 */
TaskHandle_t            StartTask_Handler;  /* 任务句柄 */
void start_task(void *pvParameters);        /* 任务函数 */

/* TASK1 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define TASK1_PRIO      2                   /* 任务优先级 */
#define TASK1_STK_SIZE  128                 /* 任务堆栈大小 */
TaskHandle_t            Task1Task_Handler;  /* 任务句柄 */
void task1(void *pvParameters);             /* 任务函数 */

/* TASK2 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define TASK2_PRIO      3                   /* 任务优先级 */
#define TASK2_STK_SIZE  128                 /* 任务堆栈大小 */
TaskHandle_t            Task2Task_Handler;  /* 任务句柄 */
void task2(void *pvParameters);             /* 任务函数 */

/******************************************************************************************************/


/**
 * @brief       FreeRTOS例程入口函数
 * @param       无
 * @retval      无
 */
void freertos_demo(void)
{
     xTaskCreate((TaskFunction_t )start_task,            /* 任务函数 */
                (const char*    )"start_task",          /* 任务名称 */
                (uint16_t       )START_STK_SIZE,        /* 任务堆栈大小 */
                (void*          )NULL,                  /* 传入给任务函数的参数 */
                (UBaseType_t    )START_TASK_PRIO,       /* 任务优先级 */
                (TaskHandle_t*  )&StartTask_Handler);   /* 任务句柄 */
    vTaskStartScheduler();
}

/**
 * @brief       start_task
 * @param       pvParameters : 传入参数(未用到)
 * @retval      无
 */
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           /* 进入临界区 */
    /* 创建任务1 */
    xTaskCreate((TaskFunction_t )task1,
                (const char*    )"task1",
                (uint16_t       )TASK1_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )TASK1_PRIO,
                (TaskHandle_t*  )&Task1Task_Handler);
    /* 创建任务2 */
    xTaskCreate((TaskFunction_t )task2,
                (const char*    )"task2",
                (uint16_t       )TASK2_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )TASK2_PRIO,
                (TaskHandle_t*  )&Task2Task_Handler);
    vTaskDelete(StartTask_Handler); /* 删除开始任务 */
    taskEXIT_CRITICAL();            /* 退出临界区 */
}

/**
 * @brief       task1
 * @param       pvParameters : 传入参数(未用到)
 * @retval      无
 */
void task1(void *pvParameters)
{
    while(1)
    {        
        LED0=!LED0;                                                  /* LED0闪烁 */
        vTaskDelay(100);                                               /* 延时1000ticks */
    }
}

/**
 * @brief       task2
 * @param       pvParameters : 传入参数(未用到)
 * @retval      无
 */
void task2(void *pvParameters)
{
    while(1)
    {
       LED1=!LED1;
        vTaskDelay(200);                           /* 延时1000ticks */
    }
}

  修改完成后再次编译工程,这时还有一个错误。

在这里插入图片描述

  双击错误提示,定位到代码中。

在这里插入图片描述

  错误提示声明语句不能出现在可执行语句之后。将这行代码移动到函数开始位置处。再次编译工程。

在这里插入图片描述

  这时候工程0错误,0警告。

下载验证

  在工程中可以看到正点原子的这个芯片用的是103RC系列的芯片,LED口为PA8和PD2口,如果自己有板子的话就可以下载程序验证了。

在这里插入图片描述

  电路板运行效果

请添加图片描述

  示波器测量LED波形。

请添加图片描述

  通过示波器波形可以看出,一个LED100ms闪烁一次,一个LED200ms闪烁一次。和代码中设置的一样,说明程序功能正常。FreeRTOS的移植已经成功了。

将工程移植到其他型号MCU上

  这个工程用只能用到STM32F103RC系列的MCU上,但是我们自己不一定都用的是这个系类的MCU,如果我们用的是其他系列的MCU,那么此时还需要将次工程移植到我们自己的MCU上去。

  下面就将这个工程移植到STM32F103C8T6芯片上去,首先将刚才的工程复制一份,并重命名。

在这里插入图片描述

  将工程重命名为 FreeRTOS_demo_103C8T6,打开工程。

修改单片机型号

  单击魔术棒按钮,选择Device选项,将单片机型号选为STM32F103C8

在这里插入图片描述

修改单片机类型

  由于STM32F103C8系列MCU是中等容量单片机,而工程默认的STM32F103RC系列MCU是大容量单片机,这里要在C/C++ 选项中将单片机宏定义的类型修改为STM32F10X_MD

在这里插入图片描述

修改下载文件

  选择debug选项,单击setting按钮,打开Flash Download 选项,选择这个512K的下载文件,然后单击Remove按钮,将默认的这个下载文件删除掉。

在这里插入图片描述

  单击Add按钮,添加新的下载文件。

在这里插入图片描述

  选择第一个128K的这个文件,然后单击下面Add按钮。

在这里插入图片描述

  此时新的下载文件就添加进来了,单击最下面的确定按钮。

在这里插入图片描述

  接着单击下面的OK按钮,保存设置。

在这里插入图片描述

替换启动文件

  在工程中CORE文件夹中的 startup_stm32f10x_hd.s 文件上单击鼠标右键,选择第二个删除当前文件。这个启动文件是大容量单片机的启动文件,需要将它替换为中等容量单片机的启动文件。

在这里插入图片描述

  在弹出的对话框中选择是

在这里插入图片描述

  在CORE文件夹上单击鼠标右键选择第三个选项,添加存在的文件到CORE分组中。

在这里插入图片描述

  打开当前项目中的CORE文件夹。

在这里插入图片描述

  选择文件夹中的 startup_stm32f10x_md.s文件,然后单击Add按钮,然后关闭窗口。

在这里插入图片描述
  此时启动文件就替换完成了。

在这里插入图片描述

编译下载

  编译工程

在这里插入图片描述

  没有错误和警告,但是此时还不能直接下载,因为这个项目的的LED的端口是PA8和PD2,而STM32F103C8T6这个MCU没有PD2端口,所以还需要修改LED文件。

在这里插入图片描述

  将LED端口初始化代码中的PD2端口修改为PC13,同时将时钟初始的PD口改为PC口。

在这里插入图片描述

  修改led.h头文件中的宏定义

在这里插入图片描述

  将头文件中的LED1修改为PC13,然后编译下载代码。
  电路板运行效果

请添加图片描述

  示波器测量LED波形

请添加图片描述

  通过示波器波形可以看出,一个LED灯每隔100ms闪烁一次,一个LED每隔200ms闪烁一次。说明程序已经正常运行了。

  到此为止,在标准库代码上移植FreeRTOS V10.4.6系统,和不同型号MCU的工程移植就全部完成了。


http://www.niftyadmin.cn/n/24958.html

相关文章

js写的一个简单的时间范围日历

该日历主要是提供一个思路,用以抛砖引玉 该日历从移动端更改而来,所以看着会比较小 日历中基于flex布局,全部使用div模拟 table 来实现,没有用 table 来布局 日历的周次列是固定的,这是基于自己需求来设定的&#x…

windows下安装不同版本Python教程

前言 博主也是很长一段时间没有更新文章了吧,因为最近都在忙着升级我的API管理系统,还有准备会考,时隔大概一个月,我带来了本次文章,如何在windows系统下安装多个版本Python,且各版本Python有不同的全局命…

SpringMVC 定义 Controller 的几种简单方式

实现 Controller 接口 可以通过实现 Controller 接口定义 Controller ,代码如下: Controller("/controller") public class HelloBeanNameUrlController implements Controller {Overrideprotected ModelAndView handleRequest(HttpServletRe…

【Linux工具】-vim介绍

Vim使用一,Vim的四种模式二,命令模式1,复制,剪切,粘贴2,撤销操作3,光标的移动4,替换,选中,删除5,h j k l键的使用6,多行注释,去多行注…

CSS学习总结

css&#xff0c;专门用来“美化”标签。基础CSS&#xff0c;写简单页面 & 看懂 & 改。模块&#xff0c;调整和修改。1、CSS应用方式1.1. 在标签上<img src"..." style"height:100px" /><div style"color:red;">中国联通<…

备受认可!中睿天下荣登“2022创业邦100未来独角兽”年度榜单

近日&#xff0c;由创业邦、复旦大学管理学院主办的2022创业邦100未来独角兽峰会暨创业邦年会在上海举办。在峰会现场&#xff0c;2022创业邦100未来独角兽榜单正式揭晓&#xff0c;中睿天下凭借出众的综合实力荣登榜单。作为一家以“实战对抗”为特点的能力价值型网络安全厂商…

第三章 Flink DataStream API

Flink 系列教程传送门 第一章 Flink 简介 第二章 Flink 环境部署 第三章 Flink DataStream API 第四章 Flink 窗口和水位线 第五章 Flink Table API&SQL 第六章 新闻热搜实时分析系统 一、DataStream API是什么&#xff1f; Flink 中的 DataStream 程序是对数据流&a…

import一个“太极”库,让Python代码提速100倍

目录 前言 计算素数的个数&#xff0c;速度x120 动态规划&#xff0c;速度x500 反应 - 扩散方程&#xff0c;效果惊人 pip install即可安装 前言 众所周知&#xff0c;Python的简单和易读性是靠牺牲性能为代价的—— 尤其是在计算密集的情况下&#xff0c;比如多重for循环。 …