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

Pointer to function in a structure

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



Joined: 17 Nov 2016
Posts: 12

View user's profile Send private message Visit poster's website

Pointer to function in a structure
PostPosted: Mon Nov 21, 2016 11:35 pm     Reply with quote

I have a declaration like this:
Code:

// -----------------------------------------------------------------------
// Callback function pointer
// -----------------------------------------------------------------------
typedef void (*statecb_t)(statecbtype_t aT, stateid_t aSt);

// -----------------------------------------------------------------------
// Structure holding one state item
// -----------------------------------------------------------------------
struct ATTRPACKED state_s {
   stateid_t      id;         // Identification
   statecb_t      cb;         // Callback function. NULL for last
};
typedef struct state_s state_t;


In the code this is used like this:
Code:

void function( void ) {
   state_t   cbstate;
   GetStateArray( &cbstate, Private_State_Stack[Private_State_SP] );
   cbstate.cb( statecbtype_init, cbstate.id );
}


And finally the compiler gives me this:
*** Error 12 "Private_PostCall.c" Line 42(62,64): Undefined identifier cbstate

This compiles well on MPLAB, avr-gcc, sdcc, cc and g++ but not with ccsc.

There are no preceding errors before that occurs.

I would like to compile this with ccsc
esko



Joined: 17 Nov 2016
Posts: 12

View user's profile Send private message Visit poster's website

PostPosted: Tue Nov 22, 2016 12:15 am     Reply with quote

I got a workaround for this which I assume is a compiler bug.

Code that does not compile:
Code:

// -----------------------------------------------------------------------
// StateRun.c
// -----------------------------------------------------------------------
#include "State_Private.h"

// -----------------------------------------------------------------------
// Call current state with an event
// -----------------------------------------------------------------------
void      StateRun      ( void ) {
   cbstate_t   cbstate;

   // -------------------------------------------------------------------
   // Previous state may have requested operation. Do it now
   // -------------------------------------------------------------------
   Private_PostCall();

   // -------------------------------------------------------------------
   // Do a callback
   // -------------------------------------------------------------------
   GetStateArray( &cbstate, Private_State_Stack[Private_State_SP] );
   cbstate.cb( statecbtype_run, cbstate.id );
}

// -----------------------------------------------------------------------
// EOF: StateRun.c
// -----------------------------------------------------------------------


Code that compiles
Code:

// -----------------------------------------------------------------------
// StateRun.c
// -----------------------------------------------------------------------
#include "State_Private.h"

// -----------------------------------------------------------------------
// Call current state with an event
// -----------------------------------------------------------------------
void      StateRun      ( void ) {
   cbstate_t   cbstate;
   statecb_t   statecb;

   // -------------------------------------------------------------------
   // Previous state may have requested operation. Do it now
   // -------------------------------------------------------------------
   Private_PostCall();

   // -------------------------------------------------------------------
   // Do a callback
   // -------------------------------------------------------------------
   GetStateArray( &cbstate, Private_State_Stack[Private_State_SP] );
   statecb = cbstate.cb;
   statecb( statecbtype_run, cbstate.id );
}

// -----------------------------------------------------------------------
// EOF: StateRun.c
// -----------------------------------------------------------------------
Ttelmah



Joined: 11 Mar 2010
Posts: 19538

View user's profile Send private message

PostPosted: Tue Nov 22, 2016 4:14 am     Reply with quote

Your calling syntax doesn't seem right.
To call the function pointed to by cbstate.cb, you would need:

(*cbstate.cb)( statecbtype_run, cbstate.id );
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Nov 22, 2016 6:03 am     Reply with quote

Here's an example of the method shown by Ttelmah:
http://www.ccsinfo.com/forum/viewtopic.php?t=53237
This example is somewhat different than your sample
program. The example has an array of structures, each
with a function pointer in it. That's why you'll see it called
as an array element. That's not important. Also there
are no parameters in this example. Again that's not
important. The important thing is how to call the function.
esko



Joined: 17 Nov 2016
Posts: 12

View user's profile Send private message Visit poster's website

PostPosted: Tue Nov 22, 2016 7:16 am     Reply with quote

Did some investigation on this because that code has been working for more than 5 years in a real life production device ... both AVR and PIC devices.

So I changed the code as suggested:
Code:

(*cbstate.cb)( statecbtype_init, cbstate.id );


The compiler then reported:
Code:

Make /modules/State/pic/CCS
>>> Warning 207 "Private_PostCall.c" Line 42(1,1): Code has no effect
*** Error 76 "Private_PostCall.c" Line 42(73,74): Expect ;
/mnt/xdisk1/Code/Lib/modules/State/pic/CCS/18F25K22/obj/Private_PostCall.o ===>  1 Errors,  1 Warnings.
/mnt/xdisk1/Code/Lib/modules/State/pic/CCS/18F25K22/obj/Private_PostCall.o ===>  1 Errors,  1 Warnings.


Then I checked the list file for the code that compiled well:
Code:

....................       statecb = cbstate.cb;
7716:  MOVFF  149,14B
771A:  MOVFF  14A,14C
....................       statecb( statecbtype_init, cbstate.id );
771E:  MOVFF  148,14D
7722:  MOVLW  01
7724:  MOVWF  FEA
7726:  MOVLW  4B
7728:  MOVWF  FE9
772A:  MOVLB  1
772C:  CLRF   x4E
772E:  MOVFF  14D,14F
7732:  MOVLB  0
7734:  CALL   011C
7738:  MOVLB  1


At 011C there is following code:
Code:

011C:  MOVFF  FEC,FFA
0120:  MOVF   FED,F
0122:  MOVFF  FEF,FE8
0126:  MOVWF  FF9
0128:  RETURN 0


Despite my rather long career on computing I have no idea whether that code is OK or not. Is it ?
My assumption is that the code is manipulating stack and the actual call happens with the RETURN 0 code.... I would have done it that way Smile

edit: I also tried the wotking approach but made the change in the call:
Code:

....................       statecb = cbstate.cb;
7716:  MOVFF  149,14B
771A:  MOVFF  14A,14C
....................       (*statecb)( statecbtype_init, cbstate.id );
771E:  MOVFF  148,14D
7722:  MOVLW  01
7724:  MOVWF  FEA
7726:  MOVLW  4B
7728:  MOVWF  FE9
772A:  MOVLB  1
772C:  CLRF   x4E
772E:  MOVFF  14D,14F
7732:  MOVLB  0
7734:  CALL   011C
7738:  MOVLB  1


The code is exactly the same no matter whether one uses (ptr)(...) or ptr(...). It also compiles with or without the '*'.
Ttelmah



Joined: 11 Mar 2010
Posts: 19538

View user's profile Send private message

PostPosted: Tue Nov 22, 2016 9:23 am     Reply with quote

No. The jump to the function occurred the line before this.

It takes the number stored in the variable, and writes it directly to the program counter latch registers. On the PIC, this results in a jump as soon as the low byte is written. Basically when you write to the low register, it copies both of these into the actual program counter, and the next instruction will be at the new address. Hopefully the code this jumps to, jumps 'back' to the next address, which then gives the 'return'.
Pushing an address onto the stack is not actually possible on some PIC's at all. So this is not used.
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