在玩32板子的时候,碰到一些好几个任务同时工作的工程时,有必要在系统上运行,而轻便高效且易移植的小型系统中,freertos无疑是最好的选择。下面,就来一步一步移植freeRTOS系统吧。
首先下载freertos系统,目前的版本是v10.2.1。对于移植来说,只有FreeRTOS中的文件是有用的,但也并不是全部需要。
源码中的文件结构如下:
Demon:适配各个平台的模板工程,需要CORTEX_STM32F103_Primer_GCC文件夹中的FreeRTOSConfig.h文件
License:没用
Soure:文件结构如下图
文件中包括7个c文件,其中list.c、queue.c和tasks.c是每个工程都需要的文件,其他的建议都加上。
include文件夹中包含了系统所需要的头文件
portable文件夹中包含了不同平台的接口,需要其中的文件。注意:MemMang文件夹中是有关freertos系统内存的文件,这个不能删除。
下面开始移植:
以管理员身份运行keil并新建一个空白工程
芯片选型见下图
运行环境管理配置如下图
拷贝stm32内核文件及标准外设文件
在工程路径下创建CMSIS 、STM32F10x_StdPeriph_Driver和User三个文件夹
CMSIS:将历程中有关文件拷贝到此文件夹中,还要拷贝stm32f10x_conf.h文件到此文件夹中。
STM32F10x_StdPeriph_Driver:将有关外设的头文件和源码拷贝到此文件中
User:创建main.c文件,拷贝
在keil中添加CMSIS 、STM32F10x_StdPeriph_Driver和User三个组并添加第二步中添加的文件,工程结构图结果如下图所示:
设置编译选项
编译
未报错,很好。
拷贝freertos文件
在工程路径下建立freeRTOS文件夹,将下载的freertos源文件中souurce-》include 和一些c文件拷贝到其中;
将source-》portable-》RVDS-》ARM_CM3中对应的port.c和portmacro.h文件拷贝到其中。
将source-》MemMang中heap_4.c文件拷贝到其中。
将FreeRTOSv10.2.1FreeRTOSDemoCORTEX_STM32F107_GCC_Rowley的FreeRTOSConfig.h拷贝到include中。
在keil工程中建立freeRTOS分组添加freeRTOS文件夹下所有c文件,并在编译路径中添加其头文件。如图:
编译
编译产生错误
这是因为从源文件Demon中拷贝的FreeRTOSConfig.h文件未按照实际做修改的原因,要修改一下几点
#define configUSE_TICK_HOOK 1 此处将1改为0
#define configCPU_CLOCK_HZ ( ( unsigned long ) 62500000 ) 此处将62500000 改为72000000
#define configCHECK_FOR_STACK_OVERFLOW 2 此处将2改为0
然后编译,产生如下错误:
解决这个问题,要在freeRTOS源文件中的tasks.c文件中添加关于ulRunTimeStatsClock的定义,在文件末添加一行代码即可
编译,未出错。很好。
修改stm32启动文件,因为freeRTOS系统的调度需要用到是stm32的中断,所以需要替换一些接口,具体如下图所示:
新添加内容为:
IMPORT xPortPendSVHandler
IMPORT xPortSysTickHandler
IMPORT vPortSVCHandler
新替换内容为:
DCD SVC_Handler -》 vPortSVCHandler
DCD PendSV_Handler -》 xPortPendSVHandler
DCD SysTick_Handler -》 xPortSysTickHandler
修改文成后,重新编译此工程。
编译,未出错。很好。
至此移植过程已经结束,下面就是系统的应用了。
freeRTOS应用实例:
系统中运行三个任务,简单的使用串口打印task_i2c 、 task_can、 task_uart。
主函数如下:
#include “stm32f10x.h”
#include “FreeRTOS.h”
#include “task.h”
#include “main.h”
#include “uart.h”
#define START_TASK_PRIO ((unsigned portBASE_TYPE)2U)
#define START_STK_SIZE 32
xTaskHandle StartTask_Handler;
#define I2C_TASK_PRIO ((unsigned portBASE_TYPE)3U)
#define I2C_STK_SIZE 64
xTaskHandle i2cTask_Handler;
#define CAN_TASK_PRIO ((unsigned portBASE_TYPE)3U)
#define CAN_STK_SIZE 64
xTaskHandle canTask_Handler;
#define UART_TASK_PRIO ((unsigned portBASE_TYPE)3U)
#define UART_STK_SIZE 64
xTaskHandle uartTask_Handler;
void task_i2c(void)
{
while(1)
{
printf(“rn task_i2c rn”);
vTaskDelay(100);
}
}
void task_can(void)
{
while(1)
{
printf(“rn task_can rn”);
vTaskDelay(100);
}
}
void task_uart(void)
{
while(1)
{
printf(“rn task_uart rn”);
vTaskDelay(100);
}
}
void vStartTaskCreate(void *pvParameters)
{
taskENTER_CRITICAL();
xTaskCreate((TaskFunction_t)task_i2c, (const char *)“task_i2c”, I2C_STK_SIZE, (void *)NULL, I2C_TASK_PRIO, (xTaskHandle *)i2cTask_Handler);
xTaskCreate((TaskFunction_t)task_can, (const char *)“task_can”, CAN_STK_SIZE, (void *)NULL, CAN_TASK_PRIO, (xTaskHandle *)canTask_Handler);
xTaskCreate((TaskFunction_t)task_uart, (const char *)“task_uart”, UART_STK_SIZE, (void *)NULL, UART_TASK_PRIO, (xTaskHandle *)uartTask_Handler);
vTaskDelete(StartTask_Handler);
taskEXIT_CRITICAL();
}
int main(void)
{
SystemInit();
uartInit();
printf(“rn uartInit() ok!!! rn”);
xTaskCreate((pdTASK_CODE)vStartTaskCreate, (const char *)“vStartTaskCreate”,
(uint16_t)START_STK_SIZE, (void *)NULL, (portTickType)START_TASK_PRIO,
(xTaskHandle *)&StartTask_Handler);
vTaskStartScheduler();
while(1);
}
烧进板子后,运行结果如下图所示:
系统可调度执行不同的任务。
在玩32板子的时候,碰到一些好几个任务同时工作的工程时,有必要在系统上运行,而轻便高效且易移植的小型系统中,freertos无疑是最好的选择。下面,就来一步一步移植freeRTOS系统吧。
首先下载freertos系统,目前的版本是v10.2.1。对于移植来说,只有FreeRTOS中的文件是有用的,但也并不是全部需要。
源码中的文件结构如下:
Demon:适配各个平台的模板工程,需要CORTEX_STM32F103_Primer_GCC文件夹中的FreeRTOSConfig.h文件
License:没用
Soure:文件结构如下图
文件中包括7个c文件,其中list.c、queue.c和tasks.c是每个工程都需要的文件,其他的建议都加上。
include文件夹中包含了系统所需要的头文件
portable文件夹中包含了不同平台的接口,需要其中的文件。注意:MemMang文件夹中是有关freertos系统内存的文件,这个不能删除。
下面开始移植:
以管理员身份运行keil并新建一个空白工程
芯片选型见下图
运行环境管理配置如下图
拷贝stm32内核文件及标准外设文件
在工程路径下创建CMSIS 、STM32F10x_StdPeriph_Driver和User三个文件夹
CMSIS:将历程中有关文件拷贝到此文件夹中,还要拷贝stm32f10x_conf.h文件到此文件夹中。
STM32F10x_StdPeriph_Driver:将有关外设的头文件和源码拷贝到此文件中
User:创建main.c文件,拷贝
在keil中添加CMSIS 、STM32F10x_StdPeriph_Driver和User三个组并添加第二步中添加的文件,工程结构图结果如下图所示:
设置编译选项
编译
未报错,很好。
拷贝freertos文件
在工程路径下建立freeRTOS文件夹,将下载的freertos源文件中souurce-》include 和一些c文件拷贝到其中;
将source-》portable-》RVDS-》ARM_CM3中对应的port.c和portmacro.h文件拷贝到其中。
将source-》MemMang中heap_4.c文件拷贝到其中。
将FreeRTOSv10.2.1FreeRTOSDemoCORTEX_STM32F107_GCC_Rowley的FreeRTOSConfig.h拷贝到include中。
在keil工程中建立freeRTOS分组添加freeRTOS文件夹下所有c文件,并在编译路径中添加其头文件。如图:
编译
编译产生错误
这是因为从源文件Demon中拷贝的FreeRTOSConfig.h文件未按照实际做修改的原因,要修改一下几点
#define configUSE_TICK_HOOK 1 此处将1改为0
#define configCPU_CLOCK_HZ ( ( unsigned long ) 62500000 ) 此处将62500000 改为72000000
#define configCHECK_FOR_STACK_OVERFLOW 2 此处将2改为0
然后编译,产生如下错误:
解决这个问题,要在freeRTOS源文件中的tasks.c文件中添加关于ulRunTimeStatsClock的定义,在文件末添加一行代码即可
编译,未出错。很好。
修改stm32启动文件,因为freeRTOS系统的调度需要用到是stm32的中断,所以需要替换一些接口,具体如下图所示:
新添加内容为:
IMPORT xPortPendSVHandler
IMPORT xPortSysTickHandler
IMPORT vPortSVCHandler
新替换内容为:
DCD SVC_Handler -》 vPortSVCHandler
DCD PendSV_Handler -》 xPortPendSVHandler
DCD SysTick_Handler -》 xPortSysTickHandler
修改文成后,重新编译此工程。
编译,未出错。很好。
至此移植过程已经结束,下面就是系统的应用了。
freeRTOS应用实例:
系统中运行三个任务,简单的使用串口打印task_i2c 、 task_can、 task_uart。
主函数如下:
#include “stm32f10x.h”
#include “FreeRTOS.h”
#include “task.h”
#include “main.h”
#include “uart.h”
#define START_TASK_PRIO ((unsigned portBASE_TYPE)2U)
#define START_STK_SIZE 32
xTaskHandle StartTask_Handler;
#define I2C_TASK_PRIO ((unsigned portBASE_TYPE)3U)
#define I2C_STK_SIZE 64
xTaskHandle i2cTask_Handler;
#define CAN_TASK_PRIO ((unsigned portBASE_TYPE)3U)
#define CAN_STK_SIZE 64
xTaskHandle canTask_Handler;
#define UART_TASK_PRIO ((unsigned portBASE_TYPE)3U)
#define UART_STK_SIZE 64
xTaskHandle uartTask_Handler;
void task_i2c(void)
{
while(1)
{
printf(“rn task_i2c rn”);
vTaskDelay(100);
}
}
void task_can(void)
{
while(1)
{
printf(“rn task_can rn”);
vTaskDelay(100);
}
}
void task_uart(void)
{
while(1)
{
printf(“rn task_uart rn”);
vTaskDelay(100);
}
}
void vStartTaskCreate(void *pvParameters)
{
taskENTER_CRITICAL();
xTaskCreate((TaskFunction_t)task_i2c, (const char *)“task_i2c”, I2C_STK_SIZE, (void *)NULL, I2C_TASK_PRIO, (xTaskHandle *)i2cTask_Handler);
xTaskCreate((TaskFunction_t)task_can, (const char *)“task_can”, CAN_STK_SIZE, (void *)NULL, CAN_TASK_PRIO, (xTaskHandle *)canTask_Handler);
xTaskCreate((TaskFunction_t)task_uart, (const char *)“task_uart”, UART_STK_SIZE, (void *)NULL, UART_TASK_PRIO, (xTaskHandle *)uartTask_Handler);
vTaskDelete(StartTask_Handler);
taskEXIT_CRITICAL();
}
int main(void)
{
SystemInit();
uartInit();
printf(“rn uartInit() ok!!! rn”);
xTaskCreate((pdTASK_CODE)vStartTaskCreate, (const char *)“vStartTaskCreate”,
(uint16_t)START_STK_SIZE, (void *)NULL, (portTickType)START_TASK_PRIO,
(xTaskHandle *)&StartTask_Handler);
vTaskStartScheduler();
while(1);
}
烧进板子后,运行结果如下图所示:
系统可调度执行不同的任务。
举报