1. main()函數在啟動調度器之前先完成兩個任務的創建。如下面所示:
static void AppTaskCreate(void) { xTaskCreate(vTaskBeep,"Task Beep", 512, NULL, 1, &xHandleTaskBeep); xTaskCreate(vTaskLed1, /* 任務函數名 */ "Task Led1", /* 任務名,字符串形式,方便調試 */ 512, /* 棧大小,單位為字,即4個字節 */ NULL, /* 任務形參 */ 2, /* 優先級,數值越大,優先級越高 */ &xHandleTaskLED1); /* 任務句柄 */ }
2、從一個任務中創建另一個任務。我們可以先在 main()中創建任務 1,然后在任務 1 中創建任務2。
這樣,在調度器啟動之前,任務 2 還沒有被創建,但是整個程序運行的輸出結果還是相同的。
void vTask1( void *pvParameters ) { const char *pcTaskName = "Task 1 is running\r\n"; volatile unsigned long ul; /* 如果已經執行到本任務的代碼,表明調度器已經啟動。在進入死循環之前創建另一個任務。 */ xTaskCreate( vTask2, "Task 2", 1000, NULL, 1, NULL ); for( ;; ) { /* Print out the name of this task. */ vPrintString( pcTaskName ); /* Delay for a period. */ for( ul = 0; ul < mainDELAY_LOOP_COUNT; ul++ ) { /* This loop is just a very crude delay implementation. There is nothing to do in here. Later examples will replace this crude loop with a proper delay/sleep function. */ } } }
3、用唯一一個任務函數代碼(vTaskFunction),
這一個任務函數代替了上例中的兩個任務函數(vTask1 與 vTask2)。
void vTaskFunction(void *pvParameters) { int * pcTaskName; pcTaskName = (int *)pvParameters; while(1) { if(*pcTaskName==1) { LED1_ON; /* 阻塞延時,單位ms */ vTaskDelay( 500 ); LED1_OFF; vTaskDelay( 500 ); } else if(*pcTaskName==2) { BEEP_ON; /* 阻塞延時,單位ms */ vTaskDelay( 500 ); BEEP_OFF; vTaskDelay( 500 ); } } }
創建任務函數修改為:
static void AppTaskCreate(void) { xTaskCreate(vTaskFunction, /* 任務函數名 */ "Task 1", /* 任務名,字符串形式,方便調試 */ 512, /* 棧大小,單位為字,即4個字節 */ (void *)&pcLED, /* 任務形參 */ 1, /* 優先級,數值越大,優先級越高 */ &xHandleTaskLED1); /* 任務句柄 */ xTaskCreate(vTaskFunction,"Task 2", 512, (void *)&pcBeep, 1, &xHandleTaskBeep); }
注意任務參數處不再是NULL;
全局區增加標志定義:
static const int pcLED = 1;
static const int pcBeep = 2;
任務參數的原型:void * const pvParameters;如果我們不強制轉化成void *將會報錯。
官方手冊源碼:


字符串常量是一個特殊的東西,把字符串常量通過函數
void vTaskFunction( void *pvParameters )
從入口參數void *pvParameters傳入,再強轉為字符指針。

圖 3 中 t1 與 t2 之間的時段就等於一個時間片。
要能夠選擇下一個運行的任務,調度器需要在每個時間片的結束時刻運行自己本身。一個稱為心跳中斷的周期性中斷用於此目的。
時間片的長度通過心跳中斷的頻率進行設定,心跳中斷頻率由FreeRTOSConfig.h 中的編譯時配置常量 configTICK_RATE_HZ 進行配置。
比如說,如果 configTICK_RATE_HZ 設為 100(HZ),則時間片長度為 10ms。可以將圖 圖 3 進行擴展,將調度器本身的執行時間在整個執行流程中體現出來。見圖 4:

FreeRTOS API 函數調用中指定的時間總是以心跳中斷為單位(通常的提法為心跳”ticks”)。
常量 portTICK_RATE_MS 用於將以心跳為單位的時間值轉化為以毫秒為單位的時間值。
有效精度依賴於系統心跳頻率。





