FreeRTOS_Stm32F407系列单片机标准库移植

news2024/10/7 12:19:23

这里写目录标题

  • 1、下载FreeRTOS源码
    • 1.1github仓库下载
    • 1.2官网下载
    • 1.3百度网盘下载
  • 2、FreeRTOS移植
    • 2.1首先需要有一个可运行的标准库工程
    • 2.2在工程内创建一个FreeRTOS文件夹,然后在FreeRTOS文件夹中再新建port、include、src三个文件夹。
    • 2.3 port文件夹移植
    • 2.4 include文件夹移植
    • 2.5 src文件夹移植
    • 2.6 移植FreeRTOSConfig.h配置文件
    • 2.7 在keil中添加文件路径
    • 2.8 打开组文件夹管理,新建FreeRTOS组
    • 2.9 添加freeRTOS源文件
    • 2.10 编译排错
      • 1、先编译链接下工程
      • 2.根据下面图操作打开FreeRTOSConfig.h文件
      • 3、修改后我们再编译,发现上面那个错误解决了,又爆了下面几个错误:
      • 4、注释掉stm32f10x_it.c中的三个中断处理空函数
      • 5、再次编译
      • 6、再次编译,我这里不报错了。
  • 3、调试测试
  • 4.移植完成的工程

1、下载FreeRTOS源码

1.1github仓库下载

链接:FreeRTOS

下面的教程是基于从github下载压缩包进行的,最好下载这个或者直接看3.1,从我百度网盘下载。如果是别的下载源也问题不大,大同小异。

此时我们需要下载以下两个仓库,
在这里插入图片描述
点进去按下面的步骤下载就行了,另一个也是这样下。
在这里插入图片描述

1.2官网下载

链接: FreeRTOS官网

打开链接我们可以看到有两个下载选项,我们下载第一个就行。
下载速度较慢。
在这里插入图片描述

1.3百度网盘下载

链接:https://pan.baidu.com/s/1x00zgnJfCae75DpJ1W4RIg?pwd=1233
提取码:1233

若上述都不行可以直接私信。

2、FreeRTOS移植

2.1首先需要有一个可运行的标准库工程

在这里插入图片描述

2.2在工程内创建一个FreeRTOS文件夹,然后在FreeRTOS文件夹中再新建port、include、src三个文件夹。

  • port文件夹存放移植平台的相关文件
  • include文件夹存放FreeRTOS相关的头文件
  • src文件夹用来存放FreeRTOS相关的源码
  • 在这里插入图片描述
  • 在这里插入图片描述

2.3 port文件夹移植

  • 将下载的源码:FreeRTOS源码\FreeRTOS-Kernel-dc09a3dd5144c4033607565c71b9919900f95cff\ portable\ MemMang路径下的heap_4.c文件复制到自己创建的port文件夹中
  • 将FreeRTOS源码\FreeRTOS-Kernel-dc09a3dd5144c4033607565c71b9919900f95cff\ portable\ RVDS\ ARM_CM4F路径下的port.cportmacro.h文件复制到自己创建的port文件夹中

注:如果下载的源码是我这个版本的,那就去按着上面的路径找就可以,肯定能找到,如果是其他版本的,那就仔细找一找,或者直接去搜名字都行。

在这里插入图片描述

2.4 include文件夹移植

  • 将下载源码:FreeRTOS源码\FreeRTOS-Kernel-dc09a3dd5144c4033607565c71b9919900f95cff\ include路径下的所有头文件复制到自己创建的include文件夹中。
    在这里插入图片描述

2.5 src文件夹移植

  • 将FreeRTOS源码\FreeRTOS-Kernel-dc09a3dd5144c4033607565c71b9919900f95cff文件夹中的所有FreeRTOS相关.c文件复制到自己创建的src文件夹中
    在这里插入图片描述
    在这里插入图片描述

2.6 移植FreeRTOSConfig.h配置文件

  • 在下载源码:FreeRTOS源码\FreeRTOS-main\ FreeRTOS\ Demo\CORTEX_M4F_STM32F407ZG-SK路径下将FreeRTOSConfig.h文件复制到自己创建的FreeRTOS文件夹中

注:我所使用的单片机为F407VET6,但是在官方例程中F407系列的单片机仅有CORTEX_M4F_STM32F407ZG-SK这个,我们这里暂时就用这个就可以,差别不大。

在这里插入图片描述

2.7 在keil中添加文件路径

在keil中点击魔术棒,进入“C/C++”,在Include Paths中添加FreeRTO、src、inc、port路径。
在这里插入图片描述

2.8 打开组文件夹管理,新建FreeRTOS组

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

2.9 添加freeRTOS源文件

按下面的操作分别添加src文件夹和port文件夹下的所有.c文件

注意:下方图片仅演示了src文件夹下.c的添加过程,port文件夹下的heap_4.c和port.c也需要添加。

在这里插入图片描述

2.10 编译排错

1、先编译链接下工程

报如下错误:

..\FreeRTOS\port\port.c(813): error:  #20: identifier "SystemCoreClock" is undefined
          portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
..\FreeRTOS\port\port.c: 0 warnings, 1 error

根据上方信息可知SystemCoreClock未定义,但是在FreeRTOSConfig.h中使用了SystemCoreClock来标记MCU的频率。(未定义就使用

2.根据下面图操作打开FreeRTOSConfig.h文件

在这里插入图片描述
在这里插入图片描述
我们可以看到,SystemCoreClock在FreeRTOSConfig.h中是条件编译的,只有当定义了__ICCARM__时,才有效。

#ifdef __ICCARM__
	#include <stdint.h>
	extern uint32_t SystemCoreClock;
#endif

我们可以给他随便增加几个可以满足的条件编译,如下:

#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
	#include <stdint.h>
	extern uint32_t SystemCoreClock;
#endif

3、修改后我们再编译,发现上面那个错误解决了,又爆了下面几个错误:

compiling tasks.c...
linking...
.\Objects\111.axf: Error: L6200E: Symbol SVC_Handler multiply defined (by port.o and stm32f4xx_it_1.o).
.\Objects\111.axf: Error: L6200E: Symbol PendSV_Handler multiply defined (by port.o and stm32f4xx_it_1.o).
.\Objects\111.axf: Error: L6200E: Symbol PendSV_Handler multiply defined (by port.o and stm32f4xx_it_1.o).
Not enough information to list image symbols.
Not enough information to list load addresses in the image map.
Finished: 2 information, 0 warning and 3 error messages.
".\Objects\111.axf" - 3 Error(s), 0 Warning(s).
Target not created.
Build Time Elapsed:  00:00:01

这几个错误是说SVC_Handler、PendSV_Handler、PendSV_Handler被重复定义了
我们可以看到在我们移植的FreeRTOSConfig.h文件的最下面几行有如下几行宏定义。
在这里插入图片描述
这里的宏定义和我们原来工程中#include "stm32f4xx_it.c"文件中的中断处理函数void SVC_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);冲突了。

4、注释掉stm32f10x_it.c中的三个中断处理空函数

注释掉以下几个函数

void SVC_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);

在这里插入图片描述

5、再次编译

此时又有如下报错:

.\Objects\111.axf: Error: L6218E: Undefined symbol vApplicationMallocFailedHook (referred from heap_4.o).
.\Objects\111.axf: Error: L6218E: Undefined symbol vApplicationIdleHook (referred from tasks.o).
.\Objects\111.axf: Error: L6218E: Undefined symbol vApplicationStackOverflowHook (referred from tasks.o).
.\Objects\111.axf: Error: L6218E: Undefined symbol vApplicationTickHook (referred from tasks.o).
Not enough information to list image symbols.
Not enough information to list load addresses in the image map.
Finished: 2 information, 0 warning and 4 error messages.
".\Objects\111.axf" - 4 Error(s), 0 Warning(s).

发现这些未定义的函数都是Hook结尾的,这些函数有个共同的名称:钩子函数,这是报错就是因为在FreeRTOSConfig.h中开启了这些钩子函数,但是没有定义这些钩子函数导致的。我们在FreeRTOSConfig.h中将相应的宏定义改为0即可。这里将宏configUSE_IDLE_HOOK、configUSE_TICK_HOOK、configUSE_MALLOC_FAILED_HOOK和configCHECK_FOR_STACK_OVERFLOW定义为0。
在这里插入图片描述

6、再次编译,我这里不报错了。

若大家还有错误的话可以自行根据错误类型在互联网上查找并修改错误。

3、调试测试

因为我这里使用的是我字节画的一块核心板(只放了个RGB灯,没放普通的LED灯),所以我这里用FreeRTOS创建一个串口打印的任务来验证下。

  • 1.首先添加几个有关FreeRTOS基本操作的头文件
#include "freertos.h"
#include "task.h"
#include "timers.h"
  • 3.简单写一个串口1打印数据的任务
TickType_t PreTime;//定义变量,用来存储任务触发的时间

void usart_task(void *pvParams)
{
	Serial_Init();
	PreTime = xTaskGetTickCount();
	while(1)
	{
		printf("hello Worid!!!\r\n");
		vTaskDelayUntil(&PreTime,1000); /*用来准确演示1000MS*/
	}
}
  • 4.创建任务并启动调度
int main(void)
{
	xTaskCreate(usart_task,"serial",1024,NULL,4,NULL);
	vTaskStartScheduler();
}
  • 5.下载到开发板上进行测试,效果很好。

main文件中的全部代码为

#include "stm32f4xx.h"                  // Device header
#include "Serial.h"
#include "freertos.h"
#include "task.h"
#include "timers.h"

TickType_t PreTime;//定义变量,用来存储任务触发的时间

void usart_task(void *pvParams)
{
	Serial_Init();
	PreTime = xTaskGetTickCount();
	while(1)
	{
		printf("hello Worid!!!\r\n");
		vTaskDelayUntil(&PreTime,1000);
	}
}
int main(void)
{
	xTaskCreate(usart_task,"serial",1024,NULL,4,NULL);
	vTaskStartScheduler();
}

Serial.c



#include "Serial.h"


void usart1_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
		//初始化GPIO引脚,以及复用
	GPIO_InitTypeDef GPIO_struct_init;
	GPIO_struct_init.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;	//引脚
	GPIO_struct_init.GPIO_Mode = GPIO_Mode_AF;			//输出模式:复位
	GPIO_struct_init.GPIO_Speed = GPIO_Speed_25MHz;		//输出速度:中速
	GPIO_struct_init.GPIO_OType = GPIO_OType_PP;		//输出类型:推挽
	GPIO_struct_init.GPIO_PuPd = GPIO_PuPd_NOPULL;		//上下拉:不拉
	GPIO_Init(GPIOA, &GPIO_struct_init);
		//复位声明
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
	//配置嵌套向量表
	NVIC_InitTypeDef NVIC_InitTypeDef_init;
	NVIC_InitTypeDef_init.NVIC_IRQChannel = USART1_IRQn;		//中断通道都不一样,一定要记得去中断向量表找,具体的中断向量表如何寻找,可查看以前中断配置
	NVIC_InitTypeDef_init.NVIC_IRQChannelPreemptionPriority = 0;//抢占优先级
	NVIC_InitTypeDef_init.NVIC_IRQChannelSubPriority = 0;//响应优先级
	NVIC_InitTypeDef_init.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitTypeDef_init);
	
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);

		//初始化串口
	USART_InitTypeDef USART_InitStruct;
	USART_InitStruct.USART_WordLength = USART_WordLength_8b;			//字长
	USART_InitStruct.USART_Parity = USART_Parity_No;					//奇偶校验位
	USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;	//硬件流控制位
	USART_InitStruct.USART_StopBits = USART_StopBits_1;					//停止位
	USART_InitStruct.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;			//模式
	USART_InitStruct.USART_BaudRate = 115200;							//波特率(可手动设置,比如函数传参)
	USART_Init(USART1,&USART_InitStruct);
	//串口使能
	USART_Cmd(USART1, ENABLE);

}


void Serial_Sendbyte(USART_TypeDef* USARTx,uint8_t Byte) //串口发字符
{
	USART_SendData(USARTx,Byte);	
	while(USART_GetFlagStatus(USARTx,USART_FLAG_TXE)==RESET);
}
//===================================================================================================
int fputc(int ch,FILE *f)        //重构定向,printf直接打印到串口1
{
	Serial_Sendbyte(USART1,ch);
	return ch;
}//***************************************************************************************************

Serial.h

#ifndef __SERIAL_H__
#define __SERIAL_H__
#include "stm32f4xx.h"                  // Device header
#include <stdarg.h>
#include "stdio.h"
#include "string.h"

void usart1_Init(void);

#endif

4.移植完成的工程

链接:https://pan.baidu.com/s/1foc3N8TcdHcrd2NGo61asQ?pwd=1233
提取码:1233

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1426264.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android使用ScrollView导致鼠标点击事件无效

平台 测试平台: RK3288 Android8.1RK3588 Android 12 问题 首先, 这个问题的前提是, 使用的输入设备是**鼠标**, 普通的触摸屏并不会出现这个问题. 大致的流程是APP的UI布局中采用ScrollView作为根容器, 之后添加各类子控件, 在一起准备就绪后, 使用鼠标进行功能测试, 出现…

AD24-固定孔放置

1、固定孔放置的一般距离&#xff0c;分为金属和非金属 2、固定孔通过焊盘完成&#xff0c;放置焊盘&#xff0c;并将层修改为Multi Layer 焊盘与固定孔的等大小的 3、金属与非金属的区别 ①非金属 ②金属 4、设置固定孔放置的距离 5、通过复制粘贴即可完成其他孔的放置 6、导…

时间序列预测模型实战案例(二)(Holt-Winter)(Python)结合K-折交叉验证进行时间序列预测实现企业级预测精度(包括运行代码以及代码讲解)

目录 引言 数据格式 运行代码 Holt-Winters模型主体 程序入口 参数讲解 开始训练 预测结果 引言 话不多说上来先上预测精度分析图,其中MAE的误差大概在0.11,以下数据均是预测未知数据&#xff0c;而不是训练数据的预测图。 开始之前我们先来简单了解一下Holt-Winters…

数据结构+算法(第02篇):玩扫雷就是优化算法

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 学习必须往深处挖&…

网安渗透攻击作业(2)

sql注入第一关 一、部署 1、环境安装 &#xff08;1&#xff09;下载phpstudy&#xff0c;下载链接&#xff1a;小皮面板(phpstudy) - 让天下没有难配的服务器环境&#xff01; &#xff0c;安装过后打开软件进入如下界面&#xff0c;接着我们开启nginx和mysql 注意&#x…

Linux--Shell基础

学习笔记&#xff0c;记录以下课程中关于Linux的Shell基础知识。 黑马程序员linux入门到精通&#xff08;下部分&#xff09;_哔哩哔哩_bilibili 目录 1.编写规范 2.变量 2.1 变量的含义 2.2 变量的定义和使用 2.3 只读变量&#xff08;了解&#xff09; 2.4 接收用户输入…

Linux 命令 —— top

Linux 命令 —— top 相对于 ps 是选取一个时间点的进程状态&#xff0c;top 则可以持续检测进程运行的状态。使用方式如下&#xff1a; 用法&#xff1a; top [-d secs] | [-p pid] 选项与参数&#xff1a; -d secs&#xff1a;整个进程界面更新 secs 秒。默认是 5 5 5 秒。…

遇到ubuntu设置交叉编译环境的问题

今天交叉编译器一直没安装成功&#xff0c;环境变量也配置了还是不对&#xff0c;最后发现Ubuntu是64位的要装 然后就好了 另外在进行嵌入式Linux开发的时候&#xff0c;要把主机、虚拟机、以及开发板设置在同一网段下&#xff0c;虚拟机一般设成临时的就可以&#xff0c;但是…

力扣之2648.生成 斐波那契数列(yield)

/*** return {Generator<number>}*/ var fibGenerator function*() {let a 0,b 1;yield 0; // 返回 0&#xff0c;并暂停执行yield 1; // 返回 1&#xff0c;并暂停执行while(true) {yield a b; // 返回 a b&#xff0c;并暂停执行[a, b] [b, a b]; // 更新 a 和 …

使用Pycharm在本地调用chatgpt的接口

目录 1.安装环境 2.建立多轮对话的完整代码&#xff08;根据自己使用的不同代理需要修改端口&#xff08;port&#xff09;&#xff09; 3.修改代码在自己的Pycharm上访问chagpt的api并实现多轮对话&#xff0c;如果不修改是无法成功运行的。需要确定秘钥和端口以保证正常访…

使用pygame建立一个简单的使用键盘方向键移动的方块小游戏

import pygame import sys# 初始化pygame pygame.init()# 设置窗口大小 screen_size (640, 480) # 创建窗口 screen pygame.display.set_mode(screen_size) # 设置窗口标题 pygame.display.set_caption("使用键盘方向键移动的方块的简单小游戏")# 设置颜色 bg_colo…

CHS_08.2.3.6_1+生产者-消费者问题

CHS_08.2.3.6_1生产者-消费者问题 问题描述问题分析思考&#xff1a;能否改变相邻P、V操作的顺序&#xff1f;知识回顾 在这个小节中 我们会学习一个经典的进程同步互斥的问题 问题描述 并且尝试用上个小节学习的p v操作 也就是信号量机制来解决这个生产者消费者问题 问题的描…

基于GAN-CNN-CNN的鲁棒笔迹识别方法(三)

上一篇文章提出了一个用于笔迹识别(鉴别)的三段式模型,同时也提出了一个新数据集HTID_1,本文主要针对模型的最后一部分--笔迹识别,在HTID_1上进行实验. 数据集 实验前先介绍一下HTID_1. HTID_1是用于笔迹识别的数据集,是基于本文提出的模型制作而成的.将互联网上收集的740人笔…

Unity Shader 滚动进度条效果

Unity Shader 滚动进度条效果 前言项目场景布置导入图片修改场景设置修改图片尺寸即可调整进度 ASE连线 前言 UI要实现一个滚动进度&#xff0c;于是使用Shader制作一个。 项目 场景布置 导入图片 修改一下导入图片的格式&#xff0c;这样才能循环起来 WrapMode改为Repea…

2024/2/1学习记录

echarts 为柱条添加背景色&#xff1a; 若想设置折线图的点的样式&#xff0c;设置 series.itemStyle 指定填充颜色就好了&#xff0c;设置线的样式设置 lineStyle 就好了。 在折线图中倘若要设置空数据&#xff0c;用 - 表示即可&#xff0c;这对于其他系列的数据也是 适用的…

Windows11 用 HyperV 安装 Ubuntu-16.04 虚拟机

Windows11 用 HyperV 安装 Ubuntu-16.04 虚拟机 1. 确保已经开启HyperV2. 准备Ubuntu16.04镜像&#xff08;推荐64位的&#xff09;3. HyperV ->快速创建 -> 更改安装源 选刚刚下载的镜像&#xff08;.iso&#xff09;文件就好 -> 创建虚拟机[^1] 前提&#xff1a;VMw…

(硬核中的硬核)链路追踪落地过程中的挑战与解决方案

&#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是蓝胖子&#x1f947; ☁️博客首页&#xff1a;CSDN主页蓝胖子的编程梦 &#x1f304;每日一句&#xff1a;编程中我们会遇到多少挫折&#xff1f;表放弃&#xff0c;沙漠尽头必是绿洲。 大家好&#xff0c;我是蓝胖子…

【Qt加密播放器】登录窗口功能补充

输入框小设计 目的&#xff1a;实现鼠标点击输入框时的聚焦效果。 首先在LoginForm构造函数中为账号和密码输入框添加事件过滤器。关于事件过滤器的具体介绍可以参考这篇博文&#xff1a;Qt消息机制和事件 ui->nameEdit->installEventFilter(this); ui->pwdEdit->…

uniapp+微信小程序+nodejs问题记录

一、前言 通过uniapp进行微信小程序调试。服务端使用NodeJs。 二、报错统计 1、本地调试时微信小程序报错&#xff1a;request:Cannot send network request to localhost 解决方法&#xff1a; 【微信小程序开发平台】-【本地设置】-勾选“不校验合法域名、web-view、TLS版本…

Python完善APC netbotz 250报告功能实现主动式运维。

首先介绍一下APC netbotz 250, 这是施耐德推出的一款机架式监控主机&#xff0c;能够对所有IT环境进行经济有效而且灵活的监控&#xff0c;号称APC史上性价比最高的环境监测方案&#xff0c;这可不是我吹的&#xff0c;是APC官网的介绍&#xff0c;可参考下面的官网截图。 我们…