在linux中,内核不会直接操作物理地址,而是使用虚拟地址,这就需要使用一个内置函数,进行从物理地址到虚拟地址的映射:
优点:1,安全,应用层访问的是虚拟内存,避免真实硬件地址泄露
2.随时释放,提高利用率
ioremap()为转化为虚拟内存的函数,第一个参数是基地址,第二个是大小。
首先定义物理与虚拟地址:
//定义物理地址 #define CCM_CCGR1_base (0x020C406C) #define SW_MUX_GPIO1_IO03_base (0x020E0068) #define SW_PAD_GPIO1_IO03_base (0x020E02F4) #define GPIO1_DR_base (0x0209C000) #define GPIO1_GDIR_base (0x0209C004) //映射后的虚拟指针 static void __iomem *IMX6U_CCM_CCGR1; static void __iomem *SW_MUX_GPIO1_IO03; static void __iomem *SW_PAD_GPIO1_IO03; static void __iomem *GPIO1_DR; static void __iomem *GPIO1_GDIR;
初始化地址映射并写入:
//初始化LED灯 地址映射
IMX6U_CCM_CCGR1=ioremap(CCM_CCGR1_base,4);//CCM--->时钟相关
SW_MUX_GPIO1_IO03=ioremap(SW_MUX_GPIO1_IO03_base,4);//-->MUX,表示复用
SW_PAD_GPIO1_IO03=ioremap(SW_PAD_GPIO1_IO03_base,4);//---->pad表示电气属性
GPIO1_DR=ioremap(GPIO1_DR_base,4);//dr输出高低电平
GPIO1_GDIR=ioremap(GPIO1_GDIR_base,4);//方向,输入or输出。
//初始化
temp=readl(IMX6U_CCM_CCGR1);
temp &=~(3 << 26);//清楚配置
temp |=3 << 26;
writel(temp,IMX6U_CCM_CCGR1);
writel(0x5,SW_MUX_GPIO1_IO03);//复用
writel(0x10B0,SW_PAD_GPIO1_IO03);
temp=readl(GPIO1_GDIR);
temp |=1 << 3;//设置电气属性,设置为输出
writel(temp,GPIO1_GDIR);
temp=readl(GPIO1_DR);
if(temp==0){
temp &=~(1 << 3);//设置电气属性,设置为输出
writel(temp,GPIO1_DR);
}



