FreeRTOS源码解析
第一章 FreeRTOS 整体架构
第二章 FreeRTOS 编程规范
第三章 FreeRTOS 内存管理
第三章 FreeRTOS 内存管理
第四章 FreeRTOS 任务管理
第五章 FreeRTOS 消息队列
第六章 FreeRTOS 软件定时器
第七章 FreeRTOS 信号量
第八章 FreeRTOS 互斥量
第九章 FreeRTOS 任务通知
第十章 FreeRTOS 事件组
FreeRTOS源码解析——第二章 编程规范
- FreeRTOS源码解析
- 前言
- 一、编码标准
- 二、命名规则
- 2.1 宏
-
- 2.2、变量
- 2.2.1 stdint 命名的变量
- 2.2.2 FreeRTOS 定义的数据类型
- 2.2.3 指针类型
- 2.3、函数
- 2.3.1 static 函数
- 2.3.2 全局函数
- 三、数据类型
- 四、注释和风格
- 总结
前言
本章主要介绍FreeRTOS的命名、注释、数据结构等编码规范。方便后续的源码阅读。
一、编码标准
FreeRTOS的核心代码遵从MISRA-C(汽车产业软件可靠性协会)编码标准。如果出现有不满足标准的会在代码中显示注释出来。可以在代码中全局搜索"MISRA exception"找到不满足MISRA-C标准的编码。在FreeRTOSV10.4.6中一共有27处不满足,不同类型的如下:
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
if( ( ( TickType_t ) ( xTimeNow - xCommandTime ) ) >= pxTimer->xTimerPeriodInTicks )
pxTopOfStack = ( StackType_t * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) );
if( pxQueue->pcWriteTo >= pxQueue->u.xQueue.pcTail )
pxQueue->pcWriteTo += pxQueue->uxItemSize;
( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.xQueue.pcReadFrom, ( size_t ) pxQueue->uxItemSize );
二、命名规则
2.1 宏
2.1.1 规则
- 前缀:小写,作为宏的起始部分(所在文件的简写)
- 其余部分为大写,两个单词之间用下划线隔开(第一个大写和前缀之间没有下划线间隔)
2.1.2 实例
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
#define configUSE_PREEMPTION 1
#define configCPU_CLOCK_HZ ( 100000000 )
#define tskDEFAULT_INDEX_TO_NOTIFY ( 0 )
#define tskRUNNING_CHAR ( 'X' )
#define queueSEND_TO_BACK ( ( BaseType_t ) 0 )
#define queueSEND_TO_FRONT ( ( BaseType_t ) 1 )
#define queueOVERWRITE ( ( BaseType_t ) 2 )
2.2、变量
命名规则:位宽前缀Name1Name2…Namex
2.2.1 stdint 命名的变量
- 8bit(char)无符号:uint8_t 前缀 ‘uc’
8bit(char)有符号:int8_t 前缀 ‘c’
uint8_t ucQueueType;
int8_t cRxLock;
char cStatus;
- 16bit(short)无符号:uint16_t 前缀 ‘us’
16bit(short)有符号:int16_t 前缀 ‘s’
FreeRTOS中没有直接用 uint16_t 和 int16_t 命名的变量
- 32bit(long)无符号:uint32_t 前缀 ‘ul’
32bit(long)有符号:int32_t 前缀 ‘l’
uint32_t ulStackDepth
int32_t lArrayIndex;
2.2.2 FreeRTOS 定义的数据类型
FreeRTOS 的自定义的数据类型如下:
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
typedef uint32_t TickType_t;
typedef struct tskTaskControlBlock * TaskHandle_t;
typedef struct QueueDefinition * QueueHandle_t;
typedef xTIMER Timer_t;
typedef struct EventGroupDef_t * EventGroupHandle_t
FreeRTOS自定义的数据类型只有两种前缀,如下:
- 整型无符号前缀 ‘ux’
- 整型有符号和FreeRTOS自定义的数据类型前缀 ‘x’
UBaseType_t uxTimerNumber;
BaseType_t xListWasEmpty;
StackType_t xStack[ STACK_SIZE ];
TickType_t xNextExpireTime;
TaskHandle_t xTimerTaskHandle = NULL;
QueueHandle_t xTimerQueue = NULL;
Timer_t xNewTimer;
EventGroupHandle_t xEventGroup = NULL;
2.2.3 指针类型
在2.2.1和2.2.2的数据类型的命名前面增加 ‘p’
uint8_t * pucStackByte;
int8_t * pcOriginalReadPosition;
uint32_t * pulNotificationValue;
StackType_t * pxTopOfStack;
BaseType_t * pxHigherPriorityTaskWoken
UBaseType_t *puxVariableToIncrement;
TickType_t * const pxTicksToWait;
TaskHandle_t *pxCreatedTask;
Queue_t * pxNewQueue ;
Timer_t * const pxTimer;
EventGroup_t * pxEventBits;
2.3、函数
2.3.1 static 函数
- 只在当前文件有效的, 被 static 修饰: 增加前缀 “prv” ,private的意思 。不区分有无返回值、返回值是否为指针等,统一固定前缀 “prv”。
- 规则: prvName1Name2…Namex
- 实例如下:
static void prvDeleteTCB( TCB_t * pxTCB )
static BaseType_t prvCopyDataToQueue( Queue_t * const pxQueue, const void * pvItemToQueue, const BaseType_t xPosition )
2.3.2 全局函数
- 有返回值前缀为 ‘x’ 或’ux’,无返回值前缀为 ‘v’
- 返回值为指针,增加前缀 ‘p’
- 前缀后面紧跟着所在文件名的缩写
- 实例如下:
UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask )
BaseType_t xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue )
void vTimerSetTimerID( TimerHandle_t xTimer, void * pvNewID )
void * pvPortMalloc( size_t xSize )
三、数据类型
见 2.2节,变量的命令。主要就是三种数据类型
- stdint.h 命名的整型
- FreeRTOS 命名的整型
- FreeRTOS自定义的 链表、句柄等服务于各个模块的结构体
四、注释和风格
- 注释:只用 /* */ 进行注释
- 头文件中会给出函数的说明和例程,方便查阅和使用
- 源文件中关键处也会有对应的注释,辅助理解
- 缩进:4个空格
- 关键字 for、if、while等后面没有空格
- 实例如下:
BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer )
{
BaseType_t xReturn;
Timer_t * pxTimer = xTimer;
configASSERT( xTimer );
taskENTER_CRITICAL();
{
if( ( pxTimer->ucStatus & tmrSTATUS_IS_ACTIVE ) == 0 )
{
xReturn = pdFALSE;
}
else
{
xReturn = pdTRUE;
}
}
taskEXIT_CRITICAL();
return xReturn;
}
总结
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)