Linux学习一 I/O内存分配与I/O访问

一:有的欧洲国家语言用的字母比26个多,占用了ASCII码表中&和其它符号的位置,所以规定了一些操作符的特殊表示方法。

C++中有些用的二联符和三联符


??=  表示 #    ??)   表示]      ??(   表示[
??!  表示 |     ??/   表示\      ??-   表示~
??>  表示 }     ??<   表示(     ??'   表示^

<%  表示 {      and    表示&&    and_eq 表示&=
%>  表示 }      bitor  表示|     or_eq  表示|=
<:  表示 [      or     表示||    xor_eq 表示^=
:>  表示 ]      xor    表示^     not    表示!
%:  表示 #      compl  表示~     not_eq 表示!=

%:%:表示 ##     bitand 表示&


二:Linux的轮询操作;Linux在驱动层提供了一种非常聪明的方法,就是在驱动层的file_operation中实现poll方法。 poll方法由操作系统每隔一段时间调用一次,当poll 返回1时, 表示可以操作;

使用非阻塞的I/O 的应用程序通常会使用select () 和 poll ()实现轮询操作。 用于查询设备的状态。


三:Linux设备驱动之内存分配与I/O 访问

 几乎每一种外设都通过读写设备上的寄存器来控制或数据操作; 外设寄存器也称为 I/O端口; 通常包括控制寄存器, 状态寄存器, 数据寄存器 3大类;CPU对外设I/O进行编址有两种方式: I/O映射方式,  内存映射方式;  arm9处理器只实现了一个屋里地址空间,而CPU将外设的I/O 物理地址映射到CPU的单一物理地址空间,因此成为内存的一部分,这是CPU就像访问内存一样访问外设的I/O 端口,这就是所谓的内存映射方式;

Linux中,我们将基于I/O映射方式的或基于内存映射方式的I/O端口成为  I/O 区域, 也就是我们所说的 I/O资源;

当编写的程序在CPU中运行时就成为一个系统进程,会涉及到5种不同的数据段;代码段数据段,就是存放程序静态分配非变量和全局变量;BSS段,BSS段包含程序中卫初始化的全局变量,BSS段在内存中全部置零;,存放进程运行中被动态分配的内存段;,是用户存放程序临时创建的局部变量;

四:操作I/O内存

1、申请I/O内存,必须先非配,在<linux/ioport.h>中定义, request_mem_region()函数分配一个开始于start 的len字节的i/o内存区;成功返回非null;

struct resource *request_men_region(unsigned long start, unsigned long len, char *name);

 2、映射,在访问i/o内存之前,分配i/o内存并不是唯一要求的步骤,还必须保证内核可存取该i/o 内存; ioremap()函数将i/o内存区映射到虚拟地址;参数phys_addr为要映射到i/o内存起始地址,size为要映射的i/o大小;

void *ioremap(unsigned long phys_addr, unsigned long size);

3、方位i/o内存;ioremap返回的地址不可以直接解引用,应当使用内核提供的访问函数,在<asm/io.h>文件中,I/O内存读函数的参数addr 应该是从ioremap获得的地址(可能包含一个偏移地址),返回值是从给定的I/O 内存读取到的值;

unsigned int ioread8(void *addr);

unsigned int ioread16(void *addr);

unsigned int ioread32(void *addr);

I/O内存写函数,参数addr同I/O内存读函数,参数value为要写的值;

void iowrite8(u8 value, void *addr);

void iowrite16(u16 value, void *addr);

void iowrite32(u32 value, void *addr);

以下这些函数将一系列值读取或写到一个给定的I/O内存地址,从给定的buf读或写 count个值到给定的addr。

void ioread8_rep(void *addr, void *buf, unsigned long count);

void ioread16_rep(void *addr, void *buf, unsigned long count);

void ioread32_rep(void *addr, void *buf, unsigned long count);

void iowrite8_rep(void *addr, const void *buf, unsigned long count);

void iowrite16_rep(void *addr, const void *buf, unsigned long count);

void iowrite32_rep(void *addr, const void *buf, unsigned long count);

需要操作一块I/O地址时,课使用夏磊函数

void memset_io(void *addr, u8 value, unsigned int count);

void memcpy_fromio(void *dest, void *source, unsigned int count);

void memcpy_toio(void *dest, void *source, unsigned int count);

4、释放I/O内存步骤

void iounmap(void *addr);

void release_mem_region(unsigned long start, unsigned long len);


不管是I/O内存还是I/O端口,Linux2.6版本内核提供了一个ioport_map函数;重新映射count个 I/O端口,使他们看起来像I/O内存,驱动在ioport_map返回的地址上使用ioread8和同类函数;


























评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值