FreeRTOS学习笔记-任务控制(FreeRTOS中文官网)

任务控制
[API]

模块

vTaskDelay
[任务控制]

task. h
 
 
void vTaskDelay( const TickType_t xTicksToDelay );

必须将 INCLUDE_vTaskDelay 定义为 1,此函数才可用。 请参阅 RTOS 配置文档,了解更多信息,

按给定的 tick 数延迟任务。任务保持阻塞的实际时间取决于 tick 频率。 常量 portTICK_PERIOD_MS 配合 tick 周期分辨率可用于从 tick 频率计算实际时间。

vTaskDelay() 会指定任务想要取消阻塞的时间,该时间是相对于 vTaskDelay() 被调用的时间。 例如,如果指定 时间块为 100 个 tick,那么在调用 vTaskDelay() 100 个 tick 后任务会取消阻塞。 vTaskDelay() 并不会因此提供一种 控制周期性任务频率的好办法,因为途径代码的路径以及其他任务和中断活动将影响 vTaskDelay() 被调用的频率,进而会影响下一个任务执行的时间。 请参阅 vTaskDelayUntil(),了解为 便于任务以固定频率执行而设计的替代 API 函数。 它通过指定调用任务应取消阻塞的绝对时间(而非相对时间)来实现这一点。

参数:

xTicksToDelay 调用任务应阻塞的 tick 周期数。

用法示例:


 void vTaskFunction( void * pvParameters )
 {
 /* Block for 500ms. */
 const TickType_t xDelay = 500 / portTICK_PERIOD_MS;

     for( ;; )
     {
         /* Simply toggle the LED every 500ms, blocking between each toggle. */
         vToggleLED();
         vTaskDelay( xDelay );
     }
}

vTaskDelayUntil
[任务控制]

task. h

 
 
void vTaskDelayUntil( TickType_t *pxPreviousWakeTime, const TickType_t xTimeIncrement );

INCLUDE_vTaskDelayUntil 必须被定义为 1 才能使用此函数。 请参阅 RTOS 配置文档,获取更多详细信息。

将任务延迟到指定时间。 此函数可以由周期性任务使用, 来确保恒定的执行频率。

此函数与 vTaskDelay() 在一个重要的方面有所不同: vTaskDelay() 会指定 任务想要取消阻塞的时间,该时间是相对于vTaskDelay() 被调用的时间, 而 vTaskDelayUntil() 会指定任务希望取消阻塞的绝对时间。

vTaskDelay() 将 导致一个任务从调用 vTaskDelay() 时起阻塞特定的 tick 数。 因此,很难单独使用 vTaskDelay() 来生成固定的 执行频率,因为任务在调用 vTaskDelay() 后取消阻塞与该任务 再次调用 vTaskDelay() 之间的时间可能不是固定的 [ 该任务可能在两次调用之间 采用不同的代码路径,或者可能在每次执行时被打断或被抢占 的次数不同 ]。

vTaskDelay() 会指定唤醒时间,该时间相对于函数被调用的时间, vTaskDelayUntil() 会指定它希望取消阻塞的绝对(精确) 时间。

应注意,如果 vTaskDelayUntil() 被用于指定已过去的唤醒时间, 该函数将立即返回(不阻塞)。 因此,使用 vTaskDelayUntil() 定期执行的任务,在周期性执行因任何原因停止 (例如,任务被暂停),而导致任务错过一个或多个周期性执行时, 必须重新计算其所需的唤醒 时间。 这可以通过检查由引用传递的变量来发现, 该变量是针对当前 tick 计数的 pxPreviousWakeTime 参数。 但是,这在大多数使用场景下 并非必要。

常量 portTICK_PERIOD_MS 配合 tick 周期分辨率 可用于从 tick 频率计算实际时间。

当调用了 vTaskSuspendAll() 暂停 RTOS 调度器时,不得调用此函数。

参数:

pxPreviousWakeTime 指向一个变量的指针,该变量 任务上次被取消阻止。 该变量在第一次使用前 必须用当前时间进行初始化(见下方示例)。 在这之后,该变量 会在 vTaskDelayUntil() 中自动更新。
xTimeIncrement 周期时间段。 该任务将在 (*pxPreviousWakeTime + xTimeIncrement)时间解除阻塞。 配合相同的 xTimeIncrement 参数值 调用 vTaskDelayUntil 将导致任务 以固定的间隔期执行。

示例用法:

 // Perform an action every 10 ticks.
 void vTaskFunction( void * pvParameters )
 {
 TickType_t xLastWakeTime;
 const TickType_t xFrequency = 10;

     // Initialise the xLastWakeTime variable with the current time.
     xLastWakeTime = xTaskGetTickCount();

     for( ;; )
     {
         // Wait for the next cycle.
         vTaskDelayUntil( &xLastWakeTime, xFrequency );

         // Perform action here.
     }
 }

xTaskDelayUntil [任务控制]

task. h

 
 
BaseType_t xTaskDelayUntil( TickType_t *pxPreviousWakeTime, const TickType_t xTimeIncrement );

INCLUDE_xTaskDelayUntil 必须定义为 1 ,此函数才可用。 有关详细信息,请参阅 RTOS 配置文档。

将任务延迟到指定时间。 此函数可以由周期性任务使用, 来确保恒定的执行频率。

此函数与 vTaskDelay() 在一个重要方面有所不同: vTaskDelay() 将 导致一个任务从调用 vTaskDelay() 时起阻塞指定的 tick 数, 而 xTaskDelayUntil() 将导致一个任务从 pxPreviousWakeTime 参数中指定的时间起阻塞指定的 tick 数。 使用 vTaskDelay() 本身很难产生一个固定的执行频率, 因为从一个任务开始执行到该任务调用 vTaskDelay() 之间的时间可能并不固定 [该任务在调用之间可能采取不同的代码路径, 或者每次执行时可能被中断或被抢占的次数不同]。 xTaskDelayUntil() 可以用来生成一个恒定的执行频率。

vTaskDelay() 指定了相对于函数被调用时的唤醒时间, 而 xTaskDelayUntil() 则指定了它希望解除阻塞的绝对(精确)时间 。

宏 pdMS_TO_TICKS() 可以用来计算以毫秒为单位的时间的 tick 数, 分辨率为一个 tick 周期。

参数:

pxPreviousWakeTime 指向一个变量的指针,该变量 用于保存任务最后一次解除阻塞的时间。 该变量在第一次使用前 必须用当前时间进行初始化(见下方示例)。 在这之后,该变量 会在 xTaskDelayUntil() 中自动更新。
xTimeIncrement 周期时间段。 该任务将在 (*pxPreviousWakeTime + xTimeIncrement)时间解除阻塞。 以相同的 xTimeIncrement 参数值调用 xTaskDelayUntil 将导致任务以固定的间隔期执行。

Returns:

一个可用于检查任务是否实际延迟的值: 如果任务延迟,则返回 pdTRUE,否则返回 pdFALSE。 如果下一个预计唤醒时间已过,则任务将不会延迟。

示例用法:

// Perform an action every 10 ticks.
void vTaskFunction( void * pvParameters )
{
TickType_t xLastWakeTime;
const TickType_t xFrequency = 10;
BaseType_t xWasDelayed;

    // Initialise the xLastWakeTime variable with the current time.
    xLastWakeTime = xTaskGetTickCount ();
    for( ;; )
    {
        // Wait for the next cycle.
        xWasDelayed = xTaskDelayUntil( &xLastWakeTime, xFrequency );

        // Perform action here. xWasDelayed value can be used to determine
        // whether a deadline was missed if the code here took too long.
    }
}

uxTaskPriorityGet
[任务控制]

task. h
 
 
UBaseType_t uxTaskPriorityGet( TaskHandle_t xTask );

必须将 INCLUDE_uxTaskPriorityGet 定义为 1,此函数才可用。要了解更多信息,请参阅 RTOS 配置文档。

获得任何任务的优先级。

参数:

xTask 待查询的任务句柄。传递 NULL 句柄会导致返回调用任务的优先级。

Returns:

XTask 的优先级。

用法示例:

void vAFunction( void )
 {
 TaskHandle_t xHandle;

     // Create a task, storing the handle.
     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );

     // ...

     // Use the handle to obtain the priority of the created task.
     // It was created with tskIDLE_PRIORITY, but may have changed
     // it itself.
     if( uxTaskPriorityGet( xHandle ) != tskIDLE_PRIORITY )
     {
         // The task has changed its priority.
     }

     // ...

     // Is our priority higher than the created task?
     if( uxTaskPriorityGet( xHandle ) < uxTaskPriorityGet( NULL ) )
     {
         // Our priority (obtained using NULL handle) is higher.
     }
 }

vTaskPrioritySet
[任务控制]

task. h
 
  
void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority );

INCLUDE_vTaskPrioritySet 必须定义为 1 才能使用此函数。详情请参阅 RTOS 配置文档。

设置任何任务的优先级。

如果正在设置的优先级高于当前执行任务的优先级,则函数返回之前将发生上下文切换。

参数:

xTask 正在设置优先级的任务的句柄。空句柄会设置调用任务的优先级。
uxNewPriority 将要设置任务的优先级。

断言优先级低于 configMAX_priority。如果未定义 configASSERT,则优先级会被静默限制为 (configMAX_PRIORITIES - 1)。

用法示例:
 void vAFunction( void )
 {
 TaskHandle_t xHandle;
     // Create a task, storing the handle.
     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
     // ...
     // Use the handle to raise the priority of the created task.
     vTaskPrioritySet( xHandle, tskIDLE_PRIORITY + 1 )
     // ...
     // Use a NULL handle to raise our priority to the same value.
     vTaskPrioritySet( NULL, tskIDLE_PRIORITY + 1 );
 }

vTaskSuspend
[任务控制]

task. h
 
  
void vTaskSuspend( TaskHandle_t xTaskToSuspend );

必须将 INCLUDE_vTaskSuspend 定义为 1 才能使用此函数。有关详细信息,请参阅 RTOS 配置文档。

暂停任意任务。无论任务优先级如何,任务被暂停后将永远无法获取任何微控制器处理时间。

对 vTaskSuspend 的调用不会累积次数,例如:若在同一任务上调用 vTaskSuspend () 两次,将仍然仅需调用一次 vTaskResume (),即可准备完毕暂停的任务。

参数:

xTaskToSuspend 被挂起的任务句柄。传递空句柄将导致调用任务被暂停。

用法示例:

 void vAFunction( void )
 {
 TaskHandle_t xHandle;

     // Create a task, storing the handle.
     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );

     // ...

     // Use the handle to suspend the created task.
     vTaskSuspend( xHandle );

     // ...

     // The created task will not run during this period, unless
     // another task calls vTaskResume( xHandle ).

     //...

     // Suspend ourselves.
     vTaskSuspend( NULL );

     // We cannot get here unless another task calls vTaskResume
     // with our handle as the parameter.
 }

vTaskResume
[任务控制]

task. h
 
  
void vTaskResume( TaskHandle_t xTaskToResume );

必须将 INCLUDE_vTaskSuspend 定义为 1 才能使用此函数。有关详细信息,请参阅 RTOS 配置文档。

恢复已挂起的任务。

由一次或多次调用 vTaskSuspend () 而挂起的任务可通过单次调用 vTaskResume () 重新运行。

参数:

xTaskToResume 要恢复的任务句柄。

用法示例:

void vAFunction( void )
 {
 TaskHandle_t xHandle;

     // Create a task, storing the handle.
     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );

     // ...

     // Use the handle to suspend the created task.
     vTaskSuspend( xHandle );

     // ...

     // The created task will not run during this period, unless
     // another task calls vTaskResume( xHandle ).

     //...

     // Resume the suspended task ourselves.
     vTaskResume( xHandle );

     // The created task will once again get microcontroller processing
     // time in accordance with its priority within the system.
 }

xTaskResumeFromISR
[任务控制]

task. h
 
  
BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume );

必须将 include_vTaskSuspend 和 INCLUDE_xTaskResumeFromISR 定义为 1 才能使用此函数。有关详细信息,请参阅 RTOS 配置文档。

可从 ISR 内调用的恢复挂起任务的函数。

由多次调用 vTaskSuspend() 中的一次调用挂起的任务可通过单次调用 xTaskResumeFromISR() 重新运行。

xTaskResumeFromISR() 通常被视为危险函数,因为其 操作未被锁定。 因此,如果中断可能在任务被挂起之前到达, 从而中断丢失, 则绝对不应使用该函数 来同步任务与中断。 可使用信号量, 或者最好是直达任务通知,来避免这种可能性。 提供了一个使用直达到任务通知的有效示例 。

参数:

xTaskToResume 要恢复的任务句柄。

Returns:

如果恢复任务导致上下文切换,则返回 pdTRUE,否则返回 pdFALSE。 ISR 使用此信息来确定 ISR 之后是否需要上下文切换。

示例用法:

TaskHandle_t xHandle;

 void vAFunction( void )
 {
     // Create a task, storing the handle.
     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );

     // ... Rest of code.
 }

 void vTaskCode( void *pvParameters )
 {
     // The task being suspended and resumed.
     for( ;; )
     {
         // ... Perform some function here.

         // The task suspends itself.
         vTaskSuspend( NULL );

         // The task is now suspended, so will not reach here until the ISR resumes it.
     }
 }


 void vAnExampleISR( void )
 {
     BaseType_t xYieldRequired;

     // Resume the suspended task.
     xYieldRequired = xTaskResumeFromISR( xHandle );

     // We should switch context so the ISR returns to a different task.
     // NOTE:  How this is done depends on the port you are using.  Check
     // the documentation and examples for your port.
     portYIELD_FROM_ISR( xYieldRequired );
 }

xTaskAbortDelay [任务控制]

task. h

BaseType_t xTaskAbortDelay( TaskHandle_t xTask );

强制任务离开阻塞状态,并 进入“准备就绪”状态,即使任务在阻塞状态下等待的事件没有发生, 并且任何指定的超时没有过期。

必须将 INCLUDE_xTaskAbortDelay 定义为 1,此函数才可用。 请参阅 RTOS 配置文档以了解更多信息。

参数:

xTask 将被强制退出阻塞状态的任务的句柄 。

要获得任务句柄,请使用 xTaskCreate() 创建任务并使用 pxCreatedTask 参数,或使用返回值创建任务xTaskCreateStatic() 并存储该值,或在 xTaskGetHandle() 时使用任务的名字。

Returns:

如果 xTask 引用的任务不在“阻塞”状态, 则返回 pdFAIL。 否则返回 pdPASS。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值