linux内核中linux中readl()和writel()函数---用于读写寄存器

现在在一些arm高级一点的处理器上配置寄存器的方式其实就是直接访问寄存器地址,可以简单的写成*(uint32_t *)(addr) = val。也可以通过readl()函数和writel()函数对一些地址进行读写。writel和readl,这两个函数实现在操作系统层,有内存保护的情况下,往一个寄存器或者内存地址写一个数据或者读数据。

1. writel()函数
原型

#include <linux/io.h>
void writel(unsigned char data , unsigned int addr ) 

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

参数
data:要写入的一个字节的数据.
addr:32位I/O 地址。

在内核中的实现
在kernel/io.c有

void writel(u32 b, volatile void __iomem *addr)
{
    __raw_writel(b, addr);
    mb();
}

这样一个writel函数的作用是向一个地址上写一个值,往下继续跟踪代码:__raw_writel(b, addr);(发现在同目录下)

void __raw_writel(u32 b, volatile void __iomem *addr)
{
    IO_CONCAT(__IO_PREFIX,writel)(b, addr);
}

再往下跟踪 IO_CONCAT,在对应的io.h中的定义如下:

#define IO_CONCAT(a,b)  _IO_CONCAT(a,b)
#define _IO_CONCAT(a,b) a ## _ ## b

跟踪__IO_PREFIX 定义如下

#undef __IO_PREFIX
#define __IO_PREFIX     apecs

对于apsec,看看以下代码段(linux-2.6.28-rc4)
/include/asm/core_apecs.h

#undef __IO_PREFIX
#define __IO_PREFIX             apecs
#define apecs_trivial_io_bw     0
#define apecs_trivial_io_lq     0
#define apecs_trivial_rw_bw     2
#define apecs_trivial_rw_lq     1
#define apecs_trivial_iounmap   1
#include <asm/io_trivial.h>

前往include/asm/io_trivial.h

__EXTERN_INLINE void
IO_CONCAT(__IO_PREFIX,writel)(u32 b, volatile void __iomem *a)
{
       *(volatile u32 __force *)a = b;
} 

就是最终通过*(volatile u32 __force *)a = b;来写入数据的。

如果在没有os,没有mmu的情况下,当开发板裸跑的时候,我们只需要一句话就一切ok:

*(unsigned long *)addr = value)

首先强制类型转换为 unsigned char * 类型指针,再取这个地址的值, 最后赋值。

2. readl()函数
原型

#include <linux/io.h>
unsigned char readl(unsigned int addr )

功能
readl() 函数从内存映射的 I/O 空间读取32位(4字节)数据。

参数
addr :I/O 地址。
返回值 : 从 I/O 空间读取的数值。

其他读写函数:

unsigned char readb (unsigned int addr )   //读1字节
unsigned short readw (unsigned int addr )   //读2字节
unsigned int readl (unsigned int addr )    //读四字节

void writeb (unsigned char data, unsigned short addr)  //写1字节
void writew (unsigned short data, unsigned short addr)  //写2字节
void writel (unsigned int data, unsigned short addr )  //写4字节
  • 6
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值