EEVblog Electronics Community Forum

Electronics => Microcontrollers => Topic started by: thewyliestcoyote on December 18, 2015, 07:05:08 am

Title: Function return address in PIC16LF1705 using the XC8 compiler
Post by: thewyliestcoyote on December 18, 2015, 07:05:08 am
Hello,

I am working on a project using a PIC16LF1705 with the Microchip XC8 compiler. I need to get that the return address of a function. I have read thru most of the documentation of the compiler and can find mention, however no code examples. I am working on doing some scheduler stuff and would like to save the address of the calling function for later use.

If someone can help,
Thanks,
Wylie
Title: Re: Function return address in PIC16LF1705 using the XC8 compiler
Post by: matseng on December 18, 2015, 07:49:49 am
I guess you have to traverse down the stack frame yourself and pull out the relevant data from it.  But that sounds like a very fragile solution though, since the frames will/might look different depending on compiler version and flags...
Title: Re: Function return address in PIC16LF1705 using the XC8 compiler
Post by: thewyliestcoyote on December 18, 2015, 08:02:05 am
Quote
I guess you have to traverse down the stack frame yourself and pull out the relevant data from it.  But that sounds like a very fragile solution though, since the frames will/might look different depending on compiler version and flags...
What I am doing is kind of standard-ish. I am unsure why I can't seem to find what the name of the thing that contains this address. There is a assembly we of doing this but I am not sure that I want to go down that road if I can avoid it. That said I may have to do something like that anyways because of some other reasons.
Title: Re: Function return address in PIC16LF1705 using the XC8 compiler
Post by: Ian.M on December 18, 2015, 08:03:30 am
XC8 uses a mixture of a software stack, and the PIC hardware stack, and decides at compile time which functions use what.  Therefore a general solution will be near-impossible.

What are you *actually* trying to write?  Is it a cooperative scheduler with a yield() function that all tasks call periodically, or is it an interrupt driven preemptive scheduler?
Title: Re: Function return address in PIC16LF1705 using the XC8 compiler
Post by: mikerj on December 18, 2015, 08:04:09 am
The 16F PICs have a hardware stack for return addresses so there are no stack 'frames' as such.  Fortunately the PIC16LF1705 is an enhanced device which provides access to the hardware stack via the TOSH:TOSL register pair and the STKPTR register. 

All the OP has to do is read the TOSH:TOSL register pair to get the return address, but this is all clearly described in the datasheet.

EDIT: Ian makes a good point, the XC8 can choose to use a software stack if you have re-entrant functions so that would complicate matters.
Title: Re: Function return address in PIC16LF1705 using the XC8 compiler
Post by: thewyliestcoyote on December 18, 2015, 08:44:07 am
Quote
XC8 uses a mixture of a software stack, and the PIC hardware stack, and decides at compile time which functions use what.  Therefore a general solution will be near-impossible.
That is not good news for me,  :palm:.

Quote
What are you *actually* trying to write?  Is it a cooperative scheduler with a yield() function that all tasks call periodically, or is it an interrupt driven preemptive scheduler?
The yield idea. I am more or less having a very very small and stupid OS on the device.

Quote
The 16F PICs have a hardware stack for return addresses so there are no stack 'frames' as such.  Fortunately the PIC16LF1705 is an enhanced device which provides access to the hardware stack via the TOSH:TOSL register pair and the STKPTR register. 

All the OP has to do is read the TOSH:TOSL register pair to get the return address, but this is all clearly described in the datasheet.
Thanks I will give it a read, I think I must have missed something.

Quote
EDIT: Ian makes a good point, the XC8 can choose to use a software stack if you have re-entrant functions so that would complicate matters.
Any workarounds that anyone knows of?

And thanks for the help,
Title: Re: Function return address in PIC16LF1705 using the XC8 compiler
Post by: Ian.M on December 18, 2015, 08:53:03 am
It *may* be possible to figure something out with setjmp() and longjmp(), or you may have to go to pure assembler.  See <BadURL>
N.B. all ASPIC FN.... directives are being depreciated in XC8 v1.35, so you will have to find some other trick to keep local variable and 'scratchpad' allocation separate for each thread.
Title: Re: Function return address in PIC16LF1705 using the XC8 compiler
Post by: thewyliestcoyote on December 18, 2015, 08:57:09 am
Well I have a good part of the other parts of the OS written. This include the memory allocation and de-allocation. Maybe I could just do some stack management in place of the compiler. I am not looking forward to this. It would be so much simpler if microchip just did what any good compiler does and give you something to say here is the return address.

Also I am not sure I understand the digikey link.
Title: Re: Function return address in PIC16LF1705 using the XC8 compiler
Post by: Ian.M on December 18, 2015, 09:00:26 am
AAAGH!!. I *thought I'd copied a microchip forum link! :(
http://www.microchip.com/forums/m695452.aspx (http://www.microchip.com/forums/m695452.aspx)
Title: Re: Function return address in PIC16LF1705 using the XC8 compiler
Post by: thewyliestcoyote on December 18, 2015, 09:14:07 am
Ah makes a lot more sense,

Many thanks,
Title: Re: Function return address in PIC16LF1705 using the XC8 compiler
Post by: Kalvin on December 18, 2015, 09:16:48 am
Or, forget the fancy OS-stuff and create application using state machines (and events). The application will be then be a simple main loop calling the individual tasks on at a time. Each task is implemented as run-to-completion state machine. Easy, simple and portable.

Here are three nice articles describing how to create a simple, state-machine based tasker:
http://petevidler.com/blog/categories/rtos-alternatives/ (http://petevidler.com/blog/categories/rtos-alternatives/)

The book Patterns for "Time-Triggered Embedded Systems: Building Reliable Applications with the 8051 Family of Microcontrollers" is recommended reading.
Title: Re: Function return address in PIC16LF1705 using the XC8 compiler
Post by: Ian.M on December 18, 2015, 09:23:54 am
There's also https://en.wikipedia.org/wiki/Protothreads (https://en.wikipedia.org/wiki/Protothreads) (follow the link to Dunkel's page for more details)   However if you thought Duff's Device was Fugly, don't look under the protothreads 'hood'!
Title: Re: Function return address in PIC16LF1705 using the XC8 compiler
Post by: nctnico on December 18, 2015, 10:41:11 am
Any workarounds that anyone knows of?
Use a controller with an ARM core. What you want is never going to work on low end PIC processors or any microcontroller which uses a CPU core that doesn't have a real stack and/or seperated memory areas. Even if you would get it to work it will be extremely slow because the CPU needs to emulate everything.
Title: Re: Function return address in PIC16LF1705 using the XC8 compiler
Post by: Ian.M on December 18, 2015, 10:58:04 am
Funny you should say that.  SourceBoost NOVO RTOS (http://www.sourceboost.com/Products/NovoRtos/Overview.html) supports cooperative multitasking on all 8 bit PIC families except Baseline.  It does require you to use a SourceBoost compiler as it needs some hooks into the compiler and linker for stuff like manipulating the task switching function's return address.   There's also Pumpkin's Salvo RTOS that supported 8 bit PIC targetsd under HiTech C.  Unfortunately Microchip broke Salvo shortly before the XC8 release when they upgraded HiTech C's so-called Omniscient Code Generation.
Title: Re: Function return address in PIC16LF1705 using the XC8 compiler
Post by: hans on December 18, 2015, 04:37:22 pm
Protothreads is basically a "automatically generated" state-machine under the hood. Don't make them too large.. jumping back into context gets slower and slower as the states count grow. In PT that are all statements that can yield; because a yield also needs the ability to re-start from there.
You're also limited to PT statements only in 1 function. Because it's a switch-case underneath, it cannot span multiple functions or files. That makes writing true multi-tasking code impossible.

But it's probably the most functional option out there.

A true preemptive scheduler on 8-bit PICs is not practical. As mentoined in the MicroChip post.. the compiler will re-use the same memory locations depending on the call tree. This makes functions non-reentrant and thus not thread-safe.
The FN-options is unsustainable:
Quote
XC8 v1.35 changelog
FN-type directives All FN-type directives are no longer supported and should not be used. Such directive include: FNBREAK, FNSIZE, FNROOT etc. The FNCALL and FNROOT directives are still issued by the compiler, but it is recommended that these not be used in handwritten assembly code.
Title: Re: Function return address in PIC16LF1705 using the XC8 compiler
Post by: mikerj on December 19, 2015, 04:40:44 pm
Protothreads is basically a "automatically generated" state-machine under the hood. Don't make them too large.. jumping back into context gets slower and slower as the states count grow. In PT that are all statements that can yield; because a yield also needs the ability to re-start from there.
You're also limited to PT statements only in 1 function. Because it's a switch-case underneath, it cannot span multiple functions or files. That makes writing true multi-tasking code impossible

It's a clever solution, but I prefer do write my own state machines rather than automate things with Protothreads, epsecialy on 8 bit devices.  Since Protothreads uses the __LINE__ macro to set the state variable, any reasonably complex module (i.e. one with more than 254 lines) is going to require a 16 bit value to hold the state, slowing things down and using more memory.  The also makes the state values are non-consecutive, making it likely the state machine will consist of a large number of 'else if' statements rather than a jump table.
Title: Re: Function return address in PIC16LF1705 using the XC8 compiler
Post by: dannyf on December 21, 2015, 02:12:54 pm
Quote
What I am doing is kind of standard-ish. I am unsure why I can't seem to find what the name of the thing that contains this address.

The fact that you have a hard time finding it would suggest that the way you approached it is probably not as standard-ish as you thought.

In cases like this, step back and re-think the big picture.
Title: Re: Function return address in PIC16LF1705 using the XC8 compiler
Post by: Kalvin on December 21, 2015, 02:29:35 pm
Protothreads is basically a "automatically generated" state-machine under the hood. Don't make them too large.. jumping back into context gets slower and slower as the states count grow. In PT that are all statements that can yield; because a yield also needs the ability to re-start from there.
You're also limited to PT statements only in 1 function. Because it's a switch-case underneath, it cannot span multiple functions or files. That makes writing true multi-tasking code impossible.

An interesting article Protothreads vs state machines:
http://embeddedgurus.com/state-space/2011/06/protothreads-versus-state-machines/ (http://embeddedgurus.com/state-space/2011/06/protothreads-versus-state-machines/)

I am not quite sure how good Protothreads is for implementing hierarcial state machines. 
Title: Re: Function return address in PIC16LF1705 using the XC8 compiler
Post by: thewyliestcoyote on December 24, 2015, 01:21:14 am
Sorry I have been a little under the weather the past couple of days and should have been a little more active. The problem I am working on is trivial for a state-machine and the hardware is timers of the PIC. The point of the OS was for the cred of doing an OS for the project. That said maybe a should just give up the idea and just do the State-Machine implementation.
Title: Re: Function return address in PIC16LF1705 using the XC8 compiler
Post by: Kalvin on December 24, 2015, 03:18:40 pm
Sorry I have been a little under the weather the past couple of days and should have been a little more active. The problem I am working on is trivial for a state-machine and the hardware is timers of the PIC. The point of the OS was for the cred of doing an OS for the project. That said maybe a should just give up the idea and just do the State-Machine implementation.

My comment on the state machines was not something what you should do or shouldn't do. I just thought that you may want to consider a lean state machine implementation with possible simple co-operative scheduler over a pre-emptive OS since your processor has quite limited resources.