S3C6410裸机中断编程

时间:2021-04-21 12:20:59
S3C6410中断 编程相对比较简单, 相关 中断寄存器需提前设置好,下面一一讲解我编写中断程序的过程,不对之处还请斧正。
       1、ARM处理器执行中断时会自动进入IRQ或FIQ模式,因此需要提前设置好该模式下的椎栈指针SP。开机启动芯片进入SVC安全模式,因此可以直接通过改变CPSR值进入IRQ或FIQ模式,并设置CP15寄存器使中断向量地址由VIC决定。参考汇编代码:
      
   LDR sp,=0x0C0003FC /*SVC模式堆栈*/          
          MRS r0,cpsr

          BIC r0,r0,#0x02
          MSR CPSR,r0   /*进入FIQ模式*/
          LDR sp,=0x0C0001FC /*FIQ模式堆栈*/
          ADD r0,r0,#0x01
          MSR cpsr,r0   /*进入IRQ模式*/
        LDR sp,=0x0c000FFC /*IRQ模式堆栈*/
        ADD r0,r0,#0x01        
       MSR cpsr,r0   /*返回SVC模式*/

        MRC p15,0,r0,c1,c0,0

        ORR r0,r0,#0x01000000
        MCR p15,0,r0,c1,c0,0  /*中断向量由VIC接口决定*/
     2、配置和使能中断。
VICXINTSELECT确定相关中断是IRQ还是FIQ中断;将中断函数地址写入对应中断向量地址寄存器;VICXINTENABLE中相应中断位为1
使能中断(当然还要清除CPSR中的I或F位,不列举代码了)。以下是我写的配置并使能中断的一个函数,编写好中断函数后调用配置函数即可使能中断:
void set_interrupt(unsigned int VEC_NUM,unsigned int IF,void (*fun)())
{   //设置并使能中断,中断号0~63,IF为0为IRQ中断,否则为FIQ中断
unsigned int *p;
if(IF>0)
  IF=1;
if(VEC_NUM>63)
  return;
if(VEC_NUM<32)
{
  VIC0INTSELECT|=(IF<<VEC_NUM);
  p=(unsigned int*)(0x71200100+4*VEC_NUM );
  *p=(unsigned int)fun;
  VIC0INTENABLE|=(1<<VEC_NUM);
}
else
{   
  VEC_NUM=VEC_NUM-32;
  VIC1INTSELECT|=(IF<<VEC_NUM);
  p=(unsigned int*)(0x71300100+4*VEC_NUM);
  *p=(unsigned int)fun;
  VIC1INTENABLE|=(1<<VEC_NUM);
}
}
   
3、编写中断函数。
      GCC中中断函数的声明:
     
void isr () __attribute__ ((interrupt ("IRQ")));  //isr为函数名,自己随便写(写入上面配置函数中的最后一个参数),interrupt后面的说明符可为: IRQ, FIQ, SWI, ABORT 和  UNDEF,定义可不用加后面的属性说明。如:
       void
__attribute__ ((interrupt ("IRQ"))) isr()
        {
          //处理程序代码
           
           VICXADDRESS=0;  (注:好像是两个ADDRESS寄存器都要写入0)
        }

       注意中断函数最后要VICXADDRESS清除当前中断。



原文地址:S3C6410裸机中断编程
http://bbs.witech.com.cn/thread-46644-1-1.html