位操作

清零

//假设为第三位
int val &= ~(1<<3); 

//假设为第三、四位
int val &= ~(3<<3);

置一

int val |=(1<<3);

切换

int val ^= (1<<3);// 异或操作:0变1,1变0

获取值

int val = readl(GPIO1_DR);
val = (val>>3)&0x01;

对寄存器读写数据

在修改寄存器数据时,如果是对位进行操作(其他位用于其他功能),则必须要进行先读后修改

否则会影响其他位

#include <linux/io.h>

void writel(unsigned char data , unsigned int addr)

unsigned char readl(unsigned int addr)

//e.g.
int val = readl(GPIO1_DR);
val |= (1<<3);
writel(val,GPIO1_DR);

内存映射

从芯片手册得到的是物理地址,需要内存映射为虚拟地址后才能使用

/* --------------------------------- CCM寄存器 --------------------------------- */
#define CCM_CCGR1_BASE                        0x20C406C

/* ------------------------------- IO复用控制寄存器 ----------------------------- */
#define IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03_BASE 0x20E0068
#define IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03_BASE 0x20E02F4

/* --------------------------------- GPIO寄存器 -------------------------------- */
#define GPIO1_DR_BASE                         0x209C000 // 写
#define GPIO1_GDIR_BASE                       0x209C004
#define GPIO1_PSR_BASE                        0x209C008 // 读

/* ------------------ 内存映射后的虚拟地址指针(入口函数中进行内存映射) --------------- */
static void __iomem *CCM_CCGR1;
static void __iomem *MUX_CTL_PAD_GPIO1_IO03;
static void __iomem *PAD_CTL_PAD_GPIO1_IO03;
static void __iomem *GPIO1_DR;
static void __iomem *GPIO1_GDIR;
static void __iomem *GPIO1_PSR;


chr_dev_init(void)
{
        //...
        
    /* ---------------------------------- 内存映射 --------------------------------- */
    CCM_CCGR1 = ioremap(CCM_CCGR1_BASE, 4);
    MUX_CTL_PAD_GPIO1_IO03 = ioremap(IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03_BASE, 4);
    PAD_CTL_PAD_GPIO1_IO03 = ioremap(IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03_BASE, 4);
    GPIO1_DR = ioremap(GPIO1_DR_BASE, 4);
    GPIO1_GDIR = ioremap(GPIO1_GDIR_BASE, 4);
    GPIO1_PSR = ioremap(GPIO1_PSR_BASE, 4);
    
    //...
}

chr_dev_exit(void)
{
        //...
        
    /* --------------------------------- 取消内存映射 -------------------------------- */
    iounmap(CCM_CCGR1);
    iounmap(MUX_CTL_PAD_GPIO1_IO03);
    iounmap(PAD_CTL_PAD_GPIO1_IO03);
    iounmap(GPIO1_DR);
    iounmap(GPIO1_GDIR);
    iounmap(GPIO1_PSR);
    
    //...
}