【OK210试用体验】裸机篇 -- S5PV210的中断体系 - 在线问答 - 电子技术论坛 - 最好最受欢迎电子论坛!

【OK210试用体验】裸机篇 -- S5PV210的中断体系

【OK210试用体验】裸机篇 -- S5PV210的中断体系


      本帖主要通过外部中断实验来学习S5PV210的中断体系。



S5PV210的中断体系结构


在官方datasheet -- S5PV210_UM_REV1.1 中的sections 04_interrupt 有对整个体系的详细介绍。

      S5PV210的中断控制器是由4个向量中断控制器(VIC)、ARM PrimeCell PL192 和 4个 TrustZone Interrupt Controller (TZIC)共同组成。

      S5PV210共支持93个中断源,datasheet中有详细的表格:



      S5PV210中的四个VIC对应的寄存器很多,但很多都是重复意义的。



OK210的按键外设


本次实验是用外部中断来实现,所以需要用到开发板的复位按键。通过OK210的核心板和底板的原理图,可以知道按键是接在哪个GPIO上:

      相对应有用的寄存器:



程序编写思路


本次实验的很多程序文件还是沿用之前的,时钟、串口的初始化直接照搬,Makefile只需做稍微的修改,main函数不用说,测试部分基本在里面,所以新增的中断int.c文件是主要的。

      在S5PV210的启动流程中,可以知道如下模块地址映射图: 其中一块是异常向量表,这个地址对于本次实验相当重要。

      

      对于start.S的启动,需要增加中断服务程序:
  1. IRQ_handle:
  2.         // 设置中断模式的栈
  3.         ldr sp, =0xD0037F80
  4.         // 保存现场
  5.         sub lr, lr, #4                               
  6.         stmfd sp!, {r0-r12, lr}
  7.         // 跳转到中断处理函数
  8.         bl        irq_handler               
  9.         // 恢复现场
  10.         ldmfd sp!, {r0-r12, pc}^
复制代码
     
初始化中断控制器的思路:
  1. // 禁止所有中断
  2.     VIC0INTENCLEAR = 0xffffffff;
  3.     VIC1INTENCLEAR = 0xffffffff;
  4.     VIC2INTENCLEAR = 0xffffffff;
  5.     VIC3INTENCLEAR = 0xffffffff;

  6.     // 选择中断类型为IRQ
  7.     VIC0INTSELECT = 0x0;
  8.     VIC1INTSELECT = 0x0;
  9.     VIC2INTSELECT = 0x0;
  10.     VIC3INTSELECT = 0x0;

  11.     // 清VICxADDR
  12.     intc_clearvectaddr();
复制代码
     清除需要处理的中断的中断处理函数的地址:
  1. // VICxADDR:当前正在处理的中断的中断处理函数的地址
  2.     VIC0ADDR = 0;
  3.     VIC1ADDR = 0;
  4.     VIC2ADDR = 0;
  5.     VIC3ADDR = 0;
复制代码
     main函数实现测试前,可以宏定义一些寄存器
  1. #define         GPH0CON         (*(volatile unsigned long *) 0xE0200C00)
  2. #define         GPH0DAT                (*(volatile unsigned long *) 0xE0200C04)

  3. #define         GPH0_3_EINT3         (0xf<<(3*4))
  4. #define         GPH0_4_EINT4         (0xf<<(4*4))
  5. #define         GPH0_5_EINT5         (0xf<<(5*4))
  6. #define         GPH0_6_EINT6         (0xf<<(6*4))
  7. #define         GPH0_7_EINT7         (0xf<<(7*4))

  8. #define                EXT_INT_0_CON                          ( *((volatile unsigned long *)0xE0200E00) )
  9. #define                EXT_INT_1_CON                          ( *((volatile unsigned long *)0xE0200E04) )
  10. #define                EXT_INT_2_CON                          ( *((volatile unsigned long *)0xE0200E08) )
  11. #define                EXT_INT_3_CON                          ( *((volatile unsigned long *)0xE0200E0C) )

  12. #define                EXT_INT_0_MASK                   ( *((volatile unsigned long *)0xE0200F00) )
  13. #define                EXT_INT_1_MASK                   ( *((volatile unsigned long *)0xE0200F04) )
  14. #define                EXT_INT_2_MASK                   ( *((volatile unsigned long *)0xE0200F08) )
  15. #define                EXT_INT_3_MASK                   ( *((volatile unsigned long *)0xE0200F0C) )

  16. #define                EXT_INT_0_PEND                   ( *((volatile unsigned long *)0xE0200F40) )
  17. #define                EXT_INT_1_PEND                   ( *((volatile unsigned long *)0xE0200F44) )
  18. #define                EXT_INT_2_PEND                   ( *((volatile unsigned long *)0xE0200F48) )
  19. #define                EXT_INT_3_PEND                   ( *((volatile unsigned long *)0xE0200F4C) )
复制代码
     外部中断相关的设置:
  1. // 1111 = EXT_INT[3]
  2.         GPH0CON |= 0xF << 12;                                                       
  3.         // 010 = Falling edge triggered
  4.         EXT_INT_0_CON |= 0x2 << 12;                       
  5.         // unmasked
  6.         EXT_INT_0_MASK &= ~(1<<3);
复制代码
     保存需要处理的中断的中断处理函数的地址:
  1. //VIC0
  2.     if(intnum<32)
  3.     {
  4.         *( (volatile unsigned long *)(VIC0VECTADDR + 4*intnum) ) = (unsigned)handler;
  5.     }
  6.     //VIC1
  7.     else if(intnum<64)
  8.     {
  9.         *( (volatile unsigned long *)(VIC1VECTADDR + 4*(intnum-32)) ) = (unsigned)handler;
  10.     }
  11.     //VIC2
  12.     else if(intnum<96)
  13.     {
  14.         *( (volatile unsigned long *)(VIC2VECTADDR + 4*(intnum-64)) ) = (unsigned)handler;
  15.     }
  16.     //VIC3
  17.     else
  18.     {
  19.         *( (volatile unsigned long *)(VIC3VECTADDR + 4*(intnum-96)) ) = (unsigned)handler;
  20.     }
复制代码
     使能中断:
  1. unsigned long temp;
  2.     if(intnum<32)
  3.     {
  4.         temp = VIC0INTENABLE;
  5.         temp |= (1<
  6.         VIC0INTENABLE = temp;
  7.     }
  8.     else if(intnum<64)
  9.     {
  10.         temp = VIC1INTENABLE;
  11.         temp |= (1<<(intnum-32));
  12.         VIC1INTENABLE = temp;
  13.     }
  14.     else if(intnum<96)
  15.     {
  16.         temp = VIC2INTENABLE;
  17.         temp |= (1<<(intnum-64));
  18.         VIC2INTENABLE = temp;
  19.     }
  20.     else if(intnum
  21.     {
  22.         temp = VIC3INTENABLE;
  23.         temp |= (1<<(intnum-96));
  24.         VIC3INTENABLE = temp;
  25.     }
  26.     // NUM_ALL : enable all interrupt
  27.     else
  28.     {
  29.         VIC0INTENABLE = 0xFFFFFFFF;
  30.         VIC1INTENABLE = 0xFFFFFFFF;
  31.         VIC2INTENABLE = 0xFFFFFFFF;
  32.         VIC3INTENABLE = 0xFFFFFFFF;
  33.     }
复制代码
      外部中断按键扫描:
  1. printf("we get company:EINT3rn");
  2.        
  3.         // clear VIC0ADDR
  4.         intc_clearvectaddr();                                       
  5.         // clear pending bit       
  6.         EXT_INT_0_PEND |= 1<<3;       
复制代码


实验现象


将程序烧入SD卡,取出插入开发板上,上电后通过SecureCRT即可看到数字从0开始递增,如果按下开发板上的 K1 键(search),就会显示信息 “we get company:EINT3”。


1个回复

星夜之北 发表于 2015-8-16 11:05:11
Mark一下~~~~~
回复

举报 使用道具

您需要登录后才可以回帖 登录 | 注册

本版积分规则


关闭

站长推荐上一条 /6 下一条

小黑屋|手机版|Archiver|电子发烧友 ( 湘ICP备2023018690号 )

GMT+8, 2024-12-22 11:06 , Processed in 0.706301 second(s), Total 60, Slave 42 queries .

Powered by 电子发烧友网

© 2015 bbs.elecfans.com

微信扫描
快速回复 返回顶部 返回列表