來源: LCD Driver 筆記 - Frame Buffer
什麼是framebuffer 設備:
framebuffer 是一種能夠提取圖形的硬件設備,是用戶進入圖形界面很好的接口。
有了framebuffer,用戶的應用程序不需要對底層的驅動的深入瞭解就能夠做出很好的圖形。
對於用戶而言,它和 /dev 下面的其他設備沒有什麼區別,用戶可以把 framebuffer 看成一塊內存,既可以向這塊內存中寫入數據,也可以從這塊內存中讀取數據。
第一個被註冊的 framebuffer 的 minor 等於0,第二個被註冊的 framebuffer的minor 等於 1,以此類推。其 major 都為 29。
framebuffer 內部結構說明:
相關檔案:
linux/include/linux/fb.h
linux/drivers/video/fbmem.c
fb_var_screeninfo 是用來描述圖形卡的特性的。通常是被用戶設置的。
struct fb_var_screeninfo /* Timing: All values in pixclocks, except pixclock (of course) */ |
fb_fix_screeninfo 定義了圖形卡的硬件特性,是不能改變的,用戶選定了哪一個圖形卡,那麼它的硬件特性也就定下來了。
struct fb_fix_screeninfo |
struct fb_cmap struct fb_info { #include <stdio.h> #include "bitmap.h" int main()
fb_cmap 描述設備無關的顏色映射信息。可以通過 FBIOGETCMAP 和 FBIOPUTCMAP 對應的 ioctl操作設定或獲取顏色映射信息。
{
__u32 start; /* First entry 第一個入口 */
__u32 len; /* Number of entries 入口的數字 */
__u16 *red; /* Red values 紅 */
__u16 *green;
__u16 *blue;
__u16 *transp; /* transparency, can be NULL 透明,可以為零 */
};
fb_info 定義了當前圖形卡 framebuffer 設備的獨立狀態,一個圖形卡可能有兩個 framebuffer, 在這種情況下,就需要兩個 fb_info 結構。這個結構是唯一在內核空間可見的。
char modename[40]; /* default video mode 默認的視頻卡類型 */
kdev_t node;
int flags;
int open; /* Has this been open already? */
#define FBINFO_FLAG_MODULE 1 /* Low-level driver is a module */
struct fb_var_screeninfo var; /* Current var 現在的視頻信息 */
struct fb_fix_screeninfo fix; /* Current fix 修正的信息 */
struct fb_monspecs monspecs; /* Current Monitor specs 現在的顯示器模式 */
struct fb_cmap cmap; /* Current cmap 當前優先級 */
struct fb_ops *fbops;
char *screen_base; /* Virtual address 物理基址 */
struct display *disp; /* initial display variable 初始化 */
struct vc_data *display_fg; /* Console visible on this display */
char fontname[40]; /* default font name 默認的字體 */
devfs_handle_t devfs_handle; /* Devfs handle for new name */
devfs_handle_t devfs_lhandle; /* Devfs handle for compat. symlink 兼容 */
int (*changevar)(int); /* tell console var has changed 告訴
console 變量修改了 */
int (*switch_con)(int, struct fb_info*);
/* tell fb to switch consoles 告訴 fb
選擇consoles */
int (*updatevar)(int, struct fb_info*);
/* tell fb to update the vars 告訴 fb 更新變量 */
void (*blank)(int, struct fb_info*);
/* tell fb to (un)blank the screen 告訴 fb
使用黑白模式(或者不黑)
arg = 0: unblank 黑白模式
arg > 0: VESA level (arg-1)
選擇VESA模式 */
void *pseudo_palette; /* Fake palette of 16 colors and the cursor's
color for nonpalette mode 修正調色板 */
/* From here on everything is device dependent */
void *par;
};
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <asm/page.h>
{
int fb;
unsigned char* fb_mem;
// open frame buffer device
fb= open("/dev/fb0", O_RDWR);
// get frame buffer memory mapping address
fb_mem = mmap (NULL, 320*240*2,
PROT_READ|PROT_WRITE, MAP_SHARED, fb, 0);
// clear frame buffer
memset(fb_mem, 0, 320*240*2);
// cpoy image to framebuffer
memcpy(fb_mem, (unsigned char *)ScreenBitmap, 320*240*2);
// close framebuffer device
close(fb);
return 0;
}
** 參考資料 **
http://moto.debian.org.tw/viewtopic.php?p=56374
http://www.91linux.com/html/article/kernel/20071204/8805.html
fb_ops 用戶應用可以使用 ioctl() 系統調用來操作設備,這個結構就是用一支持 ioctl() 的這些操作的。 (跟我在程式碼裡面看到的不太一樣??)
struct fb_ops |
LCD Frame buffer 函式呼叫順序:
s3c2410fb_probe():
- s3c2410fb_map_video_memory()
- s3c2410fb_init_registers()
- s3c2410fb_check_var()
s3c2410fb_set_par() -> s3c2410fb_activate_var():
- s3c2410fb_calculate_tft_lcd_regs()
- s3c2410fb_set_lcdaddr()
對 framebuffer 操作:
dd if=/dev/fb0 of=fbfile
可以將 fb0 中的內容保存下來存到 fbfile 裡
如果顯示模式是 1024*768 的 8 位色
dd if=/dev/zero of=/dev/fb0 bs=1024 count=768
可以清空 framebuffer (螢幕全黑)
dd if=fbfile of=/dev/fb0
將 fbfile 內的資料寫回 framebuffer
留言列表