【发布时间】:2016-08-06 14:22:10
【问题描述】:
我正在使用 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
【问题讨论】:
-
在什么情况下不能正常工作;与您的预期相比,您看到了什么行为?假设
VICVectAddr = 0;正在清除中断,那么这段代码正在正确执行所有 3 个引用步骤(提示:阅读subs pc,...的实际作用) -
@Notlikethat 当发送 I2C 启动条件时应该产生中断。它的工作。但是在中断例程之后,控制不会返回到被中断的代码。汇编代码中缺少第 2 步。
-
正如我所说,第 2 步 正在 由
subs pc...在该代码中执行。离开并找到 LPC213x 手册后,我看到该写入确实确认了 VIC 处的中断,但该中断显然是电平触发的,并且您没有做任何事情来在 I2C 控制器端取消断言它(参见第 13.9 节)。因此,当您返回时,您只是立即再次接受相同的中断,无限循环。 -
将文本发布为文本,而不是图像!
-
IDK 这个特定设备,但
VICVectAddr可能是错误的(外围寄存器名称通常全大写)或不足。 OP 应该阅读参考手册。