【发布时间】:2015-08-27 13:25:42
【问题描述】:
我在 LinuxMint 17.2 64b 上使用 arm-none-eabi-gcc 工具链 v 4.8.2。
在业余爱好者级别,我正在尝试使用 TM4C123G 板及其常用功能(编码各种 blinkies、uart 东西......)但总是试图在不使用其他库的情况下尽可能接近金属(例如CMSIS...) 尽可能。也没有 IDE(CCS、Keil...),只有 Linux 终端窗口、开发板和我...所有这些主要用于教育目的。
问题:我被困在尝试实现通常的中断功能,例如:
EnableInt(清除特殊注册表 PRIMASK 的第 0 位、第 I 位):
CPSIE I
WaitForInt:
WFI
DisableInt:
CPSID I
例如,我将此函数添加到我的 .c 文件中用于 EnableInt :
void EnableInt(void)
{ __asm(" cpsie i\n");
}
...这可以编译,但执行似乎无法正常工作(在最简单的 blinky.c 版本中,一旦我在 C 代码中调用 EnableInt(),我就无法获得任何 LED 动作)。 blinky.c 代码可以在here找到。
在 .c 文件中编写这些中断例程的正确方法是什么(最好不使用其他库,而只是设置/清除相应寄存器的位...)?
编辑:删除 bx lr 指令 - 但 EnableInt() 似乎没有更好的工作 - 仍在寻找解决方案。
EDIT2 : 实际上,如上定义的 EnableInt() 函数现在正在工作。我的 SysTick_Handler 被错误地映射到启动文件中的中断向量表(而我最初的问题是我在 Edit1 中删除的 bx lr 指令)。
【问题讨论】:
-
想一想当编译器的默认函数序言在进入
EnableInt时设置一个堆栈帧,推送返回地址,然后您的asm 强制返回而不拆除该堆栈帧时会发生什么?或者更糟糕的是,您打开了优化,并且 asm 在调用站点被内联,所以您“返回”到废话。您绝对不希望bx lr在内联汇编中。 -
对于使用 AAPCS 的 Cortex-M CPU,您不需要汇编程序。此外,除非绝对必要,否则不要锁定全局中断。并阅读有关 CMSIS 的信息,使用标准方式,而不是一些自制的东西。为什么在操纵 PRIMASK 之后还要在某个地方分支??
标签: embedded interrupt bare-metal cortex-m