ARM IRQ处理器不';在GCC中不能正常工作

ARM IRQ处理器不';在GCC中不能正常工作,c,gcc,arm,C,Gcc,Arm,我正在开发一个使用LPC2138 soc的裸机ARM项目。我已经为I2C编写了一个IRQ中断处理程序。但它不能正常返回。对于单个中断,正在重复调用处理程序 我对这个问题做了详细的调试分析 在ARM7TDMI参考手册中明确提到了以下内容 但是当我反汇编代码时,我发现GCC生成的代码并没有恢复CPSR重新注册。最后也是一个未知值 我声明了IRQ处理程序,如下所示 void I2C0_IRQ_handler(void) __attribute__ ((interrupt("IRQ"))); 这是

我正在开发一个使用LPC2138 soc的裸机ARM项目。我已经为I2C编写了一个IRQ中断处理程序。但它不能正常返回。对于单个中断,正在重复调用处理程序

我对这个问题做了详细的调试分析

在ARM7TDMI参考手册中明确提到了以下内容

但是当我反汇编代码时,我发现GCC生成的代码并没有恢复CPSR重新注册。最后也是一个未知值

我声明了IRQ处理程序,如下所示

void I2C0_IRQ_handler(void) __attribute__ ((interrupt("IRQ")));
这是GCC中的错误还是我做错了什么

我用于构建项目的编译器、汇编器和链接器标志是:

CFLAGS := -mcpu=arm7tdmi-s -g3 -Wall -I. -gdwarf-2
AS_FLAGS := -mcpu=arm7tdmi-s -g3 -gdwarf-2
LD_FLAGS := -Wl,-Map,$(TARGET:%.hex=%).map -nostartfiles

您的分析有两个致命的缺陷:第一,您是从CPU核心的角度来看它的,第二,它是错误的

第二个缺陷首先,我不知道为什么ARM7TDMI手册有如此奇怪的过度具体的措辞(无论如何,你不能实际地单独完成所有这些事情),但所有3个方面都是由你代码中的
subs pc,lr,#4
行执行的它以原子方式从SPSR恢复CPSR,并返回到固定的LR地址。由于CPU的中断禁用标志位于CPSR中,因此假设该SPSR值中的I位是清晰的(这是您所期望的,因为您在这里使用了IRQ…),IRQ也将在该过程中自动解除屏蔽

因此,从CPU内核的角度来看,您的代码已经(凭借其最终指令)完成了异常处理程序所需的所有操作,即它在与IRQ发生时相同的点和状态下恢复执行-编译器肯定没有问题。但是,它没有做的是,核心之外的外围设备仍然在断言其中断,因此,从IRQ返回后的下一件事是立即愉快地再次接受相同的IRQ。无限重复

您至少已经超越了核心,到达了中断控制器;写入
vicvectadr
,但这只会让VIC自己对任何挂起的中断进行优先级排序,并交付下一个中断,因为外部源仍然被断言(并且假设没有更高优先级的IRQ来自其他地方),所以仍然是同一个中断


要实际处理中断并取得任何进展,您需要为I2C外围设备提供服务。的第13.9节概述了每个中断条件需要执行的操作,但在清除断言的中断方面,您需要写入I2C0CONCLR的SIC字段。

您的分析有两个致命缺陷:第一,您是从CPU核心的角度来看的,第二,它是错误的

第二个缺陷首先,我不知道为什么ARM7TDMI手册有如此奇怪的过度具体的措辞(无论如何,你不能实际地单独完成所有这些事情),但所有3个方面都是由你代码中的
subs pc,lr,#4
行执行的它以原子方式从SPSR恢复CPSR,并返回到固定的LR地址。由于CPU的中断禁用标志位于CPSR中,因此假设该SPSR值中的I位是清晰的(这是您所期望的,因为您在这里使用了IRQ…),IRQ也将在该过程中自动解除屏蔽

因此,从CPU内核的角度来看,您的代码已经(凭借其最终指令)完成了异常处理程序所需的所有操作,即它在与IRQ发生时相同的点和状态下恢复执行-编译器肯定没有问题。但是,它没有做的是,核心之外的外围设备仍然在断言其中断,因此,从IRQ返回后的下一件事是立即愉快地再次接受相同的IRQ。无限重复

您至少已经超越了核心,到达了中断控制器;写入
vicvectadr
,但这只会让VIC自己对任何挂起的中断进行优先级排序,并交付下一个中断,因为外部源仍然被断言(并且假设没有更高优先级的IRQ来自其他地方),所以仍然是同一个中断


要实际处理中断并取得任何进展,您需要为I2C外围设备提供服务。的第13.9节概述了每个中断条件需要执行的操作,但在清除断言的中断方面,您需要写入I2C0CONCLR的SIC字段。

以何种方式工作不正常;与你期望的相比,你看到了什么样的行为?假设
vicvectadr=0
正在清除中断,然后此代码将适当地执行所有3个引用的步骤(提示:在
subs pc上读取,
实际执行的操作)@notlike发送I2C启动条件时,应生成中断。它起作用了。但在中断例行程序之后,控制不会返回到中断代码。汇编代码中缺少第2步。正如我所说的,第2步是在该代码中由
subs pc执行的。
。在离开并找到LPC213x手册后,我发现该写入操作确实确认了VIC的中断,但中断显然是电平触发的,并且您没有在I2C控制器端对其进行解除断言(参见第13.9节)。因此,当你返回时,你只是立即再次接受相同的中断,无限期。将文本作为文本而不是图像发布!IDK这个特定的设备,但是VICVectAddr可能是错误的(外围寄存器名通常都是大写的)或者不够。OP应阅读参考手册。它以何种方式不能正常工作;与你期望的相比,你看到了什么样的行为?假设
vicvectadr=0正在清除中断,然后此代码将适当地执行所有3个引用的步骤(提示:读取