本帖最后由 eefocus_3924226 于 2025-1-6 14:19 编辑
最近在帮另外一个项目组做一个小小的程序。程序主要是发送一串命令数据,然后,接收一串数据。项目的难度并不大,但发现其一个技术知识点还是可以分享出来的。 
在以数据字节流的传输过程中,上面这个结构体的定义是错误的。为什么?答案就是今天的主题“字节对齐”。 一、字节对齐的基本概念
字节对齐,又称为数据对齐,是计算机系统中数据存储的一种方式。它要求数据在内存中的起始地址按照某个特定的数值(通常是数据类型的宽度,如int型通常是4字节)的整数倍进行排列。这种排列方式可以提高硬件访问数据的效率,因为许多处理器在访问内存时,都是按照块(block)或字(word)为单位进行的。 在我们的Cortex-M系列MCU中,我们常常使用4字节对齐。 二、C语言中结构体的字节对齐
在C语言中,结构体(struct)是一种复合数据类型,它允许将不同类型的数据组合在一起。C语言中的结构体默认会按照最大成员类型的大小进行对齐,这是为了保证访问结构体中的任何成员时都能达到最优的性能。上面的示例代码中,结构体在内存的存储形式如下图所示: 从这张内存图上可以清楚地看到,有两个字节被系统给reserved了。一方面,其带来了存储空间的损失;另一方面,对于字节流的传输数据的内容也对不上了——本来第3字节应该是block_id的数据了嘛! 三、Keil编程环境下的字节对齐
在Keil编程环境下,我们可以使用特定的编译器指令来控制结构体的字节对齐。例如,使用#pragma pack指令可以改变结构体的对齐方式。 需要注意的是,使用#pragma pack指令改变对齐方式后,需要在使用完结构体定义后,再次使用#pragma pack()指令恢复默认的对齐方式,否则会影响后续代码中的其他结构体。 四、总结
字节对齐是C语言编程中一个重要的概念,特别是在嵌入式系统开发中。在Keil编程环境下,通过合理地使用#pragma pack指令,我们可以有效地控制结构体的字节对齐,从而平衡内存使用和硬件访问效率。通过深入理解和应用字节对齐,我们可以编写出更加高效和健壮的嵌入式系统代码。 最后,给出来文章开头处定义的结构体的正确源代码: 
|