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

How to get label address at compile time

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







How to get label address at compile time
PostPosted: Sat Sep 25, 2004 7:04 pm     Reply with quote

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
Mark M
Guest







reading label address at compile time
PostPosted: Sat Sep 25, 2004 7:11 pm     Reply with quote

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
drh



Joined: 12 Jul 2004
Posts: 192
Location: Hemet, California USA

View user's profile Send private message

PostPosted: Sun Sep 26, 2004 10:03 am     Reply with quote

See page 109 and 110 of the July, 2003 reference manual for
label_address() and goto_address().
_________________
David
Mark M
Guest







How to ge label address at compile time
PostPosted: Mon Sep 27, 2004 10:30 am     Reply with quote

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.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Sep 27, 2004 10:56 am     Reply with quote

Well, how about Mark looking at your post ?
This sounds like it's right up his alley. Mr. Green
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Wed Sep 29, 2004 6:08 pm     Reply with quote

How do you plan on handling local variables? Are you planning on making them all "static"? What does your task handler look like?
Mark M
Guest







rtos thing
PostPosted: Thu Sep 30, 2004 9:42 am     Reply with quote

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
Mark M
Guest







PostPosted: Fri Oct 01, 2004 6:38 pm     Reply with quote

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
ThadSmith



Joined: 23 Feb 2004
Posts: 5
Location: Boulder, CO, USA

View user's profile Send private message

PostPosted: Thu Oct 07, 2004 7:48 pm     Reply with quote

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
Mark M.
Guest







rtos
PostPosted: Thu Oct 21, 2004 11:35 pm     Reply with quote

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.
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