为什么我可以传递整数作为任务参数但不能传递结构变量?

Why can I pass an integer as a task parameter but can't pass a struct variable?

我试图将一组参数传递给任务。所以我创建了一个结构并将其传递给我的任务,如下所示:

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" 并且结构检索行触发了 "Conversion to non-scalar type requested" 错误。我知道如果我使用指针而不是变量本身,它会编译,但我不能这样做,因为创建任务的函数将会终止,任务将引用一个不再存在的变量。最后我将使用一个全局结构变量。

但我真正想了解的是为什么任务接受 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;

提前致谢!

您显示的代码没有将 int 值作为参数。您使用 (void*)x 传递参数,这是一个将 int x 转换为指针的表达式。

函数xTaskCreate接受一个指针。你给了它一个指针,所以编译器不会抱怨。但是,您给它的指针不是 to x 的指针(可以写成 &x),而是 converted 的指针来自 x 的值。尽管编译器没有抱怨,但这通常不是传递给 xTaskCreate.

的正确内容

这不适用于结构的原因是当 parameters_set 是结构时 (void*)parameters_set 不是正确的表达式。这是因为 C 提供将整数转换为指针,但没有提供将结构转换为指针。一般来说,整数和指针之间有一个自然的对应关系:在一个“平面”地址space中,内存中的每个字节都有一个地址,这些地址本质上是从内存地址“开始”开始的字节数space。所以一个整数可以作为一个地址,反之亦然。 (在其他地址space中,对应关系可能更复杂,但C仍然允许转换,有一些规则。)因此,当你写(void*)x时,编译器将[=中的整数值转换为13=] 指向一个指针。

结构体和指针之间没有这种对应关系,所以C标准没有定义任何从结构体到指针的转换,当你写(void*)parameters_set时编译器会报错。

您应该为该参数传递的是 一些要提供给任务的数据的地址。如果你想让任务有x中的数据,你应该传&x。如果你想让任务在parameters_set中有数据,你应该通过&parameters_set& 运算符获取其操作数的地址,这与使用 (void*) 强制转换不同,后者试图将其操作数转换为指针。

根据 RTOS documentation for xTaskCreate,您不应传递“堆栈变量”的地址,对于 C 而言,它实际上意味着具有自动存储持续时间的对象。换句话说,您不应该传递在没有 static 的函数中定义的 xparameters_set 或(可能取决于 RTOS 和 C 实现所做的安排;我不熟悉使用 RTOS)_Thread_local。或者,您可以使用 malloc 为参数分配 space (或者,根据下面的评论,RTOS 的 pvPortMalloc )并将其传递给 xTaskCreate.