发生异常时如何设置回调函数?

时间:2017-06-22 22:58:29

标签: c assembly exception-handling cortex-m3

我发现在发生异常时如何设置回调已经有一段时间了。

我有这个测试代码:

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宏中定义的whats。

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

希望我自己解释一下。欢迎任何有关此主题的信息或指示。

如果相关我正在使用GCC ARM编译器v5.4_2016q3

谢谢, 艾萨克

修改

我使用的是Cortex-M3。

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

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

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

2 个答案:

答案 0 :(得分:6)

您有两种选择:

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

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

答案 1 :(得分:0)

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

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

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