Featured image of post 移植FreeRTOS

移植FreeRTOS

移植FreeRTOS

下载源码包

去官网下载库文件

FreeRTOS™ - FreeRTOS™

复制需要使用的源代码文件

image-20260411211637604

image-20260411211710267

  1. 复制所有.c文件

  2. 复制include中所有.h文件

  3. protable中的兼容文件

这里使用的是KEIL开发的

image-20260411212054400

这里的打开Keil是一个文本,指向的RVDS中文件

MemMang选择的heap4版本

复制一个芯片的操作系统的裁剪文件

image-20260411212322248

image-20260411212357783

image-20260411212426102

复制FreeRTOSConfig.h文件

freeRTOS运行原理

运用中断

  1. SysTick(系统定时器中断)
  • 作用:产生系统时钟节拍(Tick),是 FreeRTOS 的 “心跳”
  • 频率:默认 1ms 一次(可配置)
  • 工作:每次中断触发时间片轮询、超时检查、延时到期
  • 触发点:定时到 → 进入 SysTick_Handler()
  1. SVC(系统调用中断)
  • 指令:SVC #0
  • 作用:启动第一个任务(从无调度 → 进入第一个任务)
  • 特点:只在系统启动时调用 1 次
  • 触发点:vTaskStartScheduler() 里会触发 SVC
  1. PendSV(可挂起系统调用中断)
  • 作用:任务上下文切换(任务切换的真正执行者)
  • 特点:最低优先级中断,确保所有硬件中断处理完才切换任务
  • 触发点:需要切换任务时,软件置位 PendSV 请求 → 进入 PendSV_Handler()

通过使用freeRTOS中定义的函数,实现

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
启动  vTaskStartScheduler()
       
  初始化硬件、空闲任务
       
  触发 SVC 中断
       
SVC_Handler 启动第一个任务
       
系统正常运行
       
SysTick 定时触发(1ms
       
检查是否需要切换任务
       
需要切换  挂起 PendSV
       
PendSV_Handler 执行上下文切换
       
运行下一个任务
      循环
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
void SVC_Handler(void)
{
  /* USER CODE BEGIN SVCall_IRQn 0 */
  vPortSVCHandler();
  /* USER CODE END SVCall_IRQn 0 */
  /* USER CODE BEGIN SVCall_IRQn 1 */

  /* USER CODE END SVCall_IRQn 1 */
}


void PendSV_Handler(void)
{
  /* USER CODE BEGIN PendSV_IRQn 0 */
  xPortPendSVHandler();
  /* USER CODE END PendSV_IRQn 0 */
  /* USER CODE BEGIN PendSV_IRQn 1 */

  /* USER CODE END PendSV_IRQn 1 */
}

void SysTick_Handler(void)
{
  /* USER CODE BEGIN SysTick_IRQn 0 */
  //手动调用系统滴答处理函数
  if(xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
  {
    //判断调度器是否已经启动,只有在调度器启动后才调用系统滴答处理函数
    xPortSysTickHandler();
  }
  /* USER CODE END SysTick_IRQn 0 */
  HAL_IncTick();
  /* USER CODE BEGIN SysTick_IRQn 1 */

  /* USER CODE END SysTick_IRQn 1 */
}

问题

  1. image-20260411221519983

configTICK_TYPE_WIDTH_IN_BITS 设置为不支持的时钟节拍类型位宽。

Cortex‑M3 推荐 32 位

去FreeRTOSConfig.h中找

1
#define configTICK_TYPE_WIDTH_IN_BITS              TICK_TYPE_WIDTH_32_BITS   //改为32
  1. image-20260411221826163

ucHeap (在 heap_4.o 中被引用)

搜索ucHeap

再去FreeRTOSConfig.h找

1
2
/* 启用动态内存分配(必须为1,heap_4依赖此宏) */
#define configSUPPORT_DYNAMIC_ALLOCATION    1

使用

创建任务

1
2
3
4
5
6
    BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,		//任务入口函数指针
                            const char * const pcName,		//自己定义个名字  任务名字
                            const configSTACK_DEPTH_TYPE uxStackDepth,		//任务堆栈深度
                            void * const pvParameters,		//任务函数参数
                            UBaseType_t uxPriority,			//任务优先级
                            TaskHandle_t * const pxCreatedTask )	//任务句柄 用来操控任务
1
typedef void (* TaskFunction_t)( void * arg );				//定义任务入口函数指针类型

启用任务调度器

1
vTaskStartScheduler();
最后更新于 2026-04-11 23:53
...