寄存器
在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);
}