I started using SDCC to code my programs for PIC and looking the internals I found some items that I need clarification.
--> Processor PIC18F252, sdcc command line: --use-non-free --no-crt -mpic16 -p18f252
--> SDCC Version
SDCC : mcs51/gbz80/z80/z180/r2k/r3ka/ds390/pic16/pic14/TININative/ds400/hc08/s08/stm8 3.3.1 #8721 (Jun 26 2013) (MINGW64)
-->Here's the C code fragment
...
/ TIMER Section /
void timer_init() naked {
T1CONbits.T1CKPS1=0;
T1CONbits.T1CKPS0=1;
T1CONbits.T1OSCEN=1;
T1CONbits.T1SYNC=1;
T1CONbits.TMR1CS=0;
T1CONbits.TMR1ON=1;
TMR1H=248; //OVF@1ms FOSC@16MHz
TMR1L=48;
}
void timer_delayms(unsigned char c) naked {
while(c>0){
if(PIR1bits.TMR1IF!=0) { c--; PIR1bits.TMR1IF=0; }
}
}
...
--> Now the equivalent generated .ASM code (verified in .LST)
...
; ; Starting pCode block
S_blinktimer_init code
_timer_init:
; .line 12; blink.c T1CONbits.T1CKPS1=0;
0000a6 9acd bcf 0xcd, 0x5, 0 BCF _T1CONbits, 5
; .line 13; blink.c T1CONbits.T1CKPS0=1;
0000a8 88cd bsf 0xcd, 0x4, 0 BSF _T1CONbits, 4
; .line 14; blink.c T1CONbits.T1OSCEN=1;
0000aa 86cd bsf 0xcd, 0x3, 0 BSF _T1CONbits, 3
; .line 15; blink.c T1CONbits.T1SYNC=1;
0000ac 84cd bsf 0xcd, 0x2, 0 BSF _T1CONbits, 2
; .line 16; blink.c T1CONbits.TMR1CS=0;
0000ae 92cd bcf 0xcd, 0x1, 0 BCF _T1CONbits, 1
; .line 17; blink.c T1CONbits.TMR1ON=1;
0000b0 80cd bsf 0xcd, 0, 0 BSF _T1CONbits, 0
; .line 18; blink.c TMR1H=248; //OVF@1ms FOSC@16MHz
0000b2 0ef8 movlw 0xf8 MOVLW 0xf8
0000b4 6ecf movwf 0xcf, 0 MOVWF _TMR1H
; .line 19; blink.c TMR1L=48;
0000b6 0e30 movlw 0x30 MOVLW 0x30
0000b8 6ece movwf 0xce, 0 MOVWF _TMR1L
; ; Starting pCode block
S_blinkisr_high code
...
See at last line, the compiler starts another method. but the timer_init() genereated in ASM never ends and executes the precedent code if any.
My claim is independently of having __naked or not, the RETURN (or RETFIE) must be generated.
When I remove the __naked, the RETURN (or RETFIE) is generated with the context saving code.
--> My workaround
Every __naked function declared, at end of if(before the last "}") I'm issuing a "return" via assembly (the "return" C statement does not generate the RETURN/RETFIE as I expected :( )
void func() __naked { ... __asm RETURN __endasm; } void isr() __naked __interrupt... { ... __asm RETFIE __endasm; }
I'm assuming this behaviour is a bug. Please clarify!
This is no bug but intended behavior. A __naked function has no prologue, no epilogue and no return statement.