Frame Buffer的本意幀緩沖。它是指顯示設備里的顯存。顯存里保存是像素的RGB數據。一個顯存的大小,屏幕寬度*屏幕高度*每像素字節數。
軟件修改顯存的像素值,就形成各種顯示效果.再由硬件將顯存數據送到顯示模塊輸出。顯存一般是由SDRAM一段連續的空間來充當。
Linux一般都把FB設備當成顯示設備標準接口。它的設備結點 /dev/fbn表示。比如第一個FB設備是/dev/fb0.應用程序通過一組標準IOCTL來操作FB驅動。 fbset就是查詢FB驅動的一命令行工具,以下是執行實例
[root@hxy /]# fbset mode "480x272-1" # D: 0.111 MHz, H: 0.211 kHz, V: 0.739 Hz geometry 480 272 480 272 16 timings 9009000 2 2 2 2 41 10 accel false rgba 5/11,6/5,5/0,0/0 endmode
其中最關健是紅色那行,分別表示 實際的輸出寬度,高度,虛擬輸出寬度,高度.和bpp
在描述LCD的物理長度,是指一種對角線物理長度 比如4.3"屏就是對角線為4.3英寸長,這個尺寸與結構設計有關.而與軟件編程相關幾個參數主要是屏幕分辯率和色深.
?? 屏幕分辯率 是指每行和第列的像素數的描述。比如480*272.表示每行分布著480點,每列分布著272點.
分辯率越高越意味顯示越清
每一個像素的顏色是用三原色的分量來表示,即R(red) G (Green) B (blue) 另外一個與軟件高度相關是bpp, (bits per pixel),表RGB的bits數。嵌入式LINUX常用 16bpp,18bpp,24bpp. bpp值越大,能表示顏色越豐富.但是占用空間越多.單色的bpp就是1.
一個點占的字節數移為(BPP) bytes per pixel,BPP與bpp的對應換算并不是一個簡單除8的關系,要根據硬件換算。一般是16bpp占用2byte,18,24,32均是4個字節.
bpp還一個說法是,色深(Color Deepth)
在lcd的datasheet還是另外一個描述方法,即一個點的最大顏色數,相于是2的bpp次方.因此顏色數是可以直接換算bpp的
8bpp的顏色數256 16bpp的顏色數 65,536 18bpp的顏色數262,144 24bpp的顏色數是 16.1m
FB的基本操作
每個fb驅動實際是一個字符設備結點,其主設備號固定為
1。打開FB設備 open("/dev/fb0",O_RDWR,0) 2.控制功能用
ioctl實現
3.顯存控制 顯存是LINUX內核一個空間。應用程序對顯存操作是用mmap后來操作 4.關閉設備close()
取得屏幕信息
ioctl(fd, FBIOGET_VSCREENINFO,&var);
取得屏幕信息,數據存放在var中,它是定義在linux/fb.h中struct fb_var_screeninfo當中
struct fb_var_screeninfo { ??? __u32 xres; ??????????? /* visible resolution??????? */ ??? __u32 yres; ??? __u32 xres_virtual; ??????? /* virtual resolution??????? */ ??? __u32 yres_virtual; ??? __u32 xoffset; ??????????? /* offset from virtual to visible */ ??? __u32 yoffset; ??????????? /* resolution??????????? */ ??? __u32 bits_per_pixel; ??????? /* guess what??????????? */ ??? __u32 grayscale; ??????? /* != 0 Graylevels instead of colors */ ??? struct fb_bitfield red; ??????? /* bitfield in fb mem if true color, */ ??? struct fb_bitfield green; ??? /* else only length is significant */ ??? struct fb_bitfield blue; ??? struct fb_bitfield transp; ??? /* transparency??????????? */ ??? ??? __u32 nonstd; ??????????? /* != 0 Non standard pixel format */ ??? __u32 activate; ??????????? /* see FB_ACTIVATE_*??????? */ ??? __u32 height; ??????????? /* height of picture in mm */ ??? __u32 width; ??????????? /* width of picture in mm */ ??? __u32 accel_flags; ??????? /* (OBSOLETE) see fb_info.flags */ ??? /* Timing: All values in pixclocks, except pixclock (of course) */ ??? __u32 pixclock; ??????????? /* pixel clock in ps (pico seconds) */ ??? __u32 left_margin; ??????? /* time from sync to picture??? */ ??? __u32 right_margin; ??????? /* time from picture to sync??? */ ??? __u32 upper_margin; ??????? /* time from sync to picture??? */ ??? __u32 lower_margin; ??? __u32 hsync_len; ??????? /* length of horizontal sync??? */ ??? __u32 vsync_len; ??????? /* length of vertical sync??? */ ??? __u32 sync; ??????????? /* see FB_SYNC_*??????? */ ??? __u32 vmode; ??????????? /* see FB_VMODE_*??????? */ ??? __u32 rotate ; ??????????? /* angle we rotate counter clockwise */ ??? __u32 reserved[ 5] ; ??????? /* Reserved for future compatibility */ } ;
xres /yres 是實際屏幕的分辯率. xres_virtual/yres_virtual是虛擬屏幕的尺寸 xoffset/yoffset是實際屏幕輸出虛擬屏幕. bits_per_pixel 就是BPP
這一些信息就是 設置屏幕信息 在調整的屏幕信息的作用中,主要切換bpp, 缺省的bpp是由內核配置的.但是在運行中可以切換成不同的bpp.比如一般的s3c6410可以在16bpp/18bpp/24bpp切換.但是每次的切換時只在當前打開的fd有效,關閉后又會變成缺省的bpp.
切換bpp只需要把bits_per_pixel 設為相應的值.
Ioctl(fd, FBIOSET_VSCREENINFO,&var); var一般是FBIOGET_VSCREENINFO取得缺省值,然后再在其上修改.
在實測時,發現s3c6410的LCD驅動有BUG,即在切換成18bpp時,相應的RGB排列值并未調整,仍然是上一次BPP的排列.這樣造成BUG. 解決辦法是一是調整LCD驅動,二是在應用程序切換成18bpp時,同時切換成RGB排列.即用如下代碼
if ( ioctl( fd, FBIOGET_VSCREENINFO, & var) = = - 1) ?????? { ??????? printf ( "get screen information failure\n" ) ; ???? return - 2; ?????? } ?? if ( bpp = = 18) ?????? { ??????? var. red. length = 6; ???? var. red. offset = 12; ???? var. red. msb_right = 0; ???? var. green. length = 6; ???? var. green. offset = 6; ???? var. green. msb_right = 0; ???? var. blue. length = 6; ???? var. blue. offset = 0; ???? var. blue. msb_right = 0; ???? ?????? } ?? var. bits_per_pixel = bpp; ?? if ( ioctl( fd, FBIOPUT_VSCREENINFO, & var) = = - 1) ?????? { ??????? printf ( "put screen2 information failure\n" ) ; ???? return - 2; ?????? }
總結
以上是生活随笔 為你收集整理的Linux frame buffer 编程 -- fb基本操作 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。