我目前正在使用NORDIC(32位ARM Cortex M0)的nRF51 MCU进行C语言编码。
我想通过无线电发送工会的缓冲区。为此,我必须将union的缓冲区地址提供给PACKETPTR。 否则,地址为" PACKETPTR"必须是,根据manuel参考:字节对齐的RAM地址。 如果它没有对齐,它设法采取下一个最接近的一个,但这样接收器将接收不完整的缓冲区和"虚拟"数据...
你可以猜到,我的缓冲区没有字节对齐。这是有关联盟和全局变量。
我的联盟的元素必须打包,以便它们可以适合7个字节;
typedef union
{
uint8_t buf[7]; //The buffer I give to PACKETPTR
__packed struct
{
uint8_t a[2];
uint8_t b;
uint16_t c : 10;
uint16_t d : 6;
uint16_t e : 14;
uint16_t f : 2;
}parts;
}adv_t;
adv_t m_adv; //The global variable
...
//Later in the code to set PACKETPTR
config_tx(ADV_PIPE, m_adv.buf);
...
void __INLINE config_tx(uint8_t tx_pipe, uint8_t* payload)
{
NRF_RADIO->TXADDRESS = tx_pipe;
NRF_RADIO->PACKETPTR = (uint32_t)payload;
}
一开始我在__packed
之前添加了typedef union
限定词。但就好像m_adv
被包装了#34;对于一些以前的数据,因此buf
地址与ram地址没有字节对齐。
__packed typedef union /* Previous definition */
{
uint8_t buf[7];
__packed struct
{
...
}parts;
}adv_t;
所以我删除了它,然后buf地址是正确的(即字节与RAM地址对齐)。我认为这是解决方案,但几分钟后它再次变得错位...
我的问题是:__packed
限定符是否因为联合而影响buf?有没有办法强制我的全局变量buf
地址对齐?或任何建议?
由于
答案 0 :(得分:1)
您的问题似乎是关于打包,而不是RAM地址的对齐(打包时会对齐,但对齐本身并不重要情况)。
这里的问题是你没有真正打包结构,因为属性放错了位置。它应该是:
typedef union
{
uint8_t buf[7];
struct // not here
{
uint8_t a[2];
uint8_t b;
uint16_t c : 10;
uint16_t d : 6;
uint16_t e : 14;
uint16_t f : 2;
} __packed parts; // here, __packed or __attribute__((packed))
}adv_t;
在b
之后插入了一个额外的字节,以便在16位边界上对齐以下uint16_t
。
请注意,如果您不需要访问单个字节,则无需建立联盟。您可以只使用结构并传递结构的地址。
答案 1 :(得分:0)
我不确定您使用的编译器。但是,您可以将结构实例的对齐方式与数据类型的打包分开定义。
例如,GCC定义了一个属性:_attribute__((aligned(4)))
__declspec(align(4))
。
请查看编译器手册,了解如何明确定义数据成员的对齐方式。
答案 2 :(得分:0)
感谢您的回答。
我的结构成员完全适合buf
我想要的(没有填充,MSB / LSB按我的预期放置等),我并不是说我想访问特定的bitfield成员。
我没详细说明,但问题来自接收器。
我收到了前任。 0xEF 0x00 0xFC 0xB2 0x38 0x00 0xB6
代替0xCD 0xAB 0xEF 0x00 0xFC 0xB2 0x38
(buf
内容)。
所以我认为问题是关于buf
地址和手册句子谈论PACKETPTR
的“RAM地址”我误解了它。问题实际上是来自我的接收器的帧处理。对不起!!