
FreeRTOS 定義了自己的一套數據類型,主要是為了確保在不同處理器架構和編譯器上的可移植性。
這些數據類型定義在 portmacro.h 文件中,具體實現會根據不同的編譯器和處理器進行調整。
FreeRTOS 定義了以下基本數據類型:
uint32_t(16位系統可能為 uint16_t) | |
uint32_t | |
在 FreeRTOS 源代碼中,這些類型通常這樣定義:
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
FreeRTOS 有著非常一致的代碼風格,這種風格貫穿整個項目,使得代碼易于閱讀和維護。
FreeRTOS 采用了一套嚴格的命名規則:
變量命名:
示例:
BaseType_t xResult;
char cByte;
uint8_t ucCount;
void *pvBuffer;
x:非標準類型(如 BaseType_t, TickType_t 等)c:字符類型s:字符串uc:無符號字符p:指針pc:指向字符的指針ul:無符號長整型v:void函數命名:
示例:
void vTaskDelete(TaskHandle_t xTask);
BaseType_t xQueueSend(QueueHandle_t xQueue, const void *pvItemToQueue, TickType_t xTicksToWait);
void *pvPortMalloc(size_t xSize);
v:void 返回類型x:返回 BaseType_tpv:返回 void 指針vTask:任務相關xQueue:隊列相關vSemaphore:信號量相關pvPortMalloc:內存管理相關宏命名:
示例:
#define configUSE_PREEMPTION 1
#define pdTRUE (1)
#define errQUEUE_FULL (0)
config:配置文件中的宏pd(port dependent):與移植相關的宏err:錯誤代碼縮進與括號:
示例:
if( xCondition == pdTRUE )
{
/* 縮進4個空格 */
vFunction();
}
注釋風格:
示例:
/*
* 創建一個新任務并將其添加到就緒任務列表中。
*
* @param pxTaskCode 任務函數指針
* @param pcName 任務描述性名稱
* @param usStackDepth 任務堆棧大小(以字為單位)
* @param pvParameters 傳遞給任務的參數
* @param uxPriority 任務優先級
* @param pxCreatedTask 用于傳回任務句柄
* @return 成功時返回pdPASS,失敗返回錯誤代碼
*/
BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,
const char * const pcName,
const uint16_t usStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
TaskHandle_t * const pxCreatedTask );
代碼布局:
示例:
xQueue = xQueueCreate(
uxQueueLength,
uxItemSize
);
返回值檢查:
示例:
if( xQueueSend( xQueue, &xData, xTicksToWait ) != pdPASS )
{
/* 錯誤處理 */
}
pdPASS 或 pdFAIL臨界區保護:
示例:
taskENTER_CRITICAL();
{
/* 臨界區代碼 */
}
taskEXIT_CRITICAL();
斷言:
示例:
configASSERT( xQueue != NULL );
configASSERT() 宏進行運行時檢查下面是一個典型的 FreeRTOS 任務創建代碼,展示了數據類型和代碼風格:
/* 任務函數原型 */
void vTaskFunction( void *pvParameters );
/* 任務句柄 */
TaskHandle_t xHandle = NULL;
/* 創建任務 */
BaseType_t xReturned = xTaskCreate(
vTaskFunction, /* 任務函數指針 */
"Demo Task", /* 任務名稱 */
configMINIMAL_STACK_SIZE, /* 堆棧大小 */
NULL, /* 傳遞給任務的參數 */
tskIDLE_PRIORITY + 1, /* 任務優先級 */
&xHandle /* 傳回任務句柄 */
);
/* 檢查任務是否創建成功 */
if( xReturned == pdPASS )
{
/* 任務創建成功 */
vTaskStartScheduler(); /* 啟動調度器 */
}
else
{
/* 處理錯誤 */
for( ;; );
}
/* 任務實現 */
void vTaskFunction( void *pvParameters )
{
TickType_t xLastWakeTime;
const TickType_t xFrequency = pdMS_TO_TICKS( 1000 ); /* 1秒周期 */
/* 初始化變量 */
xLastWakeTime = xTaskGetTickCount();
for( ;; )
{
/* 任務功能代碼 */
/* 延遲直到下一個周期 */
vTaskDelayUntil( &xLastWakeTime, xFrequency );
}
}
在移植 FreeRTOS 到不同平臺時,需要特別注意以下數據類型和宏定義:
FreeRTOS 的數據類型和代碼風格設計具有以下特點:
理解和遵循 FreeRTOS 的數據類型和代碼風格對于開發高質量的 FreeRTOS 應用程序至關重要,特別是在需要移植到不同平臺或與團隊協作開發時。
這種一致的風格也使得 FreeRTOS 源代碼本身成為學習嵌入式實時系統編程的優秀范例。

覺得文章不錯,點擊“分享”、“贊”、“推薦” 唄!