CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

PIC18F27K42 function pointer issue

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
garyatpt



Joined: 01 Oct 2018
Posts: 8

View user's profile Send private message

PIC18F27K42 function pointer issue
PostPosted: Mon Oct 01, 2018 9:58 pm     Reply with quote

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: 19537

View user's profile Send private message

PostPosted: Mon Oct 01, 2018 11:16 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Oct 02, 2018 3:00 am     Reply with quote

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: 19537

View user's profile Send private message

PostPosted: Tue Oct 02, 2018 10:50 am     Reply with quote


    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

View user's profile Send private message

PostPosted: Tue Oct 02, 2018 8:57 pm     Reply with quote

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: 19537

View user's profile Send private message

PostPosted: Wed Oct 03, 2018 8:43 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Oct 04, 2018 3:00 am     Reply with quote

ok!
thank you very much! Very Happy
Ttelmah



Joined: 11 Mar 2010
Posts: 19537

View user's profile Send private message

PostPosted: Thu Oct 04, 2018 8:09 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Oct 04, 2018 9:29 am     Reply with quote

Yes, I have contacted CCS about this issue today morning.
Thanks!
Ttelmah



Joined: 11 Mar 2010
Posts: 19537

View user's profile Send private message

PostPosted: Thu Oct 04, 2018 10:14 am     Reply with quote

Good. Smile
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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