2009-12-02 57 views

回答

18

使用open()右側文件中/dev(如:/dev/fb0),然後用mmap()它映射到內存中。如果您不知道如何使用這些系統調用,manpages將有助於這些系統調用。

然後有一些ioctl() S IN <linux/fb.h>一些結構和常量。像許多內核頭文件一樣,您只需瀏覽文件就可以學到很多東西。

特別有趣的是ioctl的FBIOGET_VSCREENINFOstruct fb_var_screeninfo。注意這有xres,yres(分辨率)和bits_per_pixel。此外,還有FBIOGET_FSCREENINFOstruct fb_fix_screeninfo它有像typeline_length進一步的信息。

因此,在(X,Y)的像素可能處於mmap_base_address + x * bits_per_pixel/8 + y * line_length。像素的確切格式將取決於您通過ioctl檢索的結構;這是你的工作,以決定如何讀取/寫入它們。

這已經有一段時間,因爲我已經有這個工作,所以我的更多細節幾分朦朧..

這裏有一個快速和骯髒的代碼示例只是爲了說明它是如何做...我的避風港」沒有測試過這個。

#include <sys/types.h> 
#include <sys/ioctl.h> 
#include <sys/mman.h> 

#include <linux/fb.h> 

#include <unistd.h> 
#include <fcntl.h> 

#include <stdio.h> 

int main() 
{ 
    struct fb_var_screeninfo screen_info; 
    struct fb_fix_screeninfo fixed_info; 
    char *buffer = NULL; 
    size_t buflen; 
    int fd = -1; 
    int r = 1; 

    fd = open("/dev/fb0", O_RDWR); 
    if (fd >= 0) 
    { 
     if (!ioctl(fd, FBIOGET_VSCREENINFO, &screen_info) && 
      !ioctl(fd, FBIOGET_FSCREENINFO, &fixed_info)) 
     { 
     buflen = screen_info.yres_virtual * fixed_info.line_length; 
     buffer = mmap(NULL, 
         buflen, 
         PROT_READ|PROT_WRITE, 
         MAP_SHARED, 
         fd, 
         0); 
     if (buffer != MAP_FAILED) 
     { 
      /* 
      * TODO: something interesting here. 
      * "buffer" now points to screen pixels. 
      * Each individual pixel might be at: 
      * buffer + x * screen_info.bits_per_pixel/8 
      *   + y * fixed_info.line_length 
      * Then you can write pixels at locations such as that. 
      */ 

      r = 0; /* Indicate success */ 
     } 
     else 
     { 
      perror("mmap"); 
     } 
     } 
     else 
     { 
     perror("ioctl"); 
     } 
    } 
    else 
    { 
     perror("open"); 
    } 

    /* 
    * Clean up 
    */ 
    if (buffer && buffer != MAP_FAILED) 
     munmap(buffer, buflen); 
    if (fd >= 0) 
     close(fd); 

    return r; 
} 
+0

才意識到我在「FINFO」結構忘了line_length,所以更新.. – asveikau 2009-12-02 06:42:18

+0

我編譯時我得到這樣的一些錯誤, 在文件從GC包括包括/ SYS/MMAN。h:38:錯誤:'mode_t'的衝突類型 /usr/include/linux/types.h:15:錯誤:之前的'mode_t'聲明在這裏 從gc:5包含的文件中: /usr/include /unistd.h:203:error:'gid_t'的衝突類型 /usr/include/linux/types.h:27:錯誤:之前的'gid_t'聲明在這裏 /usr/include/unistd.h:208 :錯誤:'uid_t'的衝突類型 /usr/include/linux/types.h:26:錯誤:'uid_t'的先前聲明在這裏 從/usr/include/bits/fcntl.h:25包含的文件中, – Rahul 2009-12-02 07:10:07

+0

@Rahul - 必須是我把標題放入的順序......也許先嚐試sys/types.h? – asveikau 2009-12-02 07:11:34

4

至於asveikau's answer另外,您也可以使用DirectFB,這可以大大簡化你的東西。

+0

DirectFB還具有奇妙的功能,例如用於繪製線條和複製矩形的硬件特定代碼。 – asveikau 2009-12-02 06:25:12

+0

但是如何可以訪問DFB – Rahul 2009-12-02 07:23:40

+0

這些鏈接在2015年不起作用。 – daveloyall 2015-12-18 17:17:00

0

從我的突觸上Rasbian:「DirectFB的是這是設計時考慮到嵌入式系統的圖形庫它在最低限度的資源使用和開銷提供最大的硬件加速性能。」

無論如何,我還沒有看到幀緩衝區中的這項工作,但我希望這就像我做我的大部分圖形。你有一些線性地址空間,每個像素的高度*寬度*字節數。如果要寫入特定的x,y位置,則該空間中的位置由(y * width * bytes per pixel)+(x * 3)給出。顏色是相鄰字節RGB(通常),以便獲取紅色像素的地址,爲綠色添加1,爲藍色添加2。你malloc(高*寬*每像素字節)地址空間,寫入它,然後選擇libpng,libjpeg,libtiff選擇將該緩衝區寫入文件。如果你想把文本也放在裏面,你必須自己推出,所以我偷了一箇舊的libgif。我已經達到了年齡和經驗水平,而我自己也很容易做到這一點,而不是去了解其他人是否認爲應該這樣做。我的圖形是這樣出現的: data taken as CSV from rtl_power

我一直在試圖使用一個幀緩存,如http://raspberrycompote.blogspot.com/2014/04/low-level-graphics-on-raspberry-pi.html所述,但有些錯誤。我在Pi 3上,它可能是爲2014年的Pi 1而編寫的,而不是在2017年。但是,由於GPU運行該節目,所以Pi與傳統的幀緩衝區不同。使用此方法:4: 在/ usr/http://elinux.org/RPi_Framebuffer

+0

艾倫,有趣的圖'')''。目前還不清楚您是提供對原始問題的答案,還是以答案的形式提出新問題。 (我把它看作兩者都有......)如果你的意圖是爲你的問題尋求幫助,那麼最好問一個新問題,因爲你在這裏的答案中的問題不可能提示任何進一步的答案。此外,由於它與RaspberryPi相關,所以最好的辦法是在[** Raspberry pi StackExchange **](http://raspberrypi.stackexchange.com/)上發佈。無論哪種方式,祝你好運。 – 2017-07-24 01:54:05

+0

因爲OpenBSD沒有它們,所以我還沒有真正使用framebuffer,這大部分是我運行了15年。不尋求幫助,只是解釋沒有圖書館的圖形。我打算給libvnc一個嘗試,因爲它提供了一個虛擬幀緩衝區,您可以使用vnc客戶端連接到虛擬幀緩衝區,並且它在窗口中運行,而不是接管整個顯示。我試圖用瀑布來做SDR,所以我需要移動的圖形,而不僅僅是靜止的圖像。 – 2017-07-25 01:43:54

+0

VNC本質上是遠程幀緩衝,這就是給我的想法:https://www.raspberrypi.org/forums/viewtopic.php?f=67&t=189032(我的線程在那裏) – 2017-07-25 01:56:30