目录
[4.1 头文件目录](#4.1 头文件目录)
[4.2 头文件](#4.2 头文件)
[7.1 数据类型](#7.1 数据类型)
[7.2 变量名](#7.2 变量名)
[7.3 函数名](#7.3 函数名)
[7.4 宏的名](#7.4 宏的名)
1、FreeRTOS目录结构
使用 STM32CubeMX 创建的 FreeRTOS 工程中,FreeRTOS 相关的源码如下:
主要涉及2个目录:
- Core
- Inc 目录下的 FreeRTOSConfig.h 是配置文件
- Src 目录下的 freertos.c 是 STM32CubeMX 创建的默认任务
- Middlewares\Third_Party\FreeRTOS\Source
- 根目录下是核心文件,这些文件是通用的
- portable 目录下是移植时需要实现的文件
- 目录名为:[compiler]/[architecture]
- 比如:RVDS/ARM_CM3,这表示 cortexM3 架构在 RVDS 工具上的移植文件
2、核心文件
FreeRTOS的最核心文件只有2个:
- FreeRTOS/Source/tasks.c
- FreeRTOS/Source/list.c
其他文件的作用也一起列表如下:
3、移植时涉及的文件
移植FreeRTOS时涉及的文件放在 **FreeRTOS/Source/portable/[compiler]/[architecture]**目录下, 比如:RVDS/ARM_CM3,这表示cortexM3架构在RVDS或Keil工具上的移植文件。
里面包含两个文件:
- port.c
- portmacro.h
4、头文件相关
4.1 头文件目录
FreeRTOS需要3个头文件目录:
- FreeRTOS 本身的头文件: Middlewares\Third_Party\FreeRTOS\Source\include
- 移植时用到的头文件:Middlewares\Third_Party\FreeRTOS\Source\portable\[compiler]\[architecture]
- 含有配置文件 FreeRTOSConfig.h 的目录:Core\Inc
4.2 头文件
列表如下:
|------------------|-----------------------------------------------------------------------------------------------------------------------|
| 头文件 | 作用 |
| FreeRTOSConfig.h | FreeRTOS 的配置文件,比如选择调度算法: configUSE_PREEMPTION 每个 demo 都必定含有 FreeRTOSConfig.h 建议去修改 demo 中的 FreeRTOSConfig.h,而不是从头 写一个 |
| FreeRTOS.h | 使用 FreeRTOS API 函数时,必须包含此文件。 在 FreeRTOS.h 之后,再去包含其他头文件,比如:task.h、queue.h、semphr.h、event_group.h |
5、内存管理
文件在 Middlewares\Third_Party\FreeRTOS\Source\portable\MemMang 下,它也是放 在"portable"目录下,表示你可以提供自己的函数。
源码中默认提供了5个文件,对应内存管理的5种方法。
6、入口函数
在 Core\Src\main.c 的 main 函数里,初始化了 FreeRTOS 环境、创建了任务,然后启动调度器。源码如下:
cs
/* Init scheduler */
osKernelInitialize(); /* 初始化FreeRTOS运行环境 */
MX_FREERTOS_Init(); /* 创建任务 */
/* Start scheduler */
osKernelStart(); /* 启动调度器 */
7、数据类型和编程规范
7.1 数据类型
每个移植的版本都含有自己的portmacro.h头文件,里面定义了2个数据类型:
- TickType_t:
- FreeRTOS 配置了一个周期性的时钟中断:Tick Interrupt
- 每发生一次中断,中断次数累加,这被称为 tick count
- tick count 这个变量的类型就是 TickType_t
- TickType_t 可以是 16 位的,也可以是 32 位的
- FreeRTOSConfig.h 中定义 configUSE_16_BIT_TICKS 时,TickType_t 就是 uint16_t
- 否则 TickType_t 就是 uint32_t
- 对于 32 位架构,建议把 TickType_t 配置为 uint32_t
- BaseType_t:
- 这是该架构最高效的数据类型
- 32 位架构中,它就是 uint32_t
- 16 位架构中,它就是 uint16_t
- 8 位架构中,它就是 uint8_t
- BaseType_t通常用简单的返回值的类型,还有逻辑值,比如 pdTRUE/pdFALSE
7.2 变量名
|-----------|-----------------------------------------------------|
| 变量名前缀 | 含义 |
| c | char |
| s | int16_t,short |
| I | int32_t,long |
| x | BaseType_t, 其他非标准的类型:结构体、task handle、queue handle 等 |
| u | unsigned |
| p | 指针 |
| uc | uint8_t,unsigned char |
| pc | char 指针 |
7.3 函数名
函数名的前缀有2部分:返回值类型、在哪个文件定义。
|-------------------|------------------------------------|
| 函数名前缀 | 含义 |
| vTaskPrioritySet | 返回值类型:void 在 task.c 中定义 |
| xQueueReceive | 返回值类型:BaseType_t 在 queue.c 中定义 |
| pvTimerGetTimerID | 返回值类型:pointer to void 在 tmer.c 中定义 |
7.4 宏的名
宏的名字是大小,可以添加小写的前缀。前缀是用来表示:宏在哪个文件中定义。
|----------------------------------|--------------------------|
| 宏的前缀 | 含义:在哪个文件里定义 |
| port (比如 portMAX_DELAY) | portable.h 或 portmacro.h |
| task (比如 taskENTER_CRITICAL()) | task.h |
| pd (比如 pdTRUE) | projdefs.h |
| config (比如 configUSE_PREEMPTION) | FreeRTOSConfig.h |
| err (比如 errQUEUE_FULL) | projdefs.h |
通用的宏定义如下:
|---------|-------|
| 宏 | 值 |
| pdTRUE | 1 |
| pdFALSE | 0 |
| pdPASS | 1 |
| pdFAIL | 0 |