FreeRTOS API參考——內核控制

Modules

 

taskYIELD

task.h

taskYIELD()用於請求將上下文切換到另一個任務。 但是,如果沒有其他任務比調用taskYIELD()的任務具有更高或更高的優先級,則RTOS調度程序將簡單地選擇名爲taskYIELD()的任務以再次運行。

如果configUSE_PREEMPTION設置爲1,則RTOS調度程序將始終運行能夠運行的最高優先級任務,因此調用taskYIELD()將永遠不會導致切換到更高優先級的任務。

 

taskDISABLE_INTERRUPTS()

task.h

如果使用中的端口支持configMAX_SYSCALL_INTERRUPT_PRIORITY常量(或configMAX_API_CALL_INTERRUPT_PRIORITY)常量,則taskDISABLE_INTERRUPTS將禁用所有中斷,或者屏蔽(禁用)中斷,直到configMAX_SYSCALL_INTERRUPT_PRIORITY設置。 檢查正在使用的端口的taskDISABLE_INTERRUPTS的實現。

如果使用的端口不支持configMAX_SYSCALL_INTERRUPT_PRIORITY常量,則taskDISABLE_INTERRUPTS()將全局禁用所有可屏蔽中斷。

通常,不會直接調用此宏,而應在其位置使用taskENTER_CRITICAL()和taskEXIT_CRITICAL()。

 

taskENABLE_INTERRUPTS()

task. h

啓用微控制器中斷的宏。

通常,不會直接調用此宏,而應在其位置使用taskENTER_CRITICAL()和taskEXIT_CRITICAL()。

 

taskENTER_CRITICAL()

taskEXIT_CRITICAL()

task. h
void taskENTER_CRITICAL( void );
void taskEXIT_CRITICAL( void );

通過調用taskENTER_CRITICAL()輸入關鍵部分,然後通過調用taskEXIT_CRITICAL()退出關鍵部分。

taskENTER_CRITICAL()和taskEXIT_CRITICAL()宏提供了一個基本的臨界區實現,可以通過簡單地全局禁用中斷或最高特定中斷優先級來禁用中斷。有關在不禁用中斷的情況下創建關鍵部分的信息,請參見vTaskSuspendAll()RTOS API函數。

如果正在使用的FreeRTOS端口未使用configMAX_SYSCALL_INTERRUPT_PRIORITY內核配置常量(也稱爲configMAX_API_CALL_INTERRUPT_PRIORITY),則調用taskENTER_CRITICAL()將使中斷全局禁用。如果使用的FreeRTOS端口確實使用了configMAX_SYSCALL_INTERRUPT_PRIORITY內核配置常量,則調用taskENTER_CRITICAL()將使中斷處於configMAX_SYSCALL_INTERRUPT_PRIORITY設置的中斷優先級及以下,並禁用所有優先級較高的中斷。

搶佔式上下文切換僅在中斷內部發生,因此在禁用中斷時不會發生。因此,除非任務顯式嘗試阻止或屈服(它不應在關鍵部分內部執行此操作),否則確保稱爲taskENTER_CRITICAL()的任務將保持在運行狀態,直到退出關鍵部分爲止。

對taskENTER_CRITICAL()和taskEXIT_CRITICAL()的調用被設計爲嵌套。因此,僅當對taskENTER_CRITICAL()的每個先前調用都執行了對taskEXIT_CRITICAL()的調用時,纔會退出關鍵部分。

關鍵部分必須保持很短,否則將對中斷響應時間產生不利影響。每次對taskENTER_CRITICAL()的調用都必須與對taskEXIT_CRITICAL()的調用緊密配對。

不得從關鍵部分調用FreeRTOS API函數。

不得從中斷服務程序(ISR)調用taskENTER_CRITICAL()和taskEXIT_CRITICAL()–有關等效的中斷安全信息,請參閱taskENTER_CRITICAL_FROM_ISR()和taskEXIT_CRITICAL_FROM_ISR()。

用法示例:

/* A function that makes use of a critical section. */
void vDemoFunction( void )
{
    /* Enter the critical section.  In this example, this function is itself called
    from within a critical section, so entering this critical section will result
    in a nesting depth of 2. */
    taskENTER_CRITICAL();

    /* Perform the action that is being protected by the critical section here. */


    /* Exit the critical section.  In this example, this function is itself called
    from a critical section, so this call to taskEXIT_CRITICAL() will decrement the
    nesting count by one, but not result in interrupts becoming enabled. */
    taskEXIT_CRITICAL();
}


/* A task that calls vDemoFunction() from within a critical section. */
void vTask1( void * pvParameters )
{
    for( ;; )
    {
        /* Perform some functionality here. */


        /* Call taskENTER_CRITICAL() to create a critical section. */
        taskENTER_CRITICAL();



        /* Execute the code that requires the critical section here. */


        /* Calls to taskENTER_CRITICAL() can be nested so it is safe to call a
        function that includes its own calls to taskENTER_CRITICAL() and
        taskEXIT_CRITICAL(). */
        vDemoFunction();


        /* The operation that required the critical section is complete so exit the
        critical section.  After this call to taskEXIT_CRITICAL(), the nesting depth
        will be zero, so interrupts will have been re-enabled. */
        taskEXIT_CRITICAL();
    }
}

 

taskENTER_CRITICAL_FROM_ISR()

taskEXIT_CRITICAL_FROM_ISR()

task. h

UBaseType_t taskENTER_CRITICAL_FROM_ISR( void );
void taskEXIT_CRITICAL_FROM_ISR( UBaseType_t uxSavedInterruptStatus );

可以在中斷服務程序(ISR)中使用的taskENTER_CRITICAL()和taskEXIT_CRITICAL()的版本。

在ISR中,通過調用taskENTER_CRITICAL_FROM_ISR()進入關鍵部分,然後通過調用taskEXIT_CRITICAL_FROM_ISR()退出關鍵部分。

taskENTER_CRITICAL_FROM_ISR()和taskEXIT_CRITICAL_FROM_ISR()宏提供了一個基本的臨界區實現,可以通過簡單地全局禁用中斷或最高特定中斷優先級來禁用中斷。

如果所使用的FreeRTOS端口支持中斷嵌套,則調用taskENTER_CRITICAL_FROM_ISR()將在configMAX_SYSCALL_INTERRUPT_PRIORITY(或configMAX_API_CALL_INTERRUPT_PRIORITY)內核配置設置的中斷優先級及以下禁用中斷,並使所有其他中斷優先級保持啓用狀態。如果使用的FreeRTOS端口不支持中斷嵌套,則taskENTER_CRITICAL_FROM_ISR()和taskEXIT_CRITICAL_FROM_ISR()將無效。

對taskENTER_CRITICAL_FROM_ISR()和taskEXIT_CRITICAL_FROM_ISR()的調用被設計爲嵌套,但是如何使用宏的語義與taskENTER_CRITICAL()和taskEXIT_CRITICAL()等效。

關鍵部分必須保持非常短,否則它們將對優先級較高的中斷的響應時間產生不利影響,否則該中斷將嵌套。每次對taskENTER_CRITICAL_FROM_ISR()的調用都必須與對taskEXIT_CRITICAL_FROM_ISR()的調用緊密配對。

不得從關鍵部分調用FreeRTOS API函數。

參數:

 uxSavedInterruptStatus

taskEXIT_CRITICAL_FROM_ISR()將uxSavedInterruptStatus作爲其唯一參數。 用作uxSavedInterruptStatus參數的值必須是從對taskENTER_CRITICAL_FROM_ISR()的匹配調用返回的值。

 

taskENTER_CRITICAL_FROM_ISR()不接受任何參數。

返回值:

taskENTER_CRITICAL_FROM_ISR()返回中斷屏蔽狀態,與調用宏之前一樣。 在對taskEXIT_CRITICAL_FROM_ISR()的匹配調用中,必須將taskENTER_CRITICAL_FROM_ISR()返回的值用作uxSavedInterruptStatus參數。

taskEXIT_CRITICAL_FROM_ISR()不返回值。

用法示例:

/* A function called from an ISR. */
void vDemoFunction( void )
{
UBaseType_t uxSavedInterruptStatus;


    /* Enter the critical section.  In this example, this function is itself called from
    within a critical section, so entering this critical section will result in a nesting
    depth of 2. Save the value returned by taskENTER_CRITICAL_FROM_ISR() into a local
    stack variable so it can be passed into taskEXIT_CRITICAL_FROM_ISR(). */
    uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR();


    /* Perform the action that is being protected by the critical section here. */


    /* Exit the critical section.  In this example, this function is itself called from a
    critical section, so interrupts will have already been disabled before a value was
    stored in uxSavedInterruptStatus, and therefore passing uxSavedInterruptStatus into
    taskEXIT_CRITICAL_FROM_ISR() will not result in interrupts being re-enabled. */
    taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus );
}


/* A task that calls vDemoFunction() from within an interrupt service routine. */
void vDemoISR( void )
{
UBaseType_t uxSavedInterruptStatus;


    /* Call taskENTER_CRITICAL_FROM_ISR() to create a critical section, saving the
    returned value into a local stack variable. */
    uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR();


    /* Execute the code that requires the critical section here. */


    /* Calls to taskENTER_CRITICAL_FROM_ISR() can be nested so it is safe to call a
    function that includes its own calls to taskENTER_CRITICAL_FROM_ISR() and
    taskEXIT_CRITICAL_FROM_ISR(). */
    vDemoFunction();


    /* The operation that required the critical section is complete so exit the
    critical section.  Assuming interrupts were enabled on entry to this ISR, the value
    saved in uxSavedInterruptStatus will result in interrupts being re-enabled.*/
    taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus );
}

 

vTaskStartScheduler

task. h

void vTaskStartScheduler( void );

啓動RTOS調度程序。 調用RTOS內核後,可以控制執行哪些任務以及何時執行。

啓動RTOS調度程序時,會自動創建空閒任務以及可選的計時器守護程序任務。

僅當沒有足夠的RTOS堆來創建空閒或計時器守護程序任務時,vTaskStartScheduler()纔會返回。

所有RTOS演示應用程序項目都包含使用vTaskStartScheduler()的示例,通常在main.c的main()函數中。

用法示例:

void vAFunction( void )
{
     // Tasks can be created before or after starting the RTOS scheduler
     xTaskCreate( vTaskCode,
                  "NAME",
                  STACK_SIZE,
                  NULL,
                  tskIDLE_PRIORITY,
                  NULL );

     // Start the real time scheduler.
     vTaskStartScheduler();

     // Will not get here unless there is insufficient RAM.
}

 

vTaskEndScheduler

task. h

void vTaskEndScheduler( void );

注意:這僅適用於x86實模式PC端口。

停止RTOS內核滴答。 所有創建的任務將被自動刪除,並且多任務處理(搶佔式或協作式)將停止。 然後,從調用vTaskStartScheduler()的點繼續執行,就好像vTaskStartScheduler()剛剛返回一樣。

請參閱演示應用程序文件主體。 有關使用vTaskEndScheduler()的示例,請參見demo / PC目錄中的c。

vTaskEndScheduler()要求在可移植層中定義退出功能(有關PC端口,請參見端口c中的vPortEndScheduler())。 這將執行特定於硬件的操作,例如停止RTOS內核滴答。

vTaskEndScheduler()將導致釋放RTOS內核分配的所有資源-但不會釋放應用程序任務分配的資源。

用法示例:

void vTaskCode( void * pvParameters )
{
     for( ;; )
     {
         // Task code goes here.

         // At some point we want to end the real time kernel processing
         // so call ...
         vTaskEndScheduler ();
     }
}


void vAFunction( void )
{
     // Create at least one task before starting the RTOS kernel.
     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );

     // Start the real time kernel with preemption.
     vTaskStartScheduler();


     // Will only get here when the vTaskCode () task has called
     // vTaskEndScheduler ().  When we get here we are back to single task
     // execution.
}

vTaskSuspendAll

task. h

void vTaskSuspendAll( void );

在不禁用中斷的情況下掛起調度程序。 調度程序掛起時不會發生上下文切換。 調度程序掛起時發生的RTOS滴答將保持掛起狀態,直到通過調用xTaskResumeAll()取消調度程序爲止。

掛起調度程序時,不得調用可能導致上下文切換的API函數(例如vTaskDelayUntil(),xQueueSend()等)。

用法示例:

void vTask1( void * pvParameters )
{
     for( ;; )
     {
         // Task code goes here.

         // ...

         // At some point the task wants to perform a long operation during
         // which it does not want to get swapped out.  It cannot use
         // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
         // operation may cause interrupts to be missed - including the
         // ticks.

         // Prevent the RTOS kernel swapping out the task.
         vTaskSuspendAll ();

         // Perform the operation here.  There is no need to use critical
         // sections as we have all the microcontroller processing time.  
         // During this time interrupts will still operate and the RTOS kernel
         // tick count will be maintained.

         // ...

         // The operation is complete.  Restart the RTOS kernel.
         xTaskResumeAll ();
     }
}

 

xTaskResumeAll

task. h

BaseType_t xTaskResumeAll( void );

使用對vTaskSuspendAll()的調用在掛起調度程序後繼續。

xTaskResumeAll()僅恢復調度程序。 它不會取消暫停先前通過調用vTaskSuspend()而暫停的任務。

返回值:

     如果恢復調度程序導致上下文切換,則返回pdTRUE,否則返回pdFALSE。

用法示例:

void vTask1( void * pvParameters )
{
     for( ;; )
     {
         /* Task code goes here. */


         /* ... */


         /* At some point the task wants to perform a long operation
         during which it does not want to get swapped out.  It cannot
         use taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length
         of the operation may cause interrupts to be missed -
         including the ticks.
         Prevent the RTOS kernel swapping out the task. */
         vTaskSuspendAll();

         /* Perform the operation here.  There is no need to use critical
         sections as we have all the microcontroller processing time.
         During this time interrupts will still operate and the real
         time RTOS kernel tick count will be maintained. */


         /* ... */


         /* The operation is complete.  Restart the RTOS kernel.  We want to force
         a context switch - but there is no point if resuming the scheduler
         caused a context switch already. */
         if( !xTaskResumeAll () )
         {
              taskYIELD ();
         }
     }
}

 

vTaskStepTick

task.h

void vTaskStepTick( TickType_t xTicksToJump );

如果將RTOS配置爲使用無滴答空閒功能,則只要空閒任務是唯一能夠執行的任務,滴答中斷就會停止,微控制器進入低功耗狀態。 退出低功耗狀態後,必須校正滴答計數值,以說明停止時經過的時間。

如果FreeRTOS端口包括默認的portSUPPRESS_TICKS_AND_SLEEP()實現,則內部將使用vTaskStepTick()來確保維護正確的滴答計數值。 vTaskStepTick()是一個公共API函數,它允許覆蓋默認的portSUPPRESS_TICKS_AND_SLEEP()實現,如果使用的端口不提供默認值,則可以提供portSUPPRESS_TICKS_AND_SLEEP()。

必須將configUSE_TICKLESS_IDLE配置常量設置爲1,vTaskStepTick()纔可用。

參數:

  xTicksToJump

自滴答中斷停止以來已過去的RTOS滴答次數。 爲了正確操作,該參數必須小於或等於portSUPPRESS_TICKS_AND_SLEEP()參數。

返回值:

    無

用法示例:

該示例顯示了對多個函數的調用。 只有vTaskStepTick()是FreeRTOS API的一部分。 其他功能特定於正在使用的硬件上可用的時鐘和省電模式,因此必須由應用程序編寫器提供。

/* First define the portSUPPRESS_TICKS_AND_SLEEP().  The parameter is the time,
in ticks, until the kernel next needs to execute. */
#define portSUPPRESS_TICKS_AND_SLEEP( xIdleTime ) vApplicationSleep( xIdleTime )


/* Define the function that is called by portSUPPRESS_TICKS_AND_SLEEP(). */
void vApplicationSleep( TickType_t xExpectedIdleTime )
{
unsigned long ulLowPowerTimeBeforeSleep, ulLowPowerTimeAfterSleep;


    /* Read the current time from a time source that will remain operational
    while the microcontroller is in a low power state. */
    ulLowPowerTimeBeforeSleep = ulGetExternalTime();


    /* Stop the timer that is generating the tick interrupt. */
    prvStopTickInterruptTimer();


    /* Configure an interrupt to bring the microcontroller out of its low power
    state at the time the kernel next needs to execute.  The interrupt must be
    generated from a source that is remains operational when the microcontroller
    is in a low power state. */
    vSetWakeTimeInterrupt( xExpectedIdleTime );

    /* Enter the low power state. */
    prvSleep();


    /* Determine how long the microcontroller was actually in a low power state
    for, which will be less than xExpectedIdleTime if the microcontroller was
    brought out of low power mode by an interrupt other than that configured by
    the vSetWakeTimeInterrupt() call.  Note that the scheduler is suspended
    before portSUPPRESS_TICKS_AND_SLEEP() is called, and resumed when
    portSUPPRESS_TICKS_AND_SLEEP() returns.  Therefore no other tasks will
    execute until this function completes. */
    ulLowPowerTimeAfterSleep = ulGetExternalTime();


    /* Correct the kernels tick count to account for the time the microcontroller
    spent in its low power state. */
    vTaskStepTick( ulLowPowerTimeAfterSleep - ulLowPowerTimeBeforeSleep );

    /* Restart the timer that is generating the tick interrupt. */
    prvStartTickInterruptTimer();
}

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章