嵌入式系统与单片机|技术阅读
登录|注册

您现在的位置是:嵌入式系统与单片机 > 技术阅读 > FreeRTOS学习第4篇--任务使用参数

FreeRTOS学习第4篇--任务使用参数

FreeRTOS学习第4篇--任务使用参数

本文目标:学习与使用FreeRTOS中的任务参数。

按照本文的描述,应该可以跑通实验并举一反三。

先决条件:拥有C语言基础,装有编译和集成的开发环境,比如:Keil uVision5

使用外设:USART1、GPIO、I2C

实验目的

创建3个优先级相同的PrintTask任务,在任务中,使用OLED显示任务的执行次数。

设计实验

在创建任务时,通过xTaskCreate或xTaskCreateStatic函数的pvParameters参数,将数据作为指针传递给任务函数。任务函数可以通过其入口参数pvParameters来获取数据。这种方法适用于传递静态或全局变量,或者只需要传递一次的数据。在我的这个场景中,使用xTaskCreate的动态的创建任务,相关代码片段如下:

struct TaskPrintInfo { uint8_t x; uint8_t y; char name[16];};
static struct TaskPrintInfo g_Task1Info = {0, 0, "Task1"};static struct TaskPrintInfo g_Task2Info = {0, 16, "Task2"};static struct TaskPrintInfo g_Task3Info = {0, 32, "Task3"};
/* 使用同一个函数创建不同的任务 */ xTaskCreate(PrintTask, "task1", 128, &g_Task1Info, osPriorityNormal, NULL); xTaskCreate(PrintTask, "task2", 128, &g_Task2Info, osPriorityNormal, NULL); xTaskCreate(PrintTask, "task3", 128, &g_Task3Info, osPriorityNormal, NULL);在这里插入图片描述

我这里使用一个TaskPrintInfo结构体来传入一个坐标值和一个字符串,我的这个PrintTask中,最深的栈只有96字节,我这里创建任务时使用128的任务栈,也就是512字节,绰绰有余,不必但是死机等问题。

PrintTask任务源码

void PrintTask(void *params){ struct TaskPrintInfo *pInfo = params; uint32_t cnt = 0; OLED_Init(); while (1) { /* 打印信息 */ if (g_LCDCanUse) { g_LCDCanUse = 0; OLED_ShowString(pInfo->x,pInfo->y,pInfo->name,16); OLED_ShowNum((pInfo->x + 8 * 6),pInfo->y,cnt++,4,16); OLED_Refresh(); // 刷新屏幕 g_LCDCanUse = 1; } mdelay(500); // 必要的延迟给任务让出资源,不然别的任务没机会执行 }}

源码中,也就简单的显示一些字符和运行任务的次数。使用这个g_LCDCanUse全局变量,来进行简单的保护,因为OLED屏在刷新的屏幕的时候会用到i2c,等一个任务使用完了,另一个任务接着使用,这是简单粗暴的使用,仅供学习参考。

实验现象

下载代码到板子上,发现,Task3先进行刷新,接着Task1跟着刷新,Task2最后刷新,这是因为优先级相同的任务,最后创建的任务先运行,然后按创建的任务顺序执行,在源码中也有体现:

在这里插入图片描述

最终现象

在这里插入图片描述

在OLED屏幕上显示了不同的次数,其中Task1执行的最多(图片这里执行了291次),其次是Task3(237次),最后是Task2(233次),所以本次实验成功,成功使用任务的参数进行了实验。