STM32F103C8T6标准库移植FreeRTOS教程

STM32F103C8T6标准库移植FreeRTOS教程

基础项目

找一个基础的Keil项目,在项目根目录里面新建一个FreeRTOS文件夹

image-20250911110731118

不同型号单片机的区别点

  • RVDS
  • 配置文件

Source

在里面新建Source文件夹

image-20250911110752565

把FreeRTOS源码的七个c文件复制到刚刚新建的Source文件夹里面

image-20250911110843750

portable

在项目的FreeRTOS文件夹里面新建一个portable文件夹

把FreeRTOS源码的RVDS文件夹复制过去

image-20250911111013260

只保留需要的即可。

这里我们保留ARM_CM3

image-20250911111021092

拷贝内存管理文件夹MemMang到项目的portable文件夹

image-20250911111157850

保留4即可,其余的删除。

image-20250911111204050

include

复制include文件夹到FreeRTOS文件夹下面

image-20250911111451170

结果如下

image-20250911111458090

寻找配置文件

到\FreeRTOSv202212.01\FreeRTOS\Demo文件夹下面去找一个对应的

源码里面没有demo的,去这里下载

https://github.com/FreeRTOS/FreeRTOS/releases/tag/202212.01

image-20250722215701708

image-20250911112033412

复制FreeRTOSConfig.h到项目的Core/Inc下面或者USER文件夹下面

image-20250911112043142

添加组

在工程里面新建下面两个组

  • FreeRTOS/Source

  • FreeRTOS/Portable

把7个c文件添加到FreeRTOS/Source里面去

image-20250911112819726

FreeRTOS/Portable添加port.c和heap_4.c文件

image-20250911114407098

添加Include路径

把有头文件的文件夹添加到Include Paths里面

image-20250911113026671

只有这两个文件夹里面有头文件存在

修改配置文件

打开FreeRTOSConfig.h

添加三个宏

#define xPortPendSVHandler  PendSV_Handler // 用于上下文切换(任务切换)
#define vPortSVCHandler     SVC_Handler // 用于启动第一个任务。
#define xPortSysTickHandler SysTick_Handler // `重命名系统节拍函数

image-20250911131122081

注释中断处理函数

注释掉stm32f1xx_it.c文件里面的SVC_Handler和PendSV_Handler这两个函数,避免重复定义

以及注释SysTick_Handler函数,屏蔽这个中断函数,直接使用freertos的时钟函数来作为嘀嗒定时器回调

109行

image-20250911114812567

126行

image-20250911114832007

136行

image-20250911115753257

测试程序

freertos_demo.h

#ifndef __FREERTOS_DEMO_H
#define __FREERTOS_DEMO_H
void freertos_start(void);
#endif

freertos_demo.c

#include "freertos_demo.h"
#include "FreeRTOS.h"
#include "task.h"
#include <stdio.h>
#include "led.h"

#define START_TASK_STACK 128
#define START_TASK_PRIORITY 1
TaskHandle_t start_task_handle;
void start_task(void *pvParameters);

#define TASK1_STACK 128
#define TASK1_PRIORITY 2
TaskHandle_t task1_handle;
void task1(void *pvParameters);

#define TASK2_STACK 128
#define TASK2_PRIORITY 3
TaskHandle_t task2_handle;
void task2(void *pvParameters);

#define TASK3_STACK 128
#define TASK3_PRIORITY 4
TaskHandle_t task3_handle;
void task3(void *pvParameters);

/// @brief 启动FreeRTOS
/// @param
void freertos_start(void)
{
  /* 1. 创建一个启动任务 */
  xTaskCreate(start_task,
              "start_task",
              START_TASK_STACK, NULL,
              START_TASK_PRIORITY,
              &start_task_handle);
  /* 2. 启动任务调度器 */
  vTaskStartScheduler();
}

void start_task(void *pvParameters)
{
  /* 进入临界区 */
  taskENTER_CRITICAL();
  xTaskCreate(task1,
              "start_task",
              TASK1_STACK, NULL,
              TASK1_PRIORITY,
              &task1_handle);

  /* xTaskCreate(task2,
              "start_task",
              TASK2_STACK, NULL,
              TASK2_PRIORITY,
              &task2_handle);

  xTaskCreate(task3,
              "start_task",
              TASK3_STACK, NULL,
              TASK3_PRIORITY,
              &task3_handle);
 */
  /* 删除启动任务自己 */
  vTaskDelete(NULL);

  /* 退出临界区 */
  taskEXIT_CRITICAL();
}

void task1(void *pvParameters)
{
  while (1)
  {
    printf("task1运行中...\r\n");
    LED_Toggle();
    vTaskDelay(500);
  }
  
}

/* void task2(void *pvParameters)
{
  while (1)
  {
    printf("task2运行中...\r\n");
    HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_5);
    vTaskDelay(500);
  }
}

void task3(void *pvParameters)
{
  uint8_t key = 0;
  while (1)
  {
    printf("task3运行中...\r\n");
    key = Key_Detect();
    if(key == KEY1_PRESS){
      if(task1_handle!=NULL){
        printf("执行删除task1");
        vTaskDelete(task1_handle);
        task1_handle=NULL;
      }
    }
    vTaskDelay(500);
  }
} */

main.c

xxxx
#include "freertos_demo.h"
xxxx
int main(void)
{
freertos_start();
}

参考教程

posted @ 2025-09-11 14:40  海浪博客  阅读(304)  评论(0)    收藏  举报