RSS

Posts Tagged ‘Raspberry Pi’

Visual Studio and the Raspberry Pi

Sunday, April 12th, 2015

The last few months have seen me turn my attention to the Raspberry Pi. The new Model B 2 offers some performance and memory improvements over the previous models and it has started to become more attractive as a development platform for embedded projects. Being a long term C/C++ developer I wanted an effective development environment for C++ development on the Raspberry Pi. One of the best and simplest development environments to setup on the PC is Microsoft Visual Studio. A recent article in The Mag Pi (Introducing the “game changing” Raspberry Pi 2, Ian McAlpine, Issue 30, page 23) commented that author would be interested in exploring GPIO development using Visual Studio. The good news is that there is no need to wait for Windows 10, you can use Visual Studio to develop C++ applications which will run on the Raspberry Pi today.

Visual Studio

Microsoft have recently released an update to the free versions of Visual Studio. Previous releases required that developers download a different version of Visual Studio depending upon the development language and platform being used. The newer version, Microsoft Visual Studio Community 2013 removes this requirement and offers a single download an installer for a multitude of languages and environments.

Another key change is that Visual Studio Community 2013 supports the installation of add-ons. The previous Express editions did not allow this.

The Visual Studio Community 2013 system requirements are high (1.6 GHz processor, 1 GB RAM and 20 GB disc space) when compared to the Raspberry Pi but Visual Studio will be running on the PC where these resources are commonly available in modern PCs.

The first step is to download and install Microsoft Visual Studio Community 2013 on the PC. There is plenty of information on the Visual Studio web site and the process is simple and so I will not go into any further detail here.

VisualGDB

VisualGDB is where all of the magic happens. This add-on developed by SysProgs allows Visual Studio to be used with a wide variety of development boards and systems including the Raspberry Pi. The add-on is installed on the PC and this allows Visual Studio to communicate with the target platform. Supported platforms include:

  1. Raspberry Pi
  2. Beaglebone
  3. MSP430
  4. STM32

amongst others.

VisualGDB is not a free product but the developers do offer a 30-day free trial so you can evaluate the add-on for free. Installation of VisualGDB is as simple as the Visual Studio installation. Full instructions can be found on the downloads page and as such will not be covered here. The full product is not free but there are discounts available for educational users.

Compiling Options

VisualGDb offers two options for compiling your application:

  • Native compilation
  • Cross compilation

Native compilation allows the user to edit the source files in Visual Studio, save them on the Raspberry Pi and then invoke the compiler on the Raspberry Pi.

Cross compilation downloads a compiler onto your PC, this is all setup and configured for you. Your source files are edited on the PC and then the local compiler is used to generate the application executable. The compiled application is then copied to the Raspberry Pi for execution or debugging.

For small applications there are very few advantages in using a cross compiler but for a large application the advantages are obvious. Compiling applications is notoriously memory and processor intensive. Larger applications will therefore benefit from the greater resources available on the PC compared to those available on the Raspberry Pi.

Debugging

Visual Studio connects to the Raspberry Pi using the GDB. To the programmer this is transparent and the experience is much the same as when debugging Windows applications on the PC.

The VisualGDB web site contains a number of tutorials all of which are excellent and easy to follow. The first and most basic connects your development environment to the Raspberry Pi and simply outputs the name of the Raspberry Pi to the remote console:

#include <stdio.h>
#include <unistd.h>

using namespace std;

int main(int argc, char *argv[])
{
    char szHost[128];
    gethostname(szHost, sizeof(szHost));
    printf("The host name is %s\n", szHost);
    return 0;
}

The first tutorial uses the C compiler on the Raspberry Pi to do this. The tutorial encourages you to place breakpoints in the code and execute the application in debug mode.

Interface Changes

One thing to note is that VisualGDB adds a new Project Properties to the project right click menu. This menu item, VisualGDB Project Properties, can be seen at the top of the menu:

Visual Studio Project Properties Menu

Visual Studio Project Properties Menu

Selecting this entry determines how your application is compiled and executed. It allows you to change the setting which were selected during the creation of the initial project and it’s connection to the Raspberry Pi.

Simple so far, no complex installation or configuration required. It just worked.

Talking to Hardware

There are a number of methods for accessing the GPIO pins on the Raspberry Pi. Each method has it’s own merits but for this experiment the priority will be speed. This will be achieved by using the Gert and Dom example from the elinux web site as a template.

Starting with the standard headers:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>

A small modification is required for the Raspberry Pi 2:

#ifdef RPiB2
    #define BCM2708_PERI_BASE        0x3F000000
#else
    #define BCM2708_PERI_BASE        0x20000000
#endif

From this point on the application follows much the same as that on the elinux web site.

//
//  GPIO Controller.
//
#define GPIO_BASE   (BCM2708_PERI_BASE + 0x200000)

#define PAGE_SIZE   (4 * 1024)
#define BLOCK_SIZE  (4 * 1024)

int  mem_fd;
void *gpio_map;

// I/O access
volatile unsigned *gpio;

// GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y)
#define INP_GPIO(g) *(gpio + ((g) / 10)) &= ~(7 << (((g) % 10) * 3))
#define OUT_GPIO(g) *(gpio + ((g) / 10)) |=  (1 << (((g) % 10) * 3))
#define SET_GPIO_ALT(g,a) *(gpio + (((g) / 10))) |= (((a) <= 3 ? (a) + 4 : (a) == 4 ? 3 : 2) << (((g) % 10) * 3))

#define GPIO_SET *(gpio + 7)  // sets   bits which are 1 ignores bits which are 0
#define GPIO_CLR *(gpio + 10) // clears bits which are 1 ignores bits which are 0

#define GET_GPIO(g) (*(gpio + 13) & (1 << g)) // 0 if LOW, (1<<g) if HIGH

#define GPIO_PULL *(gpio + 37) // Pull up/pull down
#define GPIO_PULLCLK0 *(gpio + 38) // Pull up/pull down clock

//
// Set up a memory regions to access GPIO
//
void setup_io()
{
    if ((mem_fd = open("/dev/mem", O_RDWR | O_SYNC)) < 0)
    {
        printf("can't open /dev/mem \n");
        exit(-1);
    }

    /* mmap GPIO */
    gpio_map = mmap(
        NULL,                   // Any adddress in our space will do
        BLOCK_SIZE,             // Map length
        PROT_READ | PROT_WRITE, // Enable reading & writting to mapped memory
        MAP_SHARED,             // Shared with other processes
        mem_fd,                 // File to map
        GPIO_BASE               // Offset to GPIO peripheral
        );

    close(mem_fd);              // No need to keep mem_fd open after mmap

    if (gpio_map == MAP_FAILED)
    {
        printf("mmap error %d\n", (int) gpio_map);  // errno also set!
        exit(-1);
    }

    // Always use volatile pointer!
    gpio = (volatile unsigned *) gpio_map;
}

The main application requires modification in order to repeatedly toggle the selected GPIO pin, in this case GPIO3.

int main(int argc, char **argv)
{
    // Set up gpio pointer for direct register access
    setup_io();

    // Set GPIO pin 3 to output
    INP_GPIO(3); // must use INP_GPIO before we can use OUT_GPIO
    OUT_GPIO(3);

    while (1)
    {
        GPIO_SET = 1 << 3;
        GPIO_CLR = 1 << 3;
    }

    return 0;
}

Running this application and connecting an oscilloscope generates a 41 MHz signal with approximately a 50% duty cycle.

Conclusion

Visual Studio is not the only option for developing applications on the Raspberry Pi, you can use a simple text editor on the Raspberry Pi or for something more sophisticated, you can set up Eclipse on the PC and connect to the Raspberry Pi using GDB. Both of these methods are free and have their own merits.

The text editor approach is basically already there on the Raspberry Pi as supplied. The disadvantage is that debugging is not integrated and can be difficult.

Eclipse is a free development environment but it can be difficult to setup although tutorials are available.

As we have seen, Visual Studio is free but requires VisualGDB to be installed and VisualGDB is not a free product although educational discounts are available. On the plus side, VisualGDB is simple to install and configure. It is also supplied with a set of project templates for the Raspberry Pi.

Bare Metal GPIO on the Raspberry Pi

Monday, June 16th, 2014

The Raspberry Pi is classically used as a single board computer running Linux but it also offers the possibility of using the board without Linux (known as bare metal development). Add to this the availability of free ARM development tools and we have the opportunity to develop on a high speed ARM processor at a reasonable cost.

This post explores the steps necessary to toggle a GPIO pin on the Raspberry Pi by directly accessing the registers without the presence of an operating system.

Project Description

For this simple project the software will need to perform three operations:

  • Configure the GPIO port
  • Set the GPIO pins for the selected port
  • Reset the GPIO pins for the selected port

The application here will toggle two GPIO pins, one connected to one of the LEDs on the board (GPIO16 connected to the OK/ACT LED) and the second connected to a pin on the header (GPIO18 connected to Pin 12 on header P1).

Resources

There are already a number of resources out on the internet which cover this topic including a large number references in the Bare Metal forum on the Raspberry Pi web site.

As well as the Raspberry Pi web site there are a number of other sites discussing OS development for the Raspberry Pi. This post was going to be a comprehensive write up of the tools and various scripts required to put together a bare metal example but I have since discovered an excellent tutorial on this subject on the OSDev web site. I would heartily recommend that you visit this web site and review the material on the Raspberry Pi C Tutorial page.

Hardware

Before we look at the registers we need to take a look at the first chapter of the Broadcom BCM2835 ARM Peripheral document. Particularly the following two paragraphs:

Physical addresses range from 0x20000000 to 0x20FFFFFF for peripherals. The bus addresses for peripherals are set up to map onto the peripheral bus address range starting at 0x7E000000. Thus a peripheral advertised here at bus address 0x7Ennnnnn is available at physical address 0x20nnnnnn.

and

The peripheral addresses specified in this document are bus addresses. Software directly accessing peripherals must translate these addresses into physical or virtual addresses, as described above. Software accessing peripherals using the DMA engines must use bus addresses.

The remainder of the document discusses the registers and uses addresses in the 0x7Ennnnnn-0x7EFFFFFF memory range. This means that any software written should translate the 0x7Ennnnnn range down to the 0x20nnnnnn range.

GPIO Configuration Register

The software will need to set the function for GPIO pins 16 and 18 using the function select registers. The description of these registers and the GPIO pins which they relate to can be found on page 92 of the Broadcom BCM2835 ARM Peripheral manual. The port is configured using three bits in the register. The three bits have the following meaning:

Bit FieldDescription
000GPIO Pin is an input
001GPIO Pin is an output
100GPIO Pin configured for alternate function 0
101GPIO Pin configured for alternate function 1
110GPIO Pin configured for alternate function 2
111GPIO Pin configured for alternate function 3
011GPIO Pin configured for alternate function 4
010GPIO Pin configured for alternate function 5

The two pins the software will be accessing are pins 16 and 18. These pins are configured using bits 24-26 for GPIO 18 and 18-20 for GPIO 16 of the GPFSEL1 register at 0x7E200004. This maps to the address 0x20200004.

Set GPIO Pin High

The GPIO pins are set by setting a bit in the GPSETn registers. Both GPIO16 and GPIO18 are set through the GPSET0 register (see page 95 of the Broadcom BCM2835 ARM Peripheral manual). The address of this register is 0x7E20001C (0x2020001C).

Set GPIO Pin Low (Clear the GPIO Pin)

The GPIO pins are reset by setting a bit in the GPCLRn registers. Both GPIO16 and GPIO18 are set through the GPCLR0 register (see page 95 of the Broadcom BCM2835 ARM Peripheral manual). The address of this register is 0x7E200028 (0x20200028).

Software

The application is a relatively simple one, toggling a GPIO pin continuously. The following should suffice:

//
//  Flags used to configure the GPIO port.
//
#define FLAG_GPIO_RESET     ((7 << 18) | (7 << 24))
#define FLAG_GPIO_CONFIG    ((1 << 18) | (1 << 24))
//
//  Bits which will allow control of GPIO0 pins for the status
//  LED and the header on the Pi.
//
#define GPIO_PINS           ((1 << 16) | (1 << 18))
//
//  The following register definitions are used to access the GPIO
//  pins on the BCM2835.  The register definitions are taken from
//  section 6 of the BCM manual and the mapping is described in
//  section 1 of the same.
//
//  Address of the register which will configure the GPIO pins.
//
volatile unsigned int *gpsel1 = (unsigned int *) 0x20200004;
//
//  Address of the register which will set the GPIO pins.
//
volatile unsigned int *gpset0 = (unsigned int *) 0x2020001C;
//
//  Address of the register which will clear the GPIO pins.
//
volatile unsigned int *gpclr0 = (unsigned int *) 0x20200028;
//
//  Contents of the GPIO configuration register.
//
unsigned int gpioConfig;
//
//  Main program loop.
//
int main()
{
    //
    //  Reconfigure GPIO 16 and 18 to be outputs.  Clear any
    //  previous GPIO configuration for these pins.
    //
    gpioConfig = *gpsel1;
    //
    //  Firstly, remove any configuration for GPIO 16 & 18.
    //
    gpioConfig &= ~FLAG_GPIO_RESET;
    //
    //  Now configure GPIO 16 & 18 to be plain GPIO outputs.
    //
    gpioConfig |= FLAG_GPIO_CONFIG;
    *gpsel1 = gpioConfig;
    //
    //  Toggle GPIO 16 and 18 forever.
    //
    while (1)
    {
        *gpclr0 = GPIO_PINS;
        *gpset0 = GPIO_PINS;
    }
    return(0);
}

The makefile I used to build the application looks as follows:

#
#   Root directory/name of the ARM tools used to build the application.
#
ARMTOOLSROOT = e:\utils\gcc-arm\bin\arm-none-eabi

#
#   C Compiler options.
#
OPTIONS = -nostdlib -ffreestanding -O3

#
#   What do we need to make to build everything?
#
all: kernel.img
    copy /y /d kernel.img j:\

HelloWorldBlinky.o : HelloWorldBlinky.c
	$(ARMTOOLSROOT)-gcc $(OPTIONS) -c HelloWorldBlinky.c -o HelloWorldBlinky.o

HelloWorldBlinky.elf : memmap HelloWorldBlinky.o 
	$(ARMTOOLSROOT)-ld HelloWorldBlinky.o -T memmap -o HelloWorldBlinky.elf
	$(ARMTOOLSROOT)-objdump -D HelloWorldBlinky.elf > HelloWorldBlinky.list

kernel.img : HelloWorldBlinky.elf
	$(ARMTOOLSROOT)-objcopy HelloWorldBlinky.elf -O binary kernel.img

#
#   Delete any previously built files.
#
clean :
	del -f HelloWorldBlinky.o
	del -f HelloWorldBlinky.elf
	del -f HelloWorldBlinky.list
	del -f kernel.img

Tools

The software present here was compiled using the version 4.8.3 of the ARM eabi tools.

Conclusion

Compiling the above code and executing the application results in the following output when the oscilloscope is connection to GPIO18:

Raspberry Pi GPIO Output

Raspberry Pi GPIO Output

It is necessary to review the documents in the resources section of this post in order to fully understand the theory behind this application.

And now it is time to take on some more complex topics.

Setting Up the Raspberry Pi

Thursday, May 31st, 2012

So having received a Raspberry Pi I suppose I should start to configure it to make it a little more to my taste but also to fit in with my local systems at home. To do this I am going to perform the following tasks:

  1. Install the operating system of choice (Debian 6)
  2. Resize the partitions
  3. Backing up your system
  4. Enable SSH
  5. Changing the message of the day
  6. Changing the hostname
  7. Changing prompt colours
  8. Using History

I have a habit of configuring the device using the root user. There are many debates on whether this is advisable or not. I do not normally work with the root account but for configuring machines I find it more convenient to login as root. I do this because you are often executing a large number of commands which require super user privileges and it is quicker to do this if you are not prefixing every command with the sudo command.

So in this tutorial I will be assuming that you have changed to the root account before running any of these commands. You can do this by executing the command:

sudo su

Remember, if you do this you can find yourself putting the system stability at risk if you mistype a command or execute a command accidentally. The most infamous example is deleting the entire file system by a mistyped command – you can do serious damage as superuser.

Throughout this article we will be editing text files. The editor being used is the nano text editor. It’s small, simple and already installed on the system.

These steps will also require a number of reboots. I have found that entering the following command:

ping -t 192.168.10.5

into a command prompt on my Windows machine will give me a good indication when my Raspberry Pi is ready for me to SSH back onto the device.

Installing Debian

First job is to download the operating system image from the Raspberry Pi web site. Extracting this to your hard drive leaves you with a 1.8 GByte disc image file.

This file can be written to a SD card using the Win32DiskImager (the link can also be found in the downloads section of the Raspberry Pi web site). Start this application, select the image file you have just extracted, select the location of the SD card and hit the Write button.

Once completed the SD card should be ready to use. Insert the SD card into the Raspberry Pi, connect a keyboard, mouse (optional) and monitor and you are ready to go.

Resizing the partitions

The default installation allows for the use of SD cards starting at 2GB and going upwards. This means that by default you have a single partition available to you and possibly a large amount of unused space. To use this space you really have two options, create alternative partitions and mount these or resize the existing partition to the full extent of the SD card. I personally went for the later option as I have always preferred not to have to worry about partition sizes and where I can put files.

Rather than describe this fully here I will simply point you to a rather good video on the subject on the unofficial RaspberryPiBeginners channel on YouTube.

Backing Up Your System

An important part of maintaining these systems is backing up on a regular basis. I have an 8 GByte SD card for the Raspberry Pi and a laptop with over 200 GBytes of free space. I have decided that for me I can afford a few GBytes on the laptop for an occasional full system image with some incremental backups of user files.

For a full backup of the SD card we need to use the same tool as we used to write the original image file. This time instead of writing the image we read the SD card and generate an image file. So insert the SD card into the computer’s SD card reader and select the drive containing the SD card. Enter a name for the image file and hit the Read button. At the end of the process you will have a file which can be written back to the SD card should any changes make the system un usable.

Enable SSH

I find it a little intrusive having to connect the Raspberry Pi to my monitor and USB hub as it disrupts the PC setup. To help avoid this I have setup the system to use SSH, I can then connect to the Raspberry Pi using PuTTY from the PC.

Enabling this is as simple as renaming a file and rebooting the device.

So logon to the Raspberry Pi and execute the following commands:


cd /boot
mv boot_enable_ssh.rc boot.rc

Next we need to make a note of the IP address of the device using the following command:

ifconfig

Make a note of the IP address of the device (look for the IP address in the eth0 section of the output from this command).

Now reboot the device with the following command:

reboot

The final thing to do is check that everything works. So start PuTTY (or your favourite SSH client) and connect to the machine using this client. You should see the login prompt in the client.

Changing the Message of the Day

This is a trivial task and I do this on each of my Linux machines so that I can see which machine I am connected to as soon as I login. The default message for the Debian distribution I have is as follows:

Linux raspberrypi 3.1.9+ #90 Wed Apr 18 18:23:05 BST 2012 armv6l

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.

This file is created on system boot by a shell script. You can change the end of the file by editing the text in the file /etc/motd.tail. So simply log on to the machine and edit this file adding the text you wish to see when you login. Remember, you will need to be superuser to do this.

sudo su
cd /etc
nano motd.tail

Now restart the system and logon once more. This time you will see your modified message appearing instead of the default message.

Changing the Host Name

Changing the host name is simple and requires that two files are edited.

  • /etc/hostname
  • /etc/hosts

The hostname file should be edited to contain the host name and nothing else. In my case I am going to call this device RPiDev. So edit the hostname file using an editor such as nano, remove the existing entry and add your selected name and save the file.

The next file is a little more complex as this contains routing information for the machine. By default, this file looks like this:

::1 raspberrypi localhost6.localdomain6 localhost6
127.0.1.1 raspberrypi

127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

We need to edit this file and replace all instances of the text raspberrypi with your chosen name. My hosts file now looks like this:

::1 RPiDev localhost6.localdomain6 localhost6
127.0.1.1 RPiDev

127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

Changing the Prompt Colour

Working with the system in console mode can be a little dull as you only get to see text in black and white. You can add a little colour to the system by changing the prompt. I did this by editing the /etc/bash.bashrc file. You will need to be the root user to edit this file. So edit this file and about half way down you will find the following text:

PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '

Try changing this to the following:

PS1='${debian_chroot:+($debian_chroot)}\! \[\033[01;32m\][\u@\h] \[\033[01;34m\]\w \$ \[\033[00m\]'

Now logout and then back in to the device. You should find your prompt has changed with the user and system name appearing in light green and the current directory appearing in a light blue.

The colour coding is performed by the text in the square brackets, particularly the [01;34m\] commands. The following colour codes can be used:

Colour Name Code
Black 00;30
Dark Gray 01;30
Blue 00;34
Light Blue 01;34
Green 00;32
Light Green 10;32
Cyan 00;36
Light Cyan 01;36
Red 00;31
Light Red 01;31
Purple 00;35
Light Purple 01;35
Brown 00;33
Yellow 01;33
Light Gray 00;37
White 01;37

Using History

In the section on changing the prompt you will see a little piece of magic when setting the PS1 variable. About half way along you will see the text:

\!

This piece of text is a special flag which indicates that the shell should insert the current history number for the command into the prompt. So on my system I use the above value for PS1 and I see the following prompt:

146 [root@RPiDev] /etc #

The number at the start of the line can be used to re-execute a particular command again. This is done by prefixing the command number with the ! character. So let’s say that command 130 was cd /etc/networks and I want to get back to this directory. I can either type the command in again or as I know this was command number 130 I can type in !130.

You can display the full history by executing the command history from the command prompt.

Framboise Pi est arrivée

Thursday, May 24th, 2012

I have been waiting for this event for more than a year now. The day when I would finally get my hands on a Raspberry Pi. Today it finally happened. It has been a roller-coaster ride with the initial release expected in December 2011 and launch delayed, finally announced and then over subscribed, it has been an eventful 12 months.

Today all of the waiting came to an end as the board finally arrived.

Raspberry Pi on desk

After waiting for 12 months, waiting for the end of a working day to play with the device was probably the most difficult. But at the end of the day it was time to hook up the device and power it up.

Raspberry Pi connected to hub and power,

And connected to a monitor:

Raspberrry Pi hooked up to Monitor

So now I know the device is working it is time to find time to play but that will have to wait as other projects are demanding my attention. In some way this is a shame as I really believe in what this project stands for but the delays and hype have dulled the edge.

Back in the bag for another day.