0、FreeRTOS编码和命名规则
FreeRTOS源码文件的编写遵循MISRA(The Motor Industry Software Reliability association,汽车工业软件可靠性联会)代码规则,同时支持各种编译器。
一、变量命名
1.1理论
在stdint.h文件中定义的变量类型,在FreeRTOS变量命名中会加上一些字母前缀。
变量命名使用驼峰式大小写(单词首字母大写),变量名要具有明确描述和含义,并使用完整的单词(通用的缩写也可以)。
数据类型标识 | 英文全称 | 中文类型 |
---|---|---|
u | unsigned | 无符号 |
l | long | 长整型 |
s | short | 短整型 |
c | char | 字符型 |
e | enum | 枚举 |
p | pointer | 指针类型 |
例如:
数据类型 / 来源 | 变量前缀 | 指针变量前缀 | 说明 |
---|---|---|---|
uint32_t | ul | pul | 32 位无符号整数(Unsigned Long) |
uint16_t | us | pus | 16 位无符号整数(Unsigned Short) |
uint8_t | uc | puc | 8 位无符号整数(Unsigned Char) |
char | c | pc | ASCII 字符或字符串 |
自定义类型(如 BaseType_t , TickType_t ) | x | — | 非标准整型或结构类型变量 |
无符号自定义类型(如 UBaseType_t ) | ux | — | 无符号的非标准类型变量 |
1.2 变量命名示例(Variable Naming)
#include <stdint.h>
#include "FreeRTOS.h"// uint32_t → 前缀 ul
uint32_t ulSystemClockHz = 168000000;// uint16_t → 前缀 us
uint16_t usAdcSampleCount = 1024;// uint8_t → 前缀 uc
uint8_t ucUartRxBuffer[64];// char → 前缀 c
char cDeviceID = 'A';
char *pcDeviceName = "STM32F407";// 自定义类型 BaseType_t → 前缀 x
BaseType_t xTaskStatus = pdPASS;// 无符号自定义类型 UBaseType_t → 前缀 ux
UBaseType_t uxTaskCount = 5;// 指针类型示例
uint32_t *pulAdcData = NULL;
uint16_t *pusSensorValue = NULL;
uint8_t *pucDataPtr = NULL;
二、函数命名
2.1理论
加上static声明的函数,在定义时要加上前缀prv。prv是单词private的缩写,意思是私有的。
带有返回值的函数,根据返回值的数据类型,加上相应的前缀;如果没有返回值,则函数的前缀加上字母v。
根据函数所在的文件吗,在定义时将文件名加到函数命名中,如在task.c文件中定义的函数vTaskDelete的名字中包含文件名task。
以下是表格形式描述:
情况 | 前缀 | 示例 | 说明 |
---|---|---|---|
文件内私有函数(static) | prv | prvTaskInit() | 仅在当前文件使用,表示 private |
无返回值函数(void) | v | vTaskDelete() | 返回值为空 |
有返回值函数 | 根据返回类型添加相应前缀 | 例如:ucGetStatus() , ulReadValue() | 与变量类型前缀一致 |
文件名关联规则 | 在函数名中包含所属文件名关键字 | 例如: (定义于 tasks.c) | 有助于模块归属识别 |
2.2 函数命名示例(Function Naming)
#include "task.h"// 文件名:tasks.c// 无返回值函数(前缀 v)
void vTaskDelete(TaskHandle_t xTaskToDelete)
{// 删除任务vPortFree(xTaskToDelete);
}// 有返回值函数(根据类型前缀,如 uc 表示返回 uint8_t)
uint8_t ucGetStatus(void)
{return 1; // 返回状态码
}// 文件内私有函数(static → prv 前缀)
static void prvTaskInit(void)
{// 初始化任务参数BaseType_t xInitStatus = pdPASS;
}// 文件名关联规则示例:任务相关函数包含 task
void vTaskStartScheduler(void)
{// 启动调度器
}
三、宏定义
3.1理论
根据宏定义所在的文件,宏定义声明时将文件名加到宏定义中,如宏定义configUSE_TIMERS定义所在文件FreeRTOSConfig.h中,宏定义中包含文件名config。
宏定义前缀小写,其余部分全部大写,同时用下划线分开。
项目 | 规则说明 | 示例 | 备注 |
---|---|---|---|
文件关联命名 | 宏名称应包含其定义所在文件的标识部分 | configUSE_TIMERS (定义于 FreeRTOSConfig.h) | 体现宏所属模块 |
前缀格式 | 宏名前缀采用小写字母(通常为文件名或模块名) | config , task , sys | 与文件或模块对应 |
主体格式 | 宏名称主体全部大写,单词间以下划线分隔 | USE_TIMERS , ENABLE_DEBUG , MAX_BUFFER_SIZE | 提高可读性与一致性 |
完整格式 | 前缀小写 + 主体大写 + 下划线分隔 | configMAX_PRIORITIES , sysENABLE_LOG | 推荐命名形式 |
命名风格 | 不使用混合大小写或驼峰命名 | ✅ ❌ | 保持宏命名统一风格 |
3.2 宏定义示例(Macro Definition)
// 文件名:FreeRTOSConfig.h// 宏名称包含文件前缀 “config”
// 前缀小写,其余大写,单词间以下划线分隔
#define configUSE_TIMERS 1
#define configMAX_PRIORITIES 5
#define configCPU_CLOCK_HZ ( ( unsigned long ) 168000000 )
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )// 模块化宏命名示例(例如系统日志宏)
#define sysENABLE_LOG 1
#define sysMAX_BUFFER_SIZE 256// ❌ 错误示例(不推荐)
// #define ConfigUseTimers 1
四、自定义数据类型
4.1理论
FreeRTOS自定义数据类型与处理器架构字长相关。
TickType_t:如果使能了宏定义configUSE_16_BIT_TICKS,则TickType_t定义的是16位无符号数;如果没有使能宏定义configUSE_16_BIT_TICKS,则TickType_t定义的是32位无符号数。
BaseType_t: 对于32位架构处理器,BaseType_t定义的是32位有符号数;对于16位架构处理器,BaseType_t定义的是16位有符号数。
UBaseType_t: BaseType_t类型的无符号版本
StackType_t:栈变量数据类型,对于16位架构处理器,StackType_t定义的是16位无符号变量;对于32位架构处理器,StackType_t定义的是32位无符号变量。
以下为上述表格形式直观阐述、温故专用:
数据类型 | 位宽(取决于架构或配置) | 有符号性 | 适用架构 / 条件 | 说明 |
---|---|---|---|---|
TickType_t | 16 位/ 32 位 | 无符号 |
- 启用 :16 位 - 未启用:32 位 | 系统时钟节拍计数类型 |
BaseType_t | 16 位/ 32 位 | 有符号 | - 16 位架构:16 位 - 32 位架构:32 位 | 通用有符号基础数据类型 |
UBaseType_t | 与 对应位宽 | 无符号 | 与 BaseType_t 同步 | 通用无符号基础数据类型 |
StackType_t | 16 位/ 32 位 | 无符号 | - 16 位架构:16 位 - 32 位架构:32 位 | 任务栈元素的数据类型 |
4.2 自定义数据类型示例(Custom Data Types)
#include "FreeRTOS.h"// TickType_t 示例
TickType_t xSystemTickCount = 0;// BaseType_t 示例(根据架构字长,32位处理器定义为 int32_t)
BaseType_t xReturnValue = pdPASS;// UBaseType_t 示例(BaseType_t 的无符号版本)
UBaseType_t uxLoopCounter = 0;// StackType_t 示例(任务栈变量)
StackType_t xTaskStack[128];// 应用场景示例
void vExampleTask(void *pvParameters)
{TickType_t xLastWakeTime = xTaskGetTickCount();const TickType_t xFrequency = pdMS_TO_TICKS(1000);for (;;){// 周期性任务执行vTaskDelayUntil(&xLastWakeTime, xFrequency);}
}