新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > 从Flash和SRAM中触发中断的过程示例

从Flash和SRAM中触发中断的过程示例

作者:时间:2016-09-12来源:网络收藏

使用LPC2106的Timer 1 进行的简单的中断处理。示例代码中Timer1分为FIQ和IRQ,用户可以从或者中运行这些代码。

本文引用地址:http://www.eepw.com.cn/article/201609/303523.htm

示例展示了ARM构架中中断是如何操作的。提供的代码表示了向量IRQ(中断请求)和FIQ(快速中断)两种情况。中断向量位于FLASH地址中的 0x00-0x1C。如果需要从中运行,则中断向量需要被remapped to 0x40000000-0x4000000C。这可以通过Memory Map register来做到。这些代码用ADS1.2开发,从FLASH中运行。提供了从中运行代码的不同之处。中断服务程序(ISR)使用C语言编写IRQ,用汇编来编写FIQ。

示例使用下面的样式排列:

1. TIMER1 被配置为触发IRQ中断,代码从FLASH中运行;

2. 代码从SRAM中运行所需要的改变和增加;

3. TIMER1被配置为触发FIQ中断,代码从FLASH中运行;

4. 代码从SRAM中运行所需要的改变和增加。

TIMER1 被配置为触发一个IRQ中断,代码从FLASH中运行

这个示例包含下述文件:

1. 中断向量表(ivt.s)

2. 启动用的汇编代码(init.s)

3. 主C文件

只包含了相关的文件。在不同的交叉编译环境下,C文件不用改变太多,而汇编文件需要改变。

中断向量表

这些代码应该被连接到0x0。

;***********************************************************

; 汇编指令

;*************************************************************

AREA IVT,CODE ;新的代码段

CODE32 ;ARM 代码

IMPORT start ;导入外部函数。Start标志不应该在这个段内定义

ENTRY ;定义程序入口

;*********************************************************************

LDR PC,=START

LDR PC,Underfined_Addr

LDR PC,SWI_Addr

LDR PC,Prefetch_Addr

LDR PC,abort_Addr

在 0x14用户应当插入一个标识(checksum),这个标识允许bootloader决定是否允许在FLASH中存放用户代码。当前大多数FLASH编程工具(debuggers and isp utility)有这个内在性能,所以用户不用担心。如果工具没有提供这个功能,这个值需要自己计算,而且应当被插入到0x14。在 LPC2104/5/6的用户手册中的FLASH编程的章节中可以找到checksum相关计算的细节。

DCD ………..

LDR PC,[PC,#=0Xff0]

LDR PC,FIQ_Addr

Undefined_Addr DCD Undefined_Handler

SWI_Addr DCD SWI_Handler

Prefetch_Addr DCD Prefetch_Handler

Abort_Addr DCD Abort_Handler

FIQ_Addr DCD FIQ_Handler

;********************************************************************

; 意外处理

;*******************************************************************

下面虚拟的操作在本例子中不做任何有用的操作。这里写下来仅仅是为了完整性

Undefined_Handler

B Undefined_Handler

SWI_Handler

B SWI_Handler

Prefetch_Handler

B Pretetch_Handler

Abort_Handler

B Abort_Handler

FIQ_Handler

B FIQ_Handler

END

复位时,本例子执行的第一条指令是:

LDR PC,=start

将转移到汇编启动代码,允许中断,建立IRQ的堆栈指针核管理员模式。

中断向量的假肢就是IRQ中断

LDR PC,[PC,#=0Xff0]

这条指令加载到PC,PC地址将从VIC向量地址寄存器(0Xffff f030)转到ISR,并在这里执行转移。其余的向量都是虚拟的中断操作。

启动汇编代码

;*********************************************************************

; 汇编指令

;******************************************************************

AREA asm_code,CODE ;新的代码段

CODE32 ;ARM模式

IMPORT _main ;main 不要在此段中定义

EXPORT start ;全局标志,参考ivt.s

;********************************************************************

start

; Enable interrupts

MSR cpsr_c,#0x13

为管理模式设置SP。由应用程序所需要的堆栈空间来决定这个值。

LDR SP,=0x4……..

设置IRQ模式的SP。在设置SP_irq前转换模式到IRQ,然后再返回管理模式。

MRS R0,CPSR

BIC R1,R0,#0x1F

ORR R1,R1,#0x12

MSR cpsr_c,R1

LDR SP,=0x4……..

MSR cpsr_c,R0

跳转到C代码

LDR lr,=_main

MOV pc,lr

END

这段代码在第一条指令链接到ivt.s。如果建立堆栈指针失败,将导致数据取消,因此堆栈的建立应当在跳转到C main()前建立。

C 代码

这样的话,TIMER1中相关的寄存器就被建立起来了,当寄存器匹配的时候,TIMER将会中断CPU的核。TIMER1 将会以60M Hz的速度运行。这段代码已经在实验板上测试过。实验板使用10 M Hz的晶振,同样地设置PLL。有关定时器的操作请参考LPC2106、5、4用户手册相关的章节。ISR的寄存器将为空,然后根据需要由后面的用户来设置。_irq编译关键字被用来定义IRQHandler()函数,作为一个IRQ ISR。

执行下面的指令,将会执行 init.s 中的C main

LDR lr,=_main

MOV pc,lr

下面是C代码:

/*********************************************************************

函数功能说明

************************************************************************/

_irq void IRQHandler(void);

void feed(void);

void Initialize(void);

/*****************************************************************

头文件

*************************************************************/

#include “LPC210x.h”


上一页 1 2 下一页

关键词: Flash SRAM 触发中断

评论


相关推荐

技术专区

关闭