(二)移植FreeRTOS到STM32中

一、概念

(1)任务(线程):根据功能的不同,将一个系统分割成一个个独立且无法返回的函数,这个函数就被称为任务
(2)任务栈:静态创建的任务保存在栈中
(3)TCB:任务控制块,保存了一个任务节点
(4)任务就绪列表:初始化的一个列表数组,每个数组元素的列表可以保存多个任务列表项
(5)任务调度器:实现任务切换,从就绪列表中找到任务优先级最高的任务执行
(6)临界段:执行的时候不能被中断的代码段,实际就是中断的开关控制
(7)空闲任务:在CPU空闲时才会运行的任务
(8)阻塞延时:任务调用此延时函数后,任务会被剥离CPU使用权,然后进入阻塞状态,直到延时结束,任务重新获取CPU使用权才可以继续运行
(9)时间片:同一优先级下的多个任务,轮流享有CPU使用权,享有CPU的时间叫做时间片
(10)free rtos官网

二、移植

(1)一级文件夹介绍
一级文件夹
FreeRTOS:freertos系统文件夹
FreeRTOS-Plus:第三方组件
(2)二级文件夹
二级文件夹
Demo:官方例程
License:放置开源协议文件
Source:系统源码文件(重要)
(3)三级文件夹
三级文件夹
include:头文件
portable:硬件接口文件
.c:源文件
(4)在STM32项目下创建freertos文件夹,然后在文件夹下创建inc、src、port文件夹
(5)将FreeRTOS源码目录下的FreeRTOS/Source/include文件夹下的.h头文件全部复制到STM32项目的freertos/inc文件夹下
(6)将FreeRTOS源码目录下的FreeRTOS/Source文件夹下的.c源文件全部复制到STM32项目的freertos/src文件夹下
(7)将FreeRTOS源码目录下的FreeRTOS/Source/portable文件夹下的MemMang和RVDS文件夹复制到STM32项目的freertos/port文件夹下,其中MemMang文件夹下是不同的内存管理文件,一般选择heap_4.c文件,RVDS/ARM_CM3文件夹下存放的是单片机m3内核,不同单片机根据不同内核进行选择
(8)打开STM32项目,创建分组,将freertos的.c源文件添加进项目中,.h头文件路径添加到魔术棒中
(9)复制freertos源码的Demo文件夹下找到对应的单片机和编译器文件夹,将下边的FreeRTOSConfig.h文件复制到项目的头文件文件夹中
(10)FreeRTOSConfig.h配置文件

#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H/***                                            基础配置*/#define configUSE_PREEMPTION		1                                   //1使用抢占式调度器 0使用协作式调度器(时间片)
#define configUSE_TIME_SLICING      1                                   //使能时间片调度
#define configUSE_PORT_OPTIMISED_TASK_SELECTION     1                   //任务选择方法,0通用方法 1优化方法,一般为计算前导零[CLZ]指令
#define configUSE_TICKLESS_IDLE     0                                   //1进入低功耗模式,下载代码可能会出错,0保持系统节拍(tick)中断一直运行
#define configCPU_CLOCK_HZ			( ( unsigned long ) 72000000 )     //定义系统时钟
#define configTICK_RATE_HZ			( ( TickType_t ) 1000 )             //系统节拍中断频率,即1s中断的次数
#define configMAX_PRIORITIES		( 32 )                              //可使用的最大优先级
#define configMINIMAL_STACK_SIZE	( ( unsigned short ) 128 )         //空闲任务栈大小
#define configMAX_TASK_NAME_LEN		( 16 )                              //任务名字最大长度
#define configUSE_16_BIT_TICKS		0                                   //系统节拍计数器变量数据类型,1表示16位无符号整型,0表示32位无符号整型
#define configIDLE_SHOULD_YIELD		1                                   //1表示空闲任务会放弃CPU使用权给其他同优先级的任务
#define configUSE_QUEUE_SETS        0                                   //1表示使能队列集合
#define configUSE_TASK_NOTIFICATIONS                1                   //1表示使能任务通知功能
#define configUSE_MUTEXES           0                                   //互斥信号量使能标志
#define configUSE_RECURSIVE_MUTEXES 0                                   //使用递归互斥信号量
#define configUSE_COUNTING_SEMAPHORES               0                   //1表示使用计数信号量
#define configQUEUE_REGISTRY_SIZE   10                                  //可以注册的信号量消息队列个数
#define configUSE_APPLICATION_TASK_TAG              0/**                                             内存申请相关配置*/#define configSUPPORT_DYNAMIC_ALLOCATION            1                   //支持动态内存申请
#define configSUPPORT_STATIC_ALLOCATION             0                   //支持静态内存
#define configTOTAL_HEAP_SIZE		( ( size_t ) ( 17 * 1024 ) )        //系统所有总的堆大小/**                                              钩子函数相关的配置*/#define configUSE_IDLE_HOOK			0                                   //1使用空闲钩子 0忽略空闲钩子 freertos规定了函数名,需要用户自己实现void vApplicationIdleHook(void)
#define configUSE_TICK_HOOK			0                                   //1使用时间片钩子 0忽略时间片钩子 freertos规定了函数名,需要用户自己实现void vApplicationTickHook(void)
#define configUSE_MALLOC_FAILED_HOOK                0                   //1使用内存申请失败钩子函数
#define configCHECK_FOR_STACK_OVERFLOW              0                   //1/2表示使用堆栈溢出检测功能 要使用此功能用户需要提供一个栈溢出钩子函数/**                                          运行时间和任务状态收集的配置*/#define configGENERATE_RUN_TIME_STATS               0                   //运行时间统计功能
#define configUSE_TRACE_FACILITY	0                                   //可视化跟踪调试功能
#define configUSE_STATS_FORMATTING_FUNCTIONS        0/**                                                  协程有关的配置*/#define configUSE_CO_ROUTINES       0                                   //协程启用状态位,启动协程必须添加croutine.c文件
#define configMAX_CO_ROUTINE_PRIORITIES              (2)                //协程的有效优先级数目/**                                               软件定时器相关配置*/#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)       //软件定时器的任务堆栈大小/**                                           可选配置,是否编译对应的函数*/#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/**                                           中断相关配置*/#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
/* This is the raw value as per the Cortex-M3 NVIC.  Values can be 255*/
#define configKERNEL_INTERRUPT_PRIORITY 		255
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!*/
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 	191 /* equivalent to 0xb0, or priority 11. *//* This is the value being used as per the ST library which permits 16
priority values, 0 to 15.  This must correspond to the
configKERNEL_INTERRUPT_PRIORITY setting.  Here 15 corresponds to the lowest
NVIC value of 255. */
#define configLIBRARY_KERNEL_INTERRUPT_PRIORITY	15#define xPortPendSVHandler  PendSV_Handler      //挂起中断,进行任务切换
#define vPortSVCHandler     SVC_Handler         //实现跳转到第一个任务的中断#endif /* FREERTOS_CONFIG_H */

(11)打开stm32f103x_it.c文件,注释掉已经实现的中断函数PendSV_Handler和SVC_Handler,修改SysTick_Handler内容为以下

extern void xPortSysTickHandler(void);
void SysTick_Handler(void)
{#if (INCLUDE_xTaskGetSchedulerState == 1)if( xTaskGetSchedulerState() != taskSCHEDULER_NOT_SATRTED){#endifxPortSysTickHandler();#if (INCLUDE_xTaskGetSchedulerState == 1)}#endif
}

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

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

相关文章

载人航天、超级计算机、深海深地探测......政府工作报告中,这些科技“关键词”令人振奋!

​​​​​​​3月5日上午,备受瞩目的十四届全国人大一次会议在人民大会堂隆重开幕。政府工作报告中提到载人航天、探月探火、深海深地探测等科技关键词。​​​​​​​ 3月5日上午,第十四届全国人民代表大会第一次会议在人民大会堂举行开幕会。 政府…

php双端交易所

php双端交易所,如需联系 完美修复版,带所有 PHP双端交易所完美版: PHP双端交易所完美版,带前端源码https://gitee.com/ycsw/ex.git

苹果笔记本硬盘被格式化了还能用吗 苹果笔记本硬盘被格式化了怎么办 硬盘被格式化了还能恢复数据吗苹果 电脑C盘文件恢复 easyrecovery易恢复软件

硬盘是计算机主要的存储设备, 它由一个或者多个铝制或者玻璃制的碟片组成。苹果笔记本硬盘和其他硬盘一样,都是用来存储和读写数据的。格式化硬盘可以清空硬盘里面的所有数据,为其他数据储存留出空间。本篇文章,我们学习苹果笔记本…

Kotlin 中List,Set,Map的创建与使用

目录 1. List 的使用 1.1 不可变 List 1.2 可变 List 2. Set 的使用 2.1 不可变 Set 2.2 可变 Set 3. Map 的使用 3.1 不可变Map 3.2 可变Map 本篇主要为已经有Java基础的同学展示Kotlin语言中的List,Set,Map的创建和使用,所以Java代…

Arduino平台软硬件原理及使用——色环电阻及贴片电阻的阻值识别

文章目录 一、四色环电阻及其阻值识别 二、五色环、六色环电阻及其阻值识别 三、三位数字及四位数字编码的贴片电阻及其阻值识别 四、E96编码的贴片电阻及其阻值识别 一、四色环电阻及其阻值识别 如上图为四色环电阻的实物图,图中左侧的三道环间距一致,第…

【ARM】DS中Coretex-M处理器的常用寄存器介绍

【更多软件使用问题请点击亿道电子官方网站查询】 1、 文档目标 了解ArmDS中Coretex-M处理器的常用寄存器的名称及作用。 2、 问题场景 在对Coretex-M处理器进行开发时,了解常用寄存器的名称及作用,可以: 编写正确的程序: 寄存器是程序员用…

数据结构:详解【顺序表】的实现

1. 顺序表的定义 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。动态顺序表与数组的本质区别是——根据需要动态的开辟空间大小。 2. 顺序表的功能 动态顺序表的功能一般有如下几个: 初始化顺序表打印顺序…

Test注解

学习2个变量:dataProvider和dataProviderClass 是什么?怎么用? dataProvider变量是什么? 看源码定义:此测试方法的数据提供程序的名称。 使用: 在Test注解中直接加程序名称 ProviderClass 数据提供者通…

揭示数据在内存中存储的秘密!

** ** 悟已往之不谏,知来者犹可追 ** ** 创作不易,宝子们!如果这篇文章对你们有帮助的话,别忘了给个免费的赞哟~ 整数在内存中的存储 整数的表达方式有三种:原码、反码、补码。 三种表示方法均有符号位和数值位两部分…

[java基础揉碎]多态参数

多态参数 方法定义的形参类型为父类类型,实参类型允许为子类类型 例子: 定义一个员工类, 有名字和工资两个属性, 有年工资的方法 定义一个普通员工继承了员工类 , 重写了年工资的方法 定义一个经理类, 也继承了员工类, 同时经理多以了一个奖金的属性, 重写的年…

Linux高级IO_select、epoll

调用send/write、read/recv这些IO接口进行网络通信时,需要等待IO条件满足(IO事件就绪)才能正常拷贝数据。比如调用send/write需要等待TCP的发送缓冲区有剩余空间才能将数据拷贝到TCP发送缓冲区中,调用read/recv需要等待TCP的接收缓…

Java双非大二找实习记录

先说结论:2.22→3.6线上线下面了七家,最后oc两家小公司,接了其中一个。 本人bg: 真名不经传双非一本,无绩点无竞赛无奖项无实习,23年12月开始学java。若非要说一点相关的经历,就是有java基础&…