【问题标题】:how are function addresses cast or assigned for interrupt vectors in C?如何在 C 中为中断向量转换或分配函数地址?
【发布时间】:2015-04-14 21:04:41
【问题描述】:

假设我有一个微控制器,我知道当它接收到中断时,它会跳转到地址 0x8000(仅作为示例)。我如何在 C 中定义它,它似乎类似于将地址转换为变量,以便我可以读取或写入内存。

通常,支持包带有一些 pragma 语句或其他方式来指示您的中断代码在哪里。但我想了解您将如何在标准 C 中做到这一点。某种函数指针或其他东西?

【问题讨论】:

  • 标准 C 中的 min 是什么?我一直认为您可以在数据表中找到所有地址,或者如果可能的话手动设置它,并为地址创建您自己的定义。
  • 如果没有特定于中断的支持包,您将需要一些汇编代码。一方面,返回顺序可能与标准函数不同。例如,对于 ARM 处理器,可能需要根据异常类型调整寄存器 14(LR - 链接寄存器)中的“返回”地址。

标签: c microcontroller


【解决方案1】:

这里不是一个直接的 C 答案,但这是我在使用过的系统上看到它的方式:

将函数放置在某个地址的最佳方法是使用某种链接描述文件。这使您可以控制代码将如何对齐和运行。不确定您使用的是哪种 C 语言,但我使用过的几乎所有 C 语言都能够通过链接器设置位置。

接下来,您可以在该位置定义一个指针,这是一条“跳转”指令,指向您希望中断代码所在的任何位置。不过,这可能最好使用汇编程序和 .org 语句来完成。这就是我们在非常旧的硬件上的做法,因为它允许我们通过将实际的跳转操作码更改为指向其他地方来轻松更改向量的作用。

【讨论】:

  • 另请注意,在许多 CPU 上,仅在中断向量处跳转到 C 函数将无法正常工作。特殊的#pragmas 还插入了汇编代码包装器,用于保存和恢复 CPU 寄存器(有时是特殊的隐藏寄存器等)的状态,因此它们不会被 ISR 破坏。大多数架构不会对内部寄存器进行内存映射,因此无法在 C 中可靠地模拟这种行为。
【解决方案2】:

对于中断例程,您希望将代码放置在所需的地址 (0x8000)。它不仅仅是您所要求的铸造地址。 #pragma 宏创建由该宏定义的所有代码的函数表。除了这个函数表,您还需要使用链接器描述符文件。该描述符文件将指定内存的物理地址区域。然后,您可以将您的#pragma 代码按部分放置在特定的物理地址中。

为了在 C 中做同样的事情,你必须在程序中遵循类似的过程。您必须将功能代码复制到所需的地址。您可以通过函数名称轻松获取函数地址。但这还不够,因为您还需要将当前 CPU 状态和变量保存在堆栈上。为局部变量设置堆栈,并正确设置外部引用。这部分由编译器在函数调用完成时为您完成。在这种情况下,诀窍之一是使用可重定位函数。但是这些仍然需要一些编译器选项来获取函数的开始和结束地址。您可以查看您的编译器指南以获取可重定位选项

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-02
    • 2013-04-01
    • 2022-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-12
    相关资源
    最近更新 更多