linux驱动中读写硬件寄存器(例如__raw_writel)

设备通常会提供一组寄存器来控制设备、读写设备和获取设备状态,即控制寄存器、数据寄存器和状态寄存器。这些寄存器可能位于I/O空间,也可能位于内存空间。当位于I/O空间时,通常被称为I/O端口,位于内存空间时,对应的内存空间被称为I/O内存。

再内核访问I/O内存前,需要将设备所处的物理地址映射到虚拟地址

 __iomem源码位置:include/linux/compiler.h

# define __force    __attribute__((force)) //变量可以进行强制转换
# define __nocast   __attribute__((nocast))

/*指针地址必须在设备地址空间,__iomem是个IO map的问题,根据系统的具体情况,
把寄存器映射到虚拟地址的特定位置,这样,访问寄存器就可以像访问普通内存一样简单方便
主要是用于编译器的检查,检查地址空间的有效性*/
# define __iomem    __attribute__((noderef, address_space(2)))     // 
# define __acquires(x)  __attribute__((context(x,0,1)))
# define __releases(x)  __attribute__((context(x,1,0)))

 

static inline u8 __raw_readb(const volatile void __iomem *addr)
{
    return *(__force volatile u8 *)addr;
}

static inline u16 __raw_readw(const volatile void __iomem *addr)
{
    return *(__force volatile u16 *)addr;
}

static inline u32 __raw_readl(const volatile void __iomem *addr)
{
    return *(__force volatile u32 *)addr;
}


static inline void __raw_writeb(u8 b, volatile void __iomem *addr)
{
    *(__force volatile u8 *)addr = b;
}


    static inline void __raw_writew(u16 w, volatile void __iomem *addr)
{
    *(__force volatile u16 *)addr = w;
}


static inline void __raw_writel(u32 l, volatile void __iomem *addr)
{
    *(__force volatile u32 *)addr = l;
}


static inline u8 __readb(const volatile void __iomem *addr)
{
    return *(__force volatile u8 *)addr;
}


static inline u16 __readw(const volatile void __iomem *addr)
{
    return flip_word(*(__force volatile u16 *)addr);
}


static inline u32 __readl(const volatile void __iomem *addr)
{
return flip_dword(*(__force volatile u32 *)addr);
}


static inline void __writeb(u8 b, volatile void __iomem *addr)
{
    *(__force volatile u8 *)addr = b;
}


static inline void __writew(u16 w, volatile void __iomem *addr)
{
    *(__force volatile u16 *)addr = flip_word(w);
}


static inline void __writel(u32 l, volatile void __iomem *addr)
{
    *(__force volatile u32 *)addr = flip_dword(l);
}


#define readb(__addr) __readb(__addr)
#define readw(__addr) __readw(__addr)
#define readl(__addr) __readl(__addr)
#define readb_relaxed(__addr) readb(__addr)
#define readw_relaxed(__addr) readw(__addr)
#define readl_relaxed(__addr) readl(__addr)


#define writeb(__b, __addr) __writeb((__b),(__addr))
#define writew(__w, __addr) __writew((__w),(__addr))
#define writel(__l, __addr) __writel((__l),(__addr))
 

writel() 往内存映射的 I/O 空间上写数据,wirtel()  I/O 上写入 32 位数据 (4字节)

其他的都是类似用法。

 

 

 

 

你可能感兴趣的:(linux,驱动)