SDCC tutorial

This is a small tutorial how to invoke and use the Small Devices C Compiler (SDCC).
SDCC can be found at http://sdcc.sourceforge.net/. It is a cross compiler for ANSI C with various MCU targets including MCS51, PIC14 and Z80.
All testing has been done under GNU/Linux and the instructions to build and operate SDCC under other operating systems may vary considerably.

Building the compiler

The compiler comes as a standard GNU package as sourcecode licensed under the GNU General Public License. Just go to http://sdcc.sourceforge.net/ and grab a current source distribution. Now follow these simple steps to build, test and install the compiler:

  • change to a directory of your choice to build the compiler ~/src/ might be an optimal choice
  • $ tar xvzf path/to/sdcc/source/sdcc*.tar.gz
  • $ cd sdcc
  • $ ./configure
  • $ make             # this will take some time!
  • $ su -c “make install”
  • now typein your root passwort to install the SDCC system into /usr/local

To build SDCC, you will need GNU Make, GCC, Flex and somemore tools. A standard GNU development and compiling environment should suffice.

First test

The first compiler test is simple: just type at your shell prompt:

  • $ sdcc -v

If you see the following output in your terminal, all went well and SDCC was properly installed on your system.

SDCC : mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51/ds400/hc08 2.4.8 #977 (Mar 202005) (UNIX)

Now SDCC is installed and should be ready to build programs for any supported MCU.

Your first program

As I have a mcu board with a MCS51 compatible controller, we’ll assume from now on that you will want to develop your C program for a MCS51 target.
Write your C program with your favourite editor, make sure to include 8051.h to gain access to all 8051 SFRs.

#include <8051.h>

Write a simple program like the following:

#include <8051.h>
void main(void)
{
int i=1;
P1=0;  /* clear PORT1  of the MCS51 – P1.7 used as LED output */
for(;;)
{
P1_7=!(P1_7);   /* toggle P1.7*/

for(i=1;i<15000;i++);
/* idle loop – eat CPU time */

}
}
Now save it as porttest.c.

Now build your C program by typing:

  • $ sdcc porttest.c

SDCC will output an awful lot of temporary and listing files while compiling the program. If all goes well, you will get an Intel HEX file called porttest.ihx.

It is a good idea to use the packihx command on the resulting .ihx as the output of SDCC is not compatible with all loaders. It works with IO redirection:

  • $ packihx <input.ihx >output.hex

By default SDCC will relocate your program to address 0x0 including a proper interrupt vector table in case you have defined interrupts from C. That is possible, just refer to the SDCC documentation. Now put the HEX file into your code memory and run it.

Relocating your program to a different location

Sometimes you will not want to relocate your program to run from 0x0. Perhaps you have a board with RAM mapped as code memory and it does not start at 0x0. Using assembly language you would simply put an ORG 0x4000 or similar into your source. SDCC has to be instructed with a compile time parameter to achieve the same effect.
Try:

  • $ sdcc –code-loc 0x4000 porttest.c

SDCC will now compile and build your program as usual but it will now have its reset vector and interrupt vector table relocated to 0x4000 and up. This means to run your program now, you have to run your code with a jump or similar from 0x4000.
Important: SDCC will still generate the interrupt vector table but it will not be initialized at the proper location. Your startup code or some sort of utility has to copy the contents of the C code interrupt vectors into the MCS51 interrupt table by hand to activate it.

Alternate output file format

SDCC cannot only output your program as a Intel HEX file but also in Motorola S-Record format. Just use a commandline like this:

  • $ sdcc –out-fmt-s19 –code-loc 0x4000 porttest.c

In case you need different output formats you can use the SRecord software package to convert from Intel Hex or Motorola S-Record to many lesser known file formats.

Using the C library

SDCC comes with a implementation of the standard C library known as libc under GNU/Linux. You can use it as normal but note that you’ll have to implement your own functions for putchar() and getchar(). All other terminal I/O functions use these and you have to link your program with a serial I/O driver and put proper putchar() and getchar() functions in. Interestingly putchar() and getchar() are no macros but real functions in SDCC contrary to the ANSI C standard.

Last words

For more detailed documentation, especially on usable memory models, inline assembler and interrupt handling, refer to the excellent SDCC documentation which should be included in your SDCC source package.
This concludes our little SDCC tutorial and we hope you will be able to get started with software development in C for your MCU with the SDCC system.