【问题标题】:Functions vs Queues vs Global Variables in CC中的函数vs队列vs全局变量
【发布时间】:2021-12-27 22:33:51
【问题描述】:

这个问题更多地是关于您认为对于运行 C 和 RTOS 的嵌入式系统最有效的方法。

我有一个任务,每个周期只更新一个变量。该变量用于程序中的其他任务:

TaskA.c

int someVar = 0

void TaskFunc(void) {
    updateVar(someVar);
}

应用程序中的其他任务没有被阻塞等待这个变量,所以这告诉我 FreeRTOS 队列可能超出了需要。它更像是一个像阅读时间一样的全局变量。

所以另一个选择是在头文件中为这个变量添加一个外部变量。

TaskA.h

extern int someVar;

我很犹豫,因为通常不建议使用全局变量。那么,如果我添加一个函数并让它成为全局函数呢?

所以 TaskA.c 会变成:

static int someVar;

void TaskFunc(void) {
    updateVar(someVar);
}

void readVar(int *reader){
    *reader = someVar;
}

还有TaskA.h

void readVar(int *reader);

然后我可以从程序中运行的任何其他任务调用 readVar 来读取 TaskA.c 中的静态变量。与仅返回 someVar 相比,此处使用指针是否弊大于利?

这是否有我没有看到的缺点,或者我只是想多了?专门询问嵌入式系统是否在这种情况下有所不同。

感谢您的反馈!

【问题讨论】:

  • 如果编译器支持 C11 标准,您可以使用 _Atomic
  • 只返回 someVar,不需要指针。如果需要避免损坏,您始终可以在关键部分进行更新等。会比队列更有效率
  • “通常不建议使用全局变量”,尤其是在内存受限的设备上,因为当不使用全局变量就可以实现相同的功能时,它们会永久占用内存位置。然而,静态也是变相的全局。内存是全局分配的,只有范围是本地的。所以,我也会避免这种情况。尽可能多地保留在函数结束时释放的堆栈上,并为任务间通信排队。

标签: c embedded microcontroller freertos


【解决方案1】:

这个问题更多地是关于您认为最有效的方法 运行 C 和 RTOS 的嵌入式系统。

好吧,我认为我们不应该在这里发表意见,所以我实际上会尽力不这样做。

我很犹豫,因为全局变量通常不是 建议

我也是,因为有这种需求通常是无法正确封装数据。但如果你有充分的理由去做这样的事情,那么一定要去做。

在这里使用指针是否弊大于利? 返回 someVar?

您可以返回 someVar,正如 cmets 中指出的那样(不是双关语)。

int readVar(void){
    return someVar;
}

那就int reader = readVar();

但是对于你所做的:

void readVar(int *reader){
    *reader = someVar;
}

需要指针。 C 通过值而不是通过引用传递,因此如果您只是传递 int reader,那么您传递的是 reader 值的副本,因此 reader = someVar; 将修改副本的值。您的代码所做的是传递reader 的内存位置值的副本,然后将someVar 的值写入该内存位置。

是否有我没有看到的缺点,或者我只是 想多了?

我认为您对这样的设计选择进行批判性思考没有任何问题。您没有列出有关此方法的任何缺点,因此我们很难说出您没有看到什么。此外,我们缺乏关于您的特定嵌入式系统的关键上下文。总的来说,一般来说,我会说实施适当的数据封装是一个不错的设计选择。

【讨论】:

    猜你喜欢
    • 2021-03-01
    • 2019-08-19
    • 2017-07-11
    • 2022-01-21
    • 2013-07-06
    • 2012-03-01
    • 2013-05-31
    • 2011-06-21
    • 1970-01-01
    相关资源
    最近更新 更多