一:有的歐洲國家語言用的字母比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和同類函數;