Forum Menu




 


Log in Problems?
New User? Sign Up!
AVR Freaks Forum Index

Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Author Message
alt0174
PostPosted: Nov 30, 2011 - 08:37 PM
Newbie


Joined: Nov 30, 2011
Posts: 5
Location: Jalisco, Mexico

Hello World!! Smile My name is Roberto and i´m new here so i wanted say hi to everybody in this great community.

Also i want to ask for help, the thing is that i´m making a round robin scheduler function but, i don't understand how to handle the stack pointer of the diferent tasks, my PCB is the following:

struct PCB_TYPE
{
unsigned char id; // the proccess id
functype process_ptr; // a pointer to the task
unsigned char status; // the status of the task
int *task_SP; // a poiner to the task´s stack
};

and i´m using this macro to read the context of the cpu

#define SAVE_CONTEXT() \
asm volatile ( \
"push r0 \n\t" \ //saving rx on stack
"push r1 \n\t" \
"push r2 \n\t" \
"push r3 \n\t" \
...
...
...
"push r29 \n\t" \
"push r30 \n\t" \
"push r31 \n\t" \
"in r0, __SREG__ \n\t" \ //save status register in r0
"push r0 \n\t" \ // save the status on stack
);
and the problem is how handle the stack pointer for read it and save it in task_SP, so would be great if someone can explain it to me, thanks for your time

[something a bit sensible added to pointless thread title]
 
 View user's profile Send private message  
Reply with quote Back to top
dak664
PostPosted: Nov 30, 2011 - 08:49 PM
Posting Freak


Joined: Jun 15, 2008
Posts: 1762
Location: North Carolina USA

Unless you allocate a separate stack space for each task on a heap you can't just back up the stack pointer to give a time slice to a stack. A function call or interrupt will overwrite stack needed for a suspended task.

Not saying you can't get around this, but you have to give more details about how you are going to accomplish this.
 
 View user's profile Send private message  
Reply with quote Back to top
bobgardner
PostPosted: Nov 30, 2011 - 09:28 PM
10k+ Postman


Joined: Sep 04, 2002
Posts: 21274
Location: Orlando Florida

Also, you can see how a dozen other software engineers wrote their version of an AVR task switcher by looking in the projects section here for RTOS (Real Time Operating System). At least a dozen.

_________________
Imagecraft compiler user
 
 View user's profile Send private message Send e-mail Visit poster's website 
Reply with quote Back to top
jgmdesign
PostPosted: Dec 01, 2011 - 04:07 AM
Raving lunatic


Joined: Apr 20, 2007
Posts: 6089
Location: Long Island New York

Oh yummy.....SPAM!!

Jim

_________________
Jim

I have decided that I am no longer going to plan anything in advance. In a court of law this is called Pre-Meditated, and does not look good for the defense.....

Timer function not working properly? Check CLKDIV8 Fuse first Wink
 
 View user's profile Send private message  
Reply with quote Back to top
alt0174
PostPosted: Dec 01, 2011 - 06:45 AM
Newbie


Joined: Nov 30, 2011
Posts: 5
Location: Jalisco, Mexico

thanks for the answers, and you´re right, i´m planing to use a diferent stack for each task, and the reality is that i don´t know how to read the addres of those stacks with asm instructions yet, this is the idea for now:

unsigned char [MAX_TASKS][35]; // one stack for each task

and read the address of every row and save into the stack pointer (at the right time), it´s maybe a bad idea, i´m new on this, so if i´m making it bad, i´ll apreciate any help.

a while, I thought this: what if i make a pointer to a defined address for example the address "100" and in that space i put the real address of the stack i think with asm i can read that address and write the stack pointer register with it, what do you think?

PS i have seen some other codes but still i don´t know how do they handle the context
 
 View user's profile Send private message  
Reply with quote Back to top
dak664
PostPosted: Dec 01, 2011 - 12:55 PM
Posting Freak


Joined: Jun 15, 2008
Posts: 1762
Location: North Carolina USA

35 bytes will store the registers but you need a lot more to store the entire stack at the time of task interruption. This will be the local storage for each subroutine and return addresses with maybe an interrupt on top of everything else. 8 bit micros don't have the memory to make that useful, in most cases.
 
 View user's profile Send private message  
Reply with quote Back to top
alt0174
PostPosted: Dec 01, 2011 - 02:12 PM
Newbie


Joined: Nov 30, 2011
Posts: 5
Location: Jalisco, Mexico

i think i just need 35 bytes because, i only need to save 32 registers plus the pc register and the status register, well i´ll grown it to 40 bytes, and i know that 8 bits mcus are weak, but at this moment i just want to learn, it won´t be to run spectacular aplications just i want it works, do you think i need to save more registers than those?
 
 View user's profile Send private message  
Reply with quote Back to top
itai_n
PostPosted: Dec 02, 2011 - 12:12 AM
Rookie


Joined: Jul 19, 2011
Posts: 47
Location: Haifa, Israel

What about local variables of functions? Return addresses?
You know a task switch may happen when you are deep in a nested function call.
 
 View user's profile Send private message  
Reply with quote Back to top
ka7ehk
PostPosted: Dec 02, 2011 - 12:17 AM
10k+ Postman


Joined: Nov 22, 2002
Posts: 12055
Location: Tangent, OR, USA

How do you deal with a variable that is shared among several tasks?

Jim

_________________
Jim Wagner
Oregon Research Electronics, Consulting Div.
Tangent, OR, USA

"The only thing standing between us and victory is defeat" P.G.Wodhouse in Wooster & Jeeves series
 
 View user's profile Send private message  
Reply with quote Back to top
Torby
PostPosted: Dec 02, 2011 - 02:07 AM
Raving lunatic


Joined: Nov 11, 2003
Posts: 3904
Location: Chicago Illinois USA

Back in the DOS days, TopSpeed Modula had a rather brain-damaged thread system. You could only start a thread 63 times: The 64th time, you program dumped. Once started, a thread could not stop, or your program dumped. Once started, you couldn't get the number back...

So here's what I did.

In a procedure call, the compiler assumed all the registers would be toast on return, so I didn't have to preserve them. I used a scrap of assembly to save the stack pointer, fetch another from the linked-list of runnable tasks, and do a return. Poof, a context switch on request.

Interrupts didn't do context switches, but the interrupt routine could manipulate the list of runnable processes, so it just set a flag or perhaps added the task that was waiting for it back into the list so it would go again.

To start a new thread, I just allocated some memory for the stack from heap put the address I wanted it to "return" to at the top, put the new "Stack Pointer" into the list of runnable tasks.

Since I figured without an IO event, there wasn't any point in tasking, so if the foreground task was waiting for a keystroke, it just took itself out of the list and called the switch procedure. The keyboard interrupt called the normal dos keyboard vector, then put the foreground process back into the ready list.

Since it wasn't preemptive, I didn't have to worry about global variables and the like. You could kill a task by taking it out of the ready list and deallocating its stack. A task could even kill itself.

The result was pretty impressive. On any "Screen" where it would take a while to sum up a bunch of records or something, it would give the user control, and the sum fields would count away. If they closed the screen before it finished, no problem, the procedure that showed the screen allocated and started the task, it just killed the task and deallocated the stack. Impressed programmers, but users thought that was how it was supposed to work.

_________________
Discursive design,

Torby

Some days, it's just not worth chewing through the restraints.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
alt0174
PostPosted: Dec 04, 2011 - 08:43 AM
Newbie


Joined: Nov 30, 2011
Posts: 5
Location: Jalisco, Mexico

thanks to all for your time and for help me, i read for my doub and the point is that i did not explain myself, the most big problem was that i didn´t know how to mix variables in c, with asm code, i´m just an ignorant novice, but i´m here to change that, now the problem is that compiler doesn´t recognize the following asm instruction

asm volatile( \
"push r0 \n\t" \
"push r1 \n\t" \
...
...
"in r16 , SREG \n\t");

it shows me "error constant value required" file:cc0Peyo.s
i know the problem is the last instruction because is i put it like comment, the compiler build the proyect

do you can explain me why? i´m using avrstudio 5
and, I had increased the stack for each task it to 60 Bytes i think is enough for the tasks that the mcu going to run, i´m doing this to get the basics skills, so for this proyect, the mcu won´t make anything extraordinary, maybe it´ll control an alphanumerical LCD module and a rotabit or something easy like those things, the objetive it´s make it work


Last edited by alt0174 on Dec 04, 2011 - 09:13 AM; edited 1 time in total
 
 View user's profile Send private message  
Reply with quote Back to top
rev
PostPosted: Dec 04, 2011 - 08:53 AM
Hangaround


Joined: Jun 25, 2001
Posts: 348
Location: Melbourne Australia

What compiler are you using ?
 
 View user's profile Send private message  
Reply with quote Back to top
alt0174
PostPosted: Dec 04, 2011 - 09:15 AM
Newbie


Joined: Nov 30, 2011
Posts: 5
Location: Jalisco, Mexico

I´m using AVR Studio 5
 
 View user's profile Send private message  
Reply with quote Back to top
JohanEkdahl
PostPosted: Dec 04, 2011 - 10:20 AM
10k+ Postman


Joined: Mar 27, 2002
Posts: 18599
Location: Lund, Sweden

Your task now is to create the smallest possible program that displays the problem. Since this is "inline assembler" producing a compilation error this should not be hard (i.e. should taker a couple of minutes or so). Then publish that minimal demonstrator here.

It just might be that you discover the problem yourself while creating this minimal demonstrator. If so, you have exercised one common fault-seeking technique - "Reduction of the problem space" - to a successful end.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
sternst
PostPosted: Dec 04, 2011 - 11:01 AM
Raving lunatic


Joined: Jul 23, 2001
Posts: 2440
Location: Osnabrueck, Germany

Quote:
"in r16 , SREG \n\t");

it shows me "error constant value required" file:cc0Peyo.s
i know the problem is the last instruction because is i put it like comment, the compiler build the proyect

do you can explain me why?
The SREG is part of a string, therefore it is not replaced by the preprocessor. You have to pass in such things as operand.
http://www.nongnu.org/avr-libc/user-man ... e_asm.html

_________________
Stefan Ernst
 
 View user's profile Send private message  
Reply with quote Back to top
SprinterSB
PostPosted: Dec 04, 2011 - 02:11 PM
Posting Freak


Joined: Dec 21, 2006
Posts: 1488
Location: Saar-Lor-Lux

alt0174 wrote:
Code:
asm volatile( \
     "push r0 \n\t" \
     "push r1 \n\t" \
     ...
     ...
     "in r16 , SREG \n\t");
Write
Code:
"in r16, __SREG__"
I don't think you'll have much fun with inline assembler for such a task.

This is not a generic C question, it's specific to avr-gcc.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
clawson
PostPosted: Dec 04, 2011 - 04:27 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62371
Location: (using avr-gcc in) Finchingfield, Essex, England

It also appears to be an attempt to simply recreate the fully explained FreeRTOS implementation:

http://www.freertos.org/implementation/index.html

Anyway I'll move this to the GCC forum.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
Display posts from previous:     
Jump to:  
All times are GMT + 1 Hour
Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Powered by PNphpBB2 © 2003-2006 The PNphpBB Group
Credits