完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
本章教程将为大家介绍基于MDK的FreeRTOS操作系统移植。移植工作比较简单,只需要用户添加需要的源码文件,不需要做任何的底层工作,再添加三个宏定义即可。
本章教程含Cortex-M3内核的STM32F103的移植和Cortex-M4内核的STM32F407以及F429的移植。 5.1 移植前准备工作说明 5.2 STM32F103移植FreeRTOS系统 5.3 STM32F407移植FreeRTOS系统 5.4 STM32F429移植FreeRTOS系统 5.5 总结 5.1 移植前准备工作说明 1. 本章节的IDE开发环境使用MDK,用MDK4.7X或者MDK5.XX均可,保证支持STM32F103,F407和F429即可(不可以使用MDK4.7X以下版本,一方面是不支持F429,另外就是FreeRTOS V8.2.3要用到C代码中嵌套汇编代码,MDK4.7X以下版本是不支持的)。 2. 找一个简单的工程,最好是跑马灯之类的,越简单越好,我们就在这个简单的工程上面移植即可。 3. 大家使用的简单工程里面不能有Systick,PendSV和SVC三个系统中断的使用,因为FreeRTOS系统要使用这三个中断。 |
|
相关推荐
|
|
5.2 STM32F103移植FreeRTOS系统
5.2.1 FreeRTOS操作系统移植 首先准备好一个简单的裸机工程模板,工程模板的制作就不做讲解了,这里的重点是教大家移植FreeRTOS系统。准备好的工程模板如下图5.1所示(大家也可以制作其它任意的工程模板,不限制): 图5.1 工程模板 准备好工程模板后,就可以开始移植了。首先要做的就是将所有需要的源码文件放到工程模板里面。下面分六步和大家进行说明,当然,不限制必须使用下面的方法添加源码到工程,只要将需要的文件添加到工程模板即可。 u 第1步:从网址https://sourceforge.net/projects/freertos/files/FreeRTOS/V8.2.3/ 下载V8.2.3版本,这个是8.X系列里面最高版本了,9.0版本还处于测试阶段,我们暂不使用。 FreeRTOSV8.2.3.zip和FreeRTOSV8.2.3.exe内容是一样的,只是后缀为exe的压缩率更高些。下载后解压出来。 |
|
|
|
|
|
第2步:在工程模板创建FreeRTOS文件夹
u 第3步:添加源码文件到相应文件夹 l 将FreeRTOSV8.2.3软件包中路径:FreeRTOSV8.2.3FreeRTOSSource里面如下所有文件 复制到刚刚创建的FreeRTOS文件夹下。 l 文件夹User中还需要添加如下文件: 文件FreeRTOSConfig.h文件在FreeRTOSV8.2.3软件包中的中的路径:FreeRTOSV8.2.3FreeRTOSDemoCORTEX_STM32F103_Keil,其实就是官方整理好的配置文件。 u 第3步:将源码文件添加到MDK的工程项目中,添加后的效果如下: 其中heap_4.c文件路径: FreeRTOSSourceportableMemMang port.c和portmacro.h文件的路径:FreeRTOSSourceportableRVDSARM_CM3,由于STM32F103是M3内核的,所以移植文件也要添加M3内核的。 |
|
|
|
|
|
u 第4步:新创建一个includes.h文件,将所有的头文件都集中到这个头文件下。
这样做的好处是引用头文件的时候,只添加这个头文件就可以了。includes.h文件放在了User文件夹中。然后再将这个文件也添加到MDK工程项目中(将.h文件添加到工程的好处是方便查看和修改) |
|
|
|
|
|
Includes.h文件中的内容如下:
/* ********************************************************************************************************* * * 模块名称 : 头文件汇总 * 文件名称 : includes.h * 版 本 : V1.0 * 说 明 : 当前使用头文件汇总 * * 修改记录 : * 版本号 日期 作者 说明 * V1.0 2015-08-02 Eric2013 首次发布 * * Copyright (C), 2015-2020, 安富莱电子 www.armfly.com * ********************************************************************************************************* */ #ifndef __INCLUDES_H__ #define __INCLUDES_H__ /* ********************************************************************************************************* * 标准库 ********************************************************************************************************* */ #include #include #include #include /* ********************************************************************************************************* * 其它库 ********************************************************************************************************* */ /* ********************************************************************************************************* * OS ********************************************************************************************************* */ #include "FreeRTOS.h" #include "task.h" #include "queue.h" #include "croutine.h" /* ********************************************************************************************************* * 宏定义 ********************************************************************************************************* */ /* ********************************************************************************************************* * APP / BSP ********************************************************************************************************* */ #include #endif |
|
|
|
|
|
第5步:添加相应的头文件路径,在原来工程模板的基础上新添加的两个路径:
u 第6步:最后一步,同时也是最重要的一步,修改FreeRTOSConfig.h配置文件(用户根据自己的配置进行修改,不修改也是没问题的,我们这里进行修改主要是为了方便初学者学习),主要修改了以下两个方面: l 添加宏定义__NVIC_PRIO_BITS,STM32系列产品优先级仅使用4位。 l 修改优先级相关的几个宏定义,具体修改了哪个可以对比原始文件查看。 修改后在这个文件的末尾加上Systick,PendSV和SVC中断函数的宏定义,目的是将FreeRTOS移植文件port.c文件里面的中断服务程序映射到CMSIS定义的标准名称,这样就不需要用户去修改工程启动代码中这几个中断的名字了,很方便就实现了两个函数的统一。(移植过uCOS-II或者III的用户,对于这个问题估计深有体会,因为uCOS要修改启动文件,其实采用这里的方式更方便) [url=]复制代码[/url]
其中vPortSVCHandler,xPortPendSVHandler和xPortSysTickHandler是在port.c文件里面定义的。SVC_Handler,PendSV_Handler和SysTick_Handler在startup_stm32f10x_hd.s文件里面进行了定义。 |
|
|
|
|
|
下面是FreeRTOSConfig.h配置文件的完整内容:
#ifndef FREERTOS_CONFIG_H #define FREERTOS_CONFIG_H /*----------------------------------------------------------- * Application specific definitions. * * These definitions should be adjusted for your particular hardware and * application requirements. * * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. * * See http://www.freertos.org/a00110.html. *----------------------------------------------------------*/ #define configUSE_PREEMPTION 1 #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configCPU_CLOCK_HZ ( ( unsigned long ) 72000000 ) #define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( ( unsigned short ) 128 ) #define configTOTAL_HEAP_SIZE ( ( size_t ) ( 17 * 1024 ) ) #define configMAX_TASK_NAME_LEN ( 16 ) #define configUSE_TRACE_FACILITY 0 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) /* Set the following definitions to 1 to include the API function, or zero to exclude the API function. */ #define INCLUDE_vTaskPrioritySet 1 #define INCLUDE_uxTaskPriorityGet 1 #define INCLUDE_vTaskDelete 1 #define INCLUDE_vTaskCleanUpResources 0 #define INCLUDE_vTaskSuspend 1 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 /* Cortex-M specific definitions. */ #ifdef __NVIC_PRIO_BITS /* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */ #define configPRIO_BITS __NVIC_PRIO_BITS #else #define configPRIO_BITS 4 /* 15 priority levels */ #endif /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0x0f /* The highest interrupt priority that can be used by any interrupt service routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER PRIORITY THAN THIS! (higher priorities are lower numeric values. */ #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 0x01 /* Interrupt priorities used by the kernel port layer itself. These are generic to all Cortex-M ports, and do not rely on any particular library functions. */ #define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) /* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ #define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) /* Normal assert() semantics without relying on the provision of an assert.h header file. */ #define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); } /* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS standard names. */ #define vPortSVCHandler SVC_Handler #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #endif /* FREERTOS_CONFIG_H */ |
|
|
|
|
|
至此,FreeRTOS的移植工作就完成了,剩下就是系统配置和应用了。其中系统配置,会在第7章专门进行讲解。
5.2.2 FreeRTOS操作系统应用实例 FreeRTOSConfig.h配置文件里面几个重要选项说明: u #define configUSE_PREEMPTION 1 使能抢占式调度器 u #define configCPU_CLOCK_HZ ( ( unsigned long ) 72000000 ) 系统主频72MHz。 u #define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) 系统时钟节拍1KHz,即1ms。 u #define configMAX_PRIORITIES ( 5 ) 定义可供用户使用的最大优先级数,如果这个定义的是5,那么用户可以使用的优先级号是0,1,2,3,4,不包含5,对于这一点,初学者要特别的注意。 u #define configTOTAL_HEAP_SIZE ( ( size_t ) ( 17 * 1024 ) ) 定义堆大小,FreeRTOS内核,用户动态内存申请,任务栈等都需要用这个空间。 |
|
|
|
|
|
经过上面的移植和配置之后,在main.c文件中添加如下代码,代码中简单地创建了四个用户任务:
vTaskTaskUserIF任务:接口消息处理,这里用作LED闪烁。 AppTaskLED任务 :LED闪烁。 vTaskMsgPro 任务 :消息处理,这里用作LED闪烁。 AppTaskStart任务 :启动任务,也是最高优先级任务,这里实现LED闪烁。 #include "includes.h" /* ********************************************************************************************************** 函数声明 ********************************************************************************************************** */ static void vTaskTaskUserIF(void *pvParameters); static void vTaskLED(void *pvParameters); static void vTaskMsgPro(void *pvParameters); static void vTaskStart(void *pvParameters); static void AppTaskCreate (void); /* ********************************************************************************************************** 变量声明 ********************************************************************************************************** */ static TaskHandle_t xHandleTaskUserIF = NULL; static TaskHandle_t xHandleTaskLED = NULL; static TaskHandle_t xHandleTaskMsgPro = NULL; static TaskHandle_t xHandleTaskStart = NULL; /* ********************************************************************************************************* * 函 数 名: main * 功能说明: 标准c程序入口。 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ int main(void) { /* 在启动调度前,为了防止初始化STM32外设时有中断服务程序执行,这里禁止全局中断(除了NMI和HardFault)。 这样做的好处是: 1. 防止执行的中断服务程序中有FreeRTOS的API函数。 2. 保证系统正常启动,不受别的中断影响。 3. 关于是否关闭全局中断,大家根据自己的实际情况设置即可。 在移植文件port.c中的函数prvStartFirstTask中会重新开启全局中断。通过指令cpsie i开启,__set_PRIMASK(1) 和cpsie i是等效的。 */ __set_PRIMASK(1); /* 硬件初始化 */ bsp_Init(); /* 创建任务 */ AppTaskCreate(); /* 启动调度,开始执行任务 */ vTaskStartScheduler(); /* 如果系统正常启动是不会运行到这里的,运行到这里极有可能是用于定时器任务或者空闲任务的 heap空间不足造成创建失败,此要加大FreeRTOSConfig.h文件中定义的heap大小: #define configTOTAL_HEAP_SIZE ( ( size_t ) ( 17 * 1024 ) ) */ while(1); } /* ********************************************************************************************************* * 函 数 名: vTaskTaskUserIF * 功能说明: 接口消息处理,这里用作LED闪烁 * 形 参: pvParameters 是在创建该任务时传递的形参 * 返 回 值: 无 * 优 先 级: 1 (数值越小优先级越低,这个跟uCOS相反) ********************************************************************************************************* */ static void vTaskTaskUserIF(void *pvParameters) { while(1) { bsp_LedToggle(1); vTaskDelay(100); } } /* ********************************************************************************************************* * 函 数 名: vTaskLED * 功能说明: LED闪烁 * 形 参: pvParameters 是在创建该任务时传递的形参 * 返 回 值: 无 * 优 先 级: 2 ********************************************************************************************************* */ static void vTaskLED(void *pvParameters) { while(1) { bsp_LedToggle(2); vTaskDelay(200); } } /* ********************************************************************************************************* * 函 数 名: vTaskMsgPro * 功能说明: 信息处理,这里是用作LED闪烁 * 形 参: pvParameters 是在创建该任务时传递的形参 * 返 回 值: 无 * 优 先 级: 3 ********************************************************************************************************* */ static void vTaskMsgPro(void *pvParameters) { while(1) { bsp_LedToggle(3); vTaskDelay(300); } } /* ********************************************************************************************************* * 函 数 名: vTaskStart * 功能说明: 启动任务,也就是最高优先级任务,这里用作LED闪烁 * 形 参: pvParameters 是在创建该任务时传递的形参 * 返 回 值: 无 * 优 先 级: 4 ********************************************************************************************************* */ static void vTaskStart(void *pvParameters) { while(1) { /* LED闪烁 */ bsp_LedToggle(4); vTaskDelay(400); } } /* ********************************************************************************************************* * 函 数 名: AppTaskCreate * 功能说明: 创建应用任务 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ static void AppTaskCreate (void) { xTaskCreate( vTaskTaskUserIF, /* 任务函数 */ "vTaskUserIF", /* 任务名 */ 512, /* 任务栈大小,单位word,也就是4字节 */ NULL, /* 任务参数 */ 1, /* 任务优先级*/ &xHandleTaskUserIF ); /* 任务句柄 */ xTaskCreate( vTaskLED, /* 任务函数 */ "vTaskLED", /* 任务名 */ 512, /* 任务栈大小,单位word,也就是4字节 */ NULL, /* 任务参数 */ 2, /* 任务优先级*/ &xHandleTaskLED ); /* 任务句柄 */ xTaskCreate( vTaskMsgPro, /* 任务函数 */ "vTaskMsgPro", /* 任务名 */ 512, /* 任务栈大小,单位word,也就是4字节 */ NULL, /* 任务参数 */ 3, /* 任务优先级*/ &xHandleTaskMsgPro ); /* 任务句柄 */ xTaskCreate( vTaskStart, /* 任务函数 */ "vTaskStart", /* 任务名 */ 512, /* 任务栈大小,单位word,也就是4字节 */ NULL, /* 任务参数 */ 4, /* 任务优先级*/ &xHandleTaskStart ); /* 任务句柄 */ } |
|
|
|
|
|
5.3 STM32F407移植FreeRTOS系统
5.3.1 FreeRTOS操作系统移植 首先准备好一个简单的裸机工程模板,工程模板的制作就不做讲解了,这里的重点是教大家移植FreeRTOS系统。准备好的工程模板如下图5.2所示(大家也可以制作其它任意的工程模板,不限制): 图5.2 工程模板 准备好工程模板后,就可以开始移植了。首先要做的就是将所有需要的源码文件放到工程模板里面。下面分六步为大家进行说明,当然,不限制必须使用下面的方法添加源码到工程,只要将需要的文件添加到工程模板即可。 u 第1步:从网址https://sourceforge.net/projects/freertos/files/FreeRTOS/V8.2.3/ 下载V8.2.3版本,这个是8.X系列里面最高版本了,9.0版本还处于测试阶段,我们暂不使用。 FreeRTOSV8.2.3.zip和FreeRTOSV8.2.3.exe内容是一样的,只是后缀为exe的压缩率更高些。下载后解压出来。 |
|
|
|
|
|
第2步:在工程模板创建FreeRTOS文件夹
u 第3步:添加源码文件到相应文件夹 l 将FreeRTOSV8.2.3软件包中路径:FreeRTOSV8.2.3FreeRTOSSource里面如下所有文件 复制到刚刚创建的FreeRTOS文件夹下。 l 文件夹User中还需要添加如下文件: 文件FreeRTOSConfig.h文件在FreeRTOSV8.2.3软件包中的中的路径:FreeRTOSV8.2.3FreeRTOSDemoCORTEX_M4F_STM32F407ZG-SK,其实就是官方整理好的配置文件。 u 第3步:将源码文件添加到MDK的工程项目中,添加后的效果如下: 其中heap_4.c文件路径:FreeRTOSSourceportableMemMang port.c和portmacro.h文件的路径:FreeRTOS SourceportableRVDSARM_CM4F,由于STM32F407是M4内核的,所以移植文件也要添加M4内核的。 |
|
|
|
|
|
第4步:新创建一个includes.h文件,将所有的头文件都集中到这个头文件下。
这样做的好处是引用头文件的时候,只添加这个头文件就可以了。includes.h文件放在了User文件夹中。然后再将这个文件也添加到MDK工程项目中(将.h文件添加到工程的好处是方便查看和修改) |
|
|
|
|
|
ncludes.h文件中的内容如下:/*
/* ********************************************************************************************************* * * 模块名称 : 头文件汇总 * 文件名称 : includes.h * 版 本 : V1.0 * 说 明 : 当前使用头文件汇总 * * 修改记录 : * 版本号 日期 作者 说明 * V1.0 2015-08-02 Eric2013 首次发布 * * Copyright (C), 2015-2020, 安富莱电子 www.armfly.com * ********************************************************************************************************* */ #ifndef __INCLUDES_H__ #define __INCLUDES_H__ /* ********************************************************************************************************* * 标准库 ********************************************************************************************************* */ #include #include #include #include /* ********************************************************************************************************* * 其它库 ********************************************************************************************************* */ /* ********************************************************************************************************* * OS ********************************************************************************************************* */ #include "FreeRTOS.h" #include "task.h" #include "queue.h" #include "croutine.h" /* ********************************************************************************************************* * 宏定义 ********************************************************************************************************* */ /* ********************************************************************************************************* * APP / BSP ********************************************************************************************************* */ #include #endif |
|
|
|
|
|
第5步:添加相应的头文件路径,在原来工程模板的基础上新添加的两个路径:
u 第6步:最后一步,同时也是最重要的一步,修改FreeRTOSConfig.h配置文件(用户根据自己的配置进行修改,不修改也是没问题的,我们这里进行修改主要是为了方便初学者学习),主要修改了以下两个方面: l 添加宏定义__NVIC_PRIO_BITS,STM32系列产品优先级仅使用4位。 l 修改优先级相关的几个宏定义,具体修改了哪个可以对比原始文件查看。 修改后在这个文件的末尾加上Systick,PendSV和SVC中断函数的宏定义,目的是将FreeRTOS移植文件port.c文件里面的中断服务程序映射到CMSIS定义的标准名称,这样就不需要用户去修改工程启动代码中这几个中断的名字了,很方便就实现了两个函数的统一。(移植过uCOS-II或者III的用户,对于这个问题估计深有体会,因为uCOS要修改启动文件,其实采用这里的方式更方便) |
|
|
|
|
|
/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
standard names. */ #define vPortSVCHandler SVC_Handler #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler |
|
|
|
|
|
其中vPortSVCHandler,xPortPendSVHandler和xPortSysTickHandler是在port.c文件里面定义的。SVC_Handler,PendSV_Handler和SysTick_Handler在startup_stm32f10x_hd.s文件里面进行了定义。
下面是FreeRTOSConfig.h配置文件的完整内容: #ifndef FREERTOS_CONFIG_H #define FREERTOS_CONFIG_H /*----------------------------------------------------------- * Application specific definitions. * * These definitions should be adjusted for your particular hardware and * application requirements. * * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. * * See http://www.freertos.org/a00110.html. *----------------------------------------------------------*/ #define configUSE_PREEMPTION 1 #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configCPU_CLOCK_HZ ( ( unsigned long ) 168000000 ) #define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( ( unsigned short ) 128 ) #define configTOTAL_HEAP_SIZE ( ( size_t ) ( 30 * 1024 ) ) #define configMAX_TASK_NAME_LEN ( 16 ) #define configUSE_TRACE_FACILITY 0 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) /* Set the following definitions to 1 to include the API function, or zero to exclude the API function. */ #define INCLUDE_vTaskPrioritySet 1 #define INCLUDE_uxTaskPriorityGet 1 #define INCLUDE_vTaskDelete 1 #define INCLUDE_vTaskCleanUpResources 0 #define INCLUDE_vTaskSuspend 1 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 /* Cortex-M specific definitions. */ #ifdef __NVIC_PRIO_BITS /* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */ #define configPRIO_BITS __NVIC_PRIO_BITS #else #define configPRIO_BITS 4 /* 15 priority levels */ #endif /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0x0f /* The highest interrupt priority that can be used by any interrupt service routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER PRIORITY THAN THIS! (higher priorities are lower numeric values. */ #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 0x01 /* Interrupt priorities used by the kernel port layer itself. These are generic to all Cortex-M ports, and do not rely on any particular library functions. */ #define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) /* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ #define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) /* Normal assert() semantics without relying on the provision of an assert.h header file. */ #define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); } /* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS standard names. */ #define vPortSVCHandler SVC_Handler #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #endif /* FREERTOS_CONFIG_H */ |
|
|
|
|
|
至此,FreeRTOS的移植工作就完成了,剩下就是系统配置和应用了。其中系统配置,会在第7章专门进行讲解。
5.3.2 FreeRTOS操作系统应用实例 FreeRTOSConfig.h配置文件里面几个重要选项说明: u #define configUSE_PREEMPTION 1 使能抢占式调度器 u #define configCPU_CLOCK_HZ ( ( unsigned long ) 168000000 ) 系统主频168MHz。 u #define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) 系统时钟节拍1KHz,即1ms。 u #define configMAX_PRIORITIES ( 5 ) 定义可供用户使用的最大优先级数,如果这个定义的是5,那么用户可以使用的优先级号是0,1,2,3,4,不包含5,对于这一点,初学者要特别的注意。 u #define configTOTAL_HEAP_SIZE ( ( size_t ) ( 30 * 1024 ) ) 定义堆大小,FreeRTOS内核,用户动态内存申请,任务栈等都需要用这个空间。 ----------------------------------------------------------------------------------------- |
|
|
|
|
|
经过上面的移植和配置之后,在main.c文件中添加如下代码,代码中简单的创建了四个用户任务:
vTaskTaskUserIF任务:接口消息处理,这里用作LED闪烁。 AppTaskLED任务 :LED闪烁。 vTaskMsgPro 任务 :消息处理,这里用作LED闪烁。 AppTaskStart任务 :启动任务,也是最高优先级任务,这里实现LED闪烁。 #include "includes.h" /* ********************************************************************************************************** 函数声明 ********************************************************************************************************** */ static void vTaskTaskUserIF(void *pvParameters); static void vTaskLED(void *pvParameters); static void vTaskMsgPro(void *pvParameters); static void vTaskStart(void *pvParameters); static void AppTaskCreate (void); /* ********************************************************************************************************** 变量声明 ********************************************************************************************************** */ static TaskHandle_t xHandleTaskUserIF = NULL; static TaskHandle_t xHandleTaskLED = NULL; static TaskHandle_t xHandleTaskMsgPro = NULL; static TaskHandle_t xHandleTaskStart = NULL; /* ********************************************************************************************************* * 函 数 名: main * 功能说明: 标准c程序入口。 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ int main(void) { /* 在启动调度前,为了防止初始化STM32外设时有中断服务程序执行,这里禁止全局中断(除了NMI和HardFault)。 这样做的好处是: 1. 防止执行的中断服务程序中有FreeRTOS的API函数。 2. 保证系统正常启动,不受别的中断影响。 3. 关于是否关闭全局中断,大家根据自己的实际情况设置即可。 在移植文件port.c中的函数prvStartFirstTask中会重新开启全局中断。通过指令cpsie i开启,__set_PRIMASK(1) 和cpsie i是等效的。 */ __set_PRIMASK(1); /* 硬件初始化 */ bsp_Init(); /* 创建任务 */ AppTaskCreate(); /* 启动调度,开始执行任务 */ vTaskStartScheduler(); /* 如果系统正常启动是不会运行到这里的,运行到这里极有可能是用于定时器任务或者空闲任务的 heap空间不足造成创建失败,此要加大FreeRTOSConfig.h文件中定义的heap大小: #define configTOTAL_HEAP_SIZE ( ( size_t ) ( 17 * 1024 ) ) */ while(1); } /* ********************************************************************************************************* * 函 数 名: vTaskTaskUserIF * 功能说明: 接口消息处理,这里用作LED闪烁 * 形 参: pvParameters 是在创建该任务时传递的形参 * 返 回 值: 无 * 优 先 级: 1 (数值越小优先级越低,这个跟uCOS相反) ********************************************************************************************************* */ static void vTaskTaskUserIF(void *pvParameters) { while(1) { bsp_LedToggle(1); vTaskDelay(100); } } /* ********************************************************************************************************* * 函 数 名: vTaskLED * 功能说明: LED闪烁 * 形 参: pvParameters 是在创建该任务时传递的形参 * 返 回 值: 无 * 优 先 级: 2 ********************************************************************************************************* */ static void vTaskLED(void *pvParameters) { while(1) { bsp_LedToggle(2); vTaskDelay(200); } } /* ********************************************************************************************************* * 函 数 名: vTaskMsgPro * 功能说明: 信息处理,这里是用作LED闪烁 * 形 参: pvParameters 是在创建该任务时传递的形参 * 返 回 值: 无 * 优 先 级: 3 ********************************************************************************************************* */ static void vTaskMsgPro(void *pvParameters) { while(1) { bsp_LedToggle(3); vTaskDelay(300); } } /* ********************************************************************************************************* * 函 数 名: vTaskStart * 功能说明: 启动任务,也就是最高优先级任务,这里用作LED闪烁 * 形 参: pvParameters 是在创建该任务时传递的形参 * 返 回 值: 无 * 优 先 级: 4 ********************************************************************************************************* */ static void vTaskStart(void *pvParameters) { while(1) { /* LED闪烁 */ bsp_LedToggle(4); vTaskDelay(400); } } /* ********************************************************************************************************* * 函 数 名: AppTaskCreate * 功能说明: 创建应用任务 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ static void AppTaskCreate (void) { xTaskCreate( vTaskTaskUserIF, /* 任务函数 */ "vTaskUserIF", /* 任务名 */ 512, /* 任务栈大小,单位word,也就是4字节 */ NULL, /* 任务参数 */ 1, /* 任务优先级*/ &xHandleTaskUserIF ); /* 任务句柄 */ xTaskCreate( vTaskLED, /* 任务函数 */ "vTaskLED", /* 任务名 */ 512, /* 任务栈大小,单位word,也就是4字节 */ NULL, /* 任务参数 */ 2, /* 任务优先级*/ &xHandleTaskLED ); /* 任务句柄 */ xTaskCreate( vTaskMsgPro, /* 任务函数 */ "vTaskMsgPro", /* 任务名 */ 512, /* 任务栈大小,单位word,也就是4字节 */ NULL, /* 任务参数 */ 3, /* 任务优先级*/ &xHandleTaskMsgPro ); /* 任务句柄 */ xTaskCreate( vTaskStart, /* 任务函数 */ "vTaskStart", /* 任务名 */ 512, /* 任务栈大小,单位word,也就是4字节 */ NULL, /* 任务参数 */ 4, /* 任务优先级*/ &xHandleTaskStart ); /* 任务句柄 */ } |
|
|
|
|
|
除了创建的4个用户任务以外,还有空闲任务,这个任务是系统创建的。至此,FreeRTOS的工程就可以运行了。可以看到4个LED在闪烁。
|
|
|
|
|
|
5.4 STM32F429移植FreeRTOS系统
5.4.1 FreeRTOS操作系统移植 首先准备好一个简单的裸机工程模板,工程模板的制作就不做讲解了,这里的重点是教大家移植FreeRTOS系统。准备好的工程模板如下图5.3所示(大家也可以制作其它任意的工程模板,不限制): 图5.3 工程模板 准备好工程模板后,就可以开始移植了。首先要做的就是将所有需要的源码文件放到工程模板里面。下面分六步和大家进行说明,当然,不限制必须使用下面的方法添加源码到工程,只要将需要的文件添加到工程模板即可。 |
|
|
|
|
|
690 浏览 0 评论
735 浏览 1 评论
基于瑞萨FPB-RA4E2智能床头灯项目——1编译环境搭建与点亮驱动ws2812全彩LED
624 浏览 0 评论
嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-LCD显示图片编程示例之介绍mmap
1099 浏览 0 评论
《DNESP32S3使用指南-IDF版_V1.6》第二章 常用的C语言知识点
1092 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
11794 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-26 11:21 , Processed in 0.974989 second(s), Total 99, Slave 82 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号