我在LinuxMint 17.2 64b上使用arm-none-eabi-gcc工具链,v 4.8.2。
我是,在业余爱好者的水平上,试图玩一个TM4C123G板和它的通常功能(编码各种眨眼,艺术的东西…),但总是试图尽可能地保持接近金属,而不使用其他库(如CMSIS…)只要可能。也没有IDE (CCS, Keil…),只是Linux终端窗口,板和我…这一切主要是为了教育目的。
问题:我被困在试图实现通常的中断函数,如:
EnableInt(清除特殊注册表PRIMASK的第0位,第1位):
CPSIE I
WaitForInt:
WFI
DisableInt:
CPSID I
例如,我为EnableInt添加了这个函数到我的。c文件中:
void EnableInt(void)
{ __asm(" cpsie in");
}
…这编译,但执行似乎不能正常工作(在最简单的blinky.c版本中,一旦我在C代码中调用EnableInt(),我就无法获得任何LED动作)。blinky.c代码可以在这里找到。
在。c文件中编写这些中断例程的正确方法是什么(理想情况下不使用其他库,但只是设置/清除适当寄存器的位…)?
编辑:删除了bx lr指令-但EnableInt()似乎没有更好的工作-仍在寻找解决方案。
EDIT2:实际上,上面定义的函数EnableInt()现在正在工作。我的SysTick_Handler被错误地映射到启动文件中的中断向量表(而我最初的问题是我在Edit1中删除的bx lr指令)。
Tivia MCU集成的ARM Cortex-M4 CPU基本上不需要软件环境为进入/退出中断处理程序采取特殊操作。唯一的要求是使用AAPCS调用标准,如果为这个CPU编译,这应该是gcc的默认值。
CPU由ARM提供的一些紧密耦合的"核心"外设支持。这些是大多数(如果不是全部)Cortex-M3/4 mcu的标准配置。MCU供应商可以配置一些功能,但基本操作总是相同的。
为了简化软件开发,ARM引入了CMSIS软件标准。这至少由一些头文件组成,这些头文件统一了对核心外设的访问和特殊CPU指令的使用。其中包括操纵特殊CPU寄存器的内在特性,如PRIMASK、BASEMASK、OPTION等。另一个头文件提供了核心外设的定义,以及在简单访问不够的情况下对其中一些外设进行操作的函数。
因此,这些外设之一支持CPU进行中断处理:NVIC
(嵌套矢量中断控制器)。这将中断按优先级排列,并为CPU提供中断向量,CPU使用该向量获取中断处理程序的地址。
NVIC还包括所有中断源的使能位。因此,要让CPU处理中断,对于典型的MCU,您必须在两个或三个位置启用中断:
- CPU中的PRIMASK/BASEMASK:最后一道防线。这些是全局中断门。PRIMASK类似于小cpu状态寄存器中的中断使能位,BASEMASK是中断优先级解析的一部分(在开始时忽略它)。
- 每个外围中断源的NVIC中断使能位。定时器,UART, SPI等。许多外设都有多个内部源连接到这条nvic线。(例如UART rx和tx中断)。
- 外设本身的中断使能位。例如:UART rx-interrupt, tx interrupt, rxerror interrupt等
一些外设可能没有内部位,所以最后一个可能会丢失。
让事情工作,你应该阅读参考手册(家庭指南,或类似的),然后经常有一些"编程的Cortex-M4"如何(例如ST有一个STM32系列)。你也应该从ARM获得文档(它们可以免费下载)。
最后,您需要MCU供应商(这里是TI)的CMSIS头。这些应该为您的MCU量身定制。您可能需要提供一些' #define'。
是的,这是相当多的东西读。但在我看来,这是值得的。或者你可以从一本书开始。有一些可能有助于首先获得整体情况(从单个文档中获取确实很难-但可能)。