【问题标题】:Embedding constant at specific memory location在特定内存位置嵌入常量
【发布时间】:2019-02-13 00:33:00
【问题描述】:

我正在为 NXP S12ZVL32 上的嵌入式应用程序编写引导加载程序。我需要应用程序知道引导加载程序的版本(主要、次要、构建)。是否可以在引导加载程序源中的特定位置声明常量以便应用程序可以找到它们?

我尝试在#pragma 部分的开头声明常量,以便知道它从哪里开始。

#pragma CODE_SEG SHADOW_ROM
const UINT8 VER_MAJOR = 0xFE;
const UINT8 VER_MINOR = 0xED;
const UINT16 VER_BUILD = 0xCEFA;

S12 是小端,所以我希望能够在生成的 .sx 文件中搜索 FEEDFACE,但甚至找不到 FEED 或 FACE。我已关闭优化,因此编译器不应删除未使用的常量。

【问题讨论】:

  • 您创建了一个XY problem“我需要应用程序知道引导加载程序的版本(主要、次要、构建)”——这是一种低质量的设计,会给应用程序带来不必要的负担。相反,引导加载程序和应用程序之间的接口应该用相应的版本号明确定义。该版本号如何传递给应用程序是 API 的一部分。
  • @sawdust 为什么你认为这是一个 XY 问题?这是一种在嵌入式系统上识别某些东西的版本的相当常见的解决方案。
  • @sawdust 应用程序需要知道引导加载程序版本的原因是,当不可避免地在引导加载程序的第一个版本中发现错误时,软件可以知道它需要应用解决方法, 如果没有安装没有错误的新引导加载程序。
  • 执行此操作的可用方法是特定于工具链的 - 您的工具链是什么?您的工具链无法识别的#pragma 指令将被忽略 - 可能但不一定带有警告。编译器/链接器不需要以任何特定顺序、邻接或对齐方式放置单独的变量 - 使用数组 UINT8 VER[] = {0xFE, 0xED, 0xFA, 0xCE} ; 来强制执行您想要的顺序和对齐方式。
  • @sawdust,在这种情况下没有 API。引导加载程序和主应用程序是完全独立的实体,并且必须保持如此。根据定义,他们不能互相交谈。引导加载程序在重置超时或完成重新刷新应用程序代码时简单地跳转到应用程序入口点。你确定你不是在考虑 Windows 编程吗?

标签: c embedded


【解决方案1】:

是的,可以在特定的内存地址定位一个常量。有不同的方法可以实现这一点,如何做到这一点的细节因工具链而异。一种方法是在源代码定义中使用编译器特定的#pragma_attribute_ 语句来指定常量应该位于的内存地址。另一种方法是通过在所需的内存地址创建一个特殊的内存部分来自定义链接器指令(也称为链接器脚本或分散加载)文件。然后在代码中使用#pragma 或其他链接器指令将常量放入自定义内存部分。有关详细信息,请参阅您的工具链文档。

【讨论】:

  • 这很有帮助。我在 codewarrior 中找到了关于 S12Z 常量、变量和代码分配的 NXP 文档。这告诉了我我需要知道的一切。 community.nxp.com/docs/DOC-334387
【解决方案2】:

首先,定义一个全局const 值允许编译器仅使用该值(作为右值,因为您通常不引用MATH_PI 的地址)并在它的每个位置使用该值可能需要。如果你想把一个常量放在一个固定的位置,最好的指定方法是在汇编程序中。

小时候,我曾经使用whatis unix 命令查看以#(@) 为前缀的字符串,其中通常存储了SCCS 修订系统中的版本信息。当我不得不切换到cvs时,我用这个想法在每个源文件中定义常量,并搜索(这可以很容易地用grep(1)或一些过滤程序)扫描二进制(是的,程序的二进制代码) 对于以$Id: 开头的行,所以我嵌入了如下行:

static const char CVS_id[] = "\n$Id$\n";

在源文件中,当grep(1)ping 二进制文件时,我得到了可执行文件中链接的每个模块的完整修订版。

Git 本身不会放置版本字符串,但最好的(因为它不需要将内容放在绝对地址中)是将版本信息放在具有某种特定模式的字符串中(git 允许放置它通过 git hook 为自己使用)不要被扫描代码与其他东西混淆。这样,您只需扫描二进制文件即可获取包含的每个源文件的版本信息。

所有这一切都不需要你把东西固定到固定的地方,所以从我的角度来看,它可以让你的内存映射更加灵活,并为你提供一种更便携的做事方式。

【讨论】:

    【解决方案3】:

    假设引导加载程序和主应用程序都在您的控制之下,您可以让引导加载程序跳转到应用程序入口点,并带有指向寄存器中版本信息(以及您希望的任何其他信息)的指针,以便应用程序生成酌情使用。这消除了对固定内存位置的任何依赖。

    【讨论】:

      猜你喜欢
      • 2022-12-29
      • 1970-01-01
      • 1970-01-01
      • 2021-10-17
      • 1970-01-01
      • 1970-01-01
      • 2013-09-30
      • 2021-11-14
      • 1970-01-01
      相关资源
      最近更新 更多