Freertos任务管理

本文介绍了嵌入式实时操作系统(RTOS)中任务状态管理、vTaskDelay和vTaskDelayUntil函数的使用,探讨了任务优先级、空闲任务与用户任务的关系,以及不同任务调度算法(如时间片轮转)的应用。
摘要由CSDN通过智能技术生成

一.任务状态理论讲解

正在执行的任务状态是running,其他执行的等待执行的任务状态是ready 

1.修改间隔时间

2.任务状态 

  

处于各个状态的任务是怎样被管理起来的:链表 

3.代码

TaskHandle_t xHandleTask1;
TaskHandle_t xHandleTask3;

static int task1flagrun = 0;
static int task2flagrun = 0;
static int task3flagrun = 0;

void Task1Function(void * param)
{
	TickType_t tStart = xTaskGetTickCount();
	TickType_t t;
	int flag = 0;
	
	while (1)
	{
		t = xTaskGetTickCount();
		
		task1flagrun = 1;
		task2flagrun = 0;
		task3flagrun = 0;
		printf("1");

		if (!flag && (t > tStart + 10))
		{
			vTaskSuspend(xHandleTask3);
			flag = 1;
		}

		if (t > tStart + 20)
		{
			vTaskResume(xHandleTask3);
		}
	}
}

void Task2Function(void * param)
{
	while (1)
	{
		task1flagrun = 0;
		task2flagrun = 1;
		task3flagrun = 0;
		printf("2");

		vTaskDelay(10);
	}
}

void Task3Function(void * param)
{
	while (1)
	{
		task1flagrun = 0;
		task2flagrun = 0; 
		task3flagrun = 1;
		printf("3");
	}
}


/*-----------------------------------------------------------*/

StackType_t xTask3Stack[100];
StaticTask_t xTask3TCB;

StackType_t xIdleTaskStack[100];
StaticTask_t xIdleTaskTCB;


/*
 * The buffers used here have been successfully allocated before (global variables)
 */
void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
                                    StackType_t ** ppxIdleTaskStackBuffer,
                                    uint32_t * pulIdleTaskStackSize )
{
    *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
    *ppxIdleTaskStackBuffer = xIdleTaskStack;
    *pulIdleTaskStackSize = 100;
}


int main( void )
{
		
#ifdef DEBUG
  debug();
#endif

	prvSetupHardware();

	printf("Hello, world!\r\n");

	xTaskCreate(Task1Function, "Task1", 100, NULL, 1, &xHandleTask1);
	xTaskCreate(Task2Function, "Task2", 100, NULL, 1, NULL);
	xHandleTask3 = xTaskCreateStatic(Task3Function, "Task3", 100, NULL, 1, xTask3Stack, &xTask3TCB);

	/* Start the scheduler. */
	vTaskStartScheduler();

	/* Will only get here if there was not enough heap space to create the
	idle task. */
	return 0;
}

 

 二.vTaskDelay和vTaskDelayUntil

vTaskDelay:至少等待指定个数的Tick Interrupt才能变为就绪状态

xTaskDelayUntil

  • 返回pdTRUE表示确实延迟了,返回pdFALSE表示没有发生延迟(因为延迟的时间点早就过了)

  • 等待到指定的绝对时刻,才能变为就绪态。

代码1 vTaskDelay

TaskHandle_t xHandleTask1;
TaskHandle_t xHandleTask3;

static int task1flagrun = 0;
static int task2flagrun = 0;
static int task3flagrun = 0;

static int rands[]={3,56,23,5,59};

void Task1Function(void * param)
{
	TickType_t tStart = xTaskGetTickCount();
	int i=0;
	int j=0;
	
	while (1)
	{		
		task1flagrun = 1;
		task2flagrun = 0;
		task3flagrun = 0;

		for( i= 0; i < rands[j] ; i++)
			printf("1");
		
		j++;
		if ( j == 5)j = 0;
		
		vTaskDelay(20);
	}
}

void Task2Function(void * param)
{
	while (1)
	{
		task1flagrun = 0;
		task2flagrun = 1;
		task3flagrun = 0;
		printf("2");
	}
}

void Task3Function(void * param)
{
	while (1)
	{
		task1flagrun = 0;
		task2flagrun = 0; 
		task3flagrun = 1;
		printf("3");
	}
}


/*-----------------------------------------------------------*/

StackType_t xTask3Stack[100];
StaticTask_t xTask3TCB;

StackType_t xIdleTaskStack[100];
StaticTask_t xIdleTaskTCB;


/*
 * The buffers used here have been successfully allocated before (global variables)
 */
void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
                                    StackType_t ** ppxIdleTaskStackBuffer,
                                    uint32_t * pulIdleTaskStackSize )
{
    *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
    *ppxIdleTaskStackBuffer = xIdleTaskStack;
    *pulIdleTaskStackSize = 100;
}


int main( void )
{
		
#ifdef DEBUG
  debug();
#endif

	prvSetupHardware();

	printf("Hello, world!\r\n");

	xTaskCreate(Task1Function, "Task1", 100, NULL, 2, &xHandleTask1);
	xTaskCreate(Task2Function, "Task2", 100, NULL, 1, NULL);
	xHandleTask3 = xTaskCreateStatic(Task3Function, "Task3", 100, NULL, 1, xTask3Stack, &xTask3TCB);

	/* Start the scheduler. */
	vTaskStartScheduler();

	/* Will only get here if there was not enough heap space to create the
	idle task. */
	return 0;
}

 可以看到任务1执行的时间不一样,但是进入delay休眠的时间是一样的,都是20ms。

 

代码2 vTaskDelayUntil

BaseType_t xTaskDelayUntil( TickType_t * const pxPreviousWakeTime,
                            const TickType_t xTimeIncrement ) ;
// 1  延迟直到 *pxPre+xTime
// 2  *pxPre=*pxPre+xTime
TaskHandle_t xHandleTask1;
TaskHandle_t xHandleTask3;

static int task1flagrun = 0;
static int task2flagrun = 0;
static int task3flagrun = 0;

static int rands[]={3,56,23,5,59};

void Task1Function(void * param)
{
	TickType_t tStart = xTaskGetTickCount();
	int i=0;
	int j=0;
	
	while (1)
	{		
		task1flagrun = 1;
		task2flagrun = 0;
		task3flagrun = 0;

		for( i= 0; i < rands[j] ; i++)
			printf("1");
		
		j++;
		if ( j == 5)j = 0;
#if 0
		vTaskDelay(20);
#else
		xTaskDelayUntil(&tStart,20);
#endif
	}
}

void Task2Function(void * param)
{
	while (1)
	{
		task1flagrun = 0;
		task2flagrun = 1;
		task3flagrun = 0;
		printf("2");
	}
}

void Task3Function(void * param)
{
	while (1)
	{
		task1flagrun = 0;
		task2flagrun = 0; 
		task3flagrun = 1;
		printf("3");
	}
}


/*-----------------------------------------------------------*/

StackType_t xTask3Stack[100];
StaticTask_t xTask3TCB;

StackType_t xIdleTaskStack[100];
StaticTask_t xIdleTaskTCB;


/*
 * The buffers used here have been successfully allocated before (global variables)
 */
void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
                                    StackType_t ** ppxIdleTaskStackBuffer,
                                    uint32_t * pulIdleTaskStackSize )
{
    *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
    *ppxIdleTaskStackBuffer = xIdleTaskStack;
    *pulIdleTaskStackSize = 100;
}


int main( void )
{
		
#ifdef DEBUG
  debug();
#endif

	prvSetupHardware();

	printf("Hello, world!\r\n");

	xTaskCreate(Task1Function, "Task1", 100, NULL, 2, &xHandleTask1);
	xTaskCreate(Task2Function, "Task2", 100, NULL, 1, NULL);
	xHandleTask3 = xTaskCreateStatic(Task3Function, "Task3", 100, NULL, 1, xTask3Stack, &xTask3TCB);

	/* Start the scheduler. */
	vTaskStartScheduler();

	/* Will only get here if there was not enough heap space to create the
	idle task. */
	return 0;
}

以每20ms周期性的执行 

三.空闲任务及钩子函数 

实验1

执行任务1,任务1的任务是创建任务2,当任务2创建成功,任务2的优先级更高,直接执行任务2。任务2的任务是打印一个2,然后进入阻塞,任务1运行删除任务。

extern void Task2Function(void * param);

void Task1Function(void * param)
{
	TaskHandle_t xHandleTask2;
	BaseType_t xReturn;
	while (1)
	{
		printf("1");
		xReturn=xTaskCreate(Task2Function, "Task2", 1024, NULL, 2, &xHandleTask2);
		if(xReturn!=pdPASS)
		{
			printf("xTaskCreate err\r\n");
		}
		vTaskDelete(xHandleTask2);
	}
}

void Task2Function(void * param)
{
	while (1)
	{
		printf("2");
		vTaskDelay(2);
	}
}


/*-----------------------------------------------------------*/

int main( void )
{
	TaskHandle_t xHandleTask1;
		
#ifdef DEBUG
  debug();
#endif

	prvSetupHardware();

	printf("Hello, world!\r\n");

	xTaskCreate(Task1Function, "Task1", 100, NULL, 1, &xHandleTask1);

	/* Start the scheduler. */
	vTaskStartScheduler();

	/* Will only get here if there was not enough heap space to create the
	idle task. */
	return 0;
}

并没有执行我们想要的清理工作。

我们进行的清理工作(内存回收工作)是放在空闲任务里面的。

实验2 

执行自杀操作

extern void Task2Function(void * param);

void Task1Function(void * param)
{
	TaskHandle_t xHandleTask2;
	BaseType_t xReturn;
	while (1)
	{
		printf("1");
		xReturn=xTaskCreate(Task2Function, "Task2", 1024, NULL, 2, &xHandleTask2);
		if(xReturn!=pdPASS)
		{
			printf("xTaskCreate err\r\n");
		}
		//vTaskDelete(xHandleTask2);
	}
}

void Task2Function(void * param)
{
	while (1)
	{
		printf("2");
		vTaskDelay(2);
		vTaskDelete(NULL);//执行自杀操作
	}
}


/*-----------------------------------------------------------*/

int main( void )
{
	TaskHandle_t xHandleTask1;
		
#ifdef DEBUG
  debug();
#endif

	prvSetupHardware();

	printf("Hello, world!\r\n");

	xTaskCreate(Task1Function, "Task1", 100, NULL, 1, &xHandleTask1);

	/* Start the scheduler. */
	vTaskStartScheduler();

	/* Will only get here if there was not enough heap space to create the
	idle task. */
	return 0;
}

执行自杀操作应该由空闲任务帮你执行清理工作

配置钩子函数

在main函数里面创建任务1,优先级是0,任务1里面创建任务2,任务2优先级更高执行完之后就自杀。之后任务1和任务0可以交替执行

 

四.任务调度算法

static int task1flagrun = 0;
static int task2flagrun = 0;
static int task3flagrun = 0;
static int taskidleflagrun = 0;

void Task1Function(void * param)
{
	//volatile char buf[500];
	//int i;
	
	while (1)
	{
		task1flagrun = 1;
		task2flagrun = 0;
		task3flagrun = 0;
		taskidleflagrun = 0;
		printf("1");
	}
}

void Task2Function(void * param)
{
	int i = 0;
	
	while (1)
	{
		task1flagrun = 0;
		task2flagrun = 1;
		task3flagrun = 0;
		taskidleflagrun = 0;
		printf("2");
	}
}

void Task3Function(void * param)
{
	const TickType_t xDelay5ms=pdMS_TO_TICKS(5UL);
	while (1)
	{
		task1flagrun = 0;
		task2flagrun = 0; 
		task3flagrun = 1;
		taskidleflagrun=0;
		printf("3");

		//如果不休眠的化,其他任务无法得到执行
		vTaskDelay(xDelay5ms);
	}
}

void vApplicationIdleHook()
{
	task1flagrun = 0;
	task2flagrun = 0; 
	task3flagrun = 0;
	taskidleflagrun=1;
}


int main( void )
{
		
#ifdef DEBUG
  debug();
#endif

	prvSetupHardware();

	printf("Hello, world!\r\n");

	xTaskCreate(Task1Function, "Task1", 1000, NULL, 0, NULL);
	xTaskCreate(Task2Function, "Task2", 1000, NULL, 0, NULL);
	xTaskCreate(Task3Function, "Task3", 1000, NULL, 2, NULL);
	//优先级最高的任务3先执行

	/* Start the scheduler. */
	vTaskStartScheduler();

	/* Will only get here if there was not enough heap space to create the
	idle task. */
	return 0;
}

1.可以抢占

这个宏定义是否可以抢占

 任务3优先级最高,先执行执行完阻塞5ms,其他任务执行。执行任务1,任务2,任务1,任务2,任务0,任务1。5ms到了立刻执行任务3...

A.时间片轮转

  任务3优先级最高,先执行执行完阻塞5ms,其他任务执行。执行任务1,任务2,任务1,任务2,任务0,任务1。5ms到了立刻执行任务3...

B.时间片不轮转

 任务3优先级最高先执行,执行完进入休眠,任务1执行直到任务3休眠结束,任务3执行结束,就接着让任务2执行....

 

2.不可以抢占

 

任务3执行完了进入阻塞,任务1一直执行。如果需要让出CPU资源还是需要自己去主动进入休眠。 

3.空闲任务是否让步于用户任务

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值