这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 基础知识 » [学习笔记]在Keil环境下如何字节对齐

共2条 1/1 1 跳转至

[学习笔记]在Keil环境下如何字节对齐

院士
2024-02-19 15:10:32     打赏

最近在帮另外一个项目组做一个小小的程序。程序主要是发送一串命令数据,然后,接收一串数据。项目的难度并不大,但发现其一个技术知识点还是可以分享出来的。

//这个结构体的定义正确吗?
typedef struct create_cmd_s
{
  uint8_t action_id;
  uint8_t section_id;
  uint32_t block_id;
  uint32_t data[8];
}create_cmd_t;

  在以数据字节流的传输过程中,上面这个结构体的定义是错误的。为什么?答案就是今天的主题“字节对齐”。

一、字节对齐的基本概念

字节对齐,又称为数据对齐,是计算机系统中数据存储的一种方式。它要求数据在内存中的起始地址按照某个特定的数值(通常是数据类型的宽度,如int型通常是4字节)的整数倍进行排列。这种排列方式可以提高硬件访问数据的效率,因为许多处理器在访问内存时,都是按照块(block)或字(word)为单位进行的。

在我们的Cortex-M系列MCU中,我们常常使用4字节对齐。

二、C语言中结构体的字节对齐

在C语言中,结构体(struct)是一种复合数据类型,它允许将不同类型的数据组合在一起。C语言中的结构体默认会按照最大成员类型的大小进行对齐,这是为了保证访问结构体中的任何成员时都能达到最优的性能。上面的示例代码中,结构体在内存的存储形式如下图所示:

align_01.png

从这张内存图上可以清楚地看到,有两个字节被系统给reserved了。一方面,其带来了存储空间的损失;另一方面,对于字节流的传输数据的内容也对不上了——本来第3字节应该是block_id的数据了嘛!

三、Keil编程环境下的字节对齐

在Keil编程环境下,我们可以使用特定的编译器指令来控制结构体的字节对齐。例如,使用#pragma pack指令可以改变结构体的对齐方式。

  1. #pragma pack(1):这条指令告诉编译器,结构体中的成员应该按照1字节对齐。这可以最大限度地节省内存空间,但可能会降低硬件访问的效率。

  2. #pragma pack(4):这条指令告诉编译器,结构体中的成员应该按照4字节对齐。这是许多处理器默认的访问宽度,因此在这种情况下,硬件访问的效率会相对较高。

需要注意的是,使用#pragma pack指令改变对齐方式后,需要在使用完结构体定义后,再次使用#pragma pack()指令恢复默认的对齐方式,否则会影响后续代码中的其他结构体。

四、总结

字节对齐是C语言编程中一个重要的概念,特别是在嵌入式系统开发中。在Keil编程环境下,通过合理地使用#pragma pack指令,我们可以有效地控制结构体的字节对齐,从而平衡内存使用和硬件访问效率。通过深入理解和应用字节对齐,我们可以编写出更加高效和健壮的嵌入式系统代码。

最后,给出来文章开头处定义的结构体的正确源代码:

#pragma pack(1)
typedef struct create_cmd_s
{
  uint8_t action_id;
  uint8_t section_id;
  uint32_t block_id;
  uint32_t data[8];
}create_cmd_t;
#pragma pack()





关键词: 笔记     字节对齐     结构体     pragma    

高工
2024-02-19 15:34:45     打赏
2楼

字节对齐的问题挺重要!貌似和硬件打交道的时候要千万小心


共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]