linux匯流排驅動程序
1. vxworks驅動跟linux驅動有什麼區別匯流排驅動怎麼寫
vxworks和linux是不同的兩個操作系統,類似的還有wince。
首先,vxworks和linux系統內部很多實現都不一樣,導致驅動層實現也不一樣。
由於Linux操作系統和Linux引導裝載器在結構上的分離,使得它倆之間的設備驅動程序不能夠通用,當然在晶元的硬體初始化一些硬體相關的代碼上可以互相借鑒。而 VxWorks的BOOTROM和運行版本的設備驅動是相同的,因為,它的運行版本和BOOTROM的結構是一致的,使用同一操作系統內核。 Linux操作系統的設備驅動運行在內核空間,用戶進程運行在用戶空間。在Linux操作系統中,內核空間和用戶空間的內存管理和映射方式是不同的,應用和設備驅動在數據交換時會涉及到不同的內存空間,會影響到一定效率,但這個問題可以通過修改系統內存空間配置等方法來解決。 VxWorks操作系統沒有分開內核空間和用戶空間,設備驅動和應用都運行於同一空間,相互之間的內存都可以訪問,數據交換非常方便,但是,這種結構的穩定性就不如 Linux系統好了。 兩種操作系統都提供了很多設備驅動的資源和模板。但是由於Linux的開源特性,它提供的設備驅動的種類和數量遠遠超過了VxWorks.
參考:http://blog.csdn.net/cybertan/article/details/5707973
2. linux 怎麼打開DIMM168pin匯流排,驅動程序系統上已經有了,不知道怎麼打開
使用insmod命令載入驅動模塊。
語法:insmod [-fkmpsvxX][-o<模塊名稱>][模塊文件]
這些參數可以查幫助文檔。
這樣便可以打開一個驅動模塊,你根據你的實際情況用這個命令就可以了。
祝你成功。
3. linux內核中i2c匯流排驅動對所有的i2c設備是否是通用的
i2C匯流排的驅動程序一般針對不同的CPU是不一樣的,所以都位於arch目錄下對應的cpu架構的common文件夾下。
對同一種架構的來看,I2C驅動僅實現底層的通信。故其是通用的。
4. 在linux上怎樣增加一個i2c設備
假設手上有一塊從淘寶上買來的開發板,我要在開發板的I2C匯流排上增加一個從設備(如at24c08),那麼我要怎樣寫這個「I2C設備驅動」,讓
應用程序可以訪問at24c08呢?
先來看一個最簡單的i2c設備驅動:
static struct i2c_board_info at24cxx_info = { //所支持的i2c設備的列表
I2C_BOARD_INFO("at24c08", 0x50), //一項代表一個支持的設備,它的名字叫做「at24c08」,器件地址是0x50
};
static struct i2c_client *at24cxx_client;
static int at24cxx_dev_init(void)
{
struct i2c_adapter *i2c_adap; //分配一個適配器的指針
i2c_adap = i2c_get_adapter(0); //調用core層的函數,獲得一個i2c匯流排。這里我們已經知道新增的器件掛接在編號為0的i2c匯流排上
at24cxx_client = i2c_new_device(i2c_adap, &at24cxx_info); // 把i2c適配器和新增的I2C器件關聯起來,這個用了i2c匯流排0,地址是0x50。這就組成了一個客戶端
at24cxx_client i2c_put_adapter(i2c_adap);
return 0;
}
static void at24cxx_dev_exit(void)
{
i2c_unregister_device(at24cxx_client);
}
mole_init(at24cxx_dev_init);
mole_exit(at24cxx_dev_exit);
從上面的程序可以看到,寫一個i2c設備驅動程序,與寫普通的字元驅動基本一樣。特別之處是它調用了i2c的core層的函數,以獲得對i2c匯流排的控制。因為用的是開發板,板上的與soc晶元(一般來說就是arm的晶元)i2c匯流排驅動一般都做好了,直接調用core層的函數就可以控制soc的i2c模塊了。也就是說,寫i2c設備驅動不需要關注arm內部的i2c模塊的寄存器,我們需要關注的是設備(at24c08)的寄存器以及它的datasheet對時序的要求。
其實,添加i2c設備的方法很靈活。根據Linux的官方文檔《linux-3.4.2\Documentation\i2c\instantiating-devices》,添加i2c設備的方法總結有4種:
1. i2c_register_board_info:根據匯流排編號、設備名字(「at24c08」)、設備地址(0x50)注冊一個字元驅動。這種方法最簡單、最粗暴,最貼近平時在開片機上開發i2c器件的。
2. i2c_new_device:根據i2c匯流排的編號,聲明一個i2c設備:這種方法就是上面例子用的方法。這種方法也簡單,但是需要事先知道器件掛接在哪條匯流排上。對於設備,還實現知道了設備地址0x50,匯流排適配器也支持名字為「at24c08」的設備
3. i2c_new_probed_device:
4.從用戶空間實例化一個器件:這個方法相當智能快速,如下輸入指令,即可增加一個i2c設備,同時增加了對應的設備文件。
# echo eeprom 0x50 > /sys/bus/i2c/devices/i2c-3/new_device
根據英文文檔的標題,添加i2c設備有稱之為「i2c設備的實例化」。
從上述可以知道,在實例化一個i2c設備之前,除了有對應的驅動支持匯流排外(這里是匯流排0),還需要有一個驅動使用了匯流排0發送時序,支持名字為"at24c08"的器件。這個驅動用匯流排驅動的函數,配置了at24c08的寄存器。
5. linux匯流排驅動模型中,匯流排也是一種設備,匯流排與表示它的設備是怎麼聯系的
設備模型中,關心匯流排,設備,驅動這三個實體,匯流排將設備和驅動綁定,在系統每注冊一個設備的時候,會尋找與之匹配的驅動。相反,在系統每注冊一個驅動的時候,尋找與之匹配的設備,匹配是由匯流排來完成的。 你還可以看一看鏈表的信息。它們都是關聯的。 有個最牛的函數contain_o
f 非常牛。還有輪詢鏈表的函數。
6. 請問linux驅動怎麼調用底層的驅動啊 比如說已有SPI匯流排驅動,現要為一個SPI設備寫驅動,怎麼調用底層驅動
spi匯流排驅動在linux中是採用了分層設計和分隔設計的思想,spi控制器的驅動和核心層的通用api內核已經寫完了,你只要寫外設驅動就好,具體你可以去看一下你的spi_s3c24xx.c這個驅動是基於platfoem寫的,裡面含有如何調用核心api。
7. 如何 理解 linux 設備 驅動 匯流排
linux
主機的硬體配備
lspci
找到的是目前主機上面的硬體配備
[root@www
~]#
lspci
[-vvn]
選項與參數:
-v
:顯示更多的
pci
介面裝置的詳細信息
-vv
:比
-v
還要更詳細的信息
-n
:直接觀察
pci
的
id
而不是廠商名稱
查閱您系統內的
pci
裝置:
[root@www
~]#
lspci
#不必加上任何選項,就能夠顯示出目前的硬體配備為何
host
bridge:
<==主板晶元
vga
compatible
controller
<==顯卡
audio
device
<==音頻設備
pci
bridge
<==介面插槽
usb
controller
<==usb控制器
isa
bridge
ide
interface
smbus
ethernet
controller
<==網卡
04:00.0
ethernet
controller:
realtek
semiconctor
co.,
ltd.
查看一般詳細信息
[root@www
~]#
lspci
-v
查看網卡詳細信息:
[root@www
~]#
lspci
-s
04:00.0
-vv
-s
:後面接的是每個設備的匯流排、插槽與相關函數功能
8. 怎樣在linux環境下輕松實現基於i2c匯流排的eeprom驅動程序
S3C2410X集成了一個LCD控制器(支持STN和TFT帶有觸摸屏的液晶顯示屏)、SDRAM控制器、3個通道的UART、4個通道的DMA、4個具有PWM功能的計時器和一個內部時鍾、8通道的10位ADC。S3C2410還有很多豐富的外部介面,例如觸摸屏介面、I2C匯流排介面、I2S總...
9. 如何寫linux pci設備驅動程序
Linux下PCI設備驅動開發
1. 關鍵數據結構
PCI設備上有三種地址空間:PCI的I/O空間、PCI的存儲空間和PCI的配置空間。CPU可以訪問PCI設備上的所有地址空間,其中I/O空間和存儲空間提供給設備驅動程序使用,而配置空間則由Linux內核中的PCI初始化代碼使用。內核在啟動時負責對所有PCI設備進行初始化,配置好所有的PCI設備,包括中斷號以及I/O基址,並在文件/proc/pci中列出所有找到的PCI設備,以及這些設備的參數和屬性。
Linux驅動程序通常使用結構(struct)來表示一種設備,而結構體中的變數則代表某一具體設備,該變數存放了與該設備相關的所有信息。好的驅動程序都應該能驅動多個同種設備,每個設備之間用次設備號進行區分,如果採用結構數據來代表所有能由該驅動程序驅動的設備,那麼就可以簡單地使用數組下標來表示次設備號。
在PCI驅動程序中,下面幾個關鍵數據結構起著非常核心的作用:
pci_driver
這個數據結構在文件include/linux/pci.h里,這是Linux內核版本2.4之後為新型的PCI設備驅動程序所添加的,其中最主要的是用於識別設備的id_table結構,以及用於檢測設備的函數probe( )和卸載設備的函數remove( ):
struct pci_driver {
struct list_head node;
char *name;
const struct pci_device_id *id_table;
int (*probe) (struct pci_dev *dev, const struct pci_device_id *id);
void (*remove) (struct pci_dev *dev);
int (*save_state) (struct pci_dev *dev, u32 state);
int (*suspend)(struct pci_dev *dev, u32 state);
int (*resume) (struct pci_dev *dev);
int (*enable_wake) (struct pci_dev *dev, u32 state, int enable);
};
pci_dev
這個數據結構也在文件include/linux/pci.h里,它詳細描述了一個PCI設備幾乎所有的
硬體信息,包括廠商ID、設備ID、各種資源等:
struct pci_dev {
struct list_head global_list;
struct list_head bus_list;
struct pci_bus *bus;
struct pci_bus *subordinate;
void *sysdata;
struct proc_dir_entry *procent;
unsigned int devfn;
unsigned short vendor;
unsigned short device;
unsigned short subsystem_vendor;
unsigned short subsystem_device;
unsigned int class;
u8 hdr_type;
u8 rom_base_reg;
struct pci_driver *driver;
void *driver_data;
u64 dma_mask;
u32 current_state;
unsigned short vendor_compatible[DEVICE_COUNT_COMPATIBLE];
unsigned short device_compatible[DEVICE_COUNT_COMPATIBLE];
unsigned int irq;
struct resource resource[DEVICE_COUNT_RESOURCE];
struct resource dma_resource[DEVICE_COUNT_DMA];
struct resource irq_resource[DEVICE_COUNT_IRQ];
char name[80];
char slot_name[8];
int active;
int ro;
unsigned short regs;
int (*prepare)(struct pci_dev *dev);
int (*activate)(struct pci_dev *dev);
int (*deactivate)(struct pci_dev *dev);
};
2. 基本框架
在用模塊方式實現PCI設備驅動程序時,通常至少要實現以下幾個部分:初始化設備模塊、設備打開模塊、數據讀寫和控制模塊、中斷處理模塊、設備釋放模塊、設備卸載模塊。下面給出一個典型的PCI設備驅動程序的基本框架,從中不難體會到這幾個關鍵模塊是如何組織起來的。
/* 指明該驅動程序適用於哪一些PCI設備 */
static struct pci_device_id demo_pci_tbl [] __initdata = {
{PCI_VENDOR_ID_DEMO, PCI_DEVICE_ID_DEMO,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEMO},
{0,}
};
/* 對特定PCI設備進行描述的數據結構 */
struct demo_card {
unsigned int magic;
/* 使用鏈表保存所有同類的PCI設備 */
struct demo_card *next;
/* ... */
}
/* 中斷處理模塊 */
static void demo_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
/* ... */
}
/* 設備文件操作介面 */
static struct file_operations demo_fops = {
owner: THIS_MODULE, /* demo_fops所屬的設備模塊 */
read: demo_read, /* 讀設備操作*/
write: demo_write, /* 寫設備操作*/
ioctl: demo_ioctl, /* 控制設備操作*/
mmap: demo_mmap, /* 內存重映射操作*/
open: demo_open, /* 打開設備操作*/
release: demo_release /* 釋放設備操作*/
/* ... */
};
/* 設備模塊信息 */
static struct pci_driver demo_pci_driver = {
name: demo_MODULE_NAME, /* 設備模塊名稱 */
id_table: demo_pci_tbl, /* 能夠驅動的設備列表 */
probe: demo_probe, /* 查找並初始化設備 */
remove: demo_remove /* 卸載設備模塊 */
/* ... */
};
static int __init demo_init_mole (void)
{
/* ... */
}
static void __exit demo_cleanup_mole (void)
{
pci_unregister_driver(&demo_pci_driver);
}
/* 載入驅動程序模塊入口 */
mole_init(demo_init_mole);
/* 卸載驅動程序模塊入口 */
mole_exit(demo_cleanup_mole);
上面這段代碼給出了一個典型的PCI設備驅動程序的框架,是一種相對固定的模式。需要注意的是,同載入和卸載模塊相關的函數或數據結構都要在前面加上__init、__exit等標志符,以使同普通函數區分開來。構造出這樣一個框架之後,接下去的工作就是如何完成框架內的各個功能模塊了。
3. 初始化設備模塊
在Linux系統下,想要完成對一個PCI設備的初始化,需要完成以下工作:
檢查PCI匯流排是否被Linux內核支持;
檢查設備是否插在匯流排插槽上,如果在的話則保存它所佔用的插槽的位置等信息。
讀出配置頭中的信息提供給驅動程序使用。
當Linux內核啟動並完成對所有PCI設備進行掃描、登錄和分配資源等初始化操作的同時,會建立起系統中所有PCI設備的拓撲結構,此後當PCI驅動程序需要對設備進行初始化時,一般都會調用如下的代碼:
static int __init demo_init_mole (void)
{
/* 檢查系統是否支持PCI匯流排 */
if (!pci_present())
return -ENODEV;
/* 注冊硬體驅動程序 */
if (!pci_register_driver(&demo_pci_driver)) {
pci_unregister_driver(&demo_pci_driver);
return -ENODEV;
}
/* ... */
return 0;
}
驅動程序首先調用函數pci_present( )檢查PCI匯流排是否已經被Linux內核支持,如果系統支持PCI匯流排結構,這個函數的返回值為0,如果驅動程序在調用這個函數時得到了一個非0的返回值,那麼驅動程序就必須得中止自己的任務了。在2.4以前的內核中,需要手工調用pci_find_device( )函數來查找PCI設備,但在2.4以後更好的辦法是調用pci_register_driver( )函數來注冊PCI設備的驅動程序,此時需要提供一個pci_driver結構,在該結構中給出的probe探測常式將負責完成對硬體的檢測工作。
static int __init demo_probe(struct pci_dev *pci_dev, const struct
pci_device_id *pci_id)
{
struct demo_card *card;
/* 啟動PCI設備 */
if (pci_enable_device(pci_dev))
return -EIO;
/* 設備DMA標識 */
if (pci_set_dma_mask(pci_dev, DEMO_DMA_MASK)) {
return -ENODEV;
}
/* 在內核空間中動態申請內存 */
if ((card = kmalloc(sizeof(struct demo_card), GFP_KERNEL)) == NULL) {
printk(KERN_ERR "pci_demo: out of memory\n");
return -ENOMEM;
}
memset(card, 0, sizeof(*card));
/* 讀取PCI配置信息 */
card->iobase = pci_resource_start (pci_dev, 1);
card->pci_dev = pci_dev;
card->pci_id = pci_id->device;
card->irq = pci_dev->irq;
card->next = devs;
card->magic = DEMO_CARD_MAGIC;
/* 設置成匯流排主DMA模式 */
pci_set_master(pci_dev);
/* 申請I/O資源 */
request_region(card->iobase, 64, card_names[pci_id->driver_data]);
return 0;
}
4. 打開設備模塊
在這個模塊里主要實現申請中斷、檢查讀寫模式以及申請對設備的控制權等。在申請控制權的時候,非阻塞方式遇忙返回,否則進程主動接受調度,進入睡眠狀態,等待其它進程釋放對設備的控制權。
static int demo_open(struct inode *inode, struct file *file)
{
/* 申請中斷,注冊中斷處理程序 */
request_irq(card->irq, &demo_interrupt, SA_SHIRQ,
card_names[pci_id->driver_data], card)) {
/* 檢查讀寫模式 */
if(file->f_mode & FMODE_READ) {
/* ... */
}
if(file->f_mode & FMODE_WRITE) {
/* ... */
}
/* 申請對設備的控制權 */
down(&card->open_sem);
while(card->open_mode & file->f_mode) {
if (file->f_flags & O_NONBLOCK) {
/* NONBLOCK模式,返回-EBUSY */
up(&card->open_sem);
return -EBUSY;
} else {
/* 等待調度,獲得控制權 */
card->open_mode |= f_mode & (FMODE_READ | FMODE_WRITE);
up(&card->open_sem);
/* 設備打開計數增1 */
MOD_INC_USE_COUNT;
/* ... */
}
}
}
5. 數據讀寫和控制信息模塊
PCI設備驅動程序可以通過demo_fops 結構中的函數demo_ioctl( ),向應用程序提供對硬體進行控制的介面。例如,通過它可以從I/O寄存器里讀取一個數據,並傳送到用戶空間里:
static int demo_ioctl(struct inode *inode, struct file *file, unsigned int
cmd, unsigned long arg)
{
/* ... */
switch(cmd) {
case DEMO_RDATA:
/* 從I/O埠讀取4位元組的數據 */
val = inl(card->iobae + 0x10);
/* 將讀取的數據傳輸到用戶空間 */
return 0;
}
/* ... */
}
事實上,在demo_fops里還可以實現諸如demo_read( )、demo_mmap( )等操作,Linux內核源碼中的driver目錄里提供了許多設備驅動程序的源代碼,找那裡可以找到類似的例子。在對資源的訪問方式上,除了有I/O指令以外,還有對外設I/O內存的訪問。對這些內存的操作一方面可以通過把I/O內存重新映射後作為普通內存進行操作,另一方面也可以通過匯流排主DMA(Bus Master DMA)的方式讓設備把數據通過DMA傳送到系統內存中。
6. 中斷處理模塊
PC的中斷資源比較有限,只有0~15的中斷號,因此大部分外部設備都是以共享的形式申請中斷號的。當中斷發生的時候,中斷處理程序首先負責對中斷進行識別,然後再做進一步的處理。
static void demo_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
struct demo_card *card = (struct demo_card *)dev_id;
u32 status;
spin_lock(&card->lock);
/* 識別中斷 */
status = inl(card->iobase + GLOB_STA);
if(!(status & INT_MASK))
{
spin_unlock(&card->lock);
return; /* not for us */
}
/* 告訴設備已經收到中斷 */
outl(status & INT_MASK, card->iobase + GLOB_STA);
spin_unlock(&card->lock);
/* 其它進一步的處理,如更新DMA緩沖區指針等 */
}
7. 釋放設備模塊
釋放設備模塊主要負責釋放對設備的控制權,釋放佔用的內存和中斷等,所做的事情正好與打開設備模塊相反:
static int demo_release(struct inode *inode, struct file *file)
{
/* ... */
/* 釋放對設備的控制權 */
card->open_mode &= (FMODE_READ | FMODE_WRITE);
/* 喚醒其它等待獲取控制權的進程 */
wake_up(&card->open_wait);
up(&card->open_sem);
/* 釋放中斷 */
free_irq(card->irq, card);
/* 設備打開計數增1 */
MOD_DEC_USE_COUNT;
/* ... */
}
8. 卸載設備模塊
卸載設備模塊與初始化設備模塊是相對應的,實現起來相對比較簡單,主要是調用函數pci_unregister_driver( )從Linux內核中注銷設備驅動程序:
static void __exit demo_cleanup_mole (void)
{
pci_unregister_driver(&demo_pci_driver);
}
小結
PCI匯流排不僅是目前應用廣泛的計算機匯流排標准,而且是一種兼容性最強、功能最全的計算機匯流排。而Linux作為一種新的操作系統,其發展前景是無法估量的,同時也為PCI匯流排與各種新型設備互連成為可能。由於Linux源碼開放,因此給連接到PCI匯流排上的任何設備編寫驅動程序變得相對容易。本文介紹如何編譯Linux下的PCI驅動程序,針對的內核版本是2.4。
10. 6. Linux-LCD 驅動程序概述
入局:應用程序是如何操控LCD顯示器的?
我們知道應用程序的調用介面,無非 open/read/write ...然後通過驅動程序最終作用到硬體設備上。以字元設備為例,對於驅動的開發者,實現了應用程序調用的驅動層中與之相匹配的 drv_open/drv_read/drv_write 函數,為應用層序提供了操作實際硬體設備的通道。那麼,對於LCD驅動程序又是如何?先來了解下兩個非常重要的概念。
LCD控制器的功能是控制驅動信號,進而驅動LCD。用戶只需要通過讀寫一系列的寄存器,完成配置和顯示驅動。在驅動LCD設計的過程中首要的是配置LCD控制器,而在配置LCD控制器中最重要的一步則是幀緩沖區(Frame Buffer)的指定。用戶所要顯示的內容皆是從緩沖區中讀出,從而顯示到屏幕上的。幀緩沖區的大小由屏幕的解析度和顯示色彩數決定。驅動幀緩沖的實現是整個驅動開發過程的重點。
幀緩沖區是出現在Linux 2.2.xx及以後版本內核當中的一種驅動程序介面,這種介面將顯示設備抽象為幀緩沖區設備區。幀緩沖區為圖像硬體設備提供了一種抽象化處理,它代表了一些視頻硬體設備,允許應用軟體通過定義明確的界面來訪問圖像硬體設備。這樣軟體無須了解任何涉及硬體底層驅動的東西(如硬體寄存器)。它允許上層應用程序在圖形模式下直接對顯示緩沖區進行讀寫和I/O控制等操作。通過專門的設備節點可對該設備進行訪問,如/dev/fb*。用戶可以將它看成是顯示內存的一個映像,將其映射到進程地址空間之後,就可以進行讀寫操作,而讀寫操作可以反映到LCD。
幀緩沖(Frame Buffer)是Linux為顯示設備提供的一個介面,把顯存抽象後的一種設備,允許上層應用程序在圖形模式下直接對顯示緩沖區進行讀寫操作。用戶不必關心物理顯存的位置、換頁機制等等具體細節,這些都是由Frame Buffer設備驅動來完成的。幀緩沖設備屬於字元設備。
Linux系統Frame Buffer本質上只是提供了對圖形設備的硬體抽象,在開發者看來,Frame Buffer是一塊顯示緩存,向顯示緩存中寫入特定格式的數據就意味著向屏幕輸出內容。
由於有了frambuffer的抽象,使得應用程序通過定義好的介面就可以訪問硬體。所以應用程序不需要考慮底層的(寄存器級)的操作。應用程序對設備文件的訪問一般在/dev目錄,如 /dev/fb*。
內核中的frambuffer在: drivers/video/fbmem.c (fb: frame buffer)
(1) 創建字元設備"fb", FB_MAJOR=29,主設備號為29。
(2)創建類,但並沒有創建設備節點,因為需要注冊了LCD驅動後,才會有設備節點;
2.1 fb_open函數如下:
(1) registered_fb[fbidx] 這個數組也是fb_info結構體,其中fbidx等於次設備號id,顯然這個數組就是保存我們各個lcd驅動的信息;
2.2 fb_read函數如下:
從.open和.read函數中可以發現,都依賴於fb_info幀緩沖信息結構體,它從registered_fb[fbidx]數組中得到,這個數組保存我們各個lcd驅動的信息。由此可見,fbmem.c提供的都是些抽象出來的東西,最終都得依賴registered_fb這個數組。
這個register_framebuffer()除了注冊fb_info,還創建了設備節點。
以s3c2410fb.c為例,分析驅動的實現。
既然是匯流排設備驅動模型,那我們關心的是它的probe函數。
看到這里驅動的寫法也大致清晰:
附:
LCD的顯示過程與時序:
1.顯示從屏幕左上角第一行的第一個點開始,一個點一個點地在LCD上顯示,點與點之間的時間間隔為VCLK(像素時鍾信號);當顯示到屏幕的最右邊就結束這一行(Line),這一行的顯示對應時序圖上的HSYNC(水平同步信號)
2. 接下來顯示指針又回到屏幕的左邊從第二行開始顯示,顯示指針針在從第一行的右邊回到第二行的左邊是需要一定的時間的,我們稱之為行切換。
3. 以此類推,顯示指針就這樣一行一行的顯示至矩形的右下角才把一幅圖像(幀:frame)顯示完成,這一幀的顯示時間在時序圖上表示為VSYNC(垂直同步信號)。
參考:
https://sites.google.com/a/hongdy.org/www/linux/kernel/lcddriver