View previous topic :: View next topic |
Author |
Message |
UpInSmoke01
Joined: 16 Sep 2013 Posts: 5
|
Callbacks on PIC18F (with return value) |
Posted: Mon Sep 16, 2013 9:21 am |
|
|
I'm trying to implement callbacks on the PIC18F.
I see the workaround posted at:
https://www.ccsinfo.com/forum/viewtopic.php?p=169565
This implements a ...
void (*fpCallback) (void);
... style callback (with no arguments or return value).
I am curious as to whether it would be possible to implement a ...
uint8 (*fpCallback) (void);
... style callback (with no arguments, but with a return value) in the same way.
Note:
I'm using version 4.128. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Mon Sep 16, 2013 10:38 am |
|
|
Yes.
Also, with later compilers the need for the bodge is starting to disappear.
Best Wishes |
|
|
UpInSmoke01
Joined: 16 Sep 2013 Posts: 5
|
|
Posted: Mon Sep 16, 2013 10:55 am |
|
|
Ttelmah,
When I try to define a struct with a callback ....
Code: |
typedef struct
{
unsigned short u16LastStartTick;
unsigned short u16Interval;
void (*fpGetExecCallback) (void); //<= Callback
}strTaskStatus;
|
... I get this compiler error:
Error 34 "C:\dev\PIC\LIS3DH\Task.c" Line 84(5,9): Unknown type
Where "\Task.c" Line 84" is referring to the callback declaration. Can you tell we what is wrong with the declaration (assuming the compiler supports callbacks)? |
|
|
UpInSmoke01
Joined: 16 Sep 2013 Posts: 5
|
|
Posted: Mon Sep 16, 2013 12:35 pm |
|
|
I just wanted to add a note. This is an excerpt from "CCS C Compiler Manual PCB, PCM & PCH" currently online.
Quote: | "
How do I make a pointer to a function?
The compiler does not permit pointers to functions so that the compiler can know at compile time the complete call tree. This is used to allocate memory for full RAM re-use. Functions that could not be in execution at the same time will use the same RAM locations. In addition since
there is no data stack in the PICĀ®, function parameters are passed in a special way that requires knowledge at compile time of what function is being called. Calling a function via a pointer will prevent knowing both of these things at compile time. Users sometimes will want function pointers to create a state machine. The following is an example of how to do this without pointers:
enum tasks {taskA, taskB, taskC};
run_task(tasks task_to_run) {
switch(task_to_run) {
case taskA : taskA_main();
break;
case taskB : taskB_main();
break;
case taskC :
taskC_main();
break;
}
}
" |
I don't like this solution because the Task module would need to 'know' about who it is executing, but unless someone has successfully implemented a function pointer with a return value it seems I will have to go down that road. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Tue Sep 17, 2013 1:05 am |
|
|
The 'excerpt', only precludes the use of functions with non static local variables.
The key about this is that CCS does RAM re-use based upon where functions are called 'from'. Provided you ensure that functions you want to call using a pointer, are declared so they have their own local variables (static), or use global variables _only_, the compiler will allocate them RAM 'permanently'.
I've used the bodge I posted, with functions both accepting, and returning values OK. However as shown in the bodge, I've always copied the value 'out' to a local variable before use, which is PCM_programmers fix.
Other thing is _you_ have to ensure you don't trigger re-entrancy.
Best Wishes |
|
|
UpInSmoke01
Joined: 16 Sep 2013 Posts: 5
|
|
Posted: Tue Sep 17, 2013 8:15 am |
|
|
Thanks for the quick and helpful responses. Ttelmah and PCM programmer. I think I'll compile in my code with the callback approach.
Hopefully, I can post my results later today or tomorrow. |
|
|
|