【问题标题】:How to set up a callback function when an Exception occurs?异常发生时如何设置回调函数?
【发布时间】:2017-06-22 22:58:28
【问题描述】:

我一直在思考如何在发生异常时设置回调。

我有这个测试代码:

void main()
{
    long * bad = (long*)0x0A000000; //Invalid address

    //When the following line gets executed 
    //it causes an error and the debugger sends me to an assembly file. 
    *bad = 123456789; 
}

我被发送到的程序集文件如下所示(真实文件的片段):

.macro DEFAULT_ISR_HANDLER name=
  .thumb_func
  .weak \name
\name:
1: b 1b /* endless loop */
.endm

DEFAULT_ISR_HANDLER SRC_IRQHandler   /*Debugger stops on this line*/

据我了解,DEFAULT_ISR_HANDLER 是一个定义无限循环的宏。 我想要做的是在 C 文件中定义我自己的函数,当发生异常时我可以调用它,而不是调用 DEFAULT_ISR_HANDLER 宏中定义的内容。

我的问题是,如何在该程序集中定义一个调用特定 C 函数的宏?

希望我能解释一下自己。感谢您提供有关此主题的任何信息或指导。

如果相关,我使用的是 GCC ARM 编译器 v5.4_2016q3

谢谢, 艾萨克

编辑

我正在使用 Cortex-M3。

直到现在我才意识到我在谈论处理器异常。根据数据表,有一个包含 16 种异常类型的列表。

显然,它的工作方式是将所有异常类型重定向到宏,然后调用一些 thumb 函数,然后是一个无限循环(根据代码中的 DEFAULT_ISR_HANDLER)。

为了方便起见,我想做的是在 C 文件中定义自己的函数,这样每次出现任何类型的处理器异常时,我都可以控制如何进行。

【问题讨论】:

  • C 不支持异常。
  • 是的,但是有 are 处理器异常/陷阱/...似乎是这样的。我认为需要进行一些澄清,例如使用的确切平台和编译器/运行时。
  • 虽然 C 不支持异常,但特定环境提供了扩展来支持它们。例如,avr-gcc 就可以。问题的答案可能在于使用的特定编译器对特定平台的支持的文档。作为一个快速提示,看起来服务例程被定义为弱符号,因此可能您在某处有一些宏可以帮助您定义具有相同符号名称的自己的处理程序,因此链接器或初始化代码会安装它而不是默认的。
  • 这取决于您的操作系统。大多数操作系统会将这些转换为您可以捕获的陷阱或信号(使用信号或结构化异常处理程序)。在“裸机”上,您需要设置自己的中断处理程序。
  • @ChrisDodd:看起来很可能没有操作系统。这似乎是一个裸机系统。但是,没有提供足够/不清楚的信息。

标签: c assembly exception-handling cortex-m3


【解决方案1】:

你有两个选择:

只需使用void SRC_IRQHandler(void) 签名定义一个 C 函数,由于宏将默认处理程序定义为弱,您的函数将在链接阶段覆盖默认处理程序。

在您的项目中应该有一个位置,SRC_IRQHandler 被放置在 Cortex-M3 架构中所谓的向量表中。您可以将此函数的名称替换为您自己的 C 函数,当此中断(异常)发生时,您的函数将被调用。

【讨论】:

  • 我正在阅读这个tutorial,你所解释的现在对我来说很有意义。我会在早上试试这个。向你致敬。
  • 我可以确认这很好用。感谢您的回复。
【解决方案2】:

cortex-m 系列通常有超过 16 个例外,加上该内核实现的中断数量,32、64、128、256。但它们基本相同。 cortex-m 系列的工作方式是,如果您愿意,它们会为您执行 EABI 调用,它们会保留一些寄存器,然后从向量表中调用的地址开始执行,这样您就可以获得地址一个正常编译的 C 函数直接在表中。从历史上看,您需要用一些代码包装该函数以保存和恢复状态,并且指令集通常有一个特殊的中断返回,但 cortex-m 他们做的有点不同。

所以知道接下来的问题是如何在表中获取该地址,这取决于您的代码、构建系统等。这些处理程序可能设置为指向 ram 中的地址,也许您正在运行在 RTOS 上,有一个函数调用运行时来为异常注册一个函数,然后 RTOS 更改 ram 中的代码或某些数据值,这些值与它们的处理程序相关联,这些处理程序基本上环绕着你的处理程序。或者您正在组装或其他一些特定于工具的东西中制作矢量表(尽管组装在那里,工作和简单)并且您只需倒数正确的条目数(或添加一百多个条目,以便您可以倒数到右边条目)并放置 C 函数的名称。

最好在运行之前反汇编或对结果进行一些其他检查,以仔细检查您是否已将处理程序地址放置在该中断/异常的正确物理地址中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-17
    • 2020-01-07
    • 2011-01-29
    • 1970-01-01
    • 2017-11-27
    • 2017-01-23
    相关资源
    最近更新 更多