查看: 1086|回复: 0

[分享] 在Keil环境下如何字节对齐

[复制链接]
  • TA的每日心情
    开心
    7 小时前
  • 签到天数: 238 天

    连续签到: 22 天

    [LV.7]常住居民III

    47

    主题

    7126

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    12553
    最后登录
    2025-9-8
    发表于 2025-1-6 14:12:14 | 显示全部楼层 |阅读模式
    本帖最后由 eefocus_3924226 于 2025-1-6 14:19 编辑

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


    1234.png

      在以数据字节流的传输过程中,上面这个结构体的定义是错误的。为什么?答案就是今天的主题“字节对齐”。
    一、字节对齐的基本概念
      字节对齐,又称为数据对齐,是计算机系统中数据存储的一种方式。它要求数据在内存中的起始地址按照某个特定的数值(通常是数据类型的宽度,如int型通常是4字节)的整数倍进行排列。这种排列方式可以提高硬件访问数据的效率,因为许多处理器在访问内存时,都是按照块(block)或字(word)为单位进行的。
      在我们的Cortex-M系列MCU中,我们常常使用4字节对齐。
    二、C语言中结构体的字节对齐
      在C语言中,结构体(struct)是一种复合数据类型,它允许将不同类型的数据组合在一起。C语言中的结构体默认会按照最大成员类型的大小进行对齐,这是为了保证访问结构体中的任何成员时都能达到最优的性能。上面的示例代码中,结构体在内存的存储形式如下图所示:
     从这张内存图上可以清楚地看到,有两个字节被系统给reserved了。一方面,其带来了存储空间的损失;另一方面,对于字节流的传输数据的内容也对不上了——本来第3字节应该是block_id的数据了嘛!
    三、Keil编程环境下的字节对齐
      在Keil编程环境下,我们可以使用特定的编译器指令来控制结构体的字节对齐。例如,使用#pragma pack指令可以改变结构体的对齐方式。
    • #pragma pack(1):这条指令告诉编译器,结构体中的成员应该按照1字节对齐。这可以最大限度地节省内存空间,但可能会降低硬件访问的效率。
    • #pragma pack(4):这条指令告诉编译器,结构体中的成员应该按照4字节对齐。这是许多处理器默认的访问宽度,因此在这种情况下,硬件访问的效率会相对较高。

      需要注意的是,使用#pragma pack指令改变对齐方式后,需要在使用完结构体定义后,再次使用#pragma pack()指令恢复默认的对齐方式,否则会影响后续代码中的其他结构体。
    四、总结
      字节对齐是C语言编程中一个重要的概念,特别是在嵌入式系统开发中。在Keil编程环境下,通过合理地使用#pragma pack指令,我们可以有效地控制结构体的字节对齐,从而平衡内存使用和硬件访问效率。通过深入理解和应用字节对齐,我们可以编写出更加高效和健壮的嵌入式系统代码。
      最后,给出来文章开头处定义的结构体的正确源代码:

    123456.png


    哎...今天够累的,签到来了~
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-9-8 08:51 , Processed in 0.074925 second(s), 20 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表