学习ARM开发(17)x

时间:2022-06-22 12:50:06 浏览量:

 学习 ARM 开发(17) 因为嵌入式系统里全部要使用中断的,那么我的 S3C44B0 怎么样中断流程呢?那我就需要了解整个流程了。要深 入了解,最好的方法,就是去写程序,然后不断地调试。在这个程序之前,先要深入去了解 ARM 的中断方式,知 道它有 7 种工作方式。下面先看初始化的代码是怎么样初始化不同模式栈的。

 /*

 IRQMODE。

 */

 orr

  r1,r0,#0x12|0xc0 msr

  cpsr,r1

  ldr

  sp,=IRQ_MODE_SP_START 这段代码,就是初始化 IRQ 模式的栈,这样在 IRQ 中断时就可以使用栈了。

 S3C44B0 的中断过运行过程是这样的:

 当有中断发生时,就会跳到 FLASH 中的地址 0x18 处理取到一条指令并执行,因为那里只允许放一条指令,因此只 能放一条跳转指令了。比如:ldr pc,=0x0c000018

 ,这条指令就是跳到 SDRAM 里运行,意思从 0x0c000018 取一 条指令运行,其实我总是在那地址里放一条跳转指令的,这样又到相应的中断处理程序了。比如在那里一条:

 b irq,这条指令就是跳到 IRQ 的中断处理程序运行,它的作用就是根据不同的中断源来进一步查找不同的 中断处理程序。它的代码如下:

 /* 采用 IRQ 中断,查找各个中断的入口函数地址,并且跳到相应的入口函数运行。

 蔡军生

 2006/02/10 */ irq:sub

  sp,sp,#4

  /* 保留一个栈给 PC */

  stmfd

  sp!,{r8-r9}

 =I_ISPR

 /* 读取中断源寄存器 */

  ldr

  r9,[r9]

  cmp

 r9, #0x0 /* 如果没有中断源发生,就退出去。

 */

  beq

 IDLE_IRQ

  mov

  r8,#0x0

 /* 计算中断源对应的中断程序位置

 */ LOOP_IRQ:

 movs

 r9,r9,lsr #1

  bcs

  HAVE_IRQ

  add

  r8,r8,#4

  /* 每个中断入口占 4 个字节 */

  b

  LOOP_IRQ HAVE_IRQ:

  ldr

  r9,=CONFIG_SDRAM_START+4*8

 /* 从 HandleADC 中断入口

 */

  add

  r9,,r8

  ldr

  ,[r9]

  str

  r9,[sp,#8]

  /* 保存到前面保留的 SP 位置 */

  ldmfd

  sp!,{r8-r9,pc}

 /* 跳到中断程序运行.

 */ IDLE_IRQ:

  /* 没有中断处理。

 */

 ldmfd sp!,{r8-r9}

 add sp,sp4

 subs pc,lr,#4 这段代码的功能就是先从 S3C44B0 的中断源保存寄存器 I_ISPR 取出中断源的标识位,然后不断移位,判断这位是 否有中断,如果有中断就处理它。根据移位来算出它的中断入口地址在那里,这样的做法,就可以动态地改变中 断入口函数。CONFIG_SDRAM_START+4*8,这个就是中断入口函数基地址,如果是第一位有中断,就是 ADC 中断。

 那么就直接跳到这个地址运行就 OK 了。

 比如我使用 S3C44B0 的 TICK 中断,就是时间片中断。就会在相应的地址设置入口函数,使用如下代码:

 / 名称TickInstall 函数功能 安装 Tick 中断函数。

 入 输出参数: 返 回 值:

 开发人员:

  蔡军生 时

 间:

  2006/02/13 修改说明:

  /// void TickInstall(unsigned int nTickFunc) {

 //

  *((unsigned int *)(INT_ADDR_START + 20*4)) = nTickFunc;

 } 上面语句就是把一个中断入口函数设置为时间片运行函数。当有 TICK 中断时,就会跑到时间片函数里运行了。

 总结一下,写一个 S3C44B0 的中断处理需要做以下几部分工作

 1FLASH 里 0x18 处放一条跳转指令,跳到 SDRAM 里运行。

 2在 SDRAM 里 0x0c000018 处,放一条跳转指令,跳到 IRQ 子程序运行。

 3段 IRQ 处理程序。

 4写一段处理实际中断源的处理函数。

 5. 设置中断寄存器,清除中断源屏蔽位。

相关热词搜索: 开发 学习 ARM