View previous topic :: View next topic |
Author |
Message |
Mark M Guest
|
How to get label address at compile time |
Posted: Sat Sep 25, 2004 7:04 pm |
|
|
I am trying to write simple task switching scheme similar to "LeanSlice" by Knudsen Data Norway. I have a following macro:
#define waitState() \
{ \
L0?:
#asm ASIS \
movlw L0?%256 \
movwf Lstate \
movf PCLATH,w \
movwf (&Lstate+1) \
return \
#endasm; \
}
Purpose of this macro is to record program counter at location L0? so that at some point my task scheduler can switch back to the L0? location by doing :
goto_address( Lstate );
I am using PCM 3.206
Any hints?
Mark M |
|
![](templates/subSilver/images/spacer.gif) |
Mark M Guest
|
reading label address at compile time |
Posted: Sat Sep 25, 2004 7:11 pm |
|
|
I just realized that the code may have to be modified because PCLATH is not readable. It would have to be something like that:
#define waitState() \
{ \
L0?:
#asm ASIS \
movlw L0?%256 \
movwf Lstate \
movlw L0?/256,w \
movwf (&Lstate+1) \
return \
#endasm; \
}
Purpose of this macro is to record program counter at location L0? so that at some point my task scheduler can switch back to the L0? location by doing :
goto_address( Lstate );
Any hints?
Mark M |
|
![](templates/subSilver/images/spacer.gif) |
drh
Joined: 12 Jul 2004 Posts: 192 Location: Hemet, California USA
|
|
Posted: Sun Sep 26, 2004 10:03 am |
|
|
See page 109 and 110 of the July, 2003 reference manual for
label_address() and goto_address(). _________________ David |
|
![](templates/subSilver/images/spacer.gif) |
Mark M Guest
|
How to ge label address at compile time |
Posted: Mon Sep 27, 2004 10:30 am |
|
|
David,
For what I want to do ( task switching in rtos ) those directives, and particularly goto_address produces a BIG chunk of code with many redundant instructions.
I acutally found a way to do it in CCS. You have to define a function as #inline instead using macro. In that case preprocessor expands function first and assigns a different address to every occurence of the same label. There is only one "but". It produces 2 redundant instructions as inthe example below:
CCS PCM C Compiler, Version 3.206, 24834 27-Sep-04 10:19
.................... int16 p;
....................
.................... Label1:
.................... p =label_address( Label1 );
008C: MOVLW 00
008D: MOVWF 7A <-- redundant, this is @SCRATCH, what is this for ??
008E: MOVLW 8C
008F: MOVWF 62 <-- this is &p
0090: MOVF 7A,W <-- redundant
0091: MOVWF 63 <-- this is &p+1
it would be more efficient to do it as:
008C: MOVLW 00
008D: MOVWF 7A <-- this is @SCRATCH, what is this for ??
008E: MOVWF 63 <-- this is &p+1
008F: MOVLW 8C
008A: MOVWF 62 <-- this is &p
or even this:
008D: MOVLW 00
008E: MOVWF 63 <-- this is &p+1
008F: MOVLW 8C
008A: MOVWF 62 <-- this is &p
but how to do this in C or better in assembly ??
I only wish the PCM programmer or Darren would look at my post ...
Mark M. |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Sep 27, 2004 10:56 am |
|
|
Well, how about Mark looking at your post ?
This sounds like it's right up his alley. ![Mr. Green](images/smiles/icon_mrgreen.gif) |
|
![](templates/subSilver/images/spacer.gif) |
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Wed Sep 29, 2004 6:08 pm |
|
|
How do you plan on handling local variables? Are you planning on making them all "static"? What does your task handler look like? |
|
![](templates/subSilver/images/spacer.gif) |
Mark M Guest
|
rtos thing |
Posted: Thu Sep 30, 2004 9:42 am |
|
|
Local variables would have to be protected, so software stack for them is one way of solving this problem. Another way, as you suggested is to use only global variables ( or local ones defined as static ).
As to the scheduler, I am still working on details. The most important thing is that this system has to work with PIC16, and possibly with lower as well. As I see it now, the scheduler can be implemented in two ways.
#1:
Scheduler works as inline code part of main():
void main() {
scheduler:
do some arbitration between tasks availabl;
determine task to run (ttr);
load ttr address from task table ( this one is in RAM) into (int16) Lstate
load it into pch and pcl; //this should produce a jump to code pointed by Lstate
// returning from task, Lstate has a new jump point for this task ( this is cooperative multitasking, task has to give up control volunteerly ). Return is dove via "goto sch_1"
sch1:
store Lstate into the task table;
goto scheduler;
This way NO stack is used.
#2. Another way is to use 1 call stack as follows:
vaid main() {
......
while(1) {
call scheduler;
sch1: // this is where task returns
/*
on returning from task, Lstate has a new jump point for this
task ( this is cooperative multitasking, task has to give up
control volunteerly ).
Return is done via "retlw".
W can hold extra information about runnung task
*/
}
......
}
void scheduler() {
do some arbitration between tasks available;
determine task to run (ttr);
load ttr address from task table ( this one is in RAM) into
(int16) Lstate into pch and pcl;
/*
This should produce a jump to code pointed by Lstate
I guess at this point a call with function pointer as argument
if function pointers can be implemented easily
- but they can not on PIC16
*/
return; /* this will never be executed since task returns
to sch_1: via call stack */
}
void task() {
....
wait(); /* this is my inline function with stuff described
as in my original post */
....
code...
......
wait();
....
etc.
}
I know the code generated will not be VERY compact, but every task will be coded as a distinct function and will be very easy to follow and maintain. Of course you have all rtos gadgets like messages, semaphores, waits etc.
This is in a nut shell. What do you think?
Regards
Mark M |
|
![](templates/subSilver/images/spacer.gif) |
Mark M Guest
|
|
Posted: Fri Oct 01, 2004 6:38 pm |
|
|
It is silly to reply to your own post but I thought I wanted to share this info with you. THERE IS A WAY to get label address at compile time. IT IS VERY simple, once you know it and after reading the manual ! Here is how it is done:
.................... #asm ASIS \
.................... L0: movplw L0 \
000D: MOVLW 0D
.................... movwf Lstate \
000E: MOVWF 70
.................... movphw L0 \
000F: MOVLW 00
.................... movwf &Lstate+1 \
0010: MOVWF 71
.................... return \
0011: RETURN
.................... #endasm
CCS assembler has 2 non-MPASM instructions. ![Very Happy](images/smiles/icon_biggrin.gif) |
|
![](templates/subSilver/images/spacer.gif) |
ThadSmith
Joined: 23 Feb 2004 Posts: 5 Location: Boulder, CO, USA
|
|
Posted: Thu Oct 07, 2004 7:48 pm |
|
|
Thanks, Mark. That's exactly what I was trying to do. The follow-up is appreciated! It's pretty hard to find in the manual, especially with no description.
Thad |
|
![](templates/subSilver/images/spacer.gif) |
Mark M. Guest
|
rtos |
Posted: Thu Oct 21, 2004 11:35 pm |
|
|
I thought I share it with everybody. My rtos written in CCS compiler works ok. Thanks to B.Knudsen Data Norway, another C compiler publisher for inspiration and code samples.
Mark M. |
|
![](templates/subSilver/images/spacer.gif) |
|