【问题标题】:Conditionally using packed struct with armcc (PACKSTRUCT in BGLib)有条件地使用带有 armcc 的打包结构(BGLib 中的 PACKSTRUCT)
【发布时间】:2015-09-02 07:17:13
【问题描述】:

我尝试使 BLE121LR 模块与外部 MCU (EFM32) 一起工作。 据我所知,这段代码声明了将结构转换为二进制数据,对吗? 有人可以解释一下如何为其添加 ARM (EFM32) 支持吗? 非常感谢!!

代码:

/* Compability */
#ifndef PACKSTRUCT
    #ifdef PACKED
        #define PACKSTRUCT(a) a PACKED 
    #else
/*Default packed configuration*/
        #ifdef __GNUC__
            #ifdef _WIN32
                #define PACKSTRUCT( decl ) decl __attribute__((__packed__,gcc_struct))
            #else
                #define PACKSTRUCT( decl ) decl __attribute__((__packed__))
            #endif
            #define ALIGNED __attribute__((aligned(0x4)))
        #else //msvc
            #define PACKSTRUCT( decl ) __pragma( pack(push, 1) ) decl __pragma( pack(pop) )
            #define ALIGNED
        #endif
    #endif
#endif

【问题讨论】:

  • 当您尝试使用 PACKSTRUCT 宏编译代码时,您会遇到哪些编译器错误?你用的是什么编译器?
  • 我的 IDE 是 uKeil 5。一些错误:..\bglib\cmd_def.h(846): error: #20: identifier "pack" is undefined PACKSTRUCT(struct ble_msg_system_reset_cmd_t ..\bglib\ cmd_def.h(846): error: #18: expected a ")" PACKSTRUCT(struct ble_msg_system_reset_cmd_t ..\bglib\cmd_def.h(846): error: #79: expected a type specifier
  • IDE 和编译器不是一回事。在我的回答中,我假设您使用的是 Keil 的 armcc。对吗?
  • @Pinetwig 哦,对不起!没错,就是 armcc!

标签: c arm c-preprocessor armcc


【解决方案1】:

是的,打包结构会影响结构在内存中的存储方式,这通常被用作将结构转换为二进制数据的一种快速而简单的方法。

PACKSTRUCT 宏不是为 keil armcc 编译器编写的。要解决这个问题,我们必须首先找到如何识别何时使用 armcc。在this page上,我们可以看到armcc提供了define __ARMCC_VERSION,我们可以使用它。

现在,我们如何使用 armcc 声明一个打包的结构? Here,我们看到我们应该使用 __packed 限定符:

/* Compability */
#ifndef PACKSTRUCT
    #ifdef PACKED
        #define PACKSTRUCT(a) a PACKED 
    #else
/*Default packed configuration*/
        #ifdef __GNUC__
            #ifdef _WIN32
                #define PACKSTRUCT( decl ) decl __attribute__((__packed__,gcc_struct))
            #else
                #define PACKSTRUCT( decl ) decl __attribute__((__packed__))
            #endif
            #define ALIGNED __attribute__((aligned(0x4)))
        #else   // not __GNUC__
            #ifdef __ARMCC_VERSION
                #define PACKSTRUCT( decl ) __packed decl
                #define ALIGNED
            #else // Assume msvc
                #define PACKSTRUCT( decl ) __pragma( pack(push, 1) ) decl __pragma( pack(pop) )
                #define ALIGNED
            #endif
        #endif
    #endif
#endif

【讨论】:

  • 阅读您提供的链接后,我发现 armcc 也支持 gnucc 打包...在添加基于 arm 的 PACKSTRUCT 后,我收到许多其他错误: 1) 。 .\bglib\cmd_def.h(862): 错误: #20: 标识符“pack”未定义 2) ..\bglib\cmd_def.h(862):错误:#247:已定义函数“__pragma” 3) ..\bglib\cmd_def.h(862):错误:#141-D:未命名原型存在身体时不允许使用参数我做错了什么?谢谢!
  • 嗯,pack 和 __pragma 是 MSVC 宏中使用的符号。似乎这些宏也在 apitypes.h 中定义,它包含在 cmd_def.h 中的定义之前(这是不好的形式 - 不要重复自己)。尝试在那里更改定义!
  • 谢谢,真的很有帮助!现在,我只有 90 个错误和 0 个警告! :) 每个错误都与 __packed 结构中的非 __packed 结构有关。应该做些什么来修复这些错误?可能我应该将所有结构定义为 __packed?
  • 现在一切正常!我在每个包含另一个结构的结构之前添加了 _packed 并注释了 PUCKSTRUCT。现在 - 0 个错误,0 个磨损 :)
猜你喜欢
  • 2023-03-07
  • 2019-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-28
  • 2020-09-01
  • 1970-01-01
相关资源
最近更新 更多