为什么我可以传递整数作为任务参数但不能传递结构变量?
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
中有数据,你应该通过¶meters_set
。 &
运算符获取其操作数的地址,这与使用 (void*)
强制转换不同,后者试图将其操作数转换为指针。
根据 RTOS documentation for xTaskCreate
,您不应传递“堆栈变量”的地址,对于 C 而言,它实际上意味着具有自动存储持续时间的对象。换句话说,您不应该传递在没有 static
的函数中定义的 x
或 parameters_set
或(可能取决于 RTOS 和 C 实现所做的安排;我不熟悉使用 RTOS)_Thread_local
。或者,您可以使用 malloc
为参数分配 space (或者,根据下面的评论,RTOS 的 pvPortMalloc
)并将其传递给 xTaskCreate
.
我试图将一组参数传递给任务。所以我创建了一个结构并将其传递给我的任务,如下所示:
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
中有数据,你应该通过¶meters_set
。 &
运算符获取其操作数的地址,这与使用 (void*)
强制转换不同,后者试图将其操作数转换为指针。
根据 RTOS documentation for xTaskCreate
,您不应传递“堆栈变量”的地址,对于 C 而言,它实际上意味着具有自动存储持续时间的对象。换句话说,您不应该传递在没有 static
的函数中定义的 x
或 parameters_set
或(可能取决于 RTOS 和 C 实现所做的安排;我不熟悉使用 RTOS)_Thread_local
。或者,您可以使用 malloc
为参数分配 space (或者,根据下面的评论,RTOS 的 pvPortMalloc
)并将其传递给 xTaskCreate
.