Linux驱动技术之一:访问I/O内存

arm是对内存空间和io空间统一编址的,所以,通过读写sfr来控制硬件也就变成了通过读写相应的sfr地址来控制硬件。这部分地址也被称为i/o内存。x86中对i/o地址和内存地址是分开编址的,这样的io地址被称为i/o端口。本文只讨论io内存的访问
io内存访问流程
我们知道,为了管理最重要的系统资源并让物理地址对进程透明,linux使用了内存映射机制,就是一个进程如果想访问一个物理内存地址(eg.sfr地址),那么首先就是将其映射成虚拟地址。
io内存申请/归还
linux提供一组函数用于申请和释放io内存的范围,这两个api在访问io内存的时候并不是必须的,但是建议使用,他们可以检查申请的资源是否可用,增加io访问的安全性,如果可用则申请成功,并标志为已用,其他驱动想在这个进程归还资源前申请就会失败。
request_mem_region()宏函数向内存申请n个内存地址,这些地址从first开始,len长,name表示设备的名称,成功返回非null失败返回null。
/** * request_mem_region - create a new busy resource region * @start: resource start address * @n: resource region size * @name: reserving caller's id string */struct resource * request_mem_region(resource_size_t start, resource_size_t n,const char *name)
release_mem_region()宏函数顾名思义就是将request_mem_region()申请的io内存资源归还给内核以便其他进程也可以访问该io内存。
/** * release_mem_region - release a previously reserved resource region * @start: resource start address * @n: resource region size */void release_mem_region(resource_size_t start, resource_size_t n,const char *name)
io内存映射/去映射
申请了io资源,接下来就是进行物理地址到虚拟地址的映射。内核提供的api如下
static inline void __iomem *ioremap(unsigned long port, unsigned long size)
static inline void iounmap(volatile void __iomem *addr)
io内存访问api
arm的sfr是32bit的,我们在经过了ioremap之后其实就可以直接通过强制类型转换来读取获取的虚拟地址,但是这种方法不够安全,一不小心就会读错位,为此,内核同样提供的标准的api来读写io内存,不但代码的安全性更高,可读性也得到了改善。
读io
unsigned int ioread8(void *addr)unsigned int ioread16(void *addr)unsigned int ioread32(void *addr)
写io
void iowrite8(u8 val,void *addr)void iowrite16(u8 val,void *addr)void iowrite32(u8 val,void *addr)
读一串io内存
void ioread8_rep(void *addr,void *buf,unsigned long len)void ioread16_rep(void *addr,void *buf,unsigned long len)void ioread32_rep(void *addr,void *buf,unsigned long len)
写一串io内存
void iowrite8_rep(void *addr,const void *buf,unsigned long len)void iowrite16_rep(void *addr,const void *buf,unsigned long len)void iowrite32_rep(void *addr,const void *buf,unsigned long len)
复制io内存
void memcpy_fromio(void *dest,void *source,unsigned long len)void memcpy_toio(void *dest,void *source,unsigned long len)
设置io内存
void memset_io(void *addr,u8 value,unsigned int len)

物联网和大数据的连接谁将受益?
华为通知将下修 Mate40 出货 砍单幅度达 30%
广汽本田首款纯电动轿车EA6重磅亮相广州车展
艾迈斯半导体发布业内首个安卓系统后置3D dToF解决方案
动力电池行业集中度的提高,掀起了一场席卷产业链的多骨诺米牌效应
Linux驱动技术之一:访问I/O内存
现代汽车与软银集团正式收购波士顿动力
50000台哪吒汽车被百家城市合伙人签约
如何提高太阳能发电的供电效率
科友提前布局:SiC行业下半场是8吋时代
苹果发布紫色iPhone12 色彩缤纷的苹果春季发布会
优特电源宣布BLD系列320W恒压产品系列获得DALI-2认证 兼容性得到了提升
特朗普签署国防授权法案,禁止只用华为和中兴的零部件
场效应管厂商:华昕科技(上海)有限公司简介
摩托罗拉Edge+已通过认证该机支持5G网络并搭载了1亿像素摄像头
多级放大器噪声系数的计算
针对固件安全、数据安全、数据销毁做了安全设计的硬盘来解决安全问题
跨平台编译工具cmake的简单使用
人工智能SOTA什么意思
华为Nova2 Plus魔镜版、小米6亮银版今日同步发售,你准备抢购哪家?