Linux系统驱动之层级中断控制器驱动程序上机实验

百问网技术交流群,百万嵌入式工程师聚集地:
https://www.100ask.net/page/2248041


参考资料:

  • linux kernel的中断子系统之(七):GIC代码分析

  • Linux 4.9.88内核源码

    • Linux-4.9.88\drivers\gpio\gpio-mxc.c
    • Linux-4.9.88\arch\arm\boot\dts\imx6ull.dtsi
  • Linux 5.4内核源码

    • Linux-5.4\drivers\pinctrl\stm32\pinctrl-stm32mp157.c
    • Linux-5.4\drivers\irqchip\irq-stm32-exti.c
    • Linux-5.4\arch\arm\boot\dts\stm32mp151.dtsi
  • 芯片手册

    • IMX6ULL: imx6ullrm.pdf
    • STM32MP157: DM00327659.pdf
  • 本节视频源码在GIT仓库里

    doc_and_source_for_drivers\
    	IMX6ULL\source\08_Interrupt\
    		07_virtual_int_controller_hierarchy_ok
      		
    doc_and_source_for_drivers\
    	STM32MP157\source\A7\08_Interrupt\
    		07_virtual_int_controller_hierarchy_ok
    

1. 确定中断号n

在这里插入图片描述

查看芯片手册,选择一个保留的、未使用的GIC SPI中断即可。

1.1 IMX6ULL

看芯片手册第3章:

在这里插入图片描述

看上图,选择122号中断,它是SPI里的122号中断,GIC里的编号是(32+122)=154。

1.2 STM32MP157

看芯片手册第21.2节:

在这里插入图片描述

看上图,选择210号中断,它是SPI里的210号中断,GIC里的编号是(32+210)=242。

2. 怎么触发中断

可以通过devmem命令直接写GIC的PENDING寄存区。

在这里插入图片描述

GICD_ISPENDRn有多个寄存器,每个寄存器中每一位对应一个GIC中断,写入1就可以触发该中断。

写哪一个GICD_ISPENDRn寄存器?写哪一位?使用下列公式来确定:

在这里插入图片描述

查看内核设备树文件imx6ull.dtsi、stm32mp151.dtsi,可以知道:

  • IMX6ULL的GIC Distributor 地址是:0x00a01000
    在这里插入图片描述

  • STM32MP157的GIC Distributor 地址是:0xa0021000
    在这里插入图片描述

芯片SPI中断号GIC中断号n,bitGICD_ISPENDRn地址命令
IMX6LLL1221544,260xa01210devmem 0xa01210 32 0x4000000
1231554,270xa01210devmem 0xa01210 32 0x8000000
1241564,280xa01210devmem 0xa01210 32 0x10000000
1251574,290xa01210devmem 0xa01210 32 0x20000000
STM32MP1572102427,180xa002121cdevmem 0xa002121c 32 0x40000
2112437,190xa002121cdevmem 0xa002121c 32 0x80000
2122447,200xa002121cdevmem 0xa002121c 32 0x100000
2132457,210xa002121cdevmem 0xa002121c 32 0x200000

3. 上机实验

3.1 设置工具链
1. STM32MP157
export ARCH=arm
export CROSS_COMPILE=arm-buildroot-linux-gnueabihf-
export PATH=$PATH:/home/book/100ask_stm32mp157_pro-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/bin
2. IMX6ULL
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-
export PATH=$PATH:/home/book/100ask_imx6ull-sdk/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/bin
3.2 编译、替换设备树
1. STM32MP157
  • 修改arch/arm/boot/dts/stm32mp157c-100ask-512d-lcd-v1.dts,添加如下代码:

    / {
       virtual_intc: virtual_intc_100ask {
            compatible = "100ask,virtual_intc";
    
            interrupt-controller;
            #interrupt-cells = <2>;
    
            interrupt-parent = <&intc>;
            //upper_hwirq_base = <122>;  // imx6ull
            upper_hwirq_base = <210>;  // stm32mp157
        };
    
        gpio_keys_100ask {
            compatible = "100ask,gpio_key";
            interrupt-parent = <&virtual_intc>;
            interrupts = <0 IRQ_TYPE_LEVEL_HIGH>,
                         <1 IRQ_TYPE_LEVEL_HIGH>,
                         <2 IRQ_TYPE_LEVEL_HIGH>,
                         <3 IRQ_TYPE_LEVEL_HIGH>;
        };
    };
    
  • 编译设备树:
    在Ubuntu的STM32MP157内核目录下执行如下命令,
    得到设备树文件:arch/arm/boot/dts/stm32mp157c-100ask-512d-lcd-v1.dtb

    make dtbs
    
  • 复制到NFS目录:

    $ cp arch/arm/boot/dts/stm32mp157c-100ask-512d-lcd-v1.dtb ~/nfs_rootfs/
    
  • 开发板上挂载NFS文件系统

    • vmware使用NAT(假设windowsIP为192.168.1.100)

      [root@100ask:~]# mount -t nfs -o nolock,vers=3,port=2049,mountport=9999 
      192.168.1.100:/home/book/nfs_rootfs /mnt
      
    • vmware使用桥接,或者不使用vmware而是直接使用服务器:假设Ubuntu IP为192.168.1.137

      [root@100ask:~]#  mount -t nfs -o nolock,vers=3 192.168.1.137:/home/book/nfs_rootfs /mnt
      
  • 更新设备树

    [root@100ask:~]# mount  /dev/mmcblk2p2  /boot
    [root@100ask:~]# cp /mnt/stm32mp157c-100ask-512d-lcd-v1.dtb /boot
    [root@100ask:~]# sync
    
  • 重启开发板

2. IMX6ULL
  • 修改arch/arm/boot/dts/100ask_imx6ull-14x14.dts,添加如下代码:

    / {
       virtual_intc: virtual_intc_100ask {
            compatible = "100ask,virtual_intc";
    
            interrupt-controller;
            #interrupt-cells = <2>;
    
            interrupt-parent = <&intc>;
            upper_hwirq_base = <122>;  // imx6ull
            //upper_hwirq_base = <210>;  // stm32mp157
        };
    
        gpio_keys_100ask {
            compatible = "100ask,gpio_key";
            interrupt-parent = <&virtual_intc>;
            interrupts = <0 IRQ_TYPE_LEVEL_HIGH>,
                         <1 IRQ_TYPE_LEVEL_HIGH>,
                         <2 IRQ_TYPE_LEVEL_HIGH>,
                         <3 IRQ_TYPE_LEVEL_HIGH>;
        };
    
    };
    
  • 编译设备树:
    在Ubuntu的IMX6ULL内核目录下执行如下命令,
    得到设备树文件:arch/arm/boot/dts/100ask_imx6ull-14x14.dtb

    make dtbs
    
  • 复制到NFS目录:

    $ cp arch/arm/boot/dts/100ask_imx6ull-14x14.dtb ~/nfs_rootfs/
    
  • 开发板上挂载NFS文件系统

    • vmware使用NAT(假设windowsIP为192.168.1.100)

      [root@100ask:~]# mount -t nfs -o nolock,vers=3,port=2049,mountport=9999 
      192.168.1.100:/home/book/nfs_rootfs /mnt
      
    • vmware使用桥接,或者不使用vmware而是直接使用服务器:假设Ubuntu IP为192.168.1.137

      [root@100ask:~]#  mount -t nfs -o nolock,vers=3 192.168.1.137:/home/book/nfs_rootfs /mnt
      
    • 更新设备树

      [root@100ask:~]# cp /mnt/100ask_imx6ull-14x14.dtb /boot
      [root@100ask:~]# sync
      
  • 重启开发板

3.3 编译、安装驱动程序
  • 编译:

    • 在Ubuntu上
    • 修改07_virtual_int_controller_hierarchy_ok中的Makefile,指定内核路径KERN_DIR,在执行make命令即可。
  • 安装:

    • 在开发板上

    • 挂载NFS,复制文件,insmod,类似如下命令:

      mount -t nfs -o nolock,vers=3 192.168.1.137:/home/book/nfs_rootfs /mnt
      // 对于IMX6ULL,想看到驱动打印信息,需要先执行
      echo "7 4 1 7" > /proc/sys/kernel/printk
      
      insmod -f /mnt/virtual_int_controller.ko
      // 安装virtual_int_controller之后即可进入/sys/kernel/irq目录查看分配的中断号
      
      insmod -f /mnt/gpio_key_drv.ko
      cat /proc/interrupts
      
      // 触发中断
      // 对于IMX6ULL
      devmem 0xa01210 32 0x4000000
      devmem 0xa01210 32 0x8000000
      devmem 0xa01210 32 0x10000000
      devmem 0xa01210 32 0x20000000
      
      // 对于stm32mp157
      devmem 0xa002121c 32 0x40000 
      devmem 0xa002121c 32 0x80000
      devmem 0xa002121c 32 0x100000  // 它不能触发中断,可能是被占用了
      devmem 0xa002121c 32 0x200000
      
  • 观察内核打印的信息


百问网技术交流群,百万嵌入式工程师聚集地:
https://www.100ask.net/page/2248041

百问网技术论坛:
http://bbs.100ask.net/

百问网嵌入式视频官网:
https://www.100ask.net/index

百问网开发板:
淘宝:https://100ask.taobao.com/
天猫:https://weidongshan.tmall.com/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值