Linux驱动操作地址(寄存器)的一些方式

简介: Linux驱动操作地址(寄存器)的一些方式

1.对绝对地址赋值操作

对绝对地址0x100000赋值操作

*(unsigned int *)0x100000=1234;

让程序跳转到绝对地址是0x100000去执行

*((void  (*) () )0x100000) ();

首先要将0x100000强制转换维函数指针,即:

(void  (*) () )0x100000

然后再调用它

*((void  (*) () )0x100000) ();

使用typedef可以更直观

typedef void(*) () voidFuncPtr;
*((voidFuncPtr)0x100000) ();

2. ioremap

2.1 void __iomem *地址

/* 寄存器物理地址 */
#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;
/* 寄存器地址映射 */
    IMX6U_CCM_CCGR1 = ioremap(CCM_CCGR1_BASE, 4);
    SW_MUX_GPIO1_IO03 = ioremap(SW_MUX_GPIO1_IO03_BASE, 4);
    SW_PAD_GPIO1_IO03 = ioremap(SW_PAD_GPIO1_IO03_BASE, 4);
    GPIO1_DR = ioremap(GPIO1_DR_BASE, 4);
    GPIO1_GDIR = ioremap(GPIO1_GDIR_BASE, 4);
int retvalue = 0;
    u32 val = 0;
    /*、使能GPIO1时钟 */
    val = readl(IMX6U_CCM_CCGR1);
    val &= ~(3 << 26);  /* 清楚以前的设置 */
    val |= (3 << 26);   /* 设置新值 */
    writel(val, IMX6U_CCM_CCGR1);
    /*设置GPIO1_IO03的复用功能,将其复用为
     *    GPIO1_IO03,最后设置IO属性。
     */
    writel(5, SW_MUX_GPIO1_IO03);
    /*寄存器SW_PAD_GPIO1_IO03设置IO属性
     *bit 16:0 HYS关闭
     *bit [15:14]: 00 默认下拉
     *bit [13]: 0 kepper功能
     *bit [12]: 1 pull/keeper使能
     *bit [11]: 0 关闭开路输出
     *bit [7:6]: 10 速度100Mhz
     *bit [5:3]: 110 R0/6驱动能力
     *bit [0]: 0 低转换率
     */
    writel(0x10B0, SW_PAD_GPIO1_IO03);
    /* 设置GPIO1_IO03为输出功能 */
    val = readl(GPIO1_GDIR);
    val &= ~(1 << 3);   /* 清除以前的设置 */
    val |= (1 << 3);    /* 设置为输出 */
    writel(val, GPIO1_GDIR);
    /* 默认关闭LED */
    val = readl(GPIO1_DR);
    val |= (1 << 3);    
    writel(val, GPIO1_DR);

2.2 volatile unsigned int *地址

static volatile unsigned int *CCM_CCGR1                       ;
static volatile unsigned int *IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03;
static volatile unsigned int *GPIO1_GDIR                      ;
static volatile unsigned int *GPIO1_DR                        ;
CCM_CCGR1                               = ioremap(0x20C406C, 4);
IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03        = ioremap(0x20E0068, 4);
GPIO1_GDIR                              = ioremap(0x0209C000 + 0x4, 4);
GPIO1_DR                                = ioremap(0x0209C000 + 0, 4);
/* GPIO1_IO03 */
/* a. 使能GPIO1
 * set CCM to enable GPIO1
 * CCM_CCGR1[CG13] 0x20C406C
 * bit[27:26] = 0b11
 */
*CCM_CCGR1 |= (3<<26);
/* b. 设置GPIO1_IO03用于GPIO
 * set IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03
 *      to configure GPIO1_IO03 as GPIO
 * IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03  0x20E0068
 * bit[3:0] = 0b0101 alt5
 */
val = *IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03;
val &= ~(0xf);
val |= (5);
*IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03 = val;
/* c. 设置GPIO1_IO03作为output引脚
 * set GPIO1_GDIR to configure GPIO1_IO03 as output
 * GPIO1_GDIR  0x0209C000 + 0x4
 * bit[3] = 0b1
 */
*GPIO1_GDIR |= (1<<3);

2.3 struct+ioremap

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 GPIO4 */
static volatile unsigned int *CCM_CCGR3; 
/* enable GPIO5 */
static volatile unsigned int *CCM_CCGR1; 
/* set GPIO5_IO03 as GPIO */
static volatile unsigned int *IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER1;
/* set GPIO4_IO14 as GPIO */
static volatile unsigned int *IOMUXC_SW_MUX_CTL_PAD_NAND_CE1_B;
static struct iomux *iomux;
static struct imx6ull_gpio *gpio4;
static struct imx6ull_gpio *gpio5;
CCM_CCGR1 = ioremap(0x20C406C, 4);
CCM_CCGR3 = ioremap(0x20C4074, 4);
IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER1 = ioremap(0x229000C, 4);
IOMUXC_SW_MUX_CTL_PAD_NAND_CE1_B        = ioremap(0x20E01B0, 4);
iomux = ioremap(0x20e0000, sizeof(struct iomux));
gpio4 = ioremap(0x020A8000, 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_IO03 as GPIO 
         * MUX_MODE, b[3:0] = 0b101
         */
        *IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3 = 5;
        /* 3. set GPIO5_IO03 as output 
         * GPIO5 GDIR, b[3] = 0b1
         */
        gpio5->gdir |= (1<<3);
    }
    else if(which == 1)
    {
        /* 1. enable GPIO1 
         * CG13, b[27:26] = 0b11
         */
        *CCM_CCGR1 |= (3<<26);
        /* 2. set GPIO1_IO03 as GPIO 
         * MUX_MODE, b[3:0] = 0b101
         */
        iomux->IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03 = 5;
        /* 3. set GPIO1_IO03 as output 
         * GPIO1 GDIR, b[3] = 0b1
         */
        gpio1->gdir |= (1<<3);
    }
    else if(which == 2)
    {
        /* 1. enable GPIO1 
         * CG13, b[27:26] = 0b11
         */
        *CCM_CCGR1 |= (3<<26);
        /* 2. set GPIO1_IO05 as GPIO 
         * MUX_MODE, b[3:0] = 0b101
         */
        iomux->IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO05 = 5;
        /* 3. set GPIO1_IO05 as output 
         * GPIO1 GDIR, b[5] = 0b1
         */
        gpio1->gdir |= (1<<5);
    }
    else if(which == 3)
    {
        /* 1. enable GPIO1 
         * CG13, b[27:26] = 0b11
         */
        *CCM_CCGR1 |= (3<<26);
        /* 2. set GPIO1_IO06 as GPIO 
         * MUX_MODE, b[3:0] = 0b101
         */
        iomux->IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO06 = 5;
        /* 3. set GPIO1_IO06 as output 
         * GPIO1 GDIR, b[6] = 0b1
         */
        gpio1->gdir |= (1<<6);
    }
   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 GPIO4 
         * CG6, b[13:12] = 0b11
         */
        *CCM_CCGR3 |= (3<<12);
        /* 2. set GPIO4_IO14 as GPIO 
         * MUX_MODE, b[3:0] = 0b101
         */
        IOMUXC_SW_MUX_CTL_PAD_NAND_CE1_B = 5;
        /* 3. set GPIO4_IO14 as input 
         * GPIO4 GDIR, b[14] = 0b0
         */
        gpio4->gdir &= ~(1<<14);
    }


目录
相关文章
|
1天前
|
存储 算法 Linux
【Linux】程序地址空间 -- 详解 & Linux 2.6 内核进程调度队列 -- 了解
【Linux】程序地址空间 -- 详解 & Linux 2.6 内核进程调度队列 -- 了解
|
8天前
|
分布式计算 Hadoop Linux
实验: 熟悉常用的Linux操作和Hadoop操作
实验: 熟悉常用的Linux操作和Hadoop操作
12 2
|
8天前
|
Linux 芯片 Ubuntu
Linux驱动入门 —— 利用引脚号操作GPIO进行LED点灯
Linux驱动入门 —— 利用引脚号操作GPIO进行LED点灯
|
8天前
|
Ubuntu Linux
Linux驱动入门 —— 利用寄存器操作GPIO进行LED点灯-2
Linux驱动入门 —— 利用寄存器操作GPIO进行LED点灯
Linux驱动入门 —— 利用寄存器操作GPIO进行LED点灯-2
|
8天前
|
Linux 芯片
Linux驱动入门 —— 利用寄存器操作GPIO进行LED点灯-1
Linux驱动入门 —— 利用寄存器操作GPIO进行LED点灯
Linux驱动入门 —— 利用寄存器操作GPIO进行LED点灯-1
|
8天前
|
Linux C语言 Ubuntu
Linux驱动入门——编写第一个驱动
Linux驱动入门——编写第一个驱动
Linux驱动入门——编写第一个驱动
|
8天前
|
存储 Linux C++
linux信号量与PV操作知识点总结
linux信号量与PV操作知识点总结
|
8天前
|
存储 算法 Linux
【Linux】线程的内核级理解&&详谈页表以及虚拟地址到物理地址之间的转化
【Linux】线程的内核级理解&&详谈页表以及虚拟地址到物理地址之间的转化
|
8天前
|
存储 Linux
Redhat Enterprise Linux磁带机简单操作
Redhat Enterprise Linux磁带机简单操作
15 2
|
8天前
|
存储 安全 Linux
Linux:进程地址空间
Linux:进程地址空间
26 10

热门文章

最新文章