ADS下的关键字_irq-待写

    费尽九牛二虎之力,终于在ADS下调正常了PXA270的中断, 得益于网上的 嵌入式开发要点,发觉英文文档的阅读能力真是至关重要,而且要养成好的工作习惯,比如,在用ADS开发程序时,完全应该把ADS开发手册看一遍的,正所谓磨刀不误砍柴工。基于此考虑,以后作工作的时候利用课余时间多多翻译一下相关权威资料,既练英文,又学技术,岂不美哉!

抽空,将ADS开发手册关于_irq的部分翻译一下。

5.5.1 Simple interrupt handlers in C

You can write simple C interrupt handlers by using the __irq function declaration
keyword. You can use the
__irq keyword both for simple one-level interrupt handlers,

and interrupt handlers that call subroutines. However, you cannot use the __irq keyword

for reentrant interrupt handlers, because it does not cause the SPSR to be saved or

restored. In this context, reentrant means that the handler re-enables interrupts, and may

itself be interrupted. See Reentrant interrupt handlers on page 5-26 for more

information.

The __irq keyword:

• preserves all ATPCS corruptible registers

• preserves all other registers (excluding the floating-point registers) used by the

function

• exits the function by setting the program counter to (lr – 4) and restoring the

CPSR to its original value.

If the function calls a subroutine, __irq preserves the link register for the interrupt mode

in addition to preserving the other corruptible registers. See Calling subroutines from

interrupt handlers for more information.

Note

C interrupt handlers cannot be produced in this way using tcc. The __irq keyword is

faulted by tcc because tcc can only produce Thumb code, and the processor is always

switched to ARM state when an interrupt, or any other exception, occurs.

However, the subroutine called by an __irq function can be compiled for Thumb, with

interworking enabled. See Chapter 3 Interworking ARM and Thumb for more

information on interworking.

Calling subroutines from interrupt handlers

If you call subroutines from your top-level interrupt handler, the __irq keyword also

restores the value of lr_IRQ from the stack so that it can be used by a SUBS instruction to

return to the correct address after the interrupt has been handled.

Example 5-13 on page 5-25 shows how this works. The top level interrupt handler reads
the value of a memory-mapped interrupt controller base address at
0x80000000. If the

value of the address is 1, the top-level handler branches to a handler written in C.

Handling Processor Exceptions

ARM DUI 0056D Copyright © 1999-2001 ARM Limited. All rights reserved. 5-25

Example 5-13

__irq void IRQHandler (void)

{

volatile unsigned int *base = (unsigned int *) 0x80000000;

if (*base == 1) // which interrupt was it?

{

C_int_handler(); // process the interrupt

}

*(base+1) = 0; // clear the interrupt

}

Compiled with armcc, Example 5-13 produces the following code:

IRQHandler PROC

STMFD sp!,{r0-r4,r12,lr}

MOV r4,#0x80000000

LDR r0,[r4,#0]

SUB sp,sp,#4

CMP r0,#1

BLEQ C_int_handler

MOV r0,#0

STR r0,[r4,#4]

ADD sp,sp,#4

LDMFD sp!,{r0-r4,r12,lr}

SUBS pc,lr,#4

ENDP

Compare this with the result when the __irq keyword is not used:

IRQHandler PROC

STMFD sp!,{r4,lr}

MOV r4,#0x80000000

LDR r0,[r4,#0]

CMP r0,#1

BLEQ C_int_handler

MOV r0,#0

STR r0,[r4,#4]

LDMFD sp!,{r4,pc}

ENDP

下面代码;timer_handle_t itcs_timer_init(timer_handle_t handle, timer_event_cb_t cb_event) { timer_priv_t *timer_priv = handle; if (timer_priv->idx < 0 || timer_priv->idx >= CONFIG_TIMER_NUM) { return NULL; } set_clock_type("cpu-pclk"); // printf("enter timer init fun in driver\n"); uint32_t tempreg = 0; switch (timer_priv->idx) { case 0: timer_priv->base = ITCS_TIMER0_BASE; break; case 1: timer_priv->base = ITCS_TIMER1_BASE; break; default: break; } // printf("unit %d ,timeridx %d, base addr // %08x\n",timer_priv->idx,timer_priv->timeridx,timer_priv->base); switch (timer_priv->timeridx) { case 1: tempreg = readl(timer_priv->base + TIMER_CCR_CONTROL_C1); tempreg |= CCR_RST_ENABLE; writel(tempreg, timer_priv->base + TIMER_CCR_CONTROL_C1); tempreg = readl(timer_priv->base + TIMER_IER_C1); tempreg &= ~(IER_EVNT_ENABLE | IER_ITRV_ENABLE | IER_M1_ENABLE | IER_M2_ENABLE | IER_M3_ENABLE); writel(tempreg, timer_priv->base + TIMER_IER_C1); if (timer_priv->idx == 0) { timer_priv->irq = TTC0_TIMER1_IRQn; request_irq(TTC0_TIMER1_IRQn, itcs_timer_irq, "itcs_timer_irq01", timer_priv); } else { timer_priv->irq = TTC1_TIMER1_IRQn; request_irq(TTC1_TIMER1_IRQn, itcs_timer_irq, "itcs_timer_irq11", timer_priv); } break; case 2: tempreg = readl(timer_priv->base + TIMER_CCR_CONTROL_C2); tempreg |= CCR_RST_ENABLE; writel(tempreg, timer_priv->base + TIMER_CCR_CONTROL_C2); tempreg = readl(timer_priv->base + TIMER_IER_C2); tempreg &= ~(IER_EVNT_ENABLE | IER_ITRV_ENABLE | IER_M1_ENABLE | IER_M2_ENABLE | IER_M3_ENABLE); writel(tempreg, timer_priv->base + TIMER_IER_C2); if (timer_priv->idx == 0) { timer_priv->irq = TTC0_TIMER2_IRQn; request_irq(TTC0_TIMER2_IRQn, itcs_timer_irq, "itcs_timer_irq02", timer_priv); } else { timer_priv->irq = TTC1_TIMER2_IRQn; request_irq(TTC1_TIMER2_IRQn, itcs_timer_irq, "itcs_timer_irq12", timer_priv); } break; case 3: tempreg = readl(timer_priv->base + TIMER_CCR_CONTROL_C3); tempreg |= CCR_RST_ENABLE; writel(tempreg, timer_priv->base + TIMER_CCR_CONTROL_C3); tempreg = readl(timer_priv->base + TIMER_IER_C3); tempreg &= ~(IER_EVNT_ENABLE | IER_ITRV_ENABLE | IER_M1_ENABLE | IER_M2_ENABLE | IER_M3_ENABLE); writel(tempreg, timer_priv->base + TIMER_IER_C3); if (timer_priv->idx == 0) { timer_priv->irq = TTC0_TIMER3_IRQn; request_irq(TTC0_TIMER3_IRQn, itcs_timer_irq, "itcs_timer_irq03", timer_priv); // printf("unit timer1 ret=%08x , request irq3 success!\n",ret); } else { timer_priv->irq = TTC1_TIMER3_IRQn; request_irq(TTC1_TIMER3_IRQn, itcs_timer_irq, "itcs_timer_irq13", timer_priv); // printf("unit timer1 ret=%08x , request irq3 success!\n",ret); } break; default: return NULL; } timer_priv->cb_event = cb_event; // printf("init status irq id num:%d\n",timer_priv->irq); // printf("INIT TIMER %d Timer Count No %d SUCCESS\n", timer_priv->idx, // timer_priv->timeridx); return (timer_handle_t)timer_priv; }
02-17
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值