FreeRTOS_Stm32F407系列单片机标准库移植

这里写目录标题

  • 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 undefinedportNVIC_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.mzph.cn/news/659449.shtml

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

相关文章

使用草料二维码表单功能,让数据收集更高效、规范

功能介绍 表单作为草料二维码的高级功能之一&#xff0c;可用于收集格式统一的数据。你可以通过组合姓名、图片、检查项等组件搭建出电子表单&#xff0c;关联到二维码中&#xff0c;扫码填写表单即可更快速、规范的收集数据。 这些数据保存在账号下形成动态档案&#xff0c;…

【 USRP 相控阵】X波段相控阵开发平台用户指南

包装 一共三件。 1、AD9081-FMCA-EBZ AD9081 MxFE Evaluation Board, https://www.analog.com/eval-ad9081 AD9081 的全功能评估板使用 ACE 软件进行控制的 PC 软件HMC7044 的板载时钟用于管理套件和 FPGA 时钟选择切换到外部直接时钟 AD9081-FMCA-EBZ 评估板包括以各种模…

CTF-WEB的入门真题讲解

EzLogin 第一眼看到这个题目我想着用SQL注入 但是我们先看看具体的情况 我们随便输入admin和密码发现他提升密码不正确 我们查看源代码 发现有二个不一样的第一个是base64 意思I hava no sql 第二个可以看出来是16进制转化为weak通过发现是个弱口令 canyouaccess 如果…

电镀槽槽号识别(接近开关BCD码检测)

电镀槽的槽号识别,常用方法有: 1、激光测量 2、8421码识别 3、伺服定位 4、RFID识别 这篇博客我们介绍利用接近开关和8421码检测识别槽号,电镀取放请求FC详细介绍可以查看下面博客: https://rxxw-control.blog.csdn.net/article/details/135536149https://rxxw-contr…

UE4 C++ 数据表

//基于结构体变量类型&#xff0c;创建数据表DataTable类型 USTRUCT(BlueprintType) struct FMyDataTableStruct : public FTableRowBase //把结构体变量公开到数据表类型 {GENERATED_BODY() //必须添加“GENERATED_BODY()”UPROPERTY(EditAnywhere, BlueprintReadWrite, Categ…

#RAG|NLP|Jieba|PDF2WORD# pdf转word-换行问题

文档在生成PDF时,文宁都发生了什么。本文讲解了配置对象、resources对象和content对象的作用,以及字体、宇号、坐标、文本摆放等过程。同时,还解释了为什么PDF转word或转文字都是一行一行的以及为什么页眉页脚的问题会加大识别难度。最后提到了文本的编码和PDF中缺少文档结构标…

hbuiderx+uniapp基于Android宠物饲养交流养宠系统 微信小程序3_reqva

3.2 APP需求分析 作为一款宠物饲养管理APP&#xff0c;面向的是大多数学者&#xff0c;软件的界面设计简洁清晰&#xff0c;用户可轻松掌握使用技巧。在调查之后&#xff0c;获得用户以下需求&#xff1a; &#xff08;1&#xff09;用户注册登录后&#xff0c;可进入系统解锁更…

Oracle 集群】RAC知识图文详细教程(四)--缓存融合技术和主要后台进程

Cache Fusion 原理 前面已经介绍了 RAC 的后台进程&#xff0c;为了更深入的了解这些后台进程的工作原理&#xff0c;先了解一下 RAC 中多节点对共享数据文件访问的管理是如何进行的。要了解 RAC 工作原理的中心&#xff0c;需要知道 Cache Fusion 这个重要的概念&#xff0c;要…

C#使用RabbitMQ-4_路由模式(直连交换机)

简介 RabbitMQ中的路由模式是一种根据Routing Key有条件地将消息筛选后发送给消费者的模式。在路由模式中&#xff0c;生产者向交换机发送消息时&#xff0c;会指定一个Routing Key。交换机接收生产者的消息后&#xff0c;根据消息的Routing Key将其路由到与Routing Key完全匹…

Win10 专业版WSL2 如何安装Ubuntu22.04

环境&#xff1a; Win10 专业版 19041 WSL2 Ubuntu22.04 问题描述&#xff1a; Win10 专业版WSL2 如何安装Ubuntu22.04 解决方案&#xff1a; 1.启用 WSL 相关功能&#xff1a; 打开cmd终端&#xff08;管理员权限&#xff09; 运行以下命令以启用虚拟机平台功能&#…

linux环境安装git、maven、jenkins等

重启 jenkins的命令&#xff1a; systemctl start jenkins 如果没有vim 命令 可以使用 yum install vim 安装 vim git 下载包地址 https://www.kernel.org/pub/software/scm/git/git-2.28.0.tar.gz 1.安装依赖环境&#xff1a; yum install -y curl-devel expat-devel ge…

CTFshow-pwn入门-栈溢出 (慢慢更

文章目录 pwn 35pwn 36pwn 37pwn 38pwn 39pwn 40 好几天没发博客了&#xff0c;忙着吃席去了 QAQ pwn 35 Partial RELRD,NX 开启 char dest;声明一个名为dest的字符变量。return strcpy(&dest, src);使用strcpy函数将src字符串复制到dest字符数组中&#xff0c;并返回指向…

【Vue】2-8、Axios 网络请求

cdn&#xff1a;<script src"https://unpkg.com/axios/dist/axios.min.js"></script> 注&#xff1a;使用 CDN 链接就可以不需要去下载对应的 js 文件到本地&#xff0c;只需要联网即可使用&#xff0c;可以减少项目的体积 <!DOCTYPE html> <…

【51单片机系列】中断优先级介绍及使用

文章来源&#xff1a;《51单片机原理及应用&#xff08;第3版&#xff09;》5.4节。 51单片机采用了自然优先级和人工设置高、低优先级的策略。 当CPU处理低优先级中断&#xff0c;又发生更高级中断时&#xff0c;此时中断处理过程如下图所示。 一个正在执行的低优先级中断服…

刷存在感,Excel转Protobuf/Json通用配置文件

使用场景 最近工作流中有将Excel转Protobuf作为配置文件的技术方案。具体实现是先定一个proto文件&#xff0c;再在一个对应excel表中定义对应字段&#xff0c;由策划在excel进行更改。proto文件可以生成对应语言的脚本&#xff0c;然后将excel转成对应protobuf的binary。 我…

Leetcode第382场周赛

Leetcode第382场周赛 本人水平有限&#xff0c;只做前三道。 一、按键变更的次数 给你一个下标从 0 开始的字符串 s &#xff0c;该字符串由用户输入。按键变更的定义是&#xff1a;使用与上次使用的按键不同的键。例如 s “ab” 表示按键变更一次&#xff0c;而 s “bBBb”…

Codeforces Round 922 (Div. 2 ABCDEF题)

A. Brick Wall Problem Statement A brick is a strip of size 1 k 1 \times k 1k, placed horizontally or vertically, where k k k can be an arbitrary number that is at least 2 2 2 ( k ≥ 2 k \ge 2 k≥2). A brick wall of size n m n \times m nm is such a…

Pandas进阶--map映射,分组聚合和透视pivot_table详解

文章目录 1.Pandas的map映射&#xff08;1&#xff09;映射&#xff08;2&#xff09;map充当运算工具 2.数据分组和透视&#xff08;1&#xff09;分组统计 - groupby功能 是pandas最重要的功能&#xff08;2&#xff09;聚合agg 3.透视表pivot_table&#xff08;1&#xff09…

小程序上的h5页面在web上面访问 页面基于vue

前提&#xff1a;BASE_URL: https://ded.toll.keeke.ai/ded-api/ 页面路径是&#xff1a;pages/webview/webview 参数是&#xff1a;id111 列表页跳转到详情页的方法是 toDetail(e) {wx.navigateTo({url: ../webview/webview?id e.currentTarget.dataset.oid})}, vue的映射…

【日常问题】Failed to enable unit: Unit file docker.service does not exist.

Failed to enable unit: Unit file docker.service does not exist. 1. 问题原因 笔者问题的产生是因为在ubuntu20.04下采用snapd安装的docker&#xff0c;因此 systemctl restart docker.servicesystemd并不能找到守护进程docker.service 同时使用docker命令时还会产生若干…