ARM异常---一个Uart中断的触发处理过程

发布时间:2023-08-31  

首先给出一些定义:


//2440addr.inc


INTOFFSET    EQU  0x4a000014    ;Interruot request source offset

 


//option.inc


_ISR_STARTADDRESS    EQU 0x33ffff00


//2440init.s


         MACRO

$HandlerLabel HANDLER $HandleLabel

$HandlerLabel

    sub        sp,sp,#4            ;decrement sp(to store jump address)

    stmfd    sp!,{r0}            ;PUSH the work register to stack(lr does t push because it return to original address)

    ldr     r0,=$HandleLabel    ;load the address of HandleXXX to r0

    ldr     r0,[r0]                 ;load the contents(service routine start address) of HandleXXX

    str     r0,[sp,#4]          ;store the contents(ISR) of HandleXXX to stack

    ldmfd   sp!,{r0,pc}         ;POP the work register and pc(jump to ISR)

    MEND


下面进入正题:


//2440init.s


    PRESERVE8

    AREA    RESET,CODE,READONLY

    ENTRY

    EXPORT    __ENTRY

__ENTRY

ResetEntry

    b    ResetHandler    ;0x0

    b    HandlerUndef    ;handler for Undefined mode

    b    HandlerSWI       ;handler for SWI interrupt

    b    HandlerPabort    ;handler for PAbort

    b    HandlerDabort    ;handler for DAbort

    b    .                       ;reserved

    b    HandlerIRQ        ;handler for IRQ interrupt

    b    HandlerFIQ        ;handler for FIQ interrupt

    b    EnterPWDN        ; Must be @0x20.


...


HandlerIRQ      HANDLER HandleIRQ


...


.............

      ; Setup IRQ handler//建立中断表

    ldr    r0,=HandleIRQ       ;This routine is needed

    ldr    r1,=IsrIRQ      ;if there isn t 'subs pc,lr,#4' at 0x18, 0x1c

    str    r1,[r0]

    

................

    ^   _ISR_STARTADDRESS        ;0x33ffff00

HandleReset     #   4

HandleUndef     #   4

HandleSWI        #   4

HandlePabort    #   4

HandleDabort    #   4

HandleReserved  #   4

HandleIRQ        #   4

HandleFIQ        #   4            ;0x33ffff1C

;IntVectorTable

;@0x33FF_FF20

HandleEINT0        #   4            ;0x33ffff20

HandleEINT1        #   4

HandleEINT2        #   4

.................................

HandleUART1        #   4            ;0x33ffff7C

.................................


uart是一个外部中断,走的是FIQ.


外部中断 --> b    HandlerFIQ ;


看代码发现HandlerFIQ在init.s中进行了宏定义,展开之后得到:


//展开宏 HandlerIRQ  HANDLER  HandleIRQ 

HandlerIRQ

        sub        sp,sp,#4          ;decrement sp(to store jump address)

        stmfd    sp!,{r0}            ;PUSH the work register to stack(lr does t push because it return to original address)

        ldr     r0,=$HandleIRQ       ;load the address of HandleXXX to r0

        ldr     r0,[r0]              ;load the contents(service routine start address) of HandleXXX

        str     r0,[sp,#4]           ;store the contents(ISR) of HandleXXX to stack

        ldmfd   sp!,{r0,pc}          ;POP the work register and pc(jump to ISR)

可以看到,HandlerIRQ是一个标准的中断处理过程(正因如此使用了宏进行封装): 首先保存现场,然后跳转到HandleIRQ,从HandleIRQ回来之后恢复现场.


HandleIRQ其实是一个函数指针,它可以在程序中被我们指向某一个处理函数. 这里我们指向了IsrIRQ. 在IsrIRQ里,我们读取INTOFFSET寄存器的值,加上外部中断的起始值HandleEINT0,这样我们就获得了世纪的中断入口HandleUART1. 通过ldmfd sp!,{r8-r9,pc},我们跳转进入了HandleUART1对应的实际的中断处理函数(见后面的分析).


//2440init.s

IsrIRQ

    sub        sp,sp,#4       ;reserved for PC

    stmfd    sp!,{r8-r9}

    ldr        r9,=INTOFFSET

    ldr        r9,[r9]

    ldr        r8,=HandleEINT0  

    add        r8,r8,r9,lsl #2  ;//r8=r8+(r9*4)

    ldr        r8,[r8]

    str        r8,[sp,#8]

    ldmfd    sp!,{r8-r9,pc}


上面说到,"通过ldmfd sp!,{r8-r9,pc},我们跳转进入了HandleUART1对应的实际的中断处理函数." 怎么跳转的呢,在代码里,我们又实现并绑定了HandleUART1的处理函数Uart1_TxRxInt:


//2440addr.h

#define pISR_UART1        (*(unsigned *)(_ISR_STARTADDRESS+0x7c))


//2440lib.c

pISR_UART1=(unsigned)Uart1_TxRxInt;

extern unsigned char UartBuf1[256];


void __irq Uart0_TxRxInt(void)//这里只处理了接收中断

{

    unsigned char *pbuf = UartBuf1;

    if(rSUBSRCPND & BIT_SUB_RXD0)  //接收中断

    {

        rINTSUBMSK |= BIT_SUB_RXD0;

        

        while((rUFSTAT0&0x3f)) 

        { 

            *pbuf++ = rURXH0;  

        }  

        *pbuf = '

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>