FreeRTOS菜鸟入门(六)·移植FreeRTOS到STM32

目录

1.  获取裸机工程模版

2.  下载 FreeRTOS V9.0.0 源码

3.  FreeRTOS文件夹内容简介

3.1  FreeRTOS文件夹

3.1.1  Demo文件夹

3.1.2  License 文件夹

3.1.3  Source 文件夹

3.2  FreeRTOS-Plus 文件夹

4.  往裸机工程添加 FreeRTOS 源码

5.  拷贝 FreeRTOSConfig.h 文件到 user 文件夹

6.  添加 FreeRTOS 源码到工程组文件夹

6.1  新建 FreeRTOS/src 和 FreeRTOS/port 组

6.2  指定 FreeRTOS 头文件的路径

7.  修改 FreeRTOSConfig.h

8.  修改 stm32f10x_it.c


1.  获取裸机工程模版

        这里我使用的是STM32F103ZET6的开发板,找了一个点亮LED的工程模版进行更改,自己随便找一个模版都行,没必要一定一样:

STM32f103ZET6移植工程模版资源-CSDN文库

2.  下载 FreeRTOS V9.0.0 源码

        在移植之前,我们首先要获取到 FreeRTOS 的官方的源码包。这里我们提供两个下载链接:

官网链接:www.freertos.org

代码托管网站:sourceforge.net

        打开网站链接之后,我们选择 FreeRTOS 的最新版本 V9.0.0(2016 年),尽管现在 FreeRTOS 的版本已经更新到 V10.0.1 了,但是我们还是选择 V9.0.0,因为内核很稳定,并且网上资料很多,因为 V10.0.0 版本之后是亚马逊收购了 FreeRTOS 之后才出来的版本,主要添加了一些云端组件:

        点击 V9.0.0 会跳转到版本目录。这里有 zip 和 exe 格式的压缩包,其实都是 FreeRTOS 的源码,只是压缩的格式不一样,所以大小也不一样,我们这里选择 zip 的下载,点击了就会出现下载的链接,下载完成解压后就可以得到我们想要的 FreeRTOS V9.0.0 版本的源码了:

有时候网站打不开,所以附带一个百度网盘的链接:

链接: https://pan.baidu.com/s/1G4ezuX0Thwy-kUarMqYYFg?pwd=svii

提取码: svii 

需要注意一点,该文件可能路径过长电脑自带的解压文件可能无法解压,试验过360解压的软件能解压,如果是在无法解压,后续也会附上配置好的文件。

3.  FreeRTOS文件夹内容简介

3.1  FreeRTOS文件夹

        FreeRTOS 包含 Demo 例程和内核源码(比较重要,我们就需要提取该目录下的大部分文件):

        FreeRTOS 文件夹下的 Source 文件夹里面包含的是 FreeRTOS 内核的源代码,我们移植 FreeRTOS 的时候就需要这部分源代码;FreeRTOS 文件夹下的Demo 文件夹里面包含了FreeRTOS 官方为各个单片机移植好的工程代码,FreeRTOS 为了推广自己,会给各种半导体厂商的评估板写好完整的工程程序,这些程序就放在 Demo 这个目录下,这部分 Demo 非常有参考价值。我们把 FreeRTOS 到 STM32 的时候,FreeRTOSConfig.h 这个头文件就是从这里拷贝过来的。

3.1.1  Demo文件夹

        这个目录下内容就是 Deme 例程,我们可以直接打开里面的工程文件,各种开发平台的完整 Demo,开发者可以方便的以此搭建出自己的项目,甚至直接使用。FreeRTOS 当然也为 ST 写了很多 Demo,其中就有 F1、F4、F7 等工程,这样子对我们学习 FreeRTOS 是非常方便的,当遇到不懂的直接就可以参考官方的 Demo:

3.1.2  License 文件夹

        这里面只有一个许可文件“license.txt”,用 FreeRTOS 做产品的话就需要看看这个文件,但是我们是学习 FreeRTOS,所以暂时不需要理会这个文件。

3.1.3  Source 文件夹

        这里我们再重点分析下 FreeRTOS/ Source 文件夹下的文件,其中include文件和下图框柱的文件包含的是FreeRTOS 的通用的头文件和 C 文件这两部分的文件试用于各种编译器和处理器,是通用的。

        而需要移植的头文件和 C文件放在portblle 这个文件夹:

        我们打开 portblle 这个文件夹,可以看到里面很多与编译器相关的文件夹,在不同的编译器中使用不同的支持文件:

        KEIL 就是我们就是我们使用的编译器,当年打开 KEIL 文件夹的时候,你会看到一句话“See-also-the-RVDS-directory.txt”,其实 KEIL里面的内容跟 RVDS 里面的内容一样,所以,我们只需要编号RVDS 文件夹里面的内容即可。而编号MemMang 文件夹下存放的是跟内存管理相关的。

        打开 RVDS 文件夹,下面包含了各种处理器相关的文件夹,从文件夹的名字我们就非常熟悉了,我们学习的 STM32 有 M0、M3、M4 等各种系列,FreeRTOS 是一个软件,单片机是一个硬件,FreeRTOS 要想运行在一个单片机上面,它们就必须关联在一起,那么怎么关联?还是得通过写代码来关联,这部分关联的文件叫接口文件,通常由汇编和 C 联合编写。这些接口文件都是跟硬件密切相关的,不同的硬件接口文件是不一样的,但都大同小异。编写这些接口文件的过程我们就叫移植,移植的过程通常由 FreeRTOS 和 mcu 原厂的人来负责,移植好的这些接口文件就放在 RVDS 这个文件夹的目录下:

        MemMang 文件夹下存放的是跟内存管理相关的,总共有五个 heap 文件以及一个 readme 说明文件,这五个 heap 文件在移植的时候必须使用一个,因为 FreeRTOS 在创建内核对象的时候使用的是动态分配内存,而这些动态内存分配的函数则在这几个文件里面实现,不同的分配算法会导致不同的效率与结果,后面在内存管理中我们会讲解每个文件的区别,由于现在是初学,所以我们选用 heap4.c 即可:

3.2  FreeRTOS-Plus 文件夹

        FreeRTOS-Plus 文件夹里面包含的是第三方的产品,一般我们不需要使用,FreeRTOSPlus 的预配置演示项目组件(组件大多数都要收费),大多数演示项目都是在 Windows 环境中运行的,使用 FreeRTOS windows 模拟器,所以暂时不需要关注这个文件夹。

4.  往裸机工程添加 FreeRTOS 源码

        首先在我们的STM32 裸机工程模板根目录下新建一个文件夹,命名 为“FreeRTOS”,并且在 FreeRTOS 文件夹下新建两个空文件夹,分别命名为“src”与“port”,src 文件夹用于保存 FreeRTOS 中的核心源文件,也就是我们常说的‘.c 文件’,port 文件夹用于保存内存管理以及处理器架构相关代码,这些代码FreeRTOS 官方已经提供给我们的,直接使用即可,在前面已经说了,FreeRTOS是软件,我们的开发版是硬件,软硬件必须有桥梁来连接,这些与处理器架构相关的代码,可以称之为 RTOS 硬件接口层,它们位于 FreeRTOS/Source/Portable 文件夹下。

        打开 FreeRTOS V9.0.0 源码,在“FreeRTOSv9.0.0\FreeRTOS\Source”目录下找到所有的‘.c 文件’:

        打开 FreeRTOS V9.0.0 源码,在“FreeRTOSv9.0.0\FreeRTOS\Source\portable”目录下找到“MemMang”文件夹与“RVDS”文件夹,将它们拷贝到我们新建的 port 文件夹中,具体见:

        打开 FreeRTOS V9.0.0 源码,在“FreeRTOSv9.0.0\ FreeRTOS\Source”目录下找到“include”文件夹,它是我们需要用到 FreeRTOS 的一些头文件,将它直接拷贝到我们新建的 FreeRTOS 文件夹中,完成这一步之后就可以看到我们新建的 FreeRTOS 文件夹已经有 3 个文件夹,这 3个文件夹就包含 FreeRTOS 的核心文件,至此,FreeRTOS 的源码就提取完成:

5.  拷贝 FreeRTOSConfig.h 文件到 user 文件夹

        FreeRTOSConfig.h 文件是 FreeRTOS 的工程配置文件,因为 FreeRTOS 是可以裁剪的实时操作内核,应用于不同的处理器平台,用户可以通过修改这个 FreeRTOS 内核的配置头文件来裁剪 FreeRTOS 的功能,所以我们把它拷贝一份放在 user 这个文件夹下面。

        打开 FreeRTOSv9.0.0 源码,在“FreeRTOSv9.0.0\FreeRTOS\Demo”文件夹下面找到“ CORTEX_STM32F103_Keil ” 这个文件夹 ,双击打开 , 在其根目录下找到这个“FreeRTOSConfig.h”文件,然后拷贝到我们工程的 user 文件夹下即可,等下我们需要对这个文件进行修改。user 文件夹,见名知义我们就可以知道里面存放的文件都是用户自己编写的。

6.  添加 FreeRTOS 源码到工程组文件夹

        在上一步我们只是将 FreeRTOS 的源码放到了本地工程目录下,还没有添加到开发环境里面的组文件夹里面,FreeRTOS 也就没有移植到我们的工程中去。

6.1  新建 FreeRTOS/src 和 FreeRTOS/port 组

        接下来我们在开发环境里面新建 FreeRTOS/src 和 FreeRTOS/port 两个组文件夹:

        其中FreeRTOS/src 用于存放 src 文件夹的内容:

        FreeRTOS/port 用于存放 port\MemMang 文件夹与 port\RVDS\ARM_CM3文件夹的内容:

        添加完成如下:

        再将FreeRTOSConfig.h文件,放到user文件夹下:

6.2  指定 FreeRTOS 头文件的路径

        FreeRTOS 的源码已经添加到开发环境的组文件夹下面,编译的时候需要为这些源文件指定头文件的路径,不然编译会报错。FreeRTOS 的源码里面只有 FreeRTOS\include 和 FreeRTOS\port\RVDS\ARM_CM3这两个文件夹下面有头文件,只需要将这两个头文件的路径在开发环境里面指定即可。同时我们还将 FreeRTOSConfig.h 这个头文件拷贝到了工程根目录下的 user 文件夹下,所以 user 的路径也要加到开发环境里面:

7.  修改 FreeRTOSConfig.h

        FreeRTOSConfig.h 是直接从 demo 文件夹下面拷贝过来的,该头文件对裁剪整个 FreeRTOS 所需的功能的宏均做了定义,有些宏定义被使能,有些宏定义被失能,一开始我们只需要配置最简单的功能即可。要想随心所欲的配置 FreeRTOS 的功能,我们必须对这些宏定义的功能有所掌握,下面我们先简单的介绍下这些宏定义的含义,然后再对这些宏定义进行修改。

/*FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.All rights reservedVISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.This file is part of the FreeRTOS distribution.FreeRTOS is free software; you can redistribute it and/or modify it underthe terms of the GNU General Public License (version 2) as published by theFree Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.***************************************************************************>>!   NOTE: The modification to the GPL is included to allow you to     !<<>>!   distribute a combined work that includes FreeRTOS without being   !<<>>!   obliged to provide the source code for proprietary components     !<<>>!   outside of the FreeRTOS kernel.                                   !<<***************************************************************************FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANYWARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESSFOR A PARTICULAR PURPOSE.  Full license text is available on the followinglink: http://www.freertos.org/a00114.html****************************************************************************                                                                       **    FreeRTOS provides completely free yet professionally developed,    **    robust, strictly quality controlled, supported, and cross          **    platform software that is more than just the market leader, it     **    is the industry's de facto standard.                               **                                                                       **    Help yourself get started quickly while simultaneously helping     **    to support the FreeRTOS project by purchasing a FreeRTOS           **    tutorial book, reference manual, or both:                          **    http://www.FreeRTOS.org/Documentation                              **                                                                       ****************************************************************************http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by readingthe FAQ page "My application does not run, what could be wrong?".  Have youdefined configASSERT()?http://www.FreeRTOS.org/support - In return for receiving this top qualityembedded software for free we request you assist our global community byparticipating in the support forum.http://www.FreeRTOS.org/training - Investing in training allows your team tobe as productive as possible as early as possible.  Now you can receiveFreeRTOS training directly from Richard Barry, CEO of Real Time EngineersLtd, and the world's leading authority on the world's leading RTOS.http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,including FreeRTOS+Trace - an indispensable productivity tool, a DOScompatible FAT file system, and our tiny thread aware UDP/IP stack.http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to HighIntegrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOSlicenses offer ticketed support, indemnification and commercial middleware.http://www.SafeRTOS.com - High Integrity Systems also provide a safetyengineered and independently SIL3 certified version for use in safety andmission critical applications that require provable dependability.*/#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H#include "stm32f10x.h"
#include "Usart.h"//针对不同的编译器调用不同的stdint.h文件
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)#include <stdint.h>extern uint32_t SystemCoreClock;
#endif//断言
#define vAssertCalled(char,int) printf("Error:%s,%d\r\n",char,int)
#define configASSERT(x) if((x)==0) vAssertCalled(__FILE__,__LINE__)/*************************************************************************               FreeRTOS基础配置配置选项 *********************************************************************/
/* 置1:RTOS使用抢占式调度器;置0:RTOS使用协作式调度器(时间片)* * 注:在多任务管理机制上,操作系统可以分为抢占式和协作式两种。* 协作式操作系统是任务主动释放CPU后,切换到下一个任务。* 任务切换的时机完全取决于正在运行的任务。*/
#define configUSE_PREEMPTION					  1//1使能时间片调度(默认式使能的)
#define configUSE_TIME_SLICING					1		/* 某些运行FreeRTOS的硬件有两种方法选择下一个要执行的任务:* 通用方法和特定于硬件的方法(以下简称“特殊方法”)。* * 通用方法:*      1.configUSE_PORT_OPTIMISED_TASK_SELECTION 为 0 或者硬件不支持这种特殊方法。*      2.可以用于所有FreeRTOS支持的硬件*      3.完全用C实现,效率略低于特殊方法。*      4.不强制要求限制最大可用优先级数目* 特殊方法:*      1.必须将configUSE_PORT_OPTIMISED_TASK_SELECTION设置为1。*      2.依赖一个或多个特定架构的汇编指令(一般是类似计算前导零[CLZ]指令)。*      3.比通用方法更高效*      4.一般强制限定最大可用优先级数目为32* 一般是硬件计算前导零指令,如果所使用的,MCU没有这些硬件指令的话此宏应该设置为0!*/
#define configUSE_PORT_OPTIMISED_TASK_SELECTION	        1                       /* 置1:使能低功耗tickless模式;置0:保持系统节拍(tick)中断一直运行* 假设开启低功耗的话可能会导致下载出现问题,因为程序在睡眠中,可用以下办法解决* * 下载方法:*      1.将开发版正常连接好*      2.按住复位按键,点击下载瞬间松开复位按键*     *      1.通过跳线帽将 BOOT 0 接高电平(3.3V)*      2.重新上电,下载*    * 			1.使用FlyMcu擦除一下芯片,然后进行下载*			STMISP -> 清除芯片(z)*/
#define configUSE_TICKLESS_IDLE													0   /** 写入实际的CPU内核时钟频率,也就是CPU指令执行频率,通常称为Fclk* Fclk为供给CPU内核的时钟信号,我们所说的cpu主频为 XX MHz,* 就是指的这个时钟信号,相应的,1/Fclk即为cpu时钟周期;*/
#define configCPU_CLOCK_HZ						  (SystemCoreClock)//RTOS系统节拍中断的频率。即一秒中断的次数,每次中断RTOS都会进行任务调度
#define configTICK_RATE_HZ						  (( TickType_t )1000)//可使用的最大优先级
#define configMAX_PRIORITIES					  (32)//空闲任务使用的堆栈大小
#define configMINIMAL_STACK_SIZE				((unsigned short)128)//任务名字字符串长度
#define configMAX_TASK_NAME_LEN					(16)//系统节拍计数器变量数据类型,1表示为16位无符号整形,0表示为32位无符号整形
#define configUSE_16_BIT_TICKS					0                      //空闲任务放弃CPU使用权给其他同优先级的用户任务
#define configIDLE_SHOULD_YIELD					1           //启用队列
#define configUSE_QUEUE_SETS					  0    //开启任务通知功能,默认开启
#define configUSE_TASK_NOTIFICATIONS    1   //使用互斥信号量
#define configUSE_MUTEXES						    0    //使用递归互斥信号量                                            
#define configUSE_RECURSIVE_MUTEXES			0   //为1时使用计数信号量
#define configUSE_COUNTING_SEMAPHORES		0/* 设置可以注册的信号量和消息队列个数 */
#define configQUEUE_REGISTRY_SIZE				10                                 #define configUSE_APPLICATION_TASK_TAG		  0                       /*****************************************************************FreeRTOS与内存申请有关配置选项                                               
*****************************************************************/
//支持动态内存申请
#define configSUPPORT_DYNAMIC_ALLOCATION        1    
//支持静态内存
#define configSUPPORT_STATIC_ALLOCATION					0					
//系统所有总的堆大小
#define configTOTAL_HEAP_SIZE					((size_t)(36*1024))    /***************************************************************FreeRTOS与钩子函数有关的配置选项                                            
**************************************************************/
/* 置1:使用空闲钩子(Idle Hook类似于回调函数);置0:忽略空闲钩子* * 空闲任务钩子是一个函数,这个函数由用户来实现,* FreeRTOS规定了函数的名字和参数:void vApplicationIdleHook(void ),* 这个函数在每个空闲任务周期都会被调用* 对于已经删除的RTOS任务,空闲任务可以释放分配给它们的堆栈内存。* 因此必须保证空闲任务可以被CPU执行* 使用空闲钩子函数设置CPU进入省电模式是很常见的* 不可以调用会引起空闲任务阻塞的API函数*/
#define configUSE_IDLE_HOOK						0      /* 置1:使用时间片钩子(Tick Hook);置0:忽略时间片钩子* * * 时间片钩子是一个函数,这个函数由用户来实现,* FreeRTOS规定了函数的名字和参数:void vApplicationTickHook(void )* 时间片中断可以周期性的调用* 函数必须非常短小,不能大量使用堆栈,* 不能调用以”FromISR" 或 "FROM_ISR”结尾的API函数*//*xTaskIncrementTick函数是在xPortSysTickHandler中断函数中被调用的。因此,vApplicationTickHook()函数执行的时间必须很短才行*/
#define configUSE_TICK_HOOK						0           //使用内存申请失败钩子函数
#define configUSE_MALLOC_FAILED_HOOK			0 /** 大于0时启用堆栈溢出检测功能,如果使用此功能 * 用户必须提供一个栈溢出钩子函数,如果使用的话* 此值可以为1或者2,因为有两种栈溢出检测方法 */
#define configCHECK_FOR_STACK_OVERFLOW			0   /********************************************************************FreeRTOS与运行时间和任务状态收集有关的配置选项   
**********************************************************************/
//启用运行时间统计功能
#define configGENERATE_RUN_TIME_STATS	        0             //启用可视化跟踪调试
#define configUSE_TRACE_FACILITY				      0    
/* 与宏configUSE_TRACE_FACILITY同时为1时会编译下面3个函数* prvWriteNameToBuffer()* vTaskList(),* vTaskGetRunTimeStats()
*/
#define configUSE_STATS_FORMATTING_FUNCTIONS	1                       /********************************************************************FreeRTOS与协程有关的配置选项                                                
*********************************************************************/
//启用协程,启用协程以后必须添加文件croutine.c
#define configUSE_CO_ROUTINES 			          0                 
//协程的有效优先级数目
#define configMAX_CO_ROUTINE_PRIORITIES       ( 2 )                   /***********************************************************************FreeRTOS与软件定时器有关的配置选项      
**********************************************************************///启用软件定时器
#define configUSE_TIMERS				            0                              
//软件定时器优先级
#define configTIMER_TASK_PRIORITY		        (configMAX_PRIORITIES-1)        
//软件定时器队列长度
#define configTIMER_QUEUE_LENGTH		        10                               
//软件定时器任务堆栈大小
#define configTIMER_TASK_STACK_DEPTH	      (configMINIMAL_STACK_SIZE*2)    /************************************************************FreeRTOS可选函数配置选项                                                     
************************************************************/
#define INCLUDE_xTaskGetSchedulerState       1                       
#define INCLUDE_vTaskPrioritySet		         1
#define INCLUDE_uxTaskPriorityGet		         1
#define INCLUDE_vTaskDelete				           1
#define INCLUDE_vTaskCleanUpResources	       1
#define INCLUDE_vTaskSuspend			           1
#define INCLUDE_vTaskDelayUntil			         1
#define INCLUDE_vTaskDelay				           1
#define INCLUDE_eTaskGetState			           1
#define INCLUDE_xTimerPendFunctionCall	     0
//#define INCLUDE_xTaskGetCurrentTaskHandle       1
//#define INCLUDE_uxTaskGetStackHighWaterMark     0
//#define INCLUDE_xTaskGetIdleTaskHandle          0/******************************************************************FreeRTOS与中断有关的配置选项                                                 
******************************************************************/
#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 #define configKERNEL_INTERRUPT_PRIORITY 		( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )	/* 240 */#define configMAX_SYSCALL_INTERRUPT_PRIORITY 	( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )/****************************************************************FreeRTOS与中断服务函数有关的配置选项                         
****************************************************************/
#define xPortPendSVHandler 	PendSV_Handler
#define vPortSVCHandler 	SVC_Handler/* 以下为使用Percepio Tracealyzer需要的东西,不需要时将 configUSE_TRACE_FACILITY 定义为 0 */
#if ( configUSE_TRACE_FACILITY == 1 )
#include "trcRecorder.h"
#define INCLUDE_xTaskGetCurrentTaskHandle               1   // 启用一个可选函数(该函数被 Trace源码使用,默认该值为0 表示不用)
#endif#endif /* FREERTOS_CONFIG_H */

部分代码解析:

//针对不同的编译器调用不同的stdint.h文件
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)#include <stdint.h>extern uint32_t SystemCoreClock;
#endif

针对不同的编译器调用不同的 stdint.h 文件,在 MDK 中,我们默认的是__CC_ARM。


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

        在使用 C 语言编写工程代码时,我们总会对某种假设条件进行检查,断言就是用于在代码中捕捉这些假设,可以将断言看作是异常处理的一种高级形式。断言表示为一些布尔表达式,程序员相信在程序中的某个特定表达式值为真。可以在任何时候启用和禁用断言验证,因此可以在测试时启用断言,而在发布时禁用断言。同样,程序投入运行后,最终用户在遇到问题时可以重新启用断言。它可以快速发现并定位软件问题,同时对系统错误进行自动报警。断言可以对在系统中隐藏很深,用其它手段极难发现的问题可以用断言来进行定位,从而缩短软件问题定位时间,提高系统的可测性。实际应用时,可根据具体情况灵活地设计断言。这里只是使用宏定义实现了断言的功能,断言作用很大,特别是在调试的时候,而 FreeRTOS 中使用了很多断言接口 configASSERT,所以我们需要实现断言,把错误信息打印出来从而在调试中快速定位,打印信息的内容是xxx 文件 xxx 行(__FILE__,__LINE__)。

        简单来说就是查找报错,打印错误。


#define configUSE_PREEMPTION					  1

        置1:RTOS使用抢占式调度器;置0:RTOS使用协作式调度器(时间片)

        抢占式调度:在这种调度方式中,系统总是选择优先级最高的任务进行调度,并且 一旦高优先级的任务准备就绪之后,它就会马上被调度而不等待低优先级的任务主动放弃 CPU,高优先级的任务抢占了低优先级任务的 CPU 使用权,这就是抢占,在实习操作系统中,这样子的方式往往是最适用的。

        协作式调度:则是由任务主动放弃CPU,然后才进行任务调度。


#define configUSE_TIME_SLICING					1	

        使能时间片调度(默认式使能的)。当优先级相同的时候,就会采用时间片调度,这意味着 RTOS 调度器总是运行处于最高优先级的就绪任务,在每个FreeRTOS 系统节拍中断时在相同优先级的多个任务间进行任务切换。如果宏configUSE_TIME_SLICING 设置为 0,FreeRTOS 调度器仍然总是运行处于最高优先级的就绪任务,但是当 RTOS 系统节拍中断发生时,相同优先级的多个任务之间不再进行任务切换,而是在执行完高优先级的任务之后才进行任务切换。一般来说,FreeRTOS 默认支持 32 个优先级,很少情况会把 32 个优先级全用完,所以,官方建议采用抢占式调度。


8.  修改 stm32f10x_it.c

        首先我们先导入串口文件,我们这里使用野火的串口文件,它的一个宏定义感觉非常方便,别的也可以,进行导入:

        运行后会发现这两个报错:

        因为SysTick 中断服务函数是一个非常重要的函数,FreeRTOS 所有跟时间相关的事情都在里面处理,SysTick 就是 FreeRTOS 的一个心跳时钟,驱动着 FreeRTOS 的运行,就像人的心跳一样,假如没有心跳,我们就相当于“死了”,同样的,FreeRTOS 没有了心跳,那么它就会卡死在某个地方,不能进行任务调度,不能运行任何的东西,因此我们需要实现一个 FreeRTOS 的心跳时钟,FreeRTOS 帮我们实现了 SysTick 的启动的配置:在 port.c 文件中已经实现 vPortSetupTimerInterrupt()函数,并且 FreeRTOS 通用的 SysTick 中断服务函数也实现了:在 port.c 文件中已经实现 xPortSysTickHandler()函数,所以移植的时候只需要我们在 stm32f10x_it.c 文件中实现我们对应(STM32)平台上的 SysTick_Handler()函数即可。FreeRTOS 为开发者考虑得特别多,PendSV_Handler()与 SVC_Handler()这两个很重要的函数都帮我们实现了,在 port.c 文件中已经实现 xPortPendSVHandler()与 vPortSVCHandler()函数,防止我们自己实现不了,那么在 stm32f10x_it.c 中就需要我们注释掉PendSV_Handler()与 SVC_Handler()这两个函数了:

/********************************************************************************* @file    Project/STM32F10x_StdPeriph_Template/stm32f10x_it.c * @author  MCD Application Team* @version V3.5.0* @date    08-April-2011* @brief   Main Interrupt Service Routines.*          This file provides template for all exceptions handler and *          peripherals interrupt service routine.******************************************************************************* @attention** THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.** <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>*******************************************************************************//* Includes ------------------------------------------------------------------*/
#include "stm32f10x_it.h"
#include "FreeRTOS.h"					 
#include "task.h" 
/** @addtogroup STM32F10x_StdPeriph_Template* @{*//* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*//******************************************************************************/
/*            Cortex-M3 Processor Exceptions Handlers                         */
/******************************************************************************//*** @brief  This function handles NMI exception.* @param  None* @retval None*/
void NMI_Handler(void)
{
}/*** @brief  This function handles Hard Fault exception.* @param  None* @retval None*/
void HardFault_Handler(void)
{/* Go to infinite loop when Hard Fault exception occurs */while (1){}
}/*** @brief  This function handles Memory Manage exception.* @param  None* @retval None*/
void MemManage_Handler(void)
{/* Go to infinite loop when Memory Manage exception occurs */while (1){}
}/*** @brief  This function handles Bus Fault exception.* @param  None* @retval None*/
void BusFault_Handler(void)
{/* Go to infinite loop when Bus Fault exception occurs */while (1){}
}/*** @brief  This function handles Usage Fault exception.* @param  None* @retval None*/
void UsageFault_Handler(void)
{/* Go to infinite loop when Usage Fault exception occurs */while (1){}
}/*** @brief  This function handles SVCall exception.* @param  None* @retval None*/
//void SVC_Handler(void)
//{
//}/*** @brief  This function handles Debug Monitor exception.* @param  None* @retval None*/
void DebugMon_Handler(void)
{
}/*** @brief  This function handles PendSVC exception.* @param  None* @retval None*/
//void PendSV_Handler(void)
//{
//}/*** @brief  This function handles SysTick Handler.* @param  None* @retval None*/
extern void xPortSysTickHandler(void);
//systick中断服务函数
void SysTick_Handler(void)
{	#if (INCLUDE_xTaskGetSchedulerState  == 1 )if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED){#endif  /* INCLUDE_xTaskGetSchedulerState */  xPortSysTickHandler();#if (INCLUDE_xTaskGetSchedulerState  == 1 )}#endif  /* INCLUDE_xTaskGetSchedulerState */
}/******************************************************************************/
/*                 STM32F10x Peripherals Interrupt Handlers                   */
/*  Add here the Interrupt Handler for the used peripheral(s) (PPP), for the  */
/*  available peripheral interrupt handler's name please refer to the startup */
/*  file (startup_stm32f10x_xx.s).                                            */
/******************************************************************************//*** @brief  This function handles PPP interrupt request.* @param  None* @retval None*/
/*void PPP_IRQHandler(void)
{
}*//*** @}*/ /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/

        这时候在运行报错解决了。

工程模版:

STM32F103ZET6的FreeRTOS工程移植模版资源-CSDN文库

FreeRTOS实时操作系统_时光の尘的博客-CSDN博客

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

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

相关文章

通过 Tailwind CSS 自定义样式 实现深色模式切换

创建vite项目或者vue-cli配置大同小异 1、当前环境 Vue.js 3.5nuxtjs/tailwindcss 6.13.1nuxt3.15.4node18 这里主要依赖是tailwindcss 因为当前项目是使用nuxt开发。 2、配置颜色模式 在assets/css下创建main.css * {padding: 0;margin: 0;box-sizing: border-box; }[dat…

PWNOS:2.0(vulnhub靶机)

文章目录 靶机地址主机发现、端口扫描web渗透目录探测漏洞利用权限提升 解密工具地址总结 靶机地址 https://download.vulnhub.com/pwnos/pWnOS_v2.0.7z 这里如果是windows系统直接使用vmware或者virtubox打开可以使用,如果是mac系统需再去做一个配置&#xff0c;比较麻烦 这里…

Gartner魔力象限(Gartner Magic Quadrant)

Gartner魔力象限&#xff08;Gartner Magic Quadrant&#xff09;是由全球领先的研究和咨询公司Gartner发布的市场研究报告&#xff0c;广泛应用于IT行业&#xff0c;尤其是在技术供应商评估中。它以图形化的方式展示了不同技术领域中各个供应商的市场表现&#xff0c;帮助企业…

信创时代开发工具选择指南:国产替代背景下的技术生态与实践路径

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家、CSDN平台优质创作者&#xff0c;高级开发工程师&#xff0c;数学专业&#xff0c;10年以上C/C, C#, Java等多种编程语言开发经验&#xff0c;拥有高级工程师证书&#xff1b;擅长C/C、C#等开发语言&#xff0c;熟悉Java常用开…

人口老龄化丨AI健康小屋如何实现防病于未然​

随着全球老龄化加剧&#xff0c;“银发浪潮” 对医疗资源、养老护理和健康管理提出了严峻挑战。 由此智绅科技应运而生&#xff0c;七彩喜智慧养老系统构筑居家养老安全网。 AI 健康小屋作为银发科技的创新载体&#xff0c;通过智能化健康监测、精准化风险预警、便捷化医疗衔…

【金仓数据库征文】金仓数据库:开启未来技术脑洞,探索数据库无限可能

我的个人主页 我的专栏&#xff1a; 人工智能领域、java-数据结构、Javase、C语言&#xff0c;希望能帮助到大家&#xff01;&#xff01;&#xff01; 点赞&#x1f44d;收藏❤ 目录 引言&#xff1a;数据库进化的下一站 —— 未来科技的无限可能金仓数据库简介&#xff1a;国…

#什么是爬虫?——从技术原理到现实应用的全面解析 VI

什么是爬虫?——从技术原理到现实应用的全面解析 V 二十六、异构数据采集技术突破 26.1 PDF文本与表格提取 import pdfplumber import pandas as pddef extract_pdf_data(pdf_path):"""从PDF中提取文本和表格数据:param pdf_path: PDF文件路径:return: 包含…

关于Spring Boot构建项目的相关知识

一 前端框架 1 VUE框架 1.1 简介 Vue是一款流行的JavaScript框架&#xff0c;用于构建用户界面和单页面应用程序。它的设计初衷是为了简化Web开发过程&#xff0c;使开发者能够快速构建交互性强、响应速度快的Web应用。 1.2 优点 简单易用&am…

PPO 强化学习机械臂 IK 训练过程可视化利器 Tensorboard

视频讲解&#xff1a; PPO 强化学习机械臂 IK 训练过程可视化利器 Tensorboard PPO 强化学习过程中&#xff0c;设置了verbose会显示数据&#xff0c;但还是不够直观&#xff0c;这里上一个可视化利器&#xff0c;Tensorboard&#xff0c;实际上stable baselines3中已经有了这部…

UE5的 Modify Curve 蓝图节点

In Unreal Engine’s Animation Blueprints, the Modify Curve node lets you drive and alter any named Animation Curve on your character at runtime. The Apply Mode setting on that node controls how the “new” value you feed in (via the added curve‐input pin)…

【Hive入门】Hive分区与分区表完全指南:从原理到企业级实践

引言 在大数据时代&#xff0c;高效管理海量数据成为企业面临的核心挑战。Hive作为Hadoop生态系统中最受欢迎的数据仓库解决方案&#xff0c;其分区技术是优化数据查询和管理的关键手段。本文将全面解析Hive分区技术的原理、实现方式及企业级最佳实践&#xff0c;帮助您构建高性…

jdk-8u202-linux-x64.tar.gz官方下载地址

https://www.oracle.com/java/technologies/javase/javase8-archive-downloads.html 点击下载&#xff0c;需要先注册oracle账号&#xff0c;很好注册随便写&#xff0c;注册完登录就可以下载了。目前就Oracle JDK 8u201/202 是最后两个可免费用于商业用途的公开版本

OpenCv高阶(十)——光流估计

文章目录 前言一、光流估计二、使用步骤1、导库读取视频、随机初始化颜色2、初始化光流跟踪3、视频帧处理循环4、光流计算与可视化5、循环控制与资源释放完整代码 总结 前言 在计算机视觉领域&#xff0c;光流估计是捕捉图像序列中像素点运动信息的核心技术。它描述了图像中每…

AIGC实战之如何构建出更好的大模型RAG系统

一、RAG 系统核心架构解析 1. 检索模块深度优化 1.1 混合检索技术实现 技术原理&#xff1a;结合稀疏检索&#xff08;BM25&#xff09;与密集检索&#xff08;DPR&#xff09;&#xff0c;通过动态权重分配提升检索精度。例如&#xff0c;在医疗领域&#xff0c;BM25 负责精…

Rust 学习笔记:函数和控制流

Rust 学习笔记&#xff1a;函数和控制流 Rust 学习笔记&#xff1a;函数和控制流函数&#xff08;Function&#xff09;语句和表达式带返回值的函数注释控制流if 表达式使用 else if 处理多个条件在 let 语句中使用 if循环loop从循环中返回值循环标签消除多个循环之间的歧义带 …

c#加密证件号的中间部分,改为*号

前言 使用场景&#xff1a;在我项目中&#xff0c;我需要给前端提供接口&#xff0c;所以我要吧证件号进行加密。例如&#xff1a;411421199510225612&#xff0c;这是一个身份证号&#xff0c;18为的&#xff0c;那么我加密完成之后就会是 411421********5612&#xff0c;类似…

存储新势力:助力DeepSeek一体机

宝子们&#xff0c;今天要给大家分享一个超酷的科技话题——各大厂商陆续推出的DeepSeek训推一体机方案。 【集成人工智能训推平台】 它就像是一个超级智能的大脑中枢&#xff0c;为各种复杂的AI任务搭建AI模型流水线。预置算法模版、训练框架、推理框架、模型任务调度和自动…

同样机身尺寸下伺服电机比无刷电机扭矩更大的原因

点击下面图片带您领略全新的嵌入式学习路线 &#x1f525;爆款热榜 88万阅读 1.6万收藏 在电机应用领域&#xff0c;伺服电机和无刷电机&#xff08;BLDC&#xff09;都是常见的动力源&#xff0c;但两者在性能上存在显著差异。尤其是在相同机身尺寸下&#xff0c;伺服电机的…

.dat 文件一般可以用什么打开

DAT文件是一种常见的文件格式,通常由多种应用程序生成。打开DAT文件的方法取决于其内容和生成它的软件。 使用文本编辑器 如果DAT文件是一个简单的文本文件,可以使用Windows的记事本或macOS的文本编辑器打开它。 右键点击文件 -> 选择“打开方式” -> 选择“记事本”…