Filling the screen with a color

We are now going to demonstrate how to fill the screen with the color red. This seems a fitting color choice since our device is named the Raspberry Pi.

This program starts off looking very similar to our previous one; however, it will introduce you to some new concepts, such as memory mapping, setting, and unmapping.

Start by creating a new program in the c_programs directory called fifth_c_prog.c:

vim fifth_c_prog.c

We are now ready to start writing our application.

Copy and paste the following code into your fifth_c_prog.c file.

Once you have done this, we will walk through the code to see what exactly is going on here:

Let's start by looking at the top of the program and the headers we have included:

The first three we also used in fourth_c_prog.c but we have included two more new ones you may not be familiar with.

The first is sys/mman.h. This library contains code for memory management. We will be using features from this library including mmap and munmap. A description of the library's functionality can be found at http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_mman.h.html.

Following this is string.h, which is used for string manipulation. We need to reference this library so we can include the memset function. This is used later in our program to set the screen color.

That wraps up our headers. Let's delve into the main()method now and look at some of the similarities and differences with our previous program:

Once again we have declared a variable that is of the struct type. The main difference to what we declared before, however, is that it uses the fb_fix_screeninfo structure rather than the variable equivalent.

fb_fix_screeninfo contains device-independent immutable information about the frame buffer. This is in contrast to fb_var_screeninfo, which you saw earlier. This contains device independent mutable information about the frame buffer, such as the bits per pixel.

Following this variable definition we declare a further two variables:

The first variable is the same as we declared in our program to check the framebuffer. However, we have also included a new variable called device_map. This will be used to store the values of the mmap function.

Next, we open a connection to the framebuffer and check to see if we were successful:

Following this we make an ioctl call to assign the FBIOGET_FSCREENINFO values to our info variable:

As before, if there is an error in attempting to do this, we exit the program.

Our next block of code introduces us to the mmap function:

The mmap function is used to map or unmap devices or files into memory. You can read a detailed description about the function at http://man7.org/linux/man-pages/man2/mmap.2.html.

In our code we pass a number of parameters into the method; in fact, we pass six in total. The first parameter is the starting address for the new mapping. We have passed in the value 0 and the Linux kernel will handle creating this mapping.

Following this we pass in length bytes derived from our info variable. The smem_len attribute is the length of the frame buffer memory.

Next we pass in two values separated by a pipe specifying the memory protection. These are PROT_READ and PROT_WRITE. This means the page can be read and written to. Here, page means a chunk of either virtual or physical memory.

Our next parameter is flags. Here we can specify whether updates to a mapping are available to other processes mapping in the same area.

In our case, we pass in the value MAP_SHARED. This means other processes that map this file can see the mappings associated with it.

The final two values we pass in are the framebuffer file description and the offset. In our case the file description is the file we opened earlier using this command:

The offset value is set to 0 and thus the length value starts from this position in the framebuff_filedesc file.

After assigning the results of the mmap to device_map we check if there was an error. You will notice that we cast the value of device_map as an integer:

If there was an issue we exit the program, displaying a message to the screen.

Our final block of code consists of the following:

Let's take a look at what exactly is going on here.

You can see we use the memset()method from the String library to turn the screen red. This is achieved by passing in a number of parameters.

First is the device_map variable we just covered. This gives us a reference to the memory space we want to update.

The next value, 0x80, represents red, the color we fill the screen with. Last of all, we have reused the info variable to get the length of the frame buffer.

Directly after memset we unmap using the munmap function. This deletes the mapping for the address range. You can read more about this function if you wish at http://linux.die.net/man/2/munmap.

The last two lines of our application are very simple. The close(framebuff_filedesc) function closes the handler to the framebuffer. We then use the return statement to exit the program.

Let's try this code out now.

We will once again be using the gcc compiler.

The command to compile our application is as follows:

You do not need to link any libraries. Once we have our program we can run it as follows:

The screen should now fill red, covering up any windows that are open, including the terminal. If you move your mouse around, the desktop will start to re-render, replacing the red.

Here we have seen how to fill the screen with color, but how about drawing a line on it?