(二)移植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配置文件

c 复制代码
#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内容为以下

c 复制代码
extern void xPortSysTickHandler(void);
void SysTick_Handler(void)
{
    #if (INCLUDE_xTaskGetSchedulerState == 1)
        if( xTaskGetSchedulerState() != taskSCHEDULER_NOT_SATRTED)
        {
    #endif
            xPortSysTickHandler();
    #if (INCLUDE_xTaskGetSchedulerState == 1)
        }
    #endif
}
相关推荐
Coding Peasant9 小时前
GD32E230 I2C从机功能深度解析与实现指南
c语言·stm32·单片机·mcu·arm
天庭鸡腿哥12 小时前
国外软件,安装即时专业版!
stm32·microsoft·macos·everything
214实验室12 小时前
STM32串口打印使用printf乱码问题
stm32·单片机·嵌入式硬件
离凌寒14 小时前
一、基于freertos下对LAN8720模块进行通信测试
网络·freertos
d111111111d15 小时前
什么是内存对齐?在STM32上面如何通过编辑器指令来实现内存对齐。
笔记·stm32·单片机·嵌入式硬件·学习·编辑器
bai54593615 小时前
STM32 CuberIDE 中断
stm32·单片机·嵌入式硬件
Dillon Dong17 小时前
从C到Simulink:用Counter模块玩转嵌入式定时器
c语言·stm32·simulink
Vizio<17 小时前
STM32HAL库开发笔记-串口通信(UART)
笔记·stm32·嵌入式硬件
进阶的猪19 小时前
stm32 GPIO输出-使用固件库点亮LED灯 Q&A
c语言·笔记·stm32·单片机
沐欣工作室_lvyiyi19 小时前
基于STM32单片机的冷链运输监测系统(论文+源码)
stm32·单片机·毕业设计·冷链运输监测系统