zoukankan      html  css  js  c++  java
  • 《设备树 — 引入设备树后对中断的影响(九)》

    1.没有引入设备树时中断

      在老的内核中断是在完全由所谓的板级支持包中指定的,同时相关的寄存器地址这些也都是在代码中写死的。

      这种代码没法在多个SOC上通用,这个就导致大量的重复代码出现。

      在2.6.35.7内核中,SMDKV210单板是这样描述的

    MACHINE_START(SMDKV210, "SMDKV210")
    	/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
    	.phys_io	= S3C_PA_UART & 0xfff00000,
    	.io_pg_offst	= (((u32)S3C_VA_UART) >> 18) & 0xfffc,
    	.boot_params	= S5P_PA_SDRAM + 0x100,
    	.init_irq	= s5pv210_init_irq,
    	.map_io		= smdkv210_map_io,
    	.init_machine	= smdkv210_machine_init,
    #ifdef CONFIG_S5P_HIGH_RES_TIMERS
    	.timer		= &s5p_systimer,
    #else
    	.timer		= &s3c24xx_timer,
    #endif
    MACHINE_END 

      可以看到这里写了很多的固定的静态映射的地址信息,如S3C_PA_UART,S5P_PA_SDRAM。

      比如进入到中断初始化函数中s5pv210_init_irq

    #define S5P_VA_CHIPID		S3C_ADDR(0x00700000)
    #define S5P_VA_GPIO		S3C_ADDR(0x00500000)
    #define S5P_VA_SYSTIMER		S3C_ADDR(0x01200000)
    #define S5P_VA_SROMC		S3C_ADDR(0x01100000)
    #define S5P_VA_AUDSS		S3C_ADDR(0X01600000)
     
    #define S5P_VA_UART0		(S3C_VA_UART + 0x0)
    #define S5P_VA_UART1		(S3C_VA_UART + 0x400)
    #define S5P_VA_UART2		(S3C_VA_UART + 0x800)
    #define S5P_VA_UART3		(S3C_VA_UART + 0xC00)
     
    #define S3C_UART_OFFSET		(0x400)
     
    #define VA_VIC(x)		(S3C_VA_IRQ + ((x) * 0x10000))
    #define VA_VIC0			VA_VIC(0)
    #define VA_VIC1			VA_VIC(1)
    #define VA_VIC2			VA_VIC(2)
    #define VA_VIC3			VA_VIC(3)
     
     
     
     
    void __init s5p_init_irq(u32 *vic, u32 num_vic)
    {
    	struct irq_chip *chip;
    	int irq;
     
    	/* initialize the VICs */
    	for (irq = 0; irq < num_vic; irq++)
    		vic_init(VA_VIC(irq), VIC_BASE(irq), vic[irq], 0);
     
    	s3c_init_vic_timer_irq(IRQ_TIMER0_VIC, IRQ_TIMER0);
    	s3c_init_vic_timer_irq(IRQ_TIMER1_VIC, IRQ_TIMER1);
    	s3c_init_vic_timer_irq(IRQ_TIMER2_VIC, IRQ_TIMER2);
    	s3c_init_vic_timer_irq(IRQ_TIMER3_VIC, IRQ_TIMER3);
    	s3c_init_vic_timer_irq(IRQ_TIMER4_VIC, IRQ_TIMER4);
     
    	s3c_init_uart_irqs(uart_irqs, ARRAY_SIZE(uart_irqs));
     
    	/* Register wakeup source. */
    	for (irq = 0; irq < ARRAY_SIZE(wakeup_source); irq++) {
    		chip = get_irq_chip(wakeup_source[irq]);
    		chip->set_wake = s3c_irq_wake;
    	}
    }
    

      可以看到好多的东西都完全是由宏定义,而固定死的。这种代码因为完全没有通用性。在4.x内核中被舍弃了。

      在3.16.57的代码中也是这样

    MACHINE_START(SMDKV210, "SMDKV210")
    	/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
    	.atag_offset	= 0x100,
    	.init_irq	= s5pv210_init_irq,
    	.map_io		= smdkv210_map_io,
    	.init_machine	= smdkv210_machine_init,
    	.init_time	= samsung_timer_init,
    	.restart	= s5pv210_restart,
    	.reserve	= &smdkv210_reserve,
    MACHINE_END
    

      

    2.引入设备树后中断

      4.19中是这样的

    static char const *const s5pv210_dt_compat[] __initconst = {
    	"samsung,s5pc110",
    	"samsung,s5pv210",
    	NULL
    };
     
    DT_MACHINE_START(S5PV210_DT, "Samsung S5PC110/S5PV210-based board")
    	.dt_compat = s5pv210_dt_compat,
    	.map_io = s5pv210_dt_map_io,
    	.restart = s5pv210_dt_restart,
    	.init_late = s5pv210_dt_init_late,
    MACHINE_END
    

      在真正的遵循了设备树的引进原因后,因为中断控制器也是一个设备,所以中断控制器也被归为了一个在driver/目录下的子系统

    drivers/irqchip/
    

      

      比较著名的中断控制器有:

      Nested Vectored Interrupt Controller (NVIC)(内嵌向量中断控制器),之前我用过的cortex-m系列的处理器,大多都是用的这种中断控制器。

      General Interrupt Controlle(GIC)(通用中断控制器),这种中断控制器目前4个版本,目前最新的是v4版本,这种架构主要是用于支持ARM V8指令集的多核处理器上使用。GIC版本越高,支持的cpu个数也就多。

      Vectored Interrupt Controller (VIC)(向量中断控制器),这种中断控制器一般是用在单核的CPU上面的,每个VIC芯片支持32个中断源输入。

      当然还有一些不同用的各个CPU厂商设计的中断控制器,如irq-s3c24xx.c里面是三星当初为24xxcpu设计的中断控制器。irq-atmel-aci系列中由公司设计的中断控制器。

      以上这些中断控制器都是需要编写响应的中断控制器的驱动程序,而在设备树引入之前,因为不同的SOC中断控制器的寄存器地址这些不同,这些对于厂商的中断处理这边都是非常杂乱的。

      带入设备树后,使用了几个中断控制器是在设备树文件定义的,每个中断控制器的寄存器地址也是在设备树中指定的,如果有子中断控制器挂在某个主中断控制器上,这个也是可以通过interrupt-parent属性来设置的。即设备树文件要表示一个SOC内外的所有控制器和外设。

      这里要注意的是在dts文件中,一个中断控制器节点,必须要有一个interrupt-controller;的属性

        
            interrupt-controller@f2200000 {
                compatible = "arm,pl192-vic";
                interrupt-controller;        //一个设备节点函有interrupt-controller属性,就表示是一个中断控制器
                reg = <0xf2200000 0x1000>;
                #interrupt-cells = <0x1>;    
                phandle = <0xa>;            //phandle表示自己这个中断控制器,0xa表示自己这个节点
            };
      
          i2c@fab00000 {
                compatible = "samsung,s3c2440-i2c";
                reg = <0xfab00000 0x1000>;
                interrupt-parent = <0xa>;   //它的父中断控制器就是phandle为0xa的节点所带表的中断控制器
                interrupts = <0xd>;
                clocks = <0x2 0x95>;
                clock-names = "i2c";
                pinctrl-names = "default";
                pinctrl-0 = <0x3b>;
                #address-cells = <0x1>;
                #size-cells = <0x0>;
                status = "disabled";
            };
    

      

    GIC的分析

    http://www.360doc.com/content/14/0813/17/14530056_401586832.shtml#

    sunsissy这位网友对GIC的分析

    https://blog.csdn.net/sunsissy/article/details/73791470

    https://blog.csdn.net/sunsissy/article/details/73842533

    https://blog.csdn.net/sunsissy/article/details/73849456

    https://blog.csdn.net/sunsissy/article/details/73849456

    这位网友对中断子系统和GIC的分析

    https://blog.csdn.net/gaojy19881225/article/details/80019103

  • 相关阅读:
    数组实现栈
    栈应用实例单词逆序
    使用JXMapViewer将地图集成到swing app中
    使用xbee连接地面站和飞控
    QWT编译、配置、使用(Qt Creator)
    Qt跨线程调用错误解析及解决办法
    SVN版本服务器搭建(服务端+客户端)
    opencv配置过程 (cmake,vs2013,qt 5.4)
    基数排序/Go实现
    c/c++ 编译器内存对齐问题
  • 原文地址:https://www.cnblogs.com/zhuangquan/p/12882180.html
Copyright © 2011-2022 走看看