以前,使用Keil编译并应用了FreeRTOS,由于Keil的版权原因,个人觉得,使用eclipse环境,是非常不错的替代工具,所以在国庆前花时间将STM32F10x的eclipse编译环境整理好了。
今天,基于新的编译环境,重新构建FreeRTOS应用程序。
首先,从FreeRTOS网上(http://www.freertos.org/RTOS_ports.html)下载V9版本的源码.
在源码中,没有STM32F103的相应工程,所以先试了一下,用eclipse直接导入FreeRTOSv9.0.0\FreeRTOS\Demo\CORTEX_STM32F100_Atollic例子程序,环境配置为STM32F103RC,开始编译,结果存贮器相应的定议有不同,也不相去找原因了,新建立一个工程来吧。
然后,新建立一个工程,建立一个文件夹“FreeRTOS”
并将FreeRTOSv9.0.0\FreeRTOS\Source文件复制到工程下FreeRTOS文件夹中
为了简单,再将FreeRTOSv9.0.0\FreeRTOS\Source\portable\GCC\ARM_CM3下的文件复制到工程下FreeRTOS文件夹中
将FreeRTOSv9.0.0\FreeRTOS\Source\portable\MemMang下的heap_2.c文件复制到工程下FreeRTOS文件夹中
文件准备好了,在工程属性中,加入FreeRTOS的路径。同时刷新eclipse工程,并将FreeRTOS加入编译
要用的port文件都复制出来了,所以需将portable文件夹删掉,或不让eclipse编译。
开始编译,会有错出来:
第一个错:FreeRTOS/port.c:409: undefined reference to `vTaskSwitchContext'
根据 https://sourceforge.net/p/freertos/discussion/382005/thread/9d963808/?limit=25 的讨论,修改task.h的定议,与task.c
task.h文件中:
注释掉函数定义 void vTaskSwitchContext( void ) PRIVILEGED_FUNCTION ;
同样修改为条件编译:
#ifdef __GNUC__ /* << EST: 'used' attribute need for LTO (Link Time Optimization) */
void vTaskSwitchContext( void ) PRIVILEGED_FUNCTION __attribute__((used));
#else
void vTaskSwitchContext( void ) PRIVILEGED_FUNCTION;
#endif
tasks.c文件中:
在void vTaskSwitchContext( void )
前加入条件编译:
#ifdef __GNUC__ /* << EST */
__attribute__((used)) /* using C++ compiler, vTaskSwitchContext() might be removed even with -O0? */
#endif
然后会有第二、三个错,如:
Description Resource Path Location Type
Symbol 'configMAX_PRIORITIES' could not be resolved tasks.c /ETA321_APP/FreeRTOS line 384 Semantic Error
这不知道是什么原因,也没有影响到编译结果,索性在tasks.c中添加相并的定义,一共在这里加入了三个定义(这些定义其实都在freertosconfig.h中已有,但没有链接上)
#define configMAX_PRIORITIES ( 5 )
#define configMAX_TASK_NAME_LEN ( 16 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 120 )
同样的,port.c文件中,也出了类似的问题,先不管,直接给它定义上再说
#define configCPU_CLOCK_HZ ( ( unsigned long ) 72000000 )
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
再编译,通过。
然后,修改中断向量表的定义。我们不直接修改,而是用宏定义的方式,进行替换。我换的文件是ExceptionHandlers.h中,关于 SVC_Handler (void);PendSV_Handler (void);SysTick_Handler (void);的定义转向。这样修改的:
原代码是:
extern void
SVC_Handler (void);
extern void
PendSV_Handler (void);
extern void
SysTick_Handler (void);
替换成这样:
#ifdef __GNUC__ // zxw for freertos
extern void vPortSVCHandler( void );
extern void xPortPendSVHandler( void );
extern void xPortSysTickHandler( void );
#define SVC_Handler vPortSVCHandler
#define PendSV_Handler xPortPendSVHandler
#define SysTick_Handler xPortSysTickHandler
#else
extern void
SVC_Handler (void);
extern void
PendSV_Handler (void);
extern void
SysTick_Handler (void);
#endif
到现在该修改的FreeRTOS相关的,都修改了,可以建立一个任务,测试一下子。
基本地,需要在代码中引用这几个头文件
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "timers.h"