Programming PIC's in Linux using C with SDCC

In my last article, Programming PIC Microcontrollers in Linux, I talked about using using gputils and gpsim to assemble and simulate a basic PIC program. After writing this article, I recieved an email from Martyn Welch regarding the article he recently wrote: Installing and using SDCC on Linux. SDCCs a free C compiler for several small devices, including the PIC microcontroller. In the past, I have worked a little bit in C for PIC's using the PICC Lite compiler. The PICC Lite compiler, which is the freeware version of the PICC compiler, ONLY supports the following processors: 16F877, 16F877A, 12F675, 12F629, 16F627, 16F627A, 16F684, 16C84, 16F84 and 16F84A. This is fine for many of us hobby PIC programmers, however, I have decided to use the Small Device C Compiler (SDCC) instead because it is open source, release under GPL, which means it's free and will remain free. I always try to support open-source software when I can, and for the work I do with robotics and hobby electronics, there is no drawbacks to using SDCC. This tutorial is written to take Martyn's article on installing SDCC to the next step. We'll compile another blinking LED program, this time written in C, and simulate it using gpsim.

Target Audience

In this article I will assume that you have already installed and tested gpsim. If you have not, see my article: Programming PIC Microcontrollers in Linux. I'm also assuming that you know a little bit of the C language. If you don't, that's okay, just don't expect to learn C from this article. You will need to be comfortable with installing software from source in Linux (as is discussed in the last article) and enter commands in a terminal. This article IS NOT an introduction to PIC programming, Linux, or C Programming. It's just to get you started compiling the programs with SDCC and simulating them with gpsim.

Resources

The information in this article is from my personal experience with setting up SDCC and gpsim. The following websites were used as references.

Installing SDCC

I'm not going to re-invent the wheel here. Please refer to Installing and using SDCC on Linux - By: Martyn Welch for an overview on installing SDCC. I used his article with the following exceptions:
  1. I didn't use the CVS to download SDCC. Instead, I downloaded version 2.4.0 from the Sourceforge download page.
  2. I was using Fedora, and not Debian, therefore my paths were different. GPUTILS and SDCC were installed to the default dir of /usr/local/share/ on my distribution, and not /usr/share/. If you're not too familiar with Linux, and don't know where they are installed, simply do a file search from your main menu looking for 'gputils' for example.
Also, pay attention to part 'Setting up PIC File Headers', as that's an importatnt part. What you're doing there, is downloading inc2h.pl and copying it to the folder where your sdcc is installed. In my case, I downloaded it to /usr/local/share. This is a perl script which takes all the header files from gputils and creates the *.h header files you will be using in your C programs. Being a script, it will need to be executable. Issue a chmod a+x inc2h.pl command to make it executable. So, assuming you have installed SDCC and downloaded inc2h.pl to the sdcc installation folder, your sequence of commands to run inc2h.pl might look like:
cd /usr/local/share/sdcc
chmod a+x inc2h.pl
cd /usr/local/share/sdcc/include
mkdir pic
cd pic

for file in `ls /usr/local/share/gputils/header/p*.inc`
do export picstring=`echo $file | sed "s/\/usr\/local\/share\/gputils\/header\/p//; s/.inc//"`
../../inc2h.pl $picstring /usr/local/share/gputils > pic$picstring.h
done
To test that SDCC is working, copy and paste the below code into a file called 'test.c':
char test; 

 void main(void) { 
 test=0; 
}
And then compile the code using:
sdcc test.c
That simple little program is a minimal C program to verify that SDCC is installed. We still could have more problems if we did not get our libraries and/or headers properly installed. See the SDCC Online Manual for additional information on the installation procedure.

Compiling a C Program for the PIC - toggle_led.c

Now, copy the below code into another file, this time called 'toggle_led.c' (or download toggle_led.c.tar.gz):
/*
 toggle_led.c
 Micah Carrick - email@micahcarrick.com
 04.25.2005

 Toggles an LED on Pin 1 of PORTB on a PIC16F627. Written
 as a sample for the article on using SDCC and GPSIM in
 Linux. http://www.micahcarrick.com/v2/content/view/14/4/

 Compile: sdcc --debug -mpic14 -p16f627 toggle_led.c
 Simulate: gpsim -pp16f627 -s toggle_led.cod toggle_led.asm

*/

/* Define processor and include header file. */
#define __16f627
#include"pic/pic16f627.h"

/* Setup chip configuration */
typedef unsigned int config;
config at 0x2007 __CONFIG = _CP_OFF & 
 _WDT_OFF & 
 _BODEN_OFF & 
 _PWRTE_OFF & 
 _ER_OSC_CLKOUT & 
 _MCLRE_ON & 
 _LVP_OFF;

#define b1 0x02 /* pin 1 on PORTB */
#define B_OUTPUTS 0xFD /* value used to setup TRISB */

void main(void) {

 /* PORTB.1 is an output pin */ 
 TRISB = B_OUTPUTS; 

 while(1) { /* Loop forever */

 /* toggle bit 1 */
 PORTB = (PORTB ^ b1); 

 }
}
This is a simple little C program (take note: I'm not very good at C!) that will simple toggle pin 1 on PORTB on and off, much like our program written in PIC assembly in Programming PIC Microcontrollers in Linux. So, now we compile our program with:
sdcc --debug -mpic14 -p16f627 toggle_led.c
The --debug option gives us the debug information that is useful during the development process. -mpic14 specifies the "port" to use, in this case for PIC microcontrollers. -p16f627 tells us which processor we are using, in this case, a PIC16F627. (If you don't actually have a PIC16F627 that's okay, we're just simulating in this article. You don't need to physically have ANY chip!). The output should have looked something like:
Processor: 16f627
message: using default linker script "/usr/local/share/gputils/lkr/16f627.lkr"
Now, if you issue the ls command, you should see a bunch of new files. Notable, toggle_led.hex which is the program we would be "burning" into the chip, and toggle_led.cod which is what we'll pass to gpsim so that we have code show up in the Source Browser window. So, let's do that...

Simulating the toggle_led.c Program with gpsim

Just like we did in Programming PIC Microcontrollers in Linux, we're going to simulate the program by passing gpsim the hex file, which is the actual machine code instructions, aswell as the cod file which contains information needed to step through the source code. Issue the following command to start the simulator with our program:
gpsim -pp16f627 -s toggle_led.cod toggle_led.asm
This will start up gpsim. If the windows don't open automatically, open the Source Browser window and the Breadboard window from the 'Windows' menu. When you first start gpsim, it should look something like the image below:

gpsim window layout with C code displayed

Notice how unlike the last tutorial, the Source Browser now shows our C code AND the assembly code. If you step through the program you'll see the PORTB.1 change to an output (indicated by the arrow pointing away from the chip in the Breadboard window) and then you'll see the pin toggle from high to low (indicating by red for high, and green for low). If you have the C code displayed in the Source Window as you step through the code, each step isn't one instruction, but rather one chucnk of instructions which make up a given line in the C code. To see this, change to the toggle_led.asm tag in the Source Browser window and step through the code.

gpsim window layout with C code displayed

As you can see now when each step is just 1 assembly instruction. This is VERY handy as it allows us to see how the code we wrote in C is translated to assembly. In our example, it is clear that our line to toggle the pin in C:
PORTB = (PORTB ^ b1)
Is compiled into the following assembly code by SDCC:
;#CSRC toggle_led.c 41
; PORTB = (PORTB ^ b1); MOVLW 0x02 BCF STATUS,5 XORWF _PORTB,F
As you see in the comments which sdcc put in there, this code is created from toggle_led.c on line 41. This is a great way to optimize your code and really understand what it's doing! So, now you're on your own. Good luck!
Did you enjoy Programming PIC's in Linux using C with SDCC? If you would like to help support my work, A donation of a buck or two would be very much appreciated.
blog comments powered by Disqus
Linux Servers on the Cloud IN MINUTES