结构定义

时间:2019-11-21 08:03:10

标签: c struct embedded chibios

我遇到了一个奇怪的代码

static ROMCONST struct testcase * ROMCONST *patterns[] = {
  patternbmk,
  NULL
};

可以找到此代码here

这是什么样的结构定义/声明?

有人可以用简单的英语解释什么意思吗?

3 个答案:

答案 0 :(得分:3)

关于ROMCONST

就我们理解这些声明而言,ROMCONST只是代替const的一些噪声宏。

这种定义在嵌入式系统中很常见,在某些嵌入式系统中,有时需要非标准的东西才能在闪存中分配数据。哈佛架构尤其臭名昭著,但也可能需要使用非标准*far指针的8/16位MCU。最后,如果该表分配在EEPROM /数据闪存中,尽管它是只读的,但仍可以在运行时进行更新,因此我们想添加volatile。所有这些东西都可以隐藏在ROMCONST内部。因此,理论上我们可能会遇到一些混乱和部分非标准的问题,例如

#define ROMCONST volatile const far PROGMEM

volatile来自eeprom /数据闪存,const代表任何类型的闪存,far代表存储的内存,PROGMEM用于声明ROM上的数据)哈佛MCU。)

现在,我将忽略它,而将其替换为const


要了解其余代码的const限定词,请从诸如patternbmk之类的指向数组开始。

const struct testcase * const patternbmk[] = {

分开:

  • struct testcase * patternbmk[]声明了一个指向结构的指针数组。
  • const struct testcase * patternbmk[]赋予那些指针只读访问权限。指向的数据为const,无法通过这些指针进行修改。
  • const struct testcase * const patternbmk[]将指针本身设为只读,主要用于确保将表分配在闪存而不是RAM中。

调整诸如*const之类的编码样式,将指针声明及其限定符一起编写可能会有所帮助。


接下来,程序员希望声明一个指向这些指针数组的指针数组。 (如您所知,这开始变得混乱了……)可以使用两种方法来指向指针数组,方法是使用 array指针指向该数组或通过在数组的第一项(带有指针到指针)。程序员选择了后者。

数组项的类型为const struct testcase * const,为了指向此类项,我们在右侧添加了一个附加的*,最后是const struct testcase * const *。从右到左读取这样的凌乱声明非常有帮助:指向const指针的指针到const struct测试用例。

然后他们希望创建一个由此类指针组成的数组,只需在末尾添加[]const struct testcase * const *patterns[]

并不是该数组中的每个初始化器都隐式地“衰减”为指向第一项的指针,所以初始化器patternbmk会衰减为&patternmk[0],而该指针恰好是指向const指向const struct的指针测试用例,与我上面讨论的类型相同。

最后,static限定词就在那里,将变量范围限制为声明它的文件。 patterns初始化程序列表末尾的NULL是标记数组的末尾值。

答案 1 :(得分:2)

ROMCONST最有可能是编译器指令,它可能是这样的:#define ROMCONST const迫使变量进入代码存储区。

patterns是数组的结构,存储另一个数组patternbmk的结构,该结构包含具有testcase结构定义的函数指针。

static ROMCONST struct testcase * ROMCONST *patterns[] = {
  patternbmk,
  NULL
};

ROMCONST struct testcase * ROMCONST patternbmk[] = {
#if !TEST_NO_BENCHMARKS
  &testbmk1,
  &testbmk2,
  &testbmk3,
  &testbmk4,
  &testbmk5,
  &testbmk6,
  &testbmk7,
  &testbmk8,
#if CH_USE_QUEUES
  &testbmk9,
#endif
  &testbmk10,
#if CH_USE_SEMAPHORES
  &testbmk11,
#endif
#if CH_USE_MUTEXES
  &testbmk12,
#endif
  &testbmk13,
#endif
  NULL
};

ROMCONST struct testcase testbmk1 = {
  "Benchmark, messages #1",
  NULL,
  NULL,
  bmk1_execute
};

struct testcase {
  const char *name;             /**< @brief Test case name.                 */
  void (*setup)(void);          /**< @brief Test case preparation function. */
  void (*teardown)(void);       /**< @brief Test case clean up function.    */
  void (*execute)(void);        /**< @brief Test case execution function.   */
};

答案 2 :(得分:0)

根据标签,显示了一些google search

  

宏定义文档

#define ROMCONST   const
     

ROM常数修饰符。

     

注意:

     

设置为在此端口中使用“ const”关键字。   在文件chtypes.h的第63行定义。