FreeRTOS移植步骤

一、FreeRTOS源码下载

FreeRTOS - Market leading RTOS (Real Time Operating System) for embedded systems with Internet of Things extensions

二、FreeRTOS源码介绍

(1) FreeRTOS源码打开

 

(2) FreeRTOS文件夹打开

(3)Soutce文件夹打开

(4)portable文件夹打开

三、FreeRTOS的移植过程

(1)新建一个FreeRTOS的文件夹

(2)将 FreeRTOS内核源码的 Source 文件夹下的所有文件添加到工程的 FreeRTOS 文件夹中

(3)打开基础工程 ,新建两个文件分组 ,分别为FreeRTOS_CORE和FreeRTOS_PORT

(4) FreeRTOS_CORE 存放 所有的 FreeRTOS 的内核 C 源文件croutine.c,event_groups.c,list.c,queue.c,stream_buffer.c,tasks.c,timers.c

(5)FreeRTOS_PORT 存放 FreeRTOS 内核的移植文件,heap_x.c 和 port.c

  • FreeRTOS/portable/MemMang 下有五个 C 源文件,这五个 C 源文件对应了五种 FreeRTOS 提供的内存管理算法,博主使用heap_4.c。
  • port.c 文件的路径在FreeRTOS/portable/RVDS 。port.c 是 FreeRTOS 这个软件与 MCU 这个硬件连接的桥梁。 FreeRTOS 针对不同的 MCU 提供了不同的 port.c 文件。例如STM32F1  系列,就使用ARM_CM3下的port.c

(6) 添加 FreeRTOS 源码的头文件路径。其中一个头文件路径就是 FreeRTOS/include,另外一个头文件路径为 port.c 文件的路径

(7)添加 FreeRTOSConfig.h  文件并添加头文件路径。获取途径:FreeRTOS官方历程或者正点原子移植工程等

四、编译看是否移植成功

        出现  .\output\Project.axf: Error: L6200E: Symbol SVC_Handler multiply defined (by port.o and gd32f30x_it.o).错误。这个错误的原因是SVC_Handler函数在多个地方被定义,所以我们需要将gd32f30x_it.o里面的SVC_Handler函数屏蔽。再次编译,没有错误

五、添加任务代码

        添加代码的原因是为了近一步确定是否移植成功

#include "FreeRTOS.h"
#include "task.h"

//任务优先级
#define START_TASK_PRIO		1
//任务堆栈大小	
#define START_STK_SIZE 		128  
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters); 

//创建开始任务
xTaskCreate((TaskFunction_t )start_task,            //任务函数
            (const char*    )"start_task",          //任务名称
            (uint16_t       )START_STK_SIZE,        //任务堆栈大小
            (void*          )NULL,                  //传递给任务函数的参数
            (UBaseType_t    )START_TASK_PRIO,       //任务优先级
            (TaskHandle_t*  )&StartTask_Handler);   //任务句柄  					
vTaskStartScheduler();          										//开启任务调度

void start_task(void *pvParameters)
{
    
	while(1)
	{
		
	}
}

六、FreeRTOS纯净版移植前后对比

移植前
croutine.c
event_groups.c
list.c
queue.c
task.c
timers.c

heap_1.c
heap_2.c
heap_3.c
heap_4.c
heap_5.c

ARM_CA9
ARM_CM0
ARM_CM3
ARM_CM4_MPU
ARM_CM4F
ARM_CM7
ARM7_LPC21xx

移植后
croutine.c
event_groups.c
list.c
queue.c
task.c
timers.c

heap_4.c(内存管理算法)

ARM_CM4F(ARM4内核)


 

七、FreeRTOS移植注意点

(1) 出现下面问题

Undefined symbol xTaskGetCurrentTaskHandle (referred from stream_buffer.o).

解决方法是在官方提供的FreeRTOS.h文件中,将INCLUDE_xTaskGetCurrentTaskHandle的值改为0即可。

#ifndef INCLUDE_xTaskGetCurrentTaskHandle
    #define INCLUDE_xTaskGetCurrentTaskHandle    0
#endif

(2)FreeRTOSConfig.h配置文件注意点:如果出现SystemCoreClock没有定义

将宏定义 #ifdef __ICCARM__  注释掉,修改成下面代码。

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

(3) FreeRTOSConfig.h配置文件注意点:四个钩子函数宏定义值改为0

configUSE_IDLE_HOOK
configUSE_TICK_HOOK
configUSE_MALLOC_FAILED_HOOK
configCHECK_FOR_STACK_OVERFLOW

(4)FreeRTOSConfig.h配置文件注意点:需要冲定义下面3个函数

#define xPortPendSVHandler 	PendSV_Handler
#define vPortSVCHandler 	SVC_Handler
#define xPortSysTickHandler SysTick_Handler

 然后修改  stm32f4xx_it.c ,将 SysTick_Handler 、PendSV_Handler 、SVC_Handler三个函数注释掉(在port.c中已经有定义)

(5)进入临界区之后需要退出临界区,不然容易出现硬件中断错误,例如下面代码。

taskENTER_CRITICAL(); //进入临界区

while(1)
{
        
}

taskEXIT_CRITICAL();//退出临界区

(6)vTaskDelay函数需要创建任务之后才能使用,否则会进入硬件中断

八、FreeRTOSConfig.h文件如下

#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H

#include "sys.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基础配置配置选项                                              */
/***************************************************************************************************************/
#define configUSE_PREEMPTION					1                       //1使用抢占式内核,0使用协程
#define configUSE_TIME_SLICING					1						//1使能时间片调度(默认式使能的)
#define configUSE_PORT_OPTIMISED_TASK_SELECTION	1                       //1启用特殊方法来选择下一个要运行的任务
                                                                        //一般是硬件计算前导零指令,如果所使用的
                                                                        //MCU没有这些硬件指令的话此宏应该设置为0!
#define configUSE_TICKLESS_IDLE					0                       //1启用低功耗tickless模式
#define configUSE_QUEUE_SETS					1                       //为1时启用队列
#define configCPU_CLOCK_HZ						(SystemCoreClock)       //CPU频率
#define configTICK_RATE_HZ						(1000)                  //时钟节拍频率,这里设置为1000,周期就是1ms
#define configMAX_PRIORITIES					(32)                    //可使用的最大优先级
#define configMINIMAL_STACK_SIZE				((unsigned short)130)   //空闲任务使用的堆栈大小
#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_TASK_NOTIFICATIONS            1                       //为1时开启任务通知功能,默认开启
#define configUSE_MUTEXES						1                       //为1时使用互斥信号量
#define configQUEUE_REGISTRY_SIZE				8                       //不为0时表示启用队列记录,具体的值是可以
                                                                        //记录的队列和信号量最大数目。
#define configCHECK_FOR_STACK_OVERFLOW			0                       //大于0时启用堆栈溢出检测功能,如果使用此功能
                                                                        //用户必须提供一个栈溢出钩子函数,如果使用的话
                                                                        //此值可以为1或者2,因为有两种栈溢出检测方法。
#define configUSE_RECURSIVE_MUTEXES				1                       //为1时使用递归互斥信号量
#define configUSE_MALLOC_FAILED_HOOK			0                       //1使用内存申请失败钩子函数
#define configUSE_APPLICATION_TASK_TAG			0                       
#define configUSE_COUNTING_SEMAPHORES			1                       //为1时使用计数信号量

/***************************************************************************************************************/
/*                                FreeRTOS与内存申请有关配置选项                                                */
/***************************************************************************************************************/
#define configSUPPORT_DYNAMIC_ALLOCATION        1                       //支持动态内存申请
#define configTOTAL_HEAP_SIZE					((size_t)(20*1024))     //系统所有总的堆大小

/***************************************************************************************************************/
/*                                FreeRTOS与钩子函数有关的配置选项                                              */
/***************************************************************************************************************/
#define configUSE_IDLE_HOOK						0                       //1,使用空闲钩子;0,不使用
#define configUSE_TICK_HOOK						0                       //1,使用时间片钩子;0,不使用

/***************************************************************************************************************/
/*                                FreeRTOS与运行时间和任务状态收集有关的配置选项                                 */
/***************************************************************************************************************/
#define configGENERATE_RUN_TIME_STATS	        0                       //为1时启用运行时间统计功能
#define configUSE_TRACE_FACILITY				1                       //为1启用可视化跟踪调试
#define configUSE_STATS_FORMATTING_FUNCTIONS	1                       //与宏configUSE_TRACE_FACILITY同时为1时会编译下面3个函数
                                                                        //prvWriteNameToBuffer(),vTaskList(),
                                                                        //vTaskGetRunTimeStats()
                                                                        
/***************************************************************************************************************/
/*                                FreeRTOS与协程有关的配置选项                                                  */
/***************************************************************************************************************/
#define configUSE_CO_ROUTINES 			        0                       //为1时启用协程,启用协程以后必须添加文件croutine.c
#define configMAX_CO_ROUTINE_PRIORITIES         ( 2 )                   //协程的有效优先级数目

/***************************************************************************************************************/
/*                                FreeRTOS与软件定时器有关的配置选项                                            */
/***************************************************************************************************************/
#define configUSE_TIMERS				        1                               //为1时启用软件定时器
#define configTIMER_TASK_PRIORITY		        (configMAX_PRIORITIES-1)        //软件定时器优先级
#define configTIMER_QUEUE_LENGTH		        5                               //软件定时器队列长度
#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	        1

/***************************************************************************************************************/
/*                                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) )
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 	( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )

/***************************************************************************************************************/
/*                                FreeRTOS与中断服务函数有关的配置选项                                          */
/***************************************************************************************************************/
#define xPortPendSVHandler 	PendSV_Handler
#define vPortSVCHandler 	SVC_Handler
#define xPortSysTickHandler SysTick_Handler

#endif /* FREERTOS_CONFIG_H */

  • 37
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值