|
|
View previous topic :: View next topic |
Author |
Message |
garyatpt
Joined: 01 Oct 2018 Posts: 8
|
PIC18F27K42 function pointer issue |
Posted: Mon Oct 01, 2018 9:58 pm |
|
|
Dear All,
1. The function pointer can not work when Optimization Level set to 9. (+Y=9)
2. The function pointer can work when Optimization Level set to 0.
(+Y=0)
Code: |
//==============================================
//ccs5.081
//function_pointer_demo
//==============================================
#include <18F27K42.h>
#fuses NOWDT
#use delay(internal=8MHz)
int8 handle_dummy=0;
//Function Prototypes//////////
int8 dummy(int8 dummy);
void function_pointer_test(void);
int8 (*p_dummy)(int8 dummy);
//~~~~~~~~~~~~~~~~~~~~~
int8 dummy(int8 dummy)
{
int16 i;
i++;
return (dummy+1);
}
//~~~~~~~~~~~~~~~~~~~~~
void function_pointer_test(void)
{
p_dummy = &dummy; //assigment
while(1)
{
handle_dummy = (*p_dummy)(0x55);
}
}
//--------------------------------------------------
void main(void)
{
function_pointer_test();
while(1)
{
}
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Mon Oct 01, 2018 11:16 pm |
|
|
I'd point this out to CCS.
It sounds as if at the high optimisation level, the actual function 'dummy' is being perceived as 'not used', and optimised away!...
On many other compilers I would declare a function like this as #noinline, and this is the standard in such cases. CCS's #separate would do the same. Try this.
Odd. I've just tried building the posted code with optimisation set to 9, and it works correctly. I've tried both from the command line, and the IDE. Are you sure the posted example demonstrates the problem?. It works perfectly for me.... |
|
|
garyatpt
Joined: 01 Oct 2018 Posts: 8
|
|
Posted: Tue Oct 02, 2018 3:00 am |
|
|
I am sure!
The function pointer can not work when Optimization Level set to 9. (+Y=9)
1. ccs5.081
2. mplabx ide v4.2
3. simulator or RealICE |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Tue Oct 02, 2018 10:50 am |
|
|
CCS PCH C Compiler, Version 5.081, xxxxx 02-Oct-18 17:46
Filename: C:\Program Files\PICC\testmplab\test\Multiplexer\ptr.lst
ROM used: 152 bytes (0%)
Largest free fragment is 65536
RAM used: 9 (0%) at main() level
12 (0%) worst case
Stack used: 1 locations (0 in main + 1 for interrupts)
Stack size: 31
*
00000: GOTO 005A
.................... //==============================================
.................... //ccs5.081
.................... //function_pointer_demo
.................... //==============================================
....................
.................... #include <18F27K42.h>
.................... //////////// Standard Header file for the PIC18F27K42 device ////////////////
.................... ///////////////////////////////////////////////////////////////////////////
.................... //// (C) Copyright 1996, 2014 Custom Computer Services ////
.................... //// This source code may only be used by licensed users of the CCS C ////
.................... //// compiler. This source code may only be distributed to other ////
.................... //// licensed users of the CCS C compiler. No other use, reproduction ////
.................... //// or distribution is permitted without written permission. ////
.................... //// Derivative programs created using this software in object code ////
.................... //// form are not restricted in any way. ////
.................... ///////////////////////////////////////////////////////////////////////////
.................... #device PIC18F27K42
00004: MOVFFL 3FEC,3FFA
*
0000A: MOVFFL 3FEC,3FFB
*
00010: MOVF 3FED,F
00012: MOVFFL 3FEF,3FE8
*
00018: MOVWF 3FF9
0001A: RETURN 0
....................
.................... #list
....................
.................... #opt 9
.................... #fuses NOWDT
.................... #use delay(internal=8MHz)
....................
....................
.................... int8 handle_dummy=0;
....................
....................
.................... //Function Prototypes//////////
.................... int8 dummy(int8 dummy);
.................... void function_pointer_test(void);
.................... int8 (*p_dummy)(int8 dummy);
....................
....................
.................... //~~~~~~~~~~~~~~~~~~~~~
.................... int8 dummy(int8 dummy)
.................... {
.................... int16 i;
....................
.................... i++;
0001C: INCF 0A,F
0001E: BTFSC 3FD8.2
00020: INCF 0B,F
.................... return (dummy+1);
00022: MOVLW 01
00024: ADDWF 09,W
00026: MOVWF 01
00028: RETURN 0
.................... }
....................
....................
.................... //~~~~~~~~~~~~~~~~~~~~~
.................... void function_pointer_test(void)
.................... {
....................
.................... p_dummy = &dummy; //assigment
0002A: CLRF 03
0002C: MOVLW 00
0002E: MOVWF 02
00030: MOVLW 00
00032: MOVWF 01
00034: MOVLW 1C
00036: MOVFF 03,08
0003A: MOVFF 02,07
0003E: MOVFF 01,06
00042: MOVWF 05
....................
....................
.................... while(1)
.................... {
.................... handle_dummy = (*p_dummy)(0x55);
00044: CLRF 3FEA
00046: MOVLW 05
00048: MOVWF 3FE9
0004A: MOVLW 55
0004C: MOVWF 09
0004E: RCALL 0004
00050: MOVFF 01,04
00054: BRA 0044
.................... }
00056: GOTO 0094 (RETURN)
....................
.................... }
....................
....................
.................... //--------------------------------------------------
.................... void main(void)
0005A: MOVLB 39
0005C: BSF xE5.7
0005E: BCF xE5.6
00060: CLRF 3FF8
00062: BCF 3FD2.5
00064: CLRF xDE
00066: CLRF xDB
00068: CLRF xDD
0006A: MOVLW 03
0006C: MOVWF xDF
0006E: MOVLW 60
00070: MOVWF xD9
00072: CLRF 04
00074: MOVLB 3A
00076: CLRF x40
00078: CLRF x50
0007A: CLRF x60
0007C: CLRF x80
0007E: MOVLB 3E
00080: CLRF xBD
00082: CLRF xBE
00084: CLRF xBF
00086: CLRF xBC
00088: CLRF xB9
0008A: CLRF xBA
0008C: CLRF xBB
0008E: CLRF xB8
.................... {
....................
.................... function_pointer_test();
00090: MOVLB 0
00092: BRA 002A
....................
.................... while(1)
.................... {
00094: BRA 0094
.................... }
.................... }
00096: SLEEP
Configuration Fuses:
Word 1: FFFC NOEXTOSC RSTOSC_EXT NOCLKOUT PRLOCK1WAY CKS FCMEN
Word 2: FFF7 MCLR NOPUT NOMVECEN IVT1WAY NOLPBOR BROWNOUT BORV24 ZCDDIS PPS1WAY STVREN NODEBUG NOXINST
Word 3: FF9F WDTSW NOWDT WDTWIN_SW WDTCLK_SW
Word 4: DFFF BBSIZ512 NOBOOTBLOCK NOSAF NOWRT NOWRTB NOWRTC NOWRTD NOWRTSAF NOLVP
Word 5: FFFF NOPROTECT
Listing attached. As you can see, 'dummy' is at 001C, and it merrily loads this value.
It does work (tested).
If your listing is different, check the compiler version number (43290). It is possible that they did an 'early' release of 5.018, with a different build number. If so, download the current version and try again.
It would be a better test, to actually use the return value. Otherwise it would be legitimate for the call to be optimised away, since the value is never used. |
|
|
garyatpt
Joined: 01 Oct 2018 Posts: 8
|
|
Posted: Tue Oct 02, 2018 8:57 pm |
|
|
Listing attached.
It's the same as yours.
I can see that 'dummy' is at 001C, but the process never enters here.
When the return value 'handle_dummy' is actually used, the process will never enter here again.
Can you use the simulator(MPLABX-IDE) to help with testing by single step?
Thanks!
Code: | CCS PCH C Compiler, Version 5.081d, 1 03-Oct-18 09:57
Compiler operating in Evaluation Mode
To obtain a fully enabled compiler visit www.ccsinfo.com/products
Filename: E:\data\ccs_codeX\Error_Test_Code\function_pointer_demo\function_pointer_demo.X\build\default\debug\function_pointer_demo-1.lst
ROM used: 152 bytes (0%)
Largest free fragment is 65536
RAM used: 9 (0%) at main() level
12 (0%) worst case
Stack used: 1 locations (0 in main + 1 for interrupts)
Stack size: 31
*
00000: GOTO 005A
.................... //==============================================
.................... //ccs5.081
.................... //function_pointer_demo
.................... //==============================================
....................
.................... #include <18F27K42.h>
.................... //////////// Standard Header file for the PIC18F27K42 device ////////////////
.................... ///////////////////////////////////////////////////////////////////////////
.................... //// (C) Copyright 1996, 2014 Custom Computer Services ////
.................... //// This source code may only be used by licensed users of the CCS C ////
.................... //// compiler. This source code may only be distributed to other ////
.................... //// licensed users of the CCS C compiler. No other use, reproduction ////
.................... //// or distribution is permitted without written permission. ////
.................... //// Derivative programs created using this software in object code ////
.................... //// form are not restricted in any way. ////
.................... ///////////////////////////////////////////////////////////////////////////
.................... #device PIC18F27K42
00004: MOVFFL 3FEC,3FFA
*
0000A: MOVFFL 3FEC,3FFB
*
00010: MOVF 3FED,F
00012: MOVFFL 3FEF,3FE8
*
00018: MOVWF 3FF9
0001A: RETURN 0
....................
.................... #list
....................
.................... #opt 9
.................... #fuses NOWDT
.................... #use delay(internal=8MHz)
....................
....................
.................... int8 handle_dummy=0;
....................
....................
.................... //Function Prototypes//////////
.................... int8 dummy(int8 dummy);
.................... void function_pointer_test(void);
.................... int8 (*p_dummy)(int8 dummy);
....................
....................
.................... //~~~~~~~~~~~~~~~~~~~~~
.................... int8 dummy(int8 dummy)
.................... {
.................... int16 i;
....................
.................... i++;
0001C: INCF 0A,F
0001E: BTFSC 3FD8.2
00020: INCF 0B,F
.................... return (dummy+1);
00022: MOVLW 01
00024: ADDWF 09,W
00026: MOVWF 01
00028: RETURN 0
.................... }
....................
....................
.................... //~~~~~~~~~~~~~~~~~~~~~
.................... void function_pointer_test(void)
.................... {
....................
.................... p_dummy = &dummy; //assigment
0002A: CLRF 03
0002C: MOVLW 00
0002E: MOVWF 02
00030: MOVLW 00
00032: MOVWF 01
00034: MOVLW 1C
00036: MOVFF 03,08
0003A: MOVFF 02,07
0003E: MOVFF 01,06
00042: MOVWF 05
....................
....................
.................... while(1)
.................... {
.................... handle_dummy = (*p_dummy)(0x55);
00044: CLRF 3FEA
00046: MOVLW 05
00048: MOVWF 3FE9
0004A: MOVLW 55
0004C: MOVWF 09
0004E: RCALL 0004
00050: MOVFF 01,04
00054: BRA 0044
.................... }
00056: GOTO 0094 (RETURN)
....................
.................... }
....................
....................
.................... //--------------------------------------------------
.................... void main(void)
0005A: MOVLB 39
0005C: BSF xE5.7
0005E: BCF xE5.6
00060: CLRF 3FF8
00062: BCF 3FD2.5
00064: CLRF xDE
00066: CLRF xDB
00068: CLRF xDD
0006A: MOVLW 03
0006C: MOVWF xDF
0006E: MOVLW 60
00070: MOVWF xD9
00072: CLRF 04
00074: MOVLB 3A
00076: CLRF x40
00078: CLRF x50
0007A: CLRF x60
0007C: CLRF x80
0007E: MOVLB 3E
00080: CLRF xBD
00082: CLRF xBE
00084: CLRF xBF
00086: CLRF xBC
00088: CLRF xB9
0008A: CLRF xBA
0008C: CLRF xBB
0008E: CLRF xB8
.................... {
....................
.................... function_pointer_test();
00090: MOVLB 0
00092: BRA 002A
....................
.................... while(1)
.................... {
00094: BRA 0094
.................... }
.................... }
00096: SLEEP
Configuration Fuses:
Word 1: FFFC NOEXTOSC RSTOSC_EXT NOCLKOUT PRLOCK1WAY CKS FCMEN
Word 2: FFF7 MCLR NOPUT NOMVECEN IVT1WAY NOLPBOR BROWNOUT BORV24 ZCDDIS PPS1WAY STVREN NODEBUG NOXINST
Word 3: FF9F WDTSW NOWDT WDTWIN_SW WDTCLK_SW
Word 4: DFFF BBSIZ512 NOBOOTBLOCK NOSAF NOWRT NOWRTB NOWRTC NOWRTD NOWRTSAF NOLVP
Word 5: FFFF NOPROTECT |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Wed Oct 03, 2018 8:43 am |
|
|
It's not doing what you think, but it is wrong.
The function pointer is not the fault. It is fine.
If you run a debug and add a breakpoint on the calling line, handle_dummy ends up being loaded with 56, so looks OK. However if you add a single 'nop' instruction afterwards (delay_cycles(1)), and put the breakpoint on this, the instruction is not reached.
What is happening is it is trying to use the quicker 'RCALL' instruction, instead of 'CALL', and getting the address maths wrong on this. Result it reboots each time round the loop. It is specific to these chips (27/47Kx2). Using any other processor I've tried the code is always fine.
Again you need to report this to CCS.... |
|
|
garyatpt
Joined: 01 Oct 2018 Posts: 8
|
|
Posted: Thu Oct 04, 2018 3:00 am |
|
|
ok!
thank you very much! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Thu Oct 04, 2018 8:09 am |
|
|
As a question to the poster, are you contacting CCS about this?.
These are new chips, and they need to know about such issues. If you are not contacting them I'll do so. |
|
|
garyatpt
Joined: 01 Oct 2018 Posts: 8
|
|
Posted: Thu Oct 04, 2018 9:29 am |
|
|
Yes, I have contacted CCS about this issue today morning.
Thanks! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Thu Oct 04, 2018 10:14 am |
|
|
Good. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|