Embedded 如何用C编写ARM中断函数
我正在LinuxMint 17.2 64b上使用工具链V4.8.2 我是一个业余爱好者,尝试使用TM4C123G板和它的常用功能(编码各种闪烁、uart等),但总是尽可能地保持接近金属,而不使用其他库(如CMSIS…)。也没有IDE(CCS,Keil…),只有Linux终端窗口,主板和I。。。所有这些主要是为了教育目的 问题:我一直在尝试实现常见的中断功能,如: EnableInt(清除特殊注册表PRIMASK的第0位、第I位): WaitForInt:Embedded 如何用C编写ARM中断函数,embedded,interrupt,bare-metal,cortex-m,Embedded,Interrupt,Bare Metal,Cortex M,我正在LinuxMint 17.2 64b上使用工具链V4.8.2 我是一个业余爱好者,尝试使用TM4C123G板和它的常用功能(编码各种闪烁、uart等),但总是尽可能地保持接近金属,而不使用其他库(如CMSIS…)。也没有IDE(CCS,Keil…),只有Linux终端窗口,主板和I。。。所有这些主要是为了教育目的 问题:我一直在尝试实现常见的中断功能,如: EnableInt(清除特殊注册表PRIMASK的第0位、第I位): WaitForInt: WFI 禁用: CPSID I 例
WFI
禁用:
CPSID I
例如,我将此函数添加到.c文件中以启用int:
void EnableInt(void)
{ __asm(" cpsie i\n");
}
。。。这可以编译,但执行似乎不能正常工作(在最简单的blinky.c版本中,在c代码中调用EnableInt()后,我无法获得任何LED操作)。可以找到blinky.c代码
在.c文件中写入这些中断例程的正确方法是什么(理想情况下不使用其他库,而只是设置/清除相应寄存器的位
编辑:删除了bx lr指令-但EnableInt()似乎没有更好的效果-仍在寻找解决方案
EDIT2:实际上,上面定义的函数EnableInt()正在工作。我的SysTick_处理程序被错误地映射到启动文件中的中断向量表(而我最初的问题是我在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,必须在两个或三个位置启用中断:
而且,是的,这是很值得一读的东西。但在我看来,这是值得努力的。或者你可以从一本书开始。有一些方法可能有助于首先了解整个情况(从单个文档中获取确实很困难,但这是可能的)。想想当编译器的默认函数prologue在
EnableInt
的条目上设置堆栈帧,推送返回地址,然后asm强制返回而不拆下堆栈帧?或者更糟糕的是,你打开了优化,asm在呼叫站点内联,所以你“回到”胡说八道。您绝对不希望在内联asm中使用bx lr
。对于使用AAPC的Cortex-M CPU,您不需要汇编程序。此外,除非绝对必要,否则不要锁定全局中断。阅读CMSIS,使用标准方式,而不是一些自制的东西。为什么在操作PRIMASK之后要在某个地方进行分支?这很有用,谢谢。当我超越blinky.c阶段时,我肯定会听从建议。@JeanAnthelme:我不是想推,但我可以问一下你为什么不接受答案吗?少了什么?
void EnableInt(void)
{ __asm(" cpsie i\n");
}