【问题标题】:header file to binary file or intel HEX file头文件到二进制文件或 intel HEX 文件
【发布时间】:2022-01-04 07:48:22
【问题描述】:

我有一个头文件。它包含我在嵌入式系统项目中使用的各种常量(作为预处理器宏定义---哈希定义)的值(IDE 是 Keil MicroVision,微控制器是 STM32,编程语言是 C)。 我想将该头文件转换为十六进制文件,以便可以将其单独写入微控制器的闪存。 因此,对于单个通用软件代码,我希望更改常量并针对特定(大约 10-15 种不同类型)硬件运行它。

我的方法:我正在尝试先找到一种将头文件转换为二进制文件的方法,然后使用一些实用程序(来自 sourceforge 的 srecorder)将 .bin 转换为 .hex

这种方法对吗?

或者任何人都可以建议一种替代且有效的方法来实现我的目标吗? 谢谢

【问题讨论】:

  • 普通的 C 程序从不在头文件中包含任何变量实例,因此这绝对不是正确的方法 - 您的 C 项目似乎设计不正确。另外,当您说常量时,您是指const 变量定义还是预处理器#define 或枚举?
  • 预处理宏定义(散列定义)
  • 不,这不是正确的方法(而且没有任何意义;头文件中的声明是对编译器的指令,而不是数据的实例化,并且数据位置由链接器确定。)这是一个X-Y 问题和您的解决方案 X 毫无意义。而是询问您的问题 Y。有许多可能的解决方案。 STM32 涵盖了广泛的部件,从具有许多 2Kb 闪存块的部件到具有更少、更大和可变大小的闪存页的其他部件。这对构成可行解决方案的内容产生了影响,其中有很多 - 因此您可能需要更具体。

标签: c build embedded keil


【解决方案1】:

预处理器定义不存储在数据闪存中,而是存储在程序闪存中 (.text),连同使用它们的代码,集成在机器代码中。它们不存储在任何特定或固定地址。所以你的请求没有任何意义——你根本无法将它们单独编程为闪存。

为了实现这一点,您需要将const uint32_t 或类似的变量存储在固定的内存位置。这些需要在 .c 文件中声明,尽管有时可以使用相应 .h 文件中的 extern 引用“全局”公开只读变量。

要在特定地址分配变量,您通常需要更改链接描述文件并使用非标准编译器扩展。

【讨论】:

    【解决方案2】:

    了解您来自哪里,我建议您沿着您建议的道路前进。让我向您展示两种解决问题的方法,我认为它们会更好。

    我假设您的常量是宏,但是,如果它们是枚举或其他东西,它应该不会有所不同。

    第一个选项是使用预处理器来选择您的平台。比如:

    #if defined(PLATFORM_A)
    #define CONSTANT_X 111
    #define CONSTANT_Y 222
    #elif defined(PLATFORM_B)
    #define CONSTANT_X 112
    #define CONSTANT_Y 221
    #else
    #error Need to define a platform
    #endif
    

    当然,如果您有很多常量,也许将每个平台保留在自己的标题中会更好(更容易阅读)。

    #if defined(PLATFORM_A)
    #include "platform_a_constants.h"
    #elif defined(PLATFORM_B)
    #include "platform_b_constants.h"
    #else
    #error Need to define a platform
    #endif
    

    如果您使用这些常量来确定数组的维度,则此选项是唯一的方法。

    我没有使用 Keil IDE 的经验,所以,我不确定如何配置它来构建具有不同宏定义的不同二进制文件,但是,这是常见的 C 语言,应该有办法做到这一点。

    另一种选择是制作这些全局变量。在这种情况下,你会有一个像这样的标题:

    extern int const constant_x;
    extern int const constant_y;
    

    然后每个平台都有一个单独的源文件:

    // platform_a.c
    int const constant_x = 111;
    int const constant_y = 222;
    
    // platform_b.c
    int const constant_x = 112;
    int const constant_y = 221;
    

    同样,如何仅链接特定目标所需的源文件取决于您的构建系统,我不熟悉 Keil IDE,但应该不难做到。

    一般来说,这个选项更容易维护,因为它只是设置链接器,你不会以任何方式弄乱源代码(并且定义预处理器常量可能会弄乱源代码丑陋的方式)。

    此外,使用此选项可以很简单地将常量转换为运行时参数,如果需要,可以在程序执行期间更改该参数 - 只需从声明和定义中删除 const

    【讨论】:

    • 这个问题显然是一个 X-Y 问题,这是对(实际)问题 X 的解决方案,而不是对无意义问题 Y 的解决方案。这很好(并且对 OP 有用),但他 OP 应该鼓励特别要求 X 使这个答案有效,然后更好地为 SO 社区服务。也就是说,你已经回答了他应该问的问题,而不是他问的关于一个不合理的解决方案的问题。
    • @Clifford 就像你说的,试图帮助那个人,因为他确实问他的想法是否是正确的方法。我进行了编辑以更清楚地表明他的想法不是正确的方法。
    猜你喜欢
    • 2011-10-08
    • 2020-03-16
    • 2011-04-14
    • 1970-01-01
    • 1970-01-01
    • 2012-10-19
    • 1970-01-01
    • 2016-10-03
    • 2013-04-19
    相关资源
    最近更新 更多