framebuffer 程式設計

2021-05-22 02:10:40 字數 3498 閱讀 1549

這是乙個關於如何程式設計的文件,因此,請在你編譯或執行例子之前,正確配置你的framebuffer裝置。

framebuffer裝置,你可以把你的計算機螢幕當成乙個真正的圖形裝置。你可以修改解析度,重新整理率,色彩深度等。最好的一點是,你可以把畫素點繪在任何你想要的地方。framebuffer裝置不是乙個圖形庫,而更確切的是乙個低階的通用裝置。這樣創造了巨大的靈活性,但同時也有它的缺點。想使用framebuffer裝置,你應該做以下事情:

通過open()呼叫開啟裝置,讀裝置意味著讀取螢幕記憶體(可稱之為視訊記憶體)。用$cat /dev/fb0 >screenshot將螢幕記憶體匯入乙個檔案,恢復剛才的螢幕截圖則可使用:$cat

screenshot >/dev/fb0。

顯然,用上述方法使用螢幕記憶體並不經濟方便。在讀或寫之前持續的定址(見man

lseek)將會導致很多的開銷。這就是為什麼你要對映你的螢幕記憶體。當你將螢幕記憶體對映到你的應用程式時,你將得到乙個直接指向螢幕記憶體的指標。

在我們可以對映螢幕記憶體之前,我們需要知道我們能夠對映多少,以及我們需要對映多少。第一件要做的事情就是從我們新得到的framebuffer裝置取回資訊。有兩個結構包含著我們需要的資訊,第乙個包含固定的螢幕資訊,這部分是由硬體和驅動的能力決定的;第二個包含著可變的螢幕資訊,這部分是由硬體的當前狀態決定的,可以由使用者空間的程式呼叫ioctl()來改變。

struct fb_fix_screeninfo ;

在這裡非常重要的域是smem_len和line-length。smem-len告訴我們framebuffer裝置的大小,第二個域告訴我們指標應該前進多少位元組去得到下一行的資料。第二個結構則要有意思的多,它給了我們可以改變的資訊。

/* more kernel header files copied shamelessly */

struct fb_bitfield ;

struct fb_var_screeninfo ;

另外乙個應用就是用來平滑的滾動整個螢幕。就像在前面螢幕中一樣,在記憶體分配800行的空間。每隔10毫秒設定乙個定時器(timer,見man settimer和man

signal / man sigaction),將offset設為1或是比上次更多,瞧,你看到了乙個平滑滾動的螢幕。確保你的訊號(signal)不要因為最佳輸出的原因被訊號處理程式阻塞。 將

examine and explain timings! )

現在我們知道了結構的細節了,但還不清楚如何去獲得或設定它們。這裡有一些ioctl的命令可以參考。

c:

#include

int main ()

這些 fbioget_*?的ioctl命令將請求的資訊寫入最後乙個變數所指向的結構體中。fbioput_vscreeninfo將所有提供的資訊複製回核心。如果核心不能啟用新的設定,將返回-1。而去訪問記憶體本身,它可以被對映,然後直接訪問。但這些需要一些步驟:

這裡有乙個樣例:

c:

#include

#include

#include

#include

#include

#include

#include

int main(

)sleep(

2);

return0;}

你可以看到我們採用了從上一部分提到的資訊取回,在這一部分新用到的是mmap函式。第乙個變數在這種情形下可以忽略,第二個是對映的記憶體大小,第三個變數宣告我們將共享記憶體進行讀和寫。第四個變數表示這段記憶體將和其他程序共享。在framebuffer上面建乙個map_private是不可能的。 通常這意味著你需要中斷控制台的切換去備份和恢復螢幕內容,而且不在自己沒有權利的時候向螢幕記憶體寫東西。

mmap詳解

mmap函式是unix/linux下的系統呼叫,來看《unix netword programming》卷二12.2節有詳細介紹。

mmap系統呼叫並不是完全為了用於共享記憶體而設計的。它本身提供了不同於一般對普通檔案的訪問方式,程序可以像讀寫記憶體一樣對普通檔案的操作。而posix或系統v的共享記憶體ipc則純粹用於共享目的,當然mmap()實現共享記憶體也是其主要應用之一。

mmap系統呼叫使得程序之間通過對映同乙個普通檔案實現共享記憶體。普通檔案被對映到程序位址空間後,程序可以像訪問普通記憶體一樣對檔案進行訪問,不必再呼叫read(),write()等操作。mmap並不分配空間, 只是將檔案對映到呼叫程序的位址空間裡, 然後你就可以用memcpy等操作寫檔案, 而不用write()了.寫完後用msync()同步一下, 你所寫的內容就儲存到檔案裡了. 不過這種方式沒辦法增加檔案的長度, 因為要對映的長度在呼叫mmap()的時候就決定了.

簡單說就是把乙個檔案的內容在記憶體裡面做乙個映像,記憶體比磁碟快些。

基本上它是把乙個檔案對應到你的virtual memory 中的一段,並傳回乙個指標。

以後對這段 memory 做訪問時,其實就是對那個檔做訪問。

它就是一種快速 file i/o 的東東,而且使用上和訪問 memory 一樣方便,只不過會佔掉你的 virutal memory。

#include

#include //檔案狀態結構

#include

#include //mmap標頭檔案

void * mmap(void *start, size_t length, int prot , int flags, int fd, off_t offset);

mmap開啟記憶體對映。

start指定記憶體位置,通常都是用null。offset指定檔案要在那裡開始對映,通常都是用0。

int munmap(void *start, size_t length);

int msync(const void *start, size_t length, int flags);

如果開啟記憶體對映是希望寫入檔案中,那麼修改過的記憶體會在一段時間內與檔案稍稍有點不同。如果您希望立即將資料寫入檔案中,可使用msync。

start為記憶體開始位置,length為長度。

flags則有三個:

ms_async : 請kernel快將資料寫入。

ms_sync : 在msync結束返回前,將資料寫入。

ms_invalidate : 讓核心自行決定是否寫入,僅在特殊狀況下使用

例子:if( (fp = open("./data.bin",o_rdonly) ) < 0 )

if( (fstat(fp,&stat_data) ) < 0 )

if( ( start_fp = mmap(null,stat_data.st_size,

prot_read,map_shared,fd_denseindex,0 )) == (void *)-1)

這樣便能從start_fp開始讀取資料啦!

Framebuffer程式設計How to

這是乙個關於如何程式設計的文件,因此,請在你編譯或執行例子之前,正確配置你的framebuffer裝置。用framebuffer裝置,你可以把你的計算機螢幕當成乙個真正的圖形裝置。你可以修改解析度,重新整理率,色彩深度等。最好的一點是,你可以把畫素點繪在任何你想要的地方。framebuffer裝置不...

FrameBuffer程式設計一(資料結構)

在framebuffer程式設計中最重要的和經常用到的資料結構有以下幾個 struct fb bitfield struct fb fix screeninfo struct fb var screeninfo 在友善之臂的源 裡面還有其他資料結構例如 struct fb cmap struct f...

FrameBuffer程式設計二(簡單的程式上)

1.framebuffer裝置介紹 2 裝置的基本用法 顯然,用上述方法使用螢幕記憶體並不經濟方便。在讀或寫之前持續的定址 見man lseek 將會導致很多的開銷。這就是為什麼你要對映你的螢幕記憶體。當你將螢幕記憶體對映到你的應用程式時,你將得到乙個直接指向螢幕記憶體的指標。在我們可以對映螢幕記憶...