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

2006-10-13 20:21 4281 11 11 分类: MCU/ 嵌入式

中断的添加过程:


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


再从汇编语言中调用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
        //PAR100) 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 );


}

文章评论0条评论)

登录后参与讨论
我要评论
0
11
关闭 站长推荐上一条 /2 下一条