Freertos学习02-Task传入参数

发布时间 2023-06-26 12:26:56作者: seekwhale13

一、前言

介绍了freertos具有许多特点,其中的任务调度将有助提高系统的实时性,并将各任务解耦,有助于产品的后续维护与开发,上一节介绍了freertos中关于任务的创建与删除,这一节介绍如何在创建函数的同时并传递参数。

二、传递参数

再次回顾xTaskCreate()函数的用法以及各输入参数,其中第四个输入参数"void* pvParameters"是一个空类型指针,使用空类型指针可以传入任意类型的数据,下面分别展示传入整型(int)、数组(array)、字符串(string)、结构体(struct)几种类型数据。

空类型指针:空指针和空类型指针是两个不同的概念。空指针是指一个指针变量指向的地址为空,而空类型指针是指一个指针变量的类型为空,需要注意的是空类型指针不能直接进行指针运算,因为它的类型未定义或未知。如果需要进行指针运算,我们需要将其转换为具体的指针类型。

image

三、示例

1.传入整型数据

1)首先定义变量testNum,并传入xTaskCreate()中,将&testNum地址强制转换为空指针类型,

int testNum = 1;
xTaskCreate(mytask, "mytask", 1024, (void *)&testNum, 1, &xHandle);

2)mytask()函数接收到该变量地址,由于空类型指针无法直接参与运算,首先将它转换为int类型指针

void mytask(void *pvParam)
{
   for (;;)
   {
      int *pInt;
      pInt = (int *)pvParam;
      printf("%d\n", *pInt);
   }
}

完整代码如下:

#include <stdio.h>
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "sdkconfig.h"

void mytask(void *pvParam)
{
   for (;;)
   {
      int *pInt;
      pInt = (int *)pvParam;
      printf("%d\n", *pInt)
   }
}
int testNum = 1;

void app_main(void)
{

   TaskHandle_t xHandle = NULL; //任务句柄,类似任务的数字标记,识别码,名字
   xTaskCreate(mytask, "mytask", 1024, (void *)&testNum, 1, &xHandle); //传入参数(void *)&testNum

}

2.传入数组类型

1)首先定义数组并赋值,并将数组地址传入xTaskCreate()函数中,由于数组的名字就是数组的地址,也就是第一个数组元素的地址,所以直接在函数中写数组名即可。

int testNum[] = {4,8,12};
xTaskCreate(mytask, "mytask", 2048, (void *)testNum, 1, &xHandle);

2)在mytask任务函数中把数组中的元素全部打印出来

void mytask(void *pvParam)
{
	for (;;)
	{
		int *pInt;
		pInt = (int *)pvParam;
		printf("%d\n", *pInt);
		printf("%d\n", *(pInt + 1));
		printf("%d\n", *(pInt + 2));
		vTaskDelay(500 / portTICK_PERIOD_MS); // 延时
	}
}

完整代码如下:

#include <stdio.h>
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "sdkconfig.h"

void mytask(void *pvParam)
{
	for (;;)
	{
		int *pInt;
		pInt = (int *)pvParam;
		printf("%d\n", *pInt);
		printf("%d\n", *(pInt + 1));
		printf("%d\n", *(pInt + 2));
		vTaskDelay(500 / portTICK_PERIOD_MS); // 延时
	}
}
int testNum[] = {4, 8, 12};

void app_main(void)
{

	TaskHandle_t xHandle = NULL;									   // 任务句柄,类似任务的数字标记,识别码,名字
	xTaskCreate(mytask, "mytask", 2048, (void *)testNum, 1, &xHandle); // 传入参数(void *)testNum
}

3.传入字符串

C语言中并没有字符串类型的变量,实际上我们可以把它理解为一个字符数组,我们一般可以这样对字符串初始化

char *message = "Hello World!";

// 上面的语句也可以拆分成下面两句
char *message;
message = "Hello World!";    // 这句话看起来像是字符串复制,其实不是,只是涉及到指针操作

更常用的是:
char charArray[] = "Hello World!"; // 声明并初始化一个字符数组
或者:
char charArray[] = {'H','e','l','l','o'}; // 声明并初始化一个字符数组
综上,C语言中并不存在字符串变量类型,将其理解为字符数组,可以通过数组进行定义,也可通过指针进行初始化。
1)定义字符串Xmessage,并将字符串地址传入xTaskCreate中

char *Xmessage = "I love noob!";
xTaskCreate(mytask, "mytask", 2048, (void *)Xmessage, 1, &xHandle);

2)在任务函数中将字符串打印出来

void mytask(void *pvParam)
{
	for (;;)
	{
		char *pInt;
		pInt = (char *)pvParam;
		printf("%s\n", pInt);
		vTaskDelay(500 / portTICK_PERIOD_MS); // 延时
	}
}

完整代码如下:

#include <stdio.h>
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "sdkconfig.h"

void mytask(void *pvParam)
{
	for (;;)
	{
		char *pInt;
		pInt = (char *)pvParam;
		printf("%s\n", pInt);
		vTaskDelay(500 / portTICK_PERIOD_MS); // 延时
	}
}
char *Xmessage = "I love noob!";

void app_main(void)
{

	TaskHandle_t xHandle = NULL;									   // 任务句柄,类似任务的数字标记,识别码,名字
	xTaskCreate(mytask, "mytask", 2048, (void *)Xmessage, 1, &xHandle); // 传入参数(void *)Xmessage
}

3.传入结构体类型

1)初始化结构体,构造一个名为xstruct的结构体,该结构体有两个成员,分别是num1和num2,d对结构体赋值并传地址入xTaskCreate()函数

typedef struct Xstruct
{
   int num1;
   int num2;

} xstruct;
xstruct xtest = {2, 4};
xTaskCreate(mytask, "mytask", 2048, (void *)&xtest, 1, &xHandle);

2)在任务函数中打印结构体成员的数值

void mytask(void *pvParam)
{
   for (;;)
   {
   	xstruct *pInt;
   	pInt = (xstruct *)pvParam;
   	printf("First num is %d\n", pInt->num1);
   	printf("Second num is %d\n", pInt->num2);
   	vTaskDelay(500 / portTICK_PERIOD_MS); // 延时
   }
}

完整代码如下:

#include <stdio.h>
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "sdkconfig.h"

typedef struct Xstruct
{
   int num1;
   int num2;

} xstruct;

void mytask(void *pvParam)
{
   for (;;)
   {
   	xstruct *pInt;
   	pInt = (xstruct *)pvParam;
   	printf("First num is %d\n", pInt->num1);
   	printf("Second num is %d\n", pInt->num2);
   	vTaskDelay(500 / portTICK_PERIOD_MS); // 延时
   }
}
xstruct xtest = {2, 4};

void app_main(void)
{

   TaskHandle_t xHandle = NULL;									  // 任务句柄,类似任务的数字标记,识别码,名字
   xTaskCreate(mytask, "mytask", 2048, (void *)&xtest, 1, &xHandle); // 传入参数
}

THE END!