STM32F107RBT6移植freeRTOS

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_43608153/article/details/98778480

在玩32板子的时候,碰到一些好几个任务同时工作的工程时,有必要在系统上运行,而轻便高效且易移植的小型系统中,freertos无疑是最好的选择。下面,就来一步一步移植freeRTOS系统吧。

首先下载freertos系统,目前的版本是v10.2.1。对于移植来说,只有FreeRTOS中的文件是有用的,但也并不是全部需要。
源码中的文件结构如下:
在这里插入图片描述
Demon:适配各个平台的模板工程,需要CORTEX_STM32F103_Primer_GCC文件夹中的FreeRTOSConfig.h文件
License:没用
Soure:文件结构如下图
123
文件中包括7个c文件,其中list.c、queue.c和tasks.c是每个工程都需要的文件,其他的建议都加上。
include文件夹中包含了系统所需要的头文件
portable文件夹中包含了不同平台的接口,需要其中的文件。注意:MemMang文件夹中是有关freertos系统内存的文件,这个不能删除。

下面开始移植:

  1. 以管理员身份运行keil并新建一个空白工程
    芯片选型见下图
    在这里插入图片描述
    运行环境管理配置如下图
    在这里插入图片描述

  2. 拷贝stm32内核文件及标准外设文件
    在工程路径下创建CMSIS 、STM32F10x_StdPeriph_Driver和User三个文件夹
    CMSIS:将历程中有关文件拷贝到此文件夹中,还要拷贝stm32f10x_conf.h文件到此文件夹中。
    STM32F10x_StdPeriph_Driver:将有关外设的头文件和源码拷贝到此文件中
    User:创建main.c文件,拷贝

  3. 在keil中添加CMSIS 、STM32F10x_StdPeriph_Driver和User三个组并添加第二步中添加的文件,工程结构图结果如下图所示:
    在这里插入图片描述

  4. 设置编译选项
    在这里插入图片描述
    在这里插入图片描述

  5. 编译
    在这里插入图片描述
    未报错,很好。

  6. 拷贝freertos文件
    在工程路径下建立freeRTOS文件夹,将下载的freertos源文件中souurce->include 和一些c文件拷贝到其中;
    将source->portable->RVDS->ARM_CM3中对应的port.c和portmacro.h文件拷贝到其中。
    将source->MemMang中heap_4.c文件拷贝到其中。
    将\FreeRTOSv10.2.1\FreeRTOS\Demo\CORTEX_STM32F107_GCC_Rowley\的FreeRTOSConfig.h拷贝到include中。

  7. 在keil工程中建立freeRTOS分组添加freeRTOS文件夹下所有c文件,并在编译路径中添加其头文件。如图:
    在这里插入图片描述在这里插入图片描述

  8. 编译
    编译产生错误
    在这里插入图片描述
    这是因为从源文件Demon中拷贝的FreeRTOSConfig.h文件未按照实际做修改的原因,要修改一下几点

    1. #define configUSE_TICK_HOOK 1 此处将1改为0
    2. #define configCPU_CLOCK_HZ ( ( unsigned long ) 62500000 ) 此处将62500000 改为72000000
    3. #define configCHECK_FOR_STACK_OVERFLOW 2 此处将2改为0
      然后编译,产生如下错误:
      在这里插入图片描述
      解决这个问题,要在freeRTOS源文件中的tasks.c文件中添加关于ulRunTimeStatsClock的定义,在文件末添加一行代码即可
      在这里插入图片描述
      编译,未出错。很好。
  9. 修改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("\r\n task_i2c \r\n");
        vTaskDelay(100);
    }
}


void task_can(void)
{
		while(1)
		{
		    printf("\r\n task_can \r\n");
            vTaskDelay(100);
		}
}


void task_uart(void)
{
    while(1)
		{
        printf("\r\n task_uart \r\n");
        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("\r\n uartInit() ok!!! \r\n");
    xTaskCreate((pdTASK_CODE)vStartTaskCreate, (const char *)"vStartTaskCreate",
                (uint16_t)START_STK_SIZE, (void *)NULL, (portTickType)START_TASK_PRIO,
                (xTaskHandle *)&StartTask_Handler);
    vTaskStartScheduler();

    while(1);

}

烧进板子后,运行结果如下图所示:
在这里插入图片描述
系统可调度执行不同的任务。

猜你喜欢

转载自blog.csdn.net/weixin_43608153/article/details/98778480