FreeRTOS 任务之间运行时序

操作系统,我们肯定会创建许多任务,而且任务的优先级不一样,但我们一般情况是采用抢占模式,也就是一直运行当前最高优先级任务,那么其他低优先级任务就无法运行,这时候需要通过其他手段来切换任务,让高优先级任务释放权限。所以了解任务之间的运行时序十分关键。

FreeRTOS任务主要切换有:阻塞、改变优先级、同等优先级、时间片,事件等方式

了解任务肯定从任务创建开始:

1、两个同优先级情况

Task1

void vTask1( void *pvParameters )
{
const char *pcTaskName = "Task 1 is running\r\n";
volatile uint32_t ul; 
 for( ;; )
 {
 vPrintString( pcTaskName );/* 输出打印任务名称 * 
 for( ul = 0; ul < mainDELAY_LOOP_COUNT; ul++ )/* 延时. */
 {
 }
 }
}

Task2

void vTask2( void *pvParameters )
{
const char *pcTaskName = "Task 2 is running\r\n";
volatile uint32_t ul; 
 for( ;; )
 {

 vPrintString( pcTaskName ); /* 输出任务名称. */

 for( ul = 0; ul < mainDELAY_LOOP_COUNT; ul++ ) /* 延时. */
 {
 }
 }
}

main

int main( void )
{
  /* 创建2个优先级一样的任务. */
 xTaskCreate( vTask1,"Task 1",1000, NULL,1, NULL ); 
 xTaskCreate( vTask2, "Task 2", 1000, NULL, 1, NULL );
 vTaskStartScheduler();  /*开始执行任务. */
 for( ;; );//如果不出意外程序永远也不会到达这里
}

注意:主程序中创建两个一样优先级的任务,那么他们会来回切换工作

 具体时序切换如下

2、不同优先级情况运行高的优先级

把上面的main修改如下

int main( void )
{
  /* 创建2个优先级一样的任务. */
 xTaskCreate( vTask1,"Task 1",1000, NULL,1, NULL ); 
 xTaskCreate( vTask2, "Task 2", 1000, NULL, 2, NULL );
 vTaskStartScheduler();  /*开始执行任务. */
 for( ;; );//如果不出意外程序永远也不会到达这里
}

也就是创建优先级不一样的任务,那么只会运行优先级高的Task情况,这在一定程度上我们不希望这么样,也不希望所有优先级一样的情况,那么就需要用其他手段来切换程序

3、事件阻塞

等待事件的任务被称为处于“阻止”状态,这是未运行状态。这时候系统就会切换到其他任务

3.1.时间(时间相关)事件,该事件是延迟期到期或达到绝对时间。

Task代码

void vTaskFunction( void *pvParameters )
{
char *pcTaskName;
const TickType_t xDelay250ms = pdMS_TO_TICKS( 250 );
 pcTaskName = ( char * ) pvParameters;
 for( ;; )
 {
 vPrintString( pcTaskName );/*打印任务名称,任务名称为传递参数*/
 vTaskDelay( xDelay250ms );/*延时,这个时候会阻塞该任务*/
 }
}

main代码

static const char *pcTextForTask1 = "Task 1 is running\r\n";//定义任务参数
static const char *pcTextForTask2 = "Task 2 is running\r\n";
int main( void )
{
 //建立两个不一样的优先级的任务
 xTaskCreate( vTaskFunction, "Task 1", 1000, (void*)pcTextForTask1, 1, NULL );
 xTaskCreate( vTaskFunction, "Task 2", 1000, (void*)pcTextForTask2, 2, NULL );
 vTaskStartScheduler(); 
 return 0;
}

 由于vTaskDelay原因产生阻塞,任务就会在task1,2之间切换其时序见下图

同时我们也看到Idle的空闲任务也出来了,这个任务时系统在运行 vTaskStartScheduler();时由系统创建。具体暂不做分析,注意这Idle十分重要,尤其是比较复杂场景。

还有vTaskDelayUntil也会产生相同效果,对于任务切换来说可能会细微差别,这里也暂不做详细介绍

3.2.同步事件,其中事件源自另一任务或中断。FreeRTOS队列、二进制信号量、计数信号量、互斥锁、递归互斥锁、,事件组和直接到任务通知都可以用于创建同步事件。

4、改变任务优先级vTaskPrioritySet

4.1改变其他任务的优先级

4.2改变自身任务的优先级

这两点十分好理解,永远运行最高优先级任务,只是注意什么时候切换,是等这个时间周期运行结束还是马上执行 ,答案是马上执行。

在任务1中提高任务2的优先级

void vTask1( void *pvParameters )
{
UBaseType_t uxPriority;
 uxPriority = uxTaskPriorityGet( NULL );
 for( ;; )
 {

 vPrintString( "Task 1 is running\r\n" );
 vPrintString( "About to raise the Task 2 priority\r\n" );
 vTaskPrioritySet( xTask2Handle, ( uxPriority + 1 ) );
 
 }
}

任务2自己降低自己的优先级

void vTask2( void *pvParameters )
{
UBaseType_t uxPriority;

 uxPriority = uxTaskPriorityGet( NULL );
 
 for( ;; )
 {
 vPrintString( "Task 2 is running\r\n" );
 vPrintString( "About to lower the Task 2 priority\r\n" );
 vTaskPrioritySet( NULL, ( uxPriority - 2 ) );
 }

mian

TaskHandle_t xTask2Handle = NULL;
int main( void )
{
 xTaskCreate( vTask1, "Task 1", 1000, NULL, 2, NULL );
 xTaskCreate( vTask2, "Task 2", 1000, NULL, 1, &xTask2Handle );
 vTaskStartScheduler(); 
 for( ;; );
}

 运行时序见下图,注意空闲任务并没机会运行

 

其他还有挂起、删除任务等能切换任务运行

以及taskYIELD()也可,当然采用协同方式也可。这里抛砖引玉,只是需要我们做系统架构时候需要注意任务切换,以及途径

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值