• 在 IMX6ULL QEMU 虚拟开发板上,我们为它设计了 2 个 按键
    • image.png
    • 只需修改框架的硬件相关代码 : board_100ask_imx6ull-qemu.c ```c /* 涉及的寄存器挺多,一个一个去执行 ioremap 效率太低。
      • 先定义结构体,然后对结构体指针进行 ioremap。
      • IOMUXC GPIO / struct iomux { volatile unsigned int unnames[23]; volatile unsigned int IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO00; / offset 0x5c */ volatile unsigned int IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO01; volatile unsigned int IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO02; volatile unsigned int IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03; volatile unsigned int IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO04; volatile unsigned int IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO05; volatile unsigned int IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO06; volatile unsigned int IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO07; volatile unsigned int IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO08; volatile unsigned int IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO09; volatile unsigned int IOMUXC_SW_MUX_CTL_PAD_UART1_TX_DATA; volatile unsigned int IOMUXC_SW_MUX_CTL_PAD_UART1_RX_DATA; volatile unsigned int IOMUXC_SW_MUX_CTL_PAD_UART1_CTS_B; };

    struct imx6ull_gpio { volatile unsigned int dr; volatile unsigned int gdir; volatile unsigned int psr; volatile unsigned int icr1; volatile unsigned int icr2; volatile unsigned int imr; volatile unsigned int isr; volatile unsigned int edge_sel; };

    / enable GPIO1,GPIO5 / static volatile unsigned int *CCM_CCGR1;

    / set GPIO5_IO03 as GPIO / static volatile unsigned int *IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER1;

    static struct iomux *iomux;

    static struct imx6ull_gpio gpio1; static struct imx6ull_gpio gpio5;

    static void board_imx6ull_button_init (int which) / 初始化button, which-哪个button /
    { if (!CCM_CCGR1) { CCM_CCGR1 = ioremap(0x20C406C, 4); IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER1 = ioremap(0x229000C, 4);

    1. iomux = ioremap(0x20e0000, sizeof(struct iomux));
    2. gpio1 = ioremap(0x209C000, sizeof(struct imx6ull_gpio));
    3. gpio5 = ioremap(0x20AC000, sizeof(struct imx6ull_gpio));
    4. }
    5. if (which == 0)
    6. {
    7. /* 1. enable GPIO5
    8. * CG15, b[31:30] = 0b11
    9. */
    10. *CCM_CCGR1 |= (3<<30);
    11. /* 2. set GPIO5_IO01 as GPIO
    12. * MUX_MODE, b[3:0] = 0b101
    13. */
    14. *IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER1 = 5;
    15. /* 3. set GPIO5_IO01 as input
    16. * GPIO5 GDIR, b[1] = 0b0
    17. */
    18. gpio5->gdir &= ~(1<<1);
    19. }
    20. else if(which == 1)
    21. {
    22. /* 1. enable GPIO1
    23. * CG13, b[27:26] = 0b11
    24. */
    25. *CCM_CCGR1 |= (3<<26);
    26. /* 2. set GPIO1_IO18 as GPIO
    27. * MUX_MODE, b[3:0] = 0b101
    28. */
    29. iomux->IOMUXC_SW_MUX_CTL_PAD_UART1_CTS_B = 5;
    30. /* 3. set GPIO1_IO18 as input
    31. * GPIO1 GDIR, b[18] = 0b0
    32. */
    33. gpio1->gdir &= ~(1<<18);
    34. }

    }

    static int boardimx6ullbuttonread (int which) / 读button, which-哪个 / { //printk(“%s %s line %d, button %d, 0x%x\n”, FILE, _FUNCTION, __LINE, which, *GPIO1_DATAIN); if (which == 0) return (gpio5->psr & (1<<1)) ? 1 : 0; else return (gpio1->psr & (1<<18)) ? 1 : 0; }

    static struct button_operations my_buttons_ops = { .count = 2, .init = board_imx6ull_button_init, .read = board_imx6ull_button_read, };

    int board_imx6ull_button_drv_init(void) { register_button_operations(&my_buttons_ops); return 0; }

    void board_imx6ull_button_drv_exit(void) { unregister_button_operations(); }

    module_init(board_imx6ull_button_drv_init); module_exit(board_imx6ull_button_drv_exit);

    MODULE_LICENSE(“GPL”); ```

    • 先启动 IMX6ULL QEMU 模拟器,挂载 NFS 文件系统

    运行 QEMU 时,
    QEMU 内部为主机虚拟出一个网卡, IP 为 10.0.2.2,
    IMX6ULL 有一个网卡, IP 为 10.0.2.15,
    它连接到主机的虚拟网卡。
    这样 IMX6ULL 就可以通过 10.0.2.2 去访问 Ubuntu 了。