Triggered from the midiboxchat today I evalued the SDCC, an open source C compiler which is available under http://sdcc.sourceforge.net.
I programmed a so called “wrapper” which maps some of the MIOS functions to the C world, so that they are accessible as common C functions:
extern void MIOS_LCD_Clear(void);
extern void MIOS_LCD_CursorSet(char pos);
extern void MIOS_LCD_PrintChar(char c);
extern void MIOS_LCD_PrintString(char *str);
extern void MIOS_LCD_PrintPreconfString(char *str);
Two MIOS hooks directly branched to the C program:
USER_Init
extern _CMIOS_Init
goto _CMIOS_Init
USER_DISPLAY_Init
extern _CMIOS_DISPLAY_Init
goto _CMIOS_DISPLAY_Init
so that following C code was possible:
void CMIOS_Init(void)
{
}
void CMIOS_DISPLAY_Init(void)
{
MIOS_LCD_Clear();
MIOS_LCD_CursorSet(0x00);
MIOS_LCD_PrintChar('1');
MIOS_LCD_PrintChar('2');
MIOS_LCD_PrintChar('3');
}
This was working and the resulting assembler code looked exactly like I would program it in assembler. Then I tried to output a string:
static char[] = {12, 0x00, "Hello World!"}
void CMIOS_DISPLAY_Init(void)
{
MIOS_LCD_Clear();
MIOS_LCD_PrintString(hello_world);
}
But the static string above produced a table with following entries
_hello_world db 0x0c, 0x00, 0xa8
It seems that the compiler feels confused about a mix of constant values and characters Next try:
void CMIOS_DISPLAY_Init(void)
{
MIOS_LCD_Clear();
MIOS_LCD_CursorSet(0x00);
MIOS_LCD_PrintPreconfString("Hello World!");
}
but no luck: the compiler crashed with a signal error - bad, it seems that the PIC18F module hasn’t been programmed properly enough. Last try:
void CMIOS_DISPLAY_Init(void)
{
int i;
MIOS_LCD_Clear();
MIOS_LCD_CursorSet(0x00);
for(i=0; i<3; ++i)
{
MIOS_LCD_PrintChar('A' + xx);
}
}
This produced so much assembler code that it was definitely clear to me that SDCC is the wrong way to program a powerfull application:
;#LINE 7; main.c void CMIOS_DISPLAY_Init(void)
MOVFF FSR2L, POSTDEC1
MOVFF FSR1L, FSR2L
MOVFF r0x10, POSTDEC1
MOVFF r0x11, POSTDEC1
;#LINE 11; main.c MIOS_LCD_Clear();
CALL _MIOS_LCD_Clear
;#LINE 12; main.c MIOS_LCD_CursorSet(0x00);
MOVLW 0x00
CALL _MIOS_LCD_CursorSet
;#LINE 14; main.c for(i=0; i<3; ++i)
CLRF r0x10
_00109_DS_:
MOVLW 0x03
SUBWF r0x10, W
BTFSC STATUS,0
GOTO _00113_DS_
;#LINE 16; main.c MIOS_LCD_PrintChar('A' + i);
MOVLW 0x41
ADDWF r0x10, W
MOVWF r0x11
MOVF r0x11, W
CALL _MIOS_LCD_PrintChar
;#LINE 14; main.c for(i=0; i<3; ++i)
INCF r0x10, F
GOTO _00109_DS_
_00113_DS_:
MOVFF PREINC1, r0x11
MOVFF PREINC1, r0x10
;;genEndFunction: _G.nRegsSaved upon exit from function: 0
MOVFF PREINC1, FSR2L
RETURN
Just to compare it with handwritten assembler code:
_CMIOS_DISPLAY_Init:
;; stack handling excluded here
call MIOS_LCD_Clear
movlw 0x00
call MIOS_LCD_CursorSet
clrf r0x10
_CMIOS_DISPLAY_Init_Loop:
movlw 0x41
addwf rx010, W
call MIOS_LCD_PrintChar
incf rx010, F
movlw 0x03-1
cpfsgt rx010
bra _CMIOS_DISPLAY_Init_Loop
;; stack handling excluded here
return
Conclusion:
- the SDCC crashes sometimes and will therefore be hard to use for people who just want to write some lines of code without knowing about those quirks
- the code optimization is far from perfection, it seems that the compiler doesn’t know about all those nice new PIC18F instructions which help to make the code shorter
- the compiler produces too much code, therefore the applications cannot include so much features anymore
- the compiler allocates all three pointers (FSR0-FSR2), therefore some code changes will be required in MIOS which will slow down the system (especially on interrupts)
- who knows which problems I haven’t seen yet…
I’m not sure if currently the C approach is worth the effort…
Best Regards, Thorsten.