我已经研究了避免全局变量这个主题,并提出了一种我在搜索中从未真正在其他任何地方看到的方法,这让我相信这可能不是一个很好的方法(或者我只是没有正确措辞我的搜索)。
举个例子,我有这样的东西:
int16_t DataProcessing(uint8_t CallType, struct DataStruct *DataIO)
{
int16_t RetVal;
static struct DataStruct StaticDataStuct;
switch (CallType)
{
case FIRSTCASE: RetVal = FirstCaseProcessing(&StaticDataStuct,DataIO); break;
case SECONDCASE: RetVal = SecondCaseProcessing(&StaticDataStuct,DataIO); break;
...
etc
...
}
return RetVal;
}
int16_t FirstCaseProcessing(struct DataStruct *StaticData, struct DataStruct *NewData)
{
// Do what you need to do here
}
对于调用的任何其他例程,想法相同。
我还做了包装函数来调用 DataProcessing(),这使得整个事情更容易阅读,并且对于将来使用它的新人来说。因此,例如:
int16_t FirstCase(uint8_t Address, uint16_t Data)
{
struct DataStruct NewData;
NewData.Address = Address;
NewData.Data= Data;
return DataProcessing(FIRSTCASE, &NewData);
}
所以,看起来不错,除了UART和计时器等中断之外,我根本没有全局变量。(我仍然认为尽可能快地进出中断比让中断调用某些东西将数据存储在某个静态变量中要好,但我很高兴被说服。
[也许]不好的是,我通过三个函数传递东西是为了避免全局变量并使其更具可读性(假设不仅仅是我发现它可读!
我会说我得到了一个 72MHz 嵌入式 32 位处理器来做八位处理器可以做的事情,以一小部分速度运行(假设它有足够的 RAM)。所以速度不是问题,尽管我对速度可能更成问题时这是否是一种好风格的意见感兴趣。
我已经看到了拥有 .c 文件并拥有静态变量的C++风格,该 .c 文件中的任何函数都可以看到和访问(但外部文件不能),使用访问器函数传入和传出值/指针等,但他们似乎使用我认为是文件"全局"的变量(或文件的本地变量,具体取决于您想要如何查看它!此外,可以有一个函数来存储静态变量,并简单地将指向该静态变量的指针传递给想要访问它的任何内容。我想知道这是否会去 OTT?
我的想法看起来好/坏/糟糕吗?
非常感谢您的任何建议和我可能会得到的所有 TL;DR。 ;~)
OP:我的想法看起来好/坏/糟糕吗?
好的OP还不是OTT。
避免嵌入式设计中的全局变量是一个很好的目标,主要是为了维护。 信息隐藏(使数据成为函数或对象的本地数据)是控制无数交互并使调试更容易的关键。 对于OP更快(可能更大内存)的处理器尤其如此。
另一种方法 - 隐藏文件范围内的数据。
OP解决方案在DataProcessing()
时是分层的,给出了命令和输入/输出参数,并且在此级别上已知DataStruc
的详细信息。
我的目标是更多地采用数据驱动的方法,使用指针或索引以及一组例程。 比如说在嵌入式程序中,我最多需要 Sally_N 个 Sally 变量的实例。 在这里,我的数据不是全局的,而是隐藏在 Sally.c 的文件范围内。 因此,数据及其详细字段隐藏在远离使用它的高级代码之外。 在OP的方法中,DataStruct
的细节是更高级别的函数DataProcessing()
已知的。
// Sally.h
struct Sally_t; // Does not expose the fields
extern struct Sally_t *Sally_Init(...);
extern void Sally_DoThis(struct Sally_t *, ...);
extern void Sally_DoThat(struct Sally_t *, ...);
// Sally.c
struct Sally_t { int a, ... }; // Structure details
static struct Sally_t Sally_Data[Sally_N];// file scope prevents global exposure
struct Sally_t *Sally_Init(...);
void Sally_DoThis(struct Sally_t *, ...);
void Sally_DoThat(struct Sally_t *, ...);