STM32G431RBT6移植FreeRTOS

这篇具有很好参考价值的文章主要介绍了STM32G431RBT6移植FreeRTOS。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

引言: 本文专门为参加了蓝桥杯嵌入式赛道的同学准备, 大家可能会有这样一个问题, 比完赛之后, 对于像继续使用STM32G431RBT6学习FreeRTOS的, 发现网上的教程使用的板子基本上都是F1和F4的, 其实呢, 随便移植一下就能在我们自己的板子上面运行FreeTROS了。如果大家有ARM Linux的学习经历, 比如系统移植的基础, 那再来学这个FreeRTOS就比较容易了。

目录

一、FreeRTOS简介

二、什么是移植

三、移植实验开始

1.源码下载

2.源码目录结构简单分析

3.创建工程

4.开始移植

5.各种报错开始

四、创建几个任务看看移植效果

五、FreeRTOS为什么能进行裁剪

六、总结

七、FreeRTOS学习资源


STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

一、FreeRTOS简介

        首先看一下FreeRTOS 的名字,可以分为两部分:“Free”和“RTOS”,“F ree”就是免费的、自由的、不受约束的意思,“RTOSRTOS”全称是R eal Time Operating System System,中文名就是实时操作系统,要注意的是,RTOS 并不是值某一特定的操作系统,而是指一类操作系统,例如,µ C/OS OS,FreeRTOSFreeRTOS,RTXRTX,RT T hread 等这些都是RTOS 类的操作系统。因此,从FreeRTOS 的名字中就能看出,F reeROTS 是一款免费的实时操作系统。
        操作系统是允许多个任务“同时运行”的,操作系统的这个特性被称为多任务。然而实际上,一个CPU 核心在某一时刻只能运行一个任务,而操作系统中任务调度器的责任就是决定在某一时刻CPU 究竟要运行哪一个任务,任务调度器使得CPU 在各个任务之间来回切换并处理任务,由于切换处理任务的速度非常快,因此就给人造成了一种同一时刻有多个任务同时运行的错觉。
        操作系统的分类方式可以由任务调度器的工作方式决定,比如有的操作系统给每个任务分配同样的运行时间,时间到了就切换到下一个任务,Unix 操作系统就是这样的。RTOS 的任务调度器被设计为可预测的,而这正是嵌入式实时操作系统所需要的。在实时环境中,要求操作系统必须实时地对某一个事件做出响应,因此任务调度器的行为必须是可预测的。像F reeRTOS这种传统的RTOS 类操作系统是由用户给每个任务分配一个任务优先级,任务调度器就可以根据此优先级来决定下一刻应该运行哪个任务。
        FreeRTOS 是众多RTOS 类操作系统中的一种,F reeRTOS 十分的小巧,可以在资源有限的微控制器中运行,当然了,F reeRTOS 也不仅仅局限于在微控制器中使用。就单从文件数量上来看F reeRTOS 要比µ C/OS 少得多。

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

国内外常见的几种物联网操作系统: 

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

题外话: Linux和物联网操作系统的区别

Linux是一个通用的操作系统内核,最初由Linus Torvalds创建,用于各种计算设备,从个人电脑到服务器再到嵌入式系统。Linux内核是一个开放源代码项目,因此可以根据需要进行定制和修改。物联网操作系统则是专门为连接到互联网的物联网设备设计的操作系统,通常具有以下特点:

1. 资源受限性:物联网设备通常具有有限的处理能力、内存和存储空间,因此物联网操作系统需要具备轻量级和高效能的特性。

2. 实时性:物联网应用中的某些任务可能对时间敏感,需要在特定时间内完成。因此,一些物联网操作系统提供实时性能,以确保任务的及时执行。

3. 低功耗:许多物联网设备需要长时间运行,因此物联网操作系统需要优化能源消耗,以延长设备的电池寿命或降低能源成本。

4. 通信支持:物联网操作系统通常需要支持各种通信协议,如Wi-Fi、蓝牙、LoRa等,以便设备能够与其他设备或云平台进行通信。

5. 安全性: 物联网设备可能面临各种安全威胁,因此物联网操作系统需要提供安全功能,如数据加密。

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

上面这张图是基于LInux内核开发的几款操作系统。

二、什么是移植

当在嵌入式系统中从一个硬件平台或操作系统移植软件时,我们称之为移植(Porting)。移植意味着将软件(通常是操作系统、驱动程序或应用程序)从一个平台或环境移植到另一个平台或环境,使其能够在目标平台上运行。 移植通常涉及以下几个方面:

硬件适配:目标平台通常具有不同的处理器架构、外设、存储器和输入/输出接口等硬件特性。因此,移植过程需要对软件进行适配,以确保其能够与目标硬件兼容并正确运行。这可能涉及修改驱动程序或底层硬件抽象层(HAL)。

操作系统适配: 如果软件依赖于特定的操作系统,那么在将其移植到新平台时,需要确保目标平台上有相应的操作系统支持。如果目标平台上没有现成的操作系统支持,可能需要移植一个新的操作系统或调整现有操作系统以适应目标平台。

编译和链接: 移植软件可能需要调整编译器、链接器和构建工具链以适应目标平台的体系结构和工具集。

性能优化:在移植软件时,通常需要对性能进行优化,以确保在目标平台上能够达到合理的性能水平。这可能涉及调整算法、数据结构或代码结构,以充分利用目标平台的硬件资源。

功能兼容性:移植软件时需要确保其功能在目标平台上能够正常运行,并且与原始平台上的行为保持一致。

总的来说,移植是将软件从一个环境移植到另一个环境的过程,涉及到对硬件、操作系统、编译工具链和性能进行适配和优化,以确保软件能够在目标平台上正确运行。想象成人类的器官移植, 在移植之前是不是得适配才能正常的工作。

三、移植实验开始

        移植实验开始之前相信大家肯定都是有裸机开发的基础的, 提前说一下我对操作系统的理解, 没有装操作系统之前, 我们下载到单片机中运行的程序都叫做裸机程序, 那么, 操作系统又是什么呢, 其实操作系统就是第一个裸机程序, 它的作用是为应用程序的执行提供运行环境。如果在有人问题操作系统是什么, 你就可以说操作系统其实就是一个裸机程序, 为应用程序的运行提供运行的环境。对于Linux这样的通用型操作系统内核来说, 它的作用和上面一样, 但是还需要加上这几句话, 向上提供接口, 向下控制硬件, 它的几大功能模块分别是内存管理, 进程管理、文件系统、设备驱动、网络协议栈。

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

上面这张图就展示了Linux整体框架构图。

1.源码下载

官网: www.freertos.org

下载可能有些慢, 嫌慢的兄弟可以去码云下载。

2.源码目录结构简单分析

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

3.创建工程

这里使用cubeMx创建工程我就大致掠过了, 相信大家都是会的。

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

打开Keil工程

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

编译一下

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

接着去到源码目录下, 准备一个存放BSP相关代码的地方

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

头文件的地方我们也来一个

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

4.开始移植

去到FreeRTOS源码位置, 将内存管理, 和M4相关的代码拿到我们创建号的工程目录下

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

继续, 把下面的代码移植过去先

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

接着把FreeRTOS的头文件拿过来

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

其实这些步骤大家可以自己按照自己的习惯来,这些都不是关键的地方。

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

修改一下调试器相关的内容

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

到此我们先编译一下, 说找不到这个配置文件, 这个文件很重要, 稍后做出解释。

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

这个文件有几种办法获取, 第一自己编写, 需要对整个FreeRTOS的源码非常的熟悉, 不推荐, 第二去源码中找示例, 推荐。

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

将其拷贝到我们的工程目录的头文件路径下面去

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

又报错了, 头文件找不到

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

下问题, 找一下

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

这个位置, 存放cpu代码的目录下面有一个头文件, 加一下

5.各种报错开始

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

这个错误出现的原因是因为FreeRTOS的源码中因为需要匹配各种架构的cpu和板卡, 使用了大量的条件编译, 以达到根据条件编译的定义内容编译不同的架构的代码。

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

方便大家复制

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

继续报错STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

把FreeRTOSConfig.h文件包含在port.c文件中, 这样就能找到了

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

再次编译

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

又又报错了, 这次的原因是因为这几个异常的ISR定义重复了, 为什么会重复呢, 是因为在FreeRTOS的任务调度代码中就是利用了这几个异常的机制, 实现的任务每隔一个时间片调度依次任务。就是FreeRTOS定义了。

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

请看上图, 在FreeRTOS的配置文件中定义了, 所谓的配置文件, 没办法因为咱们嵌入式开发是没有啥子精美的界面的, 又不可能搞一个很漂亮的界面给我们自己根据cpu的架构, 板卡的资源信息自行选配, 所以就是用了大量的宏开关, 简单来说就是编译器在编译整个项目源码的时候, 会根据这些宏开关,或者说是符号的定义轻快选择不同的代码编译。

回到这几个ISR符号重复定义的问题, 解决办法是去到我们的xxx_it.c中注释掉这几个符号

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

再次编译

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

又又又报错了, 说这几个函数没有定义,是因为我们的配置文件选上了这些配置, 解决办法是去到配置文件中将相应的宏开关关闭, 这样在编译的使用就不编译这几个函数了。

修改前

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

修改后

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

其实还可以我们自己定义这些钩子函数, 其实就是回调函数, 是官方留给我们的接口, 可以自己定义在出现这些错误的时候, 做一些出错处理

再次编译

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

0error 0warning, nice, 恭喜, 大家马上接近成功了。为什么这样说呢, 是因为咱们的这个栈空间的设置是有问题的, 一会再最后给大家演示。

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

这个是因为我们再创建工程的时候没有用到adc uart timer等, 所以Mx没有拷贝对应的定以到工程中。我们自己添加一下

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

打开咱们使用到的

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

如果大家有移植的是由栈空间不够了,教大家怎么修改

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

但还是要基于我们的硬件来改。

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

内存布局:

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

四、创建几个任务看看移植效果

http://www.freertos.org

可以去FreeRTOS的官网查看API示例, 还是非常简单的这些函数

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

#include "main.h"
#include "bsp_led.h"
#include "FreeRTOS.h"
#include "task.h"
#include "bsp_uart.h"
#include <stdio.h>
#include "FreeRTOSConfig.h"
#include "lcd.h"

TaskHandle_t start_handle;
void start_task(void *arg);
void FreeRTOS_Entry(void);

int main(void)
{
	
	
	HAL_Init();
	SystemClock_Config();

	Led_Init();
	Uart_Init();
	
	FreeRTOS_Entry();
}
     



void FreeRTOS_Entry(void)
{
	BaseType_t retval;
	printf("1\r\n");
	 retval = xTaskCreate(      start_task,
								(const char *) " start_task",
								128,
								NULL,
								1,
								(TaskHandle_t *)&start_handle
                         );
	
	if(retval != pdPASS ) {
		Error_Handler();
	}
	printf("2\r\n");
	
	
	vTaskStartScheduler();
	printf("3\r\n");
	
	
}

void start_task(void *arg)
{
	
	while(1) {
		printf("task running\r\n");
	
		Led_Control(LED_ON, 1);
		Led_Control(LED_TOGGLE, 1);
		Led_Control(LED_TOGGLE, 3);
		Led_Control(LED_TOGGLE, 5);
		Led_Control(LED_TOGGLE, 7);
		
		vTaskDelay(1000);
	}
	
}

五、FreeRTOS为什么能进行裁剪

就是因为freeRtos根据不同的不同的硬件情况、包括不同的PCU架构, 不同的Flash SRAM大小, 

FreeRTOS还提供不同的内存分配算法。

#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H

/* 头文件 */
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include <stdint.h>

extern uint32_t SystemCoreClock;

/* 基础配置项 */
#define configUSE_PREEMPTION                            1                       /* 1: 抢占式调度器, 0: 协程式调度器, 无默认需定义 */
#define configUSE_PORT_OPTIMISED_TASK_SELECTION         1                       /* 1: 使用硬件计算下一个要运行的任务, 0: 使用软件算法计算下一个要运行的任务, 默认: 0 */
#define configUSE_TICKLESS_IDLE                         0                       /* 1: 使能tickless低功耗模式, 默认: 0 */
#define configCPU_CLOCK_HZ                              SystemCoreClock         /* 定义CPU主频, 单位: Hz, 无默认需定义 */
//#define configSYSTICK_CLOCK_HZ                          (configCPU_CLOCK_HZ / 8)/* 定义SysTick时钟频率,当SysTick时钟频率与内核时钟频率不同时才可以定义, 单位: Hz, 默认: 不定义 */
#define configTICK_RATE_HZ                              1000                    /* 定义系统时钟节拍频率, 单位: Hz, 无默认需定义 */
#define configMAX_PRIORITIES                            32                      /* 定义最大优先级数, 最大优先级=configMAX_PRIORITIES-1, 无默认需定义 */
#define configMINIMAL_STACK_SIZE                        128                     /* 定义空闲任务的栈空间大小, 单位: Word, 无默认需定义 */
#define configMAX_TASK_NAME_LEN                         16                      /* 定义任务名最大字符数, 默认: 16 */
#define configUSE_16_BIT_TICKS                          0                       /* 1: 定义系统时钟节拍计数器的数据类型为16位无符号数, 无默认需定义 */
#define configIDLE_SHOULD_YIELD                         1                       /* 1: 使能在抢占式调度下,同优先级的任务能抢占空闲任务, 默认: 1 */
#define configUSE_TASK_NOTIFICATIONS                    1                       /* 1: 使能任务间直接的消息传递,包括信号量、事件标志组和消息邮箱, 默认: 1 */
#define configTASK_NOTIFICATION_ARRAY_ENTRIES           1                       /* 定义任务通知数组的大小, 默认: 1 */
#define configUSE_MUTEXES                               1                       /* 1: 使能互斥信号量, 默认: 0 */
#define configUSE_RECURSIVE_MUTEXES                     1                       /* 1: 使能递归互斥信号量, 默认: 0 */
#define configUSE_COUNTING_SEMAPHORES                   1                       /* 1: 使能计数信号量, 默认: 0 */
#define configUSE_ALTERNATIVE_API                       0                       /* 已弃用!!! */
#define configQUEUE_REGISTRY_SIZE                       8                       /* 定义可以注册的信号量和消息队列的个数, 默认: 0 */
#define configUSE_QUEUE_SETS                            1                       /* 1: 使能队列集, 默认: 0 */
#define configUSE_TIME_SLICING                          1                       /* 1: 使能时间片调度, 默认: 1 */
#define configUSE_NEWLIB_REENTRANT                      0                       /* 1: 任务创建时分配Newlib的重入结构体, 默认: 0 */
#define configENABLE_BACKWARD_COMPATIBILITY             0                       /* 1: 使能兼容老版本, 默认: 1 */
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS         0                       /* 定义线程本地存储指针的个数, 默认: 0 */
#define configSTACK_DEPTH_TYPE                          uint16_t                /* 定义任务堆栈深度的数据类型, 默认: uint16_t */
#define configMESSAGE_BUFFER_LENGTH_TYPE                size_t                  /* 定义消息缓冲区中消息长度的数据类型, 默认: size_t */

/* 内存分配相关定义 */
#define configSUPPORT_STATIC_ALLOCATION                 0                       /* 1: 支持静态申请内存, 默认: 0 */
#define configSUPPORT_DYNAMIC_ALLOCATION                1                       /* 1: 支持动态申请内存, 默认: 1 */
#define configTOTAL_HEAP_SIZE                           ((size_t)(10 * 1024))   /* FreeRTOS堆中可用的RAM总量, 单位: Byte, 无默认需定义 */
#define configAPPLICATION_ALLOCATED_HEAP                0                       /* 1: 用户手动分配FreeRTOS内存堆(ucHeap), 默认: 0 */
#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP       0                       /* 1: 用户自行实现任务创建时使用的内存申请与释放函数, 默认: 0 */

/* 钩子函数相关定义 */
#define configUSE_IDLE_HOOK                             0                       /* 1: 使能空闲任务钩子函数, 无默认需定义  */
#define configUSE_TICK_HOOK                             0                       /* 1: 使能系统时钟节拍中断钩子函数, 无默认需定义 */
#define configCHECK_FOR_STACK_OVERFLOW                  0                       /* 1: 使能栈溢出检测方法1, 2: 使能栈溢出检测方法2, 默认: 0 */
#define configUSE_MALLOC_FAILED_HOOK                    0                       /* 1: 使能动态内存申请失败钩子函数, 默认: 0 */
#define configUSE_DAEMON_TASK_STARTUP_HOOK              0                       /* 1: 使能定时器服务任务首次执行前的钩子函数, 默认: 0 */

/* 运行时间和任务状态统计相关定义 */
#define configGENERATE_RUN_TIME_STATS                   0                       /* 1: 使能任务运行时间统计功能, 默认: 0 */
#if configGENERATE_RUN_TIME_STATS
#include "./BSP/TIMER/btim.h"
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()        ConfigureTimeForRunTimeStats()
extern uint32_t FreeRTOSRunTimeTicks;
#define portGET_RUN_TIME_COUNTER_VALUE()                FreeRTOSRunTimeTicks
#endif
#define configUSE_TRACE_FACILITY                        1                       /* 1: 使能可视化跟踪调试, 默认: 0 */
#define configUSE_STATS_FORMATTING_FUNCTIONS            1                       /* 1: configUSE_TRACE_FACILITY为1时,会编译vTaskList()和vTaskGetRunTimeStats()函数, 默认: 0 */

/* 协程相关定义 */
#define configUSE_CO_ROUTINES                           0                       /* 1: 启用协程, 默认: 0 */
#define configMAX_CO_ROUTINE_PRIORITIES                 2                       /* 定义协程的最大优先级, 最大优先级=configMAX_CO_ROUTINE_PRIORITIES-1, 无默认configUSE_CO_ROUTINES为1时需定义 */

/* 软件定时器相关定义 */
#define configUSE_TIMERS                                1                               /* 1: 使能软件定时器, 默认: 0 */
#define configTIMER_TASK_PRIORITY                       ( configMAX_PRIORITIES - 1 )    /* 定义软件定时器任务的优先级, 无默认configUSE_TIMERS为1时需定义 */
#define configTIMER_QUEUE_LENGTH                        5                               /* 定义软件定时器命令队列的长度, 无默认configUSE_TIMERS为1时需定义 */
#define configTIMER_TASK_STACK_DEPTH                    ( configMINIMAL_STACK_SIZE * 2) /* 定义软件定时器任务的栈空间大小, 无默认configUSE_TIMERS为1时需定义 */

/* 可选函数, 1: 使能 */
#define INCLUDE_vTaskPrioritySet                        1                       /* 设置任务优先级 */
#define INCLUDE_uxTaskPriorityGet                       1                       /* 获取任务优先级 */
#define INCLUDE_vTaskDelete                             1                       /* 删除任务 */
#define INCLUDE_vTaskSuspend                            1                       /* 挂起任务 */
#define INCLUDE_xResumeFromISR                          1                       /* 恢复在中断中挂起的任务 */
#define INCLUDE_vTaskDelayUntil                         1                       /* 任务绝对延时 */
#define INCLUDE_vTaskDelay                              1                       /* 任务延时 */
#define INCLUDE_xTaskGetSchedulerState                  1                       /* 获取任务调度器状态 */
#define INCLUDE_xTaskGetCurrentTaskHandle               1                       /* 获取当前任务的任务句柄 */
#define INCLUDE_uxTaskGetStackHighWaterMark             1                       /* 获取任务堆栈历史剩余最小值 */
#define INCLUDE_xTaskGetIdleTaskHandle                  1                       /* 获取空闲任务的任务句柄 */
#define INCLUDE_eTaskGetState                           1                       /* 获取任务状态 */
#define INCLUDE_xEventGroupSetBitFromISR                1                       /* 在中断中设置事件标志位 */
#define INCLUDE_xTimerPendFunctionCall                  1                       /* 将函数的执行挂到定时器服务任务 */
#define INCLUDE_xTaskAbortDelay                         1                       /* 中断任务延时 */
#define INCLUDE_xTaskGetHandle                          1                       /* 通过任务名获取任务句柄 */
#define INCLUDE_xTaskResumeFromISR                      1                       /* 恢复在中断中挂起的任务 */

/* 中断嵌套行为配置 */
#ifdef __NVIC_PRIO_BITS
    #define configPRIO_BITS __NVIC_PRIO_BITS
#else
    #define configPRIO_BITS 4
#endif

#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY         15                  /* 中断最低优先级 */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY    5                   /* FreeRTOS可管理的最高中断优先级 */
#define configKERNEL_INTERRUPT_PRIORITY                 ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#define configMAX_SYSCALL_INTERRUPT_PRIORITY            ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#define configMAX_API_CALL_INTERRUPT_PRIORITY           configMAX_SYSCALL_INTERRUPT_PRIORITY

/* FreeRTOS中断服务函数相关定义 */
#define xPortPendSVHandler                              PendSV_Handler
#define vPortSVCHandler                                 SVC_Handler

/* 断言 */
#define vAssertCalled(char, int) printf("Error: %s, %d\r\n", char, int)
#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ )

/* FreeRTOS MPU 特殊定义 */
//#define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0
//#define configTOTAL_MPU_REGIONS                                8
//#define configTEX_S_C_B_FLASH                                  0x07UL
//#define configTEX_S_C_B_SRAM                                   0x07UL
//#define configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY            1
//#define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS             1

/* ARMv8-M 安全侧端口相关定义。 */
//#define secureconfigMAX_SECURE_CONTEXTS         5

#endif /* FREERTOS_CONFIG_H */

 

六、总结

上述实验中虽然实现了将FreeRTOS移植到了比赛指定的板子上面, 但是由于SRAM的大小有限, 当代码量很大的时候就会出现硬件异常。所以咱们比赛使用的板子还是不适合移植FreeRTOS。

七、FreeRTOS学习资源

正点原子资料下载: 正点原子资料下载中心 — 正点原子资料下载中心 1.0.0 文档

B站教程

STM32G431RBT6移植FreeRTOS,物联网,嵌入式底层原理,stm32,嵌入式硬件,单片机

在这里对正点原子背后的工作人员、授课老师致以崇高的敬意。文章来源地址https://www.toymoban.com/news/detail-856029.html

到了这里,关于STM32G431RBT6移植FreeRTOS的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 解决STM32G431输出PWM扫频消失问题

            最近练习蓝桥杯嵌入式的题目,需要输出一个PWM扫频的信号,遇到了PWM变频率时有几率消失的问题, 下面来研究下原因和解决方案。          由于Keil怎么改设置都不肯给我看外设寄存器,下面用CubeIDE复现下PWM消失的情况,用ST-Link调试。         时钟倍频

    2024年04月10日
    浏览(49)
  • 蓝桥杯嵌入式CT117E-M4学习笔记02-STM32G431RBT6芯片学习

    首先学习了解一下蓝桥杯嵌入式CT117E-M4开发板的主控芯片STM32G431RBT6,本文仅为个人学习成果总结,如有错误,恳请指正。 上图为STM32CubeMX选型界面,如图可以看出STM32G431RBT6具有以下特点和硬件集成。 采用Cortex-M4 32位RISC核心架构,工作频率最高可达170Mhz。 128kBytes的FLASH,32

    2023年04月09日
    浏览(63)
  • STM32G070RBT6基于STM32CubeMX自动生成ADC输入电压采样工程全过程讲解

    📌相关篇《【硬件开源电路】STM32G070RBT6开发板》 🛠STM32CubeMX工程配置过程演示 📢Keil工程完成业务代码以及烧录演示放在资源中,gif文件过大无法上传。 📚工程概要 本工程是基于STM32CubeMX工具来配置项目,功能需求:在PA0引脚接入一个外部模拟量信号(单片机能承受的电

    2024年02月01日
    浏览(45)
  • 蓝桥杯电子类嵌入式(STM32G431)备赛学习记录(一)——LED

    2023年2月10日,距离第十四届蓝桥杯正式比赛还有不到两个月的样子,从今天开始正式备赛。之前博主有看过野火的教程,学的是STM32F103。蓝桥杯嵌入式组现在用的是STM32G431,板子在二手平台上买的,视频参考b站up主01Studio相关教程(后面提到简写为教程)。学习的模块按照教

    2024年01月25日
    浏览(72)
  • 解决keil5无法生成axf文件(国信长天STM32G431R8)

    我安装了keil5和STM32cubemx,这两个软件都是从官网下载,速度挺快的,参考博文如下: 【STM32】STM32 CubeMx使用教程一--安装教程_Z小旋的博客-CSDN博客 这里需要注意的就是Java版本一定要选对,我一般的处理方式就是全都 下载最新 的,基本上就不会出错。  Keil

    2024年02月05日
    浏览(57)
  • 蓝桥杯嵌入式基础模块——LCD显示器的基本使用(新板)STM32G431(HAL库开发)

            在蓝桥杯嵌入式官方给我们提供好了,LCD显示的底层源码,我们只需要,记住里面的API函数,会用这些函数就行。         在官方给的资料中找到这个文件名字DK117_G4 Data Packet-开发板驱动文件里面就是所有的底层文件有两种类型,一种是基于HAL库的一种是标准库

    2024年02月09日
    浏览(63)
  • [蓝桥杯嵌入式]STM32G431——第十二届第一场省赛停车计费系统真题及程序设计代码详解

    最近,我报名了今年的蓝桥杯嵌入式比赛,为此刷了一下以往的真题。以下是我对十二届蓝桥杯省赛真题的一些思路和心得,还有一些具体代码的实现。 1、相关模块 第十二届比赛主要用到的模块包括:LED、KEY、LCD、TIM、USART 2、重难点分析 这道题主要目的是做一个停车管理

    2024年01月18日
    浏览(96)
  • STM32 G431

    1.家族 STM32:32代表32位MCU,有32根地址线,可以寻找4GB的地址 STC15单片机是8位CPU,地址以16进制表示:0x_ _ ; STM32: 0x_ _ _ _ _ _ _ _ 容量为 2^32 = 4,294,967,296 ≈ 4×10^9 (其中 1GB = 10^9) 2.产品类别 G: 支持DSP和FPU指令的可适用信号应用 像正点原子的F4,F:基础型,通用型 3.特点功能 103

    2024年02月03日
    浏览(53)
  • STM32F105RBT6 -- RCC 系统时钟

    打开STM32Cube MX 软件可以找到STM32F105RBT6 的系统时钟树,数据手册里面缺失了,F103 和F105 系统时钟树有点区别的 STM32F103xx 的系统时钟树可以在《数据手册_STM32F103RCT6_ARMCORTEX-M3_72MHZ_2016-11-30.PDF》 资料里面找到,这pdf名字是我自己取的,可以去正点原子论坛找 startup_stm32f10x_hd.s 中

    2024年02月07日
    浏览(38)
  • STM32F105RBT6 使用定时器TIM3输出PWM波

    2.1 相关函数 RCC_APB1PeriphClockCmd、GPIO_Init、TIM_TimeBaseInit、TIM_OC4Init、TIM_OC4PreloadConfig、NVIC_Init、TIM_ITConfig、TIM_Cmd、 3.1 在启动文件里面找到TIM3 对应的中断入口函数,也就是中断服务函数 TIM3_IRQHandler 4.1 中断服务函数需要快速地执行完毕。中断服务函数应该避免执行太多的计算复

    2024年02月08日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包