Many developers accustomed to the use of the Keil development tools for 8051 targets may not have had exposure to the free SDCC tools. SoftConsole uses SDCC for compiling and linking your Core8051s projects. As you develop your programs, or port your existing Keil-compatible code to use under SoftConsole for a Core8051s target, there are some fundamental differences you will want to keep in mind.
The SDCC compiler's User Manual (available under the Start menu entry for SoftConsole) covers such differences in detail. Some of the more important differences are highlighted here.
Syntax Differences
In your code developed with Keil, you can use
#pragma NOEXTEND
to make sure you've weeded out exactly what compiler-specific keywords exist.
SFR declarations
The Keil syntax with
sfr IOA = 0x80;
looks slightly different with SDCC, using either of
sfr at 0x80 IOA;
__sfr __at 0x80 IOA;
The SDCC "
at" and "
__at" keywords are used in place of an initialization-style statement. In the interests of pointing out possible compatibility issues, many users opt to choose the leading "__" version of these keywords to make their use more clear.
Also, SDCC does not require the bytes to be adjacent in memory for sfr or sfr16.
SBIT declarations
Also the case with SBIT, you use the "
at" keyword. Instead of
sbit SEL = 0x86+0;
you should have one of
sbit at 0x86+0 SEL;
__sbit __at 0x86+0 SEL;
External Registers
Keil compilers looks for "
_AT_" in the declaration of an external register, such as
EXTERN xdata volatile BYTE GPIO_LED_REG _AT_ 0xF200;
Instead, the SDCC style is
EXTERN xdata at 0xF200 volatile BYTE GPIO_LED_REG;
Printf Functionality
The SDCC compiler does support the use of printf(); however, you will need to create your own putc() function to implement the actual emitting of bytes to a specific device for stdout.
Macro Workarounds
Some users elect to take advantage of macro text substitution in their source code to make the creation of more compatible code less labour-intensive. For example, you can employ:
#define SFR(a,b) __sfr __at(a) b
#define SBIT(a,c) __sbit __at(a) c
#define SBIT(a,b,c) __sbit __at(a+b) c
#define SFR16(a,b) __sfr16 __at(((b+1)<<8) | b) a
This will enable you to use "SFR(0x80, IOA)" regardless of which specific syntax they're using.
Assembly Language Programming
If you are writing a program in assembly language rather than in C, you should be aware of some differences between the asx8051 assembler and Keil's A51. As noted by Daniel Clemente in his description of using SDCC with a particular development board:
- Global symbols (tags accessible from outside) are specified with .globl (or with tag::). Then you don't need the -g when compiling.
- Files are included with .include
- Constants (equ) are done with NAME = value
- You must use .area CSEG (CODE) before the code.
- The hexadecimal values are written with 0xVALUE, and binary with 0bVALUE. In A51 they have the letter at the end.
- You don't need the end instruction at the bottom of each file.
- Keil ignores everything about upper/lower case, and even when in your code you're calling EZUSB_Delay1ms, for instance, at the assembler there's only defined the symbol EZUSB_DELAY1MS.
- Symbols created by asx8051 must have the prefix _ (it means external symbol). sdcc adds it automatically when compiling C.
ISO/ANSI Compliance
There are some traits of the SDCC compiler that are not in full compliance with the ISO standard for the C programming language. Users who would like to know the specifics are encouraged to consult section 8.2, "ANSI-Compliance", in the SDCC User Manual (available in HTML and PDF format under the Start menu entry for SoftConsole).