2009-12-02 19 views

Respuesta

18

Uso open() en el archivo correcto en /dev (por ejemplo. /dev/fb0), a continuación, utilizar mmap() hacer un mapa en la memoria. Las páginas de manual ayudarán con estos syscalls si no sabe cómo usarlos.

Luego hay algunas estructuras y constantes para algunos ioctl() s en <linux/fb.h>. Al igual que muchos encabezados de kernel, puede aprender mucho simplemente navegando por el archivo.

Particularmente interesante es el ioctl FBIOGET_VSCREENINFO con struct fb_var_screeninfo. Tenga en cuenta que esto tiene xres, yres (resolución) y bits_per_pixel. Luego está FBIOGET_FSCREENINFO y struct fb_fix_screeninfo que cuenta con más información como type y line_length.

Así que un píxel en (x, y) podría estar en mmap_base_address + x * bits_per_pixel/8 + y * line_length. El formato exacto de los píxeles dependerá de las estructuras que recupere mediante ioctl; es su trabajo decidir cómo leerlos/escribirlos.

Ha sido un tiempo desde que he trabajado con este así que estoy un poco confusa en más detalles ..

Aquí está un ejemplo de código rápido y sucio sólo para ilustrar cómo se hace ... No he t probado esto.

#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

acabo de dar cuenta que me olvidé de line_length en el "finfo" estructura, por lo que la actualización .. – asveikau

+0

cuando compilo que estoy recibiendo algunos errores como este, En el archivo incluído en GC: 4: /usr/include/sys/mman.h: 38: error: tipos conflictivos para 'mode_t' /usr/include/linux/types.h:15: error: la declaración anterior de 'mode_t' estaba aquí En el archivo incluido de gc: 5: /usr/include /unistd.h:203: error: tipos conflictivos para 'gid_t' /usr/include/linux/types.h:27: error: la declaración anterior de 'gid_t' estaba aquí /usr/include/unistd.h:208 : error: tipos conflictivos para 'uid_t' /usr/include/linux/types.h:26: error: la declaración anterior de 'uid_t' estaba aquí en el archivo incluido en /usr/include/bits/fcntl.h:25 , – Rahul

+0

@Rahul - Debe ser el orden en el que puse los encabezados ... Tal vez intente sys/types.h primero? – asveikau

4

Como alternativa a asveikau's answer, se podría utilizar DirectFB, lo que puede simplificar mucho las cosas para usted.

+0

DirectFB también tiene cosas maravillosas, como el código específico del hardware para dibujar líneas y copiar rectángulos. – asveikau

+0

Pero cómo se puede acceder al DFB – Rahul

+0

Estos enlaces no funcionan en 2015. – daveloyall

0

De mi Synaptic en Rasbian: "DirectFB es una biblioteca de gráficos diseñada con sistemas incorporados en mente. Ofrece el máximo rendimiento acelerado por hardware con un mínimo de uso de recursos y gastos generales".

De todos modos, no he visto este trabajo en un buffer de cuadro todavía, pero estoy esperando que es como lo hago la mayoría de mis gráficos. Tiene un espacio de direcciones lineal, altura * ancho * bytes por número de píxeles de bytes. Si desea escribir en una ubicación particular x, y, la posición en ese espacio viene dada por (y * ancho * bytes por píxel) + (x * 3). Los colores son bytes adyacentes RGB (generalmente), de modo que obtendrá la dirección del píxel rojo, agregue 1 para verde, 2 para azul. Usted malloc (alto * ancho * bytes por píxel) un espacio de direcciones, escriba en él, luego escoja libpng, libjpeg, libtiff para escribir ese buffer en un archivo. Si quieres poner texto en él también tienes que hacer el tuyo, así que robé uno de un libgif antiguo. He alcanzado el nivel de edad y experiencia en el que es más fácil hacerlo yo mismo que aprender cómo alguien más pensó que debería hacerse. Mis gráficos salen como esto: data taken as CSV from rtl_power

que he estado tratando de utilizar un uso de este dispositivo como se describe en http://raspberrycompote.blogspot.com/2014/04/low-level-graphics-on-raspberry-pi.html pero algo está mal. Estoy en un Pi 3, probablemente fue escrito para un Pi 1 ya que era 2014, no 2017 en ese momento. Pero el Pi es diferente de los framebuffers tradicionales porque la GPU ejecuta el programa. Utilice este método: http://elinux.org/RPi_Framebuffer

+0

Alan, gráfico de aspecto interesante ':)'. No está claro si proporciona una respuesta a la pregunta original, o una nueva pregunta en forma de respuesta. (Lo leí como un poco de ambos ...) Si su intención es obtener ayuda con su problema, entonces es mejor hacer una nueva pregunta, ya que es poco probable que las preguntas en su respuesta sugieran alguna otra respuesta. Además, dado que está relacionado con RaspberryPi, la mejor opción es publicar en [** Raspberry pi StackExchange **] (http://raspberrypi.stackexchange.com/). La mejor de las suertes de cualquier manera. –

+0

Todavía tengo que usar un framebuffer ya que OpenBSD no los tiene y eso es principalmente lo que he estado haciendo durante 15 años. No buscando ayuda, simplemente explicando gráficos sin bibliotecas. Estoy a punto de probar libvnc ya que proporciona un framebuffer virtual al que puedes conectarte con un cliente vnc, y se ejecuta en una ventana en lugar de ocupar toda la pantalla. Estoy tratando de hacer SDR con una cascada, así que necesito gráficos que se muevan, no solo imágenes fijas. –

+0

VNC es esencialmente framebuffer remoto, eso es lo que me dio la idea: https://www.raspberrypi.org/forums/viewtopic.php?f=67&t=189032 (mi hilo allí) –

Cuestiones relacionadas