How to draw the graph in framebuffer using c language..?

19,744

Solution 1

Use open() on the right file in /dev (eg. /dev/fb0), then use mmap() to map it into memory. Manpages will help for these syscalls if you do not know how to use them.

Then there are some structures and constants for some ioctl()s in <linux/fb.h>. Like many kernel headers, you can learn a lot simply browsing the file.

Particularly interesting is the ioctl FBIOGET_VSCREENINFO with struct fb_var_screeninfo. Note this has xres, yres (resolution) and bits_per_pixel. Then there's FBIOGET_FSCREENINFO and struct fb_fix_screeninfo which has further information like type and line_length.

So a pixel at (x, y) might be at mmap_base_address + x * bits_per_pixel/8 + y * line_length. The exact format of the pixels will depend on the structures you retrieve via ioctl; it's your job to decide how to read/write them.

It's been a while since I've worked with this so I'm a bit hazy on more details..

Here's a quick and dirty code sample just to illustrate how it's done... I haven't tested this.

#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;
}

Solution 2

As an alternative to asveikau's answer, you could use DirectFB, which may greatly simplify things for you.

Share:
19,744

Related videos on Youtube

Rahul
Author by

Rahul

Updated on April 15, 2022

Comments

  • Rahul
    Rahul about 1 month

    i am new to this linux framebuffer so do anybody guide me to draw the line-graph in framebuffer. And i have the code to draw graph in turbo c but now in linux. So please help me out.

    Thank You, Rahul

  • asveikau
    asveikau over 12 years
    DirectFB also has marvelous things such as hardware specific code for drawing lines and copying rectangles.
  • Rahul
    Rahul over 12 years
    But how that DFB can be accessed
  • Alessandro Mascolo
    Alessandro Mascolo almost 5 years
    I don't want to create problems, but DirectFB is a sex website, not a FB API.
  • greyfade
    greyfade almost 5 years
    @AlessandroMascolo It apparently moved. I've updated the link.
  • David C. Rankin
    David C. Rankin almost 5 years
    Alan, interesting looking graph :). It is unclear whether you are providing an answer to the original question, or a new question in the form of the answer. (I read it as a bit of both...) If your intent is to get help with your issue, then it is better to ask a new question, as the questions in your answer here are unlikely to prompt any further answer. Additionally, since it is RaspberryPi related, your best bet is probably to post on Raspberry pi StackExchange. Best of luck either way.
  • Alan Corey
    Alan Corey almost 5 years
    I've yet to actually use a framebuffer since OpenBSD doesn't have them and that's mostly what I've run for 15 years. Not looking for help, just explaining graphics without libraries. I'm about to give libvnc a try since it gives a virtual framebuffer you can connect to with a vnc client, and it runs in a window instead of taking over the whole display. I'm trying to do SDR with a waterfall so I need graphics that move, not just still images.
  • Alan Corey
    Alan Corey almost 5 years
    VNC is essentially remote framebuffer, that's what gave me the idea: raspberrypi.org/forums/viewtopic.php?f=67&t=189032 (my thread there)
  • Alan Corey
    Alan Corey almost 5 years
    Yes, it seems to work exactly as I expected. I wrote a loop sending 900 bytes to the virtual framebuffer and it drew a line as I expected. I connected from another machine to see it, it was on a Raspberry Pi, I was on an i386 OpenBSD box. Bad documentation took me the longest time, the argc and argv in the demos do nothing at all, they're just placeholders.
  • David C. Rankin
    David C. Rankin almost 5 years
    That's pretty cool, I'm glad you have it working. I have a Pi3 that I generally interface with via ssh, but I'm intrigued by your results. (I'm actually amazed at what they crammed into the Pi3, and how well Debian runs on it) Using the vnc framebuffer in place of the hardware. Probably more forgiving as well. As long as you have the correct address for the virtual framebuffer -- I guess the worst case is crashing vnc instead of taking the box down.