- 在 IMX6ULL QEMU 虚拟开发板上,我们为它设计了 2 个 按键
- 只需修改框架的硬件相关代码 : 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);
iomux = ioremap(0x20e0000, sizeof(struct iomux));
gpio1 = ioremap(0x209C000, sizeof(struct imx6ull_gpio));
gpio5 = ioremap(0x20AC000, sizeof(struct imx6ull_gpio));
}
if (which == 0)
{
/* 1. enable GPIO5
* CG15, b[31:30] = 0b11
*/
*CCM_CCGR1 |= (3<<30);
/* 2. set GPIO5_IO01 as GPIO
* MUX_MODE, b[3:0] = 0b101
*/
*IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER1 = 5;
/* 3. set GPIO5_IO01 as input
* GPIO5 GDIR, b[1] = 0b0
*/
gpio5->gdir &= ~(1<<1);
}
else if(which == 1)
{
/* 1. enable GPIO1
* CG13, b[27:26] = 0b11
*/
*CCM_CCGR1 |= (3<<26);
/* 2. set GPIO1_IO18 as GPIO
* MUX_MODE, b[3:0] = 0b101
*/
iomux->IOMUXC_SW_MUX_CTL_PAD_UART1_CTS_B = 5;
/* 3. set GPIO1_IO18 as input
* GPIO1 GDIR, b[18] = 0b0
*/
gpio1->gdir &= ~(1<<18);
}
}
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 了。