我发现在发生异常时如何设置回调已经有一段时间了。
我有这个测试代码:
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文件中定义我自己的函数,为方便起见,因此每次出现任何类型的处理器异常时,我都可以控制如何继续。
答案 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函数的名称。
好主意在运行之前反汇编或对结果进行一些其他检查,以仔细检查是否已将处理程序地址放在该中断/异常的正确物理地址处。