FreeRTOS——任务控制(2)

vTaskDelay

task.h

void vTaskDelay( const TickType_t xTicksToDelay );

vTaskDelay( 任务延时时间 );

必须将INCLUDE_vTaskDelay 定义为 1,此函数才可用。

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

vTaskDelay() 会指定任务想要取消阻塞的时间,该时间是相对于 vTaskDelay() 被调用的时间。

例如,如果指定 时间块为 100 个 tick,那么在调用 vTaskDelay() 100 个 tick 后任务会取消阻塞。

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

vTaskDelayUntil

task. h

void vTaskDelayUntil( TickType_t *pxPreviousWakeTime,

const TickType_t xTimeIncrement );

vTaskDelayUntil( 指针,频率 );

INCLUDE_vTaskDelayUntil 必须被定义为 1 才能使用此函数。

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

vTaskDelay() 会指定 任务想要取消阻塞的时间,该时间是相对于 vTaskDelay() 被调用的时间,

而 vTaskDelayUntil() 会指定任务希望取消阻塞的绝对时间。

应注意,如果vTaskDelayUntil() 被用于指定已过去的唤醒时间, 该函数将立即返回(不阻塞)。

使用 vTaskDelayUntil() 定期执行的任务,在周期性执行因任何原因停止 (例如,任务被暂停),而导致任务错过一个或多个周期性执行时, 必须重新计算其所需的唤醒 时间。

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

任务的状态

运行状态:当前正在执行的任务的状态,只可能会一个当前正在执行的任务。初运行态外,下述的情况都可以归类到 非运行 态。

就绪状态随时可以运行的任务的状态,就绪状态的任务随时等待任务调度器调度,是在被任务调度器赋予 CPU 使用权之前的状态。刚创建的任务立即进入就绪状态,比如系统中正在运行优先级为 2 的任务,优先级为1 的任务因为优先级低而未进入运行状态时,就处于就绪状态。

阻塞状态:任务因为某些原因暂时不能被任务调度器赋予 CPU 使用权状态。一般情况下正在等待某些事件的发生比如调用了 xTaskNotifyWait() 等待任务通知的任务,或者等待延时时间结束的事件比如调用了 xTaskDelay() 的任务,在一段时间内任务会被阻塞,在这些事件达成后任务会自动回到就绪状态。

挂起状态:vTaskSuspend()函数会让任务进入挂起状态,这时候这个任务不会执行。调用xTaskResume()函数才能让这些任务回到就绪状态

删除状态:一个任务被使用vTaskDelete()函数后被删除,处于删除状态。

vTaskSuspend

task.h

void vTaskSuspend( TaskHandle_t xTaskToSuspend );

vTaskSuspend( 任务句柄 );

vTaskSuspend( null );//暂停当前调用任务

必须将INCLUDE_vTaskSuspend 定义为 1 才能使用此函数。

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

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

vTaskResume

task.h

void vTaskResume( TaskHandle_t xTaskToResume );

vTaskResume( 需要恢复的任务句柄 );恢复已挂起的任务。

必须将INCLUDE_vTaskSuspend 定义为 1 才能使用此函数。

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

代码:

void vAFunction( void )

{

TaskHandle_t xHandle;

xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );

vTaskSuspend( xHandle );//暂停xHandle任务

//vTaskSuspend( NULL ); 暂停调用这个函数的任务

vTaskResume( xHandle ); //恢复挂起的任务

}

xTaskResumeFromISR

task.h

BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume );

可从 ISR (中断服务程序)内调用的恢复挂起任务的函数。

必须将include_vTaskSuspend 和INCLUDE_xTaskResumeFromISR 定义为 1 才能使用此函数。

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

xTaskResumeFromISR() 通常被视为危险函数,因为其 操作未被锁定。

因此,如果中断可能在任务被挂起之前到达, 从而中断丢失, 则绝对不应使用该函数 来同步任务与中断。可使用信号量, 或者最好是直达任务通知,来避免这种可能性。

这个函数只适用于中断的时候

中断任务的优先级,数值越小,优先级越大

freertos的优先级,数值越大,优先级越大

因此当中断优先级为0-4的时候,中断的优先级是大于freertos的

因此当中断优先级为5-15的时候,中断的优先级是小于freertos的

xTaskAbortDelay

task. h

BaseType_t xTaskAbortDelay( TaskHandle_t xTask );

xTaskAbortDelay( 任务句柄 );

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

必须将 INCLUDE_xTaskAbortDelay 定义为 1,此函数才可用。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值