我试图将一组参数传递给任务。所以我创建了一个结构体并将其传递给我的任务,如下所示:
my_type_t parameters_set;
//... assigning values to parameters_set
xTaskCreate( vMyTask, "MyTask", STACK_SIZE, (void*)parameters_set, 2,
&xHandle);
字符串
在我的任务中,我尝试检索结构体值,执行以下操作:
my_type_t received_parameters = (my_type_t) pvParameters;
型
任务创建行在编译时触发以下错误:“cannot convert to a pointer type”and the struct retrieving line triggers the“Conversion to non-scalar type requested”error.我知道如果我使用指针而不是变量本身,它会编译,但我不能这样做,因为创建任务的函数将死亡,任务将引用一个不再存在的变量。最后我将使用一个全局结构变量。
但我真正想理解的是为什么任务接受int值(而不是引用),而不接受typedef结构体?例如,下面的代码片段构建和工作没有问题:
//Inside the function that creates the task
int x = 0;
xTaskCreate( vMyTask, "MyTask", STACK_SIZE, (void*)x, 2,
&xHandle);
//Inside the Task
int received_parameter = (int) pvParameters;
型
提前感谢!
1条答案
按热度按时间siv3szwd1#
您所展示的代码没有将
int
值作为参数。您使用(void*)x
传递参数,这是一个将int
x
转换为指针的表达式。函数
xTaskCreate
接受一个指针。你已经给了它一个指针,所以编译器不会抱怨。但是,你给它的指针不是指向**x
的指针(将被写为&x
),但它是从**x
的值转换而来的指针**。尽管编译器没有抱怨,这通常不是传递给xTaskCreate
的正确事情。这不适用于结构体的原因是,当
parameters_set
是一个结构体时,(void*)parameters_set
不是一个正确的表达式。这是因为C提供了将整数转换为指针,但不提供将结构体转换为指针。通常,整数和指针之间存在自然的对应关系:在“平面”地址空间中,内存中的每个字节都有一个地址,这些地址本质上是从内存地址空间的“开始”开始的字节计数。因此,整数可以作为地址,反之亦然。(在其他地址空间中,对应关系可能更复杂,但C仍然允许转换,但有一些规则。)因此,当您编写(void*)x
时,编译器将x
中的整数值转换为指针。在结构和指针之间没有这样的对应关系,所以C标准没有定义任何从结构到指针的转换,当你写
(void*)parameters_set
时编译器会抱怨。你应该为这个参数传递的是**要给任务的一些数据的地址。如果你想让任务有
x
的数据,你应该传递&x
。如果你想让任务有parameters_set
的数据,你应该传递¶meters_set
。&
运算符接受它的操作数的地址,这与使用(void*)
强制转换不同,后者试图将其操作数转换为指针。根据RTOS documentation for
xTaskCreate
,你不应该传递一个“栈变量”的地址,这实际上意味着,对于C,一个具有自动存储持续时间的对象。换句话说,你不应该传递一个在没有static
或parameters_set
的函数中定义的x
或parameters_set
。(可能,取决于RTOS和C实现的安排;我不熟悉RTOS)_Thread_local
。或者,您可以使用malloc
为参数分配空间(或者,根据下面的注解,RTOS的pvPortMalloc
)并将其传递给xTaskCreate
。