linux驱动(点灯篇)

寄存器

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

你可能感兴趣的:(linux)