重新开始学stm32 FreeRTOS系统(2)——任务相关的API函数

这一期我们接着学习 FreeRTOS 系统的知识,这一期我们讲的内容是任务相关的API函数,讲完这一期,我们就可以去创建一个多任务程序的模板了。


任务创建和删除API函数

FreeRTOS 最基本的功能就是任务管理,而任务管理最基本的操作就是创建和删除任务,FreeRTOS 的任务创建和删除 API 函数如表 6.1.1.1 所示:

 xTaxkCreate()函数

此函数用来创建一个任务,任务需要 RAM 来保存与任务有关的状态信息(任务控制块),任务也需要一定的 RAM 来作为任务堆栈。如果使用函数 xTaskCreate()来创建任务的话那么这些所需的 RAM 就会自动的从 FreeRTOS 的堆中分配,因此必须提供内存管理文件,默认我们使用heap_4.c 这个内存管理文件,而且宏 configSUPPORT_DYNAMIC_ALLOCATION 必须为 1。如果使用函数 xTaskCreateStatic()创建的话这些 RAM 就需要用户来提供了。新创建的任务默认就是就绪态的,如果当前没有比它更高优先级的任务运行那么此任务就会立即进入运行态开始运行,不管在任务调度器启动前还是启动后,都可以创建任务。此函数也是我们以后经常用到的,函数原型如下:

BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,
                        const char * const pcName,
                        const uint16_t usStackDepth,
                        void * const pvParameters,
                        UBaseType_t uxPriority,
                        TaskHandle_t * const pxCreatedTask )

参数:

pxTaskCode:        任务函数。
pcName:               任务名字,一般用于追踪和调试,任务名字长度不能超过                                                         configMAX_TASK_NAME_LEN。
usStackDepth:     任务堆栈大小,注意实际申请到的堆栈是 usStackDepth 的 4 倍。其中                                   空闲任务的任务堆栈大小为 configMINIMAL_STACK_SIZE。
pvParameters:     传递给任务函数的参数。
uxPriotiry:            任务优先级,范围 0~ configMAX_PRIORITIES-1
pxCreatedTask:    任务句柄,任务创建成功以后会返回此任务的任务句柄,这个句柄其实                                   就是任务的任务堆栈。此参数就用来保存这个任务句柄。其他 API 函数                                   可能会使用到这个句柄。
返回值:
pdPASS:         任务创建成功。
errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY : 任务创建失败,因为堆内存不足!

 xTaskCreateStatic()函数

此函数和 xTaskCreate()的功能相同,也是用来创建任务的,但是使用此函数创建的任务所需 的 RAM 需 要 用 用 户 来 提 供 。 如 果 要 使 用 此 函 数 的 话 需 要 将 宏configSUPPORT_STATIC_ALLOCATION 定义为 1。函数原型如下:

TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode,
                                const char * const pcName,
                                const uint32_t ulStackDepth,
                                void * const pvParameters,
                                UBaseType_t uxPriority,
                                StackType_t * const puxStackBuffer,
                                StaticTask_t * const pxTaskBuffer )

参数和xTaskCreate()函数相比多出了一个puxStackBufferpxTaskBuffer,puxStackBuffer这个东西在上一期讲过。

puxStackBuffer:任务堆栈,一般为数组,数组类型要为 StackType_t 类型。

pxTaskBuffer:任务控制块。

返回值:
NULL    任务创建失败,puxStackBuffer pxTaskBuffer NULL 的时候会导致这个错误                   的发生。
其他值 :     任务创建成功,返回任务的任务句柄。

xTaskCreateRestricted()函数

此函数也是用来创建任务的,只不过此函数要求所使用的 MCU MPU( 内存保护单元 ) , 用此函数创建的任务会受到 MPU 的保护。其他的功能和函数 xTaxkCreate() 一样。这个函数个人觉得使用的很少(至少我还没真正的用过)
BaseType_t xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, 
                                  TaskHandle_t * pxCreatedTask )
参数:
pxTaskDefinition:     指向一个结构体 TaskParameters_t ,这个结构体描述了任务的任务函                                     数、 堆栈大小、优先级等。此结构体在文件 task.h 中有定义。
pxCreatedTask:        任务句柄。
返回值:
pdPASS:       任务创建成功。
其他值 :          任务未创建成功,很有可能是因为 FreeRTOS 的堆太小了。

vTaskDelete()函数

删除一个用函数 xTaskCreate()或者 xTaskCreateStatic()创建的任务 ,被删除了的任务不再存 在,也就是说再也不会进入运行态。任务被删除以后就不能再使用此任务的句柄!如果此任务 是使用动态方法创建的,也就是使用函数 xTaskCreate() 创建的,那么在此任务被删除以后此任 务之前申请的堆栈和控制块内存会在空闲任务中被释放掉,因此当调用函数 vTaskDelete() 删除 任务以后必须给空闲任务一定的运行时间。
只有那些由内核分配给任务的内存才会在任务被删除以后自动的释放掉,用户分配给任务 的内存需要用户自行释放掉,比如某个任务中用户调用函数 pvPortMalloc() 分配了 500 字节的内 存,那么在此任务被删除以后用户也必须调用函数 vPortFree() 将这 500 字节的内存释放掉,否 则会导致内存泄露。此函数原型如下:
vTaskDelete( TaskHandle_t xTaskToDelete )
参数:
xTaskToDelete:         要删除的任务的任务句柄。

任务创建和删除实验

完成前面两期的学习,我们现在可以进行创建和删除实验,写一个自己的多任务程序模板了。

首先第一步是进行任务设置

#define START_TASK_PRIO 1               //任务优先级      (1)
#define START_STK_SIZE 128              //任务堆栈大小    (2)
TaskHandle_t StartTask_Handler;         //任务句柄        (3)
void start_task(void *pvParameters);    //任务函数        (4)

/*
...
同样地宏定义START任务外其他任务如:TASK1任务等的各个参数
*/
(1) start_task 任务的任务优先级,此处用宏来表示,以后所有的任务优先级都用宏来表示。创建任务设置优先级的时候就用这个宏,当然了也可以直接在创建任务的时候指定任务优 先级。
(2) start_task 任务的任务堆栈大小。
(3) start_task 任务的任务句柄。
(4) start_task 任务的任务函数声明。

第二步就是写主函数

int main(void)
{
    /*
    ...
    初始化处理
    */

    //创建开始任务
    xTaskCreate((TaskFunction_t )start_task, //任务函数     (1)
                (const char* )"start_task",  //任务名称
                (uint16_t )START_STK_SIZE,   //任务堆栈大小
                (void* )NULL,                //传递给任务函数的参数
                (UBaseType_t )START_TASK_PRIO,        //任务优先级
                (TaskHandle_t* )&StartTask_Handler);  //任务句柄
    vTaskStartScheduler(); //开启任务调度                   (2)
}
(1) 、调用函数 xTaskCreate() 创建 tart_task 任务,函数中的各个参数就是上面的任务设置中
定义的,其他任务的创建也用这种方法。
(2) 、调用函数 vTaskStartScheduler() 开启 FreeRTOS 的任务调度器, FreeRTOS 开始行。

接下来第三步我们来写任务函数

//开始任务任务函数
void start_task(void *pvParameters)
{
	taskENTER_CRITICAL();           //进入临界区

	BinarySemaphore2=xSemaphoreCreateBinary();
	BinarySemaphore3=xSemaphoreCreateBinary();


	//创建 TASK1 任务
	xTaskCreate((TaskFunction_t )Task1_task,     	
							(const char*    )"Task1_task",   	
							(uint16_t       )TASK1_STK_SIZE, 
							(void*          )NULL,				
							(UBaseType_t    )TASK1_TASK_PRIO,	
							(TaskHandle_t*  )&TASK1_Handler); 	

	//创建 TASK2 任务
	xTaskCreate((TaskFunction_t )Task2_task,     	
							(const char*    )"Task2_task",   	
							(uint16_t       )TASK2_STK_SIZE, 
							(void*          )NULL,				
							(UBaseType_t    )TASK2_TASK_PRIO,	
							(TaskHandle_t*  )&TASK2_Handler); 		
								
	vTaskDelete(StartTask_Handler); //删除开始任务
	taskEXIT_CRITICAL();            //退出临界区
}
(1) start_task 任务的任务函数,在此任务函数中我们创建了另外两个任务 task1_task
task2_task start_task 任务的职责就是用来创建其他的任务或者信号量、消息队列等的,当创建
完成以后就可以删除掉 start_task 任务。
(2) 、删除 start_task 任务,注意函数 vTaskDelete() 的参数就是 start_task 任务的任务句柄
StartTask_Handler

这里我的是START函数的任务函数,START函数任务就是创建其他任务函数,我们其他的任务函数就是实现各种相应任务的函数,其他任务函数基本格式如下:

void Task1_task(void *pvParameters)
{
    while(1)
    {
        /*
        ...
        相应任务功能
        */
        vTaskDelay(10);    //延时
    }
}

上面是创建任务的动态方法,也是最常用的方法,而静态创建任务和动态创建有一点点的不同,在这里就不讲静态创建任务的方法了,想要学习的小伙伴可以自己去看资料学习。

这一期的内容就到这里,我们下期见。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值