FreeRTOS——使用任務參數創建任務


 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 用於將以心跳為單位的時間值轉化為以毫秒為單位的時間值。
  有效精度依賴於系統心跳頻率。

 

  

 

 



 

 



 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM