【问题标题】:How to assign a variable to an absolute address in c?如何将变量分配给c中的绝对地址?
【发布时间】:2015-11-21 15:38:13
【问题描述】:

我正在尝试访问 PMC_PCER0 并在 ARM Cortex M3 上为 PID14 启用它。我被要求创建一个读取按钮并“返回”(正如我的教授坚持称之为)其值的 void 函数。无论如何,这是问题所在:

void readButton( unsigned int *button)
{
   do something yo;
}

我有一个PMC_PCER0 的地址,为了这个问题,我们假设它位于0xfff123da,而这个PMC_PER0 有 32 个 PIO,其中一个是 PID,恰好从第 14 位开始,所以我需要激活这个。

为了激活它,我是否需要使用 `or 运算符屏蔽PMC_PCER0

我知道我可以如下定义PMC_PCER0

#define PMC_PCER0 (0xfff123da)

但是,这只会给PMC_PCER0 提供0xfff123da 的值,但我想做的是PMC_PCER0 实际拥有该地址。后来我想掩盖它。如果您能详细解释一下,我将不胜感激。

【问题讨论】:

  • 为什么不在您的 MCU 中为外围模块使用供应商 (CMSIS) 接头?每个 MCU 制造商都提供此类接头。
  • @Olaf 这不是 PC 程序,而是嵌入式处理器 ARM Cortex M3。硬件工程师已经提供了要使用的地址。编译器/链接器生成的地址不起作用。
  • @QuentinUK:我很确定 CMSIS 标头不适用于 PC。而且 PC 没有 MCU,而是有 CPU(尽管差异正在缩小)。无论如何应该有一个头文件。该名称来自 Atmel MCU (AT91SAM3*) 中外围模块的寄存器,我非常有信心 Atmel 确实 提供标头。那你的意思是什么?
  • 所以向公众提问的目的是让自己感觉不好,因为这里的人实际上什么都不擅长,只会降低您的问题的评分。却没有人给出满意的答复!当然我不是说评论的你们^^

标签: c pointers memory-address cortex-m


【解决方案1】:

那么你如何在 C 中的某个地址加载或存储一些东西呢?你需要一个数组或指针吗?如何为指针分配地址?

unsigned int *p;
...
p = (unsigned int *)0x12345678;

然后 *p = 10;会写一个 10 到那个地址吗?或 p[0] = 10;,初级 C 语言编程,与微控制器或操作系统无关。

您最终遇到的问题是优化器。如果以后不使用 *p 或 p[0] ,则根本没有理由生成代码。即使它确实生成了代码,也不能保证它确实进行了存储或加载

void myfun ( unsigned int x )
{
    unsigned int *p;
    p = (unsigned int *)0x12345678;
    *p = x;
}

你如何告诉编译器或者你如何使用语言来要求编译器实际进行内存操作?

volatile unsigned int *p;
p = (unsigned int *)0x12345678;

所以试着让你的定义看起来像这样

#define PMC_PCER0   (*((volatile unsigned int *)0xfff123da))

并理解这仍然不能保证 1) 编译器将执行总线操作 2) 总线操作将是您想要的大小。如果你想保证这样的事情,那么改为

#define PMC_PCER0 (0xfff123da)

并制作一个小的 asm 文件以链接到项目中,或者将其放入您的引导程序中。

.thumb_func
.globl PUT32
PUT32:
    str r1,[r0]
    bx lr
.thumb_func
.globl GET32
GET32:
    ldr r0,[r0]
    bx lr

然后使用它

void myfun ( unsigned int x )
{
    PUT32(PMC_PCER0,x);
}

这有性能成本,但它也有显着的好处,首先是编译器,如果远程兼容必须按顺序执行函数调用并且所有这些调用。所以你被保险你得到你的负载或存储,你被保险它是正确的大小。其次,您对外围设备和其他特殊地址的所有访问都是通过抽象层控制的,当放置在芯片模拟器或操作系统之上时,或者当您对手工测试台(模拟器)进行自己的测试时,您已经拥有一个易于移植的 C 函数级别的抽象层。如果你想调试正在发生的事情,你可以使用这个抽象层来插入断点或 printfs 或其他任何东西。

要么接受,要么放弃,我花了好几年的时间才使编译器无法使用 volatile 技巧生成正确的指令。如果您至少没有学习一点汇编语言,并且没有定期反汇编工具生成的代码,那么当出现错误(例如编译器生成错误的指令或链接器将项目加载到错误的位置)时,您将付出更多的努力(芯片不启动,程序挂起等)。然后是如何将工具链移过问题。

是的,我知道您想要的功能是负载而不是商店,我假设您可以从这里弄清楚。

这都是 C 语言编程的基本内容,这可能是为什么没有人想跳进去回答的原因。此外,为您正在使用的微控制器以及所有其他家庭和品牌免费提供的库也使用了这些技巧,尽管其中一些有点吓人,所以对它们持保留态度(或将它们用作参考,但不一定直接因为你可能最终拥有他们的问题和维护)。

【讨论】:

    猜你喜欢
    • 2012-11-13
    • 2013-05-22
    • 1970-01-01
    • 1970-01-01
    • 2015-09-30
    • 2013-01-24
    • 2013-08-29
    • 1970-01-01
    相关资源
    最近更新 更多