EDN首页   博客首页

日志档案

发表于 2006-10-13 20:21:09

12

标签: 无标签

如何在FreeRTOSforx256中增加自己的中断

中断的添加过程:

首先,因为中断要调用上下文切换代码,所以用汇编语言入口。

再从汇编语言中调用C语言。 需然在中断程序中不会完成多少任务,但是用C毕竟简化了工作,并给了代码充分的可读性。

最后就是将中断向量写入AIC的中断向寄存器了。

中断程序:

汇编部分:

  RSEG ICODE:CODE
  CODE32

  EXTERN vUARTISR
  PUBLIC vUARTISREntry

; Wrapper for the EMAC interrupt service routine.  This can cause a
; context switch so requires an assembly wrapper.

; Defines the portSAVE_CONTEXT and portRESTORE_CONTEXT macros.


#include "ISR_Support.h"

vUARTISREntry:

 portSAVE_CONTEXT   ; Save the context of the current task.

 bl vUARTISR    ; Call the ISR routine.

 portRESTORE_CONTEXT   ; Restore the context of the current task -
        ; which may be different to the task that
        ; was interrupted.

  END

C语言部分:

 __arm void vUARTISR( void )
{
        unsigned int status;
        int i;
       
        status = AT91C_BASE_US0->US_CSR;
        AT91C_BASE_US0->US_CR = AT91C_US_RSTSTA;
       
       if(  status & AT91C_US_ENDRX )
        {
                for( i = 0; i < Rx_Count; i++ )
                {
                        US0_BuffTx[ i ] = US0_BuffRx[ i ];
                }


                Tx_Count = Rx_Count;
                AT91C_BASE_US0->US_TPR = ( unsigned int )US0_BuffTx;
                AT91C_BASE_US0->US_TCR = ( unsigned int )Tx_Count;
               
                AT91C_BASE_US0->US_RPR = (unsigned int )US0_BuffRx;
                Rx_Count = 8;
                AT91C_BASE_US0->US_RCR = Rx_Count;
        }
        else if( status & AT91C_US_ENDTX )
        {
          
        }
        else
        {
                AT91C_BASE_US0->US_THR = 'C';
        }
        

        //中断结束之后要通知系统中断处理完毕,否则下次此器件将不会产生中断
        AT91C_BASE_AIC->AIC_EOICR = 0x1234;
              
}


其中有一部分是在外面定义的全局变量。

unsigned int US0_BuffRx[256];
int Rx_Count;
unsigned int US0_BuffTx[256];
int Tx_Count;

中断设置部分:

/*-----------------------------------------------------------*/
void Init_UART_DMA()
{
        AT91PS_PIO pIO = AT91C_BASE_PIOA;
        pIO->PIO_PDR |= 0x03;
        pIO->PIO_ASR |= 0x03;
       
        AT91C_BASE_PMC->PMC_PCER |=  ( 1 << AT91C_ID_US0 );
        //USART :Normal Mode
        //USCLKS:MCK
        //CHRL(CHARACTER LENGTH):8BIT(11)
        //SYNC:0 In Asynchronous Mode
        //PAR:(100) No Parity
        //NBSTOP:1 stop bit
        //CHMODE(CHANNEL MODE):Normal Mode
        AT91C_BASE_US0->US_MR = 0x08C0;
       
        //baudrate = Select_Clock/(8(2-over)CD) = 47923200/(16*312) = 9600
        AT91C_BASE_US0->US_BRGR = 312;
       
        //reset usart0
        AT91C_BASE_US0->US_CR = 0x010C;
        //set interrupt bit
        AT91C_BASE_US0->US_IDR = 0xFFFFF;
        //enable rxen and txen
        AT91C_BASE_US0->US_CR = 0x0050;
        //Disable AIC interrupt
        AT91F_AIC_DisableIt( AT91C_BASE_AIC, AT91C_ID_US0 );
        //Enable Interrupt in us0
        AT91C_BASE_US0->US_IER = 0x00018;
      
        AT91F_DBGU_Print32( AT91C_BASE_US0->US_CSR );
       
        AT91C_BASE_US0->US_PTCR = 0x00000101;
       
        prvSetupUARTInterrupt( );
       
        AT91C_BASE_US0->US_RPR = ( unsigned int )US0_BuffRx;
        Rx_Count = 8;
        AT91C_BASE_US0->US_RCR = Rx_Count;
 
}
/*-----------------------------------------------------------*/

static void prvSetupUARTInterrupt( void )
{
   /* Enable the interrupts in the AIC. */
   AT91F_AIC_ConfigureIt(

           AT91C_BASE_AIC,

           AT91C_ID_US0, 6,  

           AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL,

           ( void (*)( void ) ) vUARTISREntry

          );

           AT91F_AIC_EnableIt( AT91C_BASE_AIC, AT91C_ID_US0 );

}

系统分类: ARM   |   用户分类: 无分类   |   来源: 无分类   |   【推荐给朋友】   |   【添加到收藏夹】

    阅读(771)    回复(0)  

投一票您将和博主都有获奖机会!