CS452 - Real-Time Programming - Fall 2009
Lecture 7 - Creating a Task
Reminder
The Software Interrupt
What happens when the execution reaches a software interrupt
instruction?
- The PSR is saved in spsr_svc.
- The address of the instruction immediately following swi is put in
lr_svc
- In the PSR
- execution mode is changed to supervisor
- interrupts are disabled
- 0x08 is put in the pc.
This is done by the hardware; the rest is up to you.
In the calling code
swi n
In the kernel
The order matters
kernel entry:
- Change to system state
- Save the user state
- on its stack
- This includes the arguments, which you may or may not need
later.
- Put
sp_usr in a scratch register
- Return to supervisor mode
- Get the request
ldr r3, [lr, #-4]
- Retrieve the kernel state, which does not include the scratch registers
- You now have the kernel frame pointer
- You can use it to put stuff in kernel memory
- Put what you want in the task's TD
active is indexed off the frame pointer
active is a pointer to the TD of the requester
- Return from
getNextRequest( active ) and get to work
- Don't forget to store the return value in the TD
After a while it's time to leave the kernel
- Schedule the next task to run
- Call
GetNextRequest( active )
- Save kernel state on kernel stack
- From TD
- set spsr_svc
- set lr_svc
- get sp_usr
- Set return value by overwriting r0 on user stack
- Switch to system mode
- Load registers from user stack
- Return to supervisor mode
- Let it go
movs pc, lr
Creating a Task
In creating a task you have to do two things
- Get and initialize resources needed by the task
- Make the task look as if it had just entered the kernel
Things you need to do
Get an unused TD and memory for its stack
- memory could be associated with TD during initialization
- actually a form of constant time memory allocation
- unless you implement Destroy
Mostly filling in fields in the TD.
- task id
- stack pointer
- SPSR
- link register
- parent tid
- return value
- dummy
- different return value for the active task, which goes in its
TD
- state
- install in the ready queues
Must also create the initial stack
The Create Function
You also need a int Create( int priority, void (*code) ( ) )
function to call from user tasks.
Although it's no more than a wrapper there are a few problems to solve.
- Passing arguments
- On entry the arguments are somewhere, usually r0 & r1
- You have to put them where the kernel can find them.
- gcc's function extry code immediately puts them on the stack.
- In assembly you can find them using the frame pointer.
- Jumping into the kernel
- Getting the return value from the kernel and returning it.
- You find it where the kernel put it
- gcc's function exit code expects it to be indexed off the frame
pointer
- from where it does into r0
What follows just seems to say the same thing again. But we might as well
leave it here because some student might find it useful.
How do we implement the API for user code?
- This requires a bit of assembly language.
- In assembly language all arguments & return values are words.
- usually pointers
- stored in registers
- What happens when there are too many arguments?
- What happens when
Create is called?
- Two arguments
- stored in
r0 and r1
- which is which?
- Immediately placed on the stack, referred to by
fp
- Create puts them in the special place you choose
swi switches context into the kernel.
- What happens when
Create returns?
- When the kernel is finished manipulating
TDs and
PQs
- it knows the tid to be returned
- it places the tid in the caller's return value in its
TD
- When the caller is next activated,
- as part of activation the return value is put in your special
place, usually
r0
- user code has to get it and put it in the compiler's special
place,
r0 for gcc.
Return to: