FreeRTOS学习笔记——(3)任务管理

本文详细介绍了FreeRTOS中任务的创建与删除,包括动态和静态创建任务的函数使用,任务的优先级设定,任务的状态转换,Delay函数的两种形式,以及空闲任务和钩子函数的作用。同时,还探讨了任务调度的基本原理。
摘要由CSDN通过智能技术生成

系列文章目录

FreeRTOS学习笔记—— 系列文章目录


一、任务的创建与删除

1、什么是任务

在FreeRTOS中,任务就是一个函数,例如

void TaskFunction(void * param)
{
//
	while (1)   //任务函数通常实现为无限循环
	{
		printf("Task");
	}
}

2、创建任务

创建任务有两种方法:动态创建任务、静态创建任务,于是有两个创建任务函数:

1、动态创建任务函数

// 动态创建任务
BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, //函数指针,任务函数
                        const char * const pcName, //任务的名字
                        const configSTACK_DEPTH_TYPE usStackDepth,//栈大小,单位为 word ;例如10,表示40个字节
                        void * const pvParameters,//调用任务函数时传入的参数
                        UBaseType_t uxPriority, //任务的优先级
                        TaskHandle_t * const pxCreatedTask ); //任务句柄,用这个句柄来操作这个任务
//返回值:创建任务成功返回  pdPASS;  宏定义为 1
//				失败返回  errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;  宏定义为 -1  
//        失败的原因为内存不足

在这个函数的内部创建了任务结构体 TCB_t类型,TCB表示任务控制块,_t表示结构体。
在使用 xTaskCreate 函数创建任务时,在函数内部使用 malloc 从堆里分配出结构体。

2、静态创建任务函数

在这里插入图片描述
静态创建任务函数:xTaskCreateStatic
由图中可看到,在使用这个函数创建任务必须先定义宏 configSUPPORT_STATIC_ALLOCATION1 ,再实现 vApplicationGetIdleTaskMemory 函数。才能创建静态任务。
创建任务函数:xTaskCreateStatic的参数有有 7 个,其中前五个参数的含义与创建动态任务函数的前 5 个参数的含义一样,第 6 个参数为栈,即自己定义的数组。第 7 个参数为TCB结构体。

静态创建任务函数xTaskCreateStatic 的返回值为该任务的句柄,可使用这个句柄来操作此任务

3、创建任务及删除任务

//   动态创建任务
void Task1Function(void * param)
{
	while (1)
	{
		printf("Task1");
	}
}
void Task2Function(void * param)
{
	int i = 0;
	while (1)
	{
		printf("Task2");
		if(i++ == 100)  //循环100次删除任务1
			vTaskDelete(xHandleTask1); //  往vTaskDelete();里传入任务的句柄,即删除任务
		if(i == 200)
		{
			vTaskDelete(NULL); //传入NULL 表示任务自杀,自杀的任务由空闲任务清理
		}
			
	}
}

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

	prvSetupHardware();

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

	xTaskCreate(Task1Function, "Task1", 100, NULL, 0, &xHandleTask1);
	xTaskCreate(Task2Function, "Task2", 100, NULL, 0, NULL);
	/* Start the scheduler. */
	vTaskStartScheduler();

	/* Will only get here if there was not enough heap space to create the
	idle task. */
	return 0;
}
//   静态创建任务
//   1、需要在 FreeRTOSConfig.h 中进行宏定义  configSUPPORT_STATIC_ALLOCATION  为  1
//   2、需要实现 vApplicationGetIdleTaskMemory 函数


//   1、需要在 FreeRTOSConfig.h 中进行宏定义 
#define configSUPPORT_STATIC_ALLOCATION 1   //写在  FreeRTOSConfig.h  文件中


//   2、需要实现 vApplicationGetIdleTaskMemory 函数
StackType_t xTask3Stack[100]; //定义栈,及大小。来存储此任务的数据
StaticTask_t xTask3TCB;       //定义  TCB 结构体

StackType_t xIdleTaskStack[100];
StaticTask_t xIdleTaskTCB;

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");
	
	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;
}

二、 任务优先级

在FreeRTOS中,优先级的取值范围是:0~(configMAX_PRIORITIES – 1),数值越大优先级越高。高优先级的、可运行的任务,马上就能执行。相同优先级的、可运行的任务,轮流执行。
轮流执行即你执行一会,我执行一会;执行一会为 Tick

三、任务状态

在FreeRTOS中,任务分为 4 中状态:

  1. 阻塞状态(Blocked) :当任务等待某个事件或信号的时候处于此状态
  2. 暂停状态(Suspended):当任务被vTaskSuspend()函数禁止运行的时候处于此状态
  3. 就绪状态(Ready):准备好了,随时可以运行
  4. 运行状态(Runing):当前正在运行的任务
    图:百文网图

四、Delay函数

  1. vTaskDelay:至少等待指定个数的Tick Interrupt才能变为就绪状态
  2. vTaskDelayUntil:等待到指定的绝对时刻,才能变为就绪状态
void vTaskDelay( const TickType_t xTicksToDelay ); /* xTicksToDelay: 等待多少Tick */

BaseType_t vTaskDelayUntil( TickType_t * const pxPreviousWakeTime,//pxPreviousWakeTime: 上一次被唤醒的时间
							const TickType_t xTimeIncrement );//xTimeIncrement: 要阻塞到(pxPreviousWakeTime + xTimeIncrement),单位都是Tick Count

在这里插入图片描述
vTaskDelay( N ); //表示上图,函数运行时间不时间一致,延时时间一致。为 N 个Tick
vTaskDelay( pdMS_TO_TICKS( 50UL ) ); // 调用 pdMS_TO_TICKS(); 函数,将 Tick单位 改为 ms 单位,,,延时 50ms

在这里插入图片描述
TickType_t tStart = xTaskGetTickCount(); // 记录任务的启动时间
vTaskDelayUntil(&tStart , 20); //上图 t1-t2 = t2-t1

五、空闲函数及钩子函数

空闲任务的作用是:释放被删除的任务的内存。
在使用 vTaskStartScheduler() 函数来创建、启动调度器时,这个函数内部会创建空闲任务:空闲任务的优先级为 0 ,它不能阻碍用户任务的运行。
使用 vTaskDelete() 来删除任务时,要确保空闲任务有机会执行,否则就无法释放被删除任务的内存。

可以添加一个空闲任务的钩子函数,空闲任务的循环没执行一次,就会调用一次钩子函数。钩子函数不能导致空闲任务进入阻塞状态、暂停状态。

钩子函数
1、可以执行一些低优先级的、后台的、需要连续执行的函数;
2、 可以测量系统的空闲时间:空闲任务能被执行就意味着所有的高优先级任务都停止了,所以测量空闲任务占据的时间,就可以算出处理器占用率;
3、可以让系统进入省电模式:空闲任务能被执行就意味着没有重要的事情要做,当然可以进入省电模式了。

在这里插入图片描述
vApplicationIdleHook(); 钩子函数
使用之前需要在 FreeRTOSConfig.h 中将宏定义 configUSE_IDLE_HOOK 的宏改为 1 ;然后就可以实现这个函数了。

六、任务调度

图:百文网图


本专栏内容均是学习韦东山老师讲课,学习笔记方便以后复习复盘。
附上韦东山老师百问网官网:https://www.100ask.net/index

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值