我可以将多个位域结构替换为 C 中的数组吗?

标签 c embedded

我正在开发一个具有 CAN 通信功能的微 Controller ,它有 32 个邮箱用于通信。 在制造商提供的头文件中,它们有以下声明:

struct CANMSGID_BITS {    // bits  description
   Uint16 EXTMSGID_L:16;  // 15:0
   Uint16 EXTMSGID_H:2;   // 17:16
   Uint16 STDMSGID:11;    // 28:18
   Uint16 AAM:1;          // 29
   Uint16 AME:1;          // 30
   Uint16 IDE:1;          // 31
};

/* Allow access to the bit fields or entire register */
union CANMSGID_REG {
   Uint32               all;
   struct CANMSGID_BITS bit;
};

/* eCAN Message Control Register (MSGCTRL) bit definitions */
struct CANMSGCTRL_BITS {  // bits  description
   Uint16 DLC:4;          // 3:0
   Uint16 RTR:1;          // 4
   Uint16 rsvd1:3;        // 7:5   reserved
   Uint16 TPL:5;          // 12:8
   Uint16 rsvd2:3;        // 15:13 reserved
   Uint16 rsvd3:16;       // 31:16 reserved
};

/* Allow access to the bit fields or entire register */
union CANMSGCTRL_REG {
   Uint32                  all;
   struct CANMSGCTRL_BITS  bit;
};

/* eCAN Message Data Register low (MDR_L) word definitions */
struct CANMDL_WORDS {    // bits  description
   Uint16 LOW_WORD:16;   // 15:0
   Uint16 HI_WORD:16;    // 31:16
};

/* eCAN Message Data Register low (MDR_L) byte definitions */
struct CANMDL_BYTES {  // bits   description
   Uint16 BYTE3:8;     // 7:0
   Uint16 BYTE2:8;     // 15:8
   Uint16 BYTE1:8;     // 23:16
   Uint16 BYTE0:8;     // 31:24
};

/* Allow access to the bit fields or entire register */
union CANMDL_REG {
   Uint32              all;
   struct CANMDL_WORDS word;
   struct CANMDL_BYTES byte;
};

/* eCAN Message Data Register high  (MDR_H) word definitions */
struct CANMDH_WORDS {     // bits  description
   Uint16 LOW_WORD:16;    // 15:0
   Uint16 HI_WORD:16;     // 31:16
};

/* eCAN Message Data Register low (MDR_H) byte definitions */
struct CANMDH_BYTES {  // bits   description
   Uint16 BYTE7:8;     // 7:0
   Uint16 BYTE6:8;     // 15:8
   Uint16 BYTE5:8;     // 23:16
   Uint16 BYTE4:8;     // 31:24
};

/* Allow access to the bit fields or entire register */
union CANMDH_REG {
   Uint32              all;
   struct CANMDH_WORDS word;
   struct CANMDH_BYTES byte;
};

struct MBOX {
   union CANMSGID_REG   MSGID;
   union CANMSGCTRL_REG MSGCTRL;
   union CANMDL_REG     MDL;
   union CANMDH_REG     MDH;
};

这是针对单个邮箱的,但有 32 个邮箱,因此邮箱的定义如下:

struct ECAN_MBOXES {
   struct MBOX MBOX0;
   struct MBOX MBOX1;
   struct MBOX MBOX2;
   .
   .
   .
   struct MBOX MBOX30;
   struct MBOX MBOX31;
}; 

最后我们有:

extern volatile struct ECAN_MBOXES ECanaMboxes;

其中“ECanaMboxes”在链接器命令文件中定义。

我仅用以下声明替换了struct ECAN_MBOXES:

struct ECAN_MBOXES {
    struct MBOX MBOX[32];
};

这是一个有效的更改还是不允许我们从位域中创建数组? 我已经尝试了两种方式的代码,并且无论哪种方式,代码都运行良好。我更喜欢阵列,因为它更容易出于特定目的访问特定邮箱,而且所有邮箱的配置都可以以迭代方式完成。我想知道结构体声明是否会导致意外问题?

最佳答案

是否struct ECAN_MBOXES包含 struct MBOX 的 32 个不同实例或 32 struct MBOX 的数组与如何struct MBOX无关是内部布局的。

后者显然更可取,因为您可以索引数组,但它不会破坏 struct MBOX 的任何内容。 ,无论它是否包含 union 和位域。

请注意,您实际上并没有创建位域数组,而是创建包含位域的结构体数组。实际的位域数组不是合法的构造,如果您尝试这样做,编译器会给您一个错误。

关于我可以将多个位域结构替换为 C 中的数组吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59305681/

相关文章:

linux - 优化嵌入式Linux系统的根文件系统大小

java - 如何使用加速度计进行手势识别

c - 我如何确定是否可以在 C 中计算 x+y 而不会溢出?

c - 卡在 C 中的乘法表上

embedded - 将 newlib 移植到自定义 ARM 设置

c - 链表的意外行为

ARM Cortex-M3 从 RAM 初始状态启动

c - 为什么 msgrcv() 将 msqid 设置为 0?

c - [strcat&malloc&free],当我使用 strcat() 时,指针似乎不是 NULL,即使我故意将其设为 NULL(没有额外赋值)?

C 信号(SIGSEGV)为什么会无限循环?