Semaphores, OS tasks
I was wondering if any of you would know some links to learn more about OS tasks and semaphores (more or less concerning uC/OS-II realtime kernel. I want to create a task which I could start by posting a semaphore.
In theory this is what I am after:
I would, ofcourse, write functions os_semaphore_pend() and os_semaphore_post() myself to add some own checks in it.
static int foo_Task( void );
static os_event *foo_Task_Sem;
int StartFooTask( void );
foo_Task(); // OSTaskCreate() should be called instead of calling the function?
os_semaphore_pend( foo_Task_Sem );
// Do the task here
int StartFooTask( void )
os_semaphore_post( foo_Task_Sem );
Anyway, above code does not work, since code execution will end up in forever loop in foo_Task() function.
I read about OSTaskCreate() and I figure that's what I need to call to create a task which would be foo_Task() then. Am I right? Will OSTaskCreate() actually call the function and leave it running behind? (that's how I understood it).
I would really appreciate some help or any information about resources / links to details about OS tasks and semaphores.
> Will OSTaskCreate() actually call the function and leave it running behind?
Not really. It will create a new task, allocate a stack for the new task, and add the task to the list of tasks that are known to the OS.
The first call to foo_Task() would appear to come from nowhere because the calling function is really the OS Scheduler calling the function with the freshly created stack.
In Unix terms, the nearest equivalent is the fork()/exec() sequence. At the end of it, there is a new separate process running which has little to do with the process which started it. One notable thing is that Unix has process heirarchies (parent/child) relationships.
Most real time operating systems just have a flat list of tasks.
Ok, so I am in right tracks then I think. It's just that knowing exactly what happens seems to be essential for me to go on.
I found this book "MicroC/OS-II The Real-Time Kernel, Second Edition" by Jean J. Labrosse. (CmpBooks). Cant wait to receive that one :)
So, Task Scheduler is part of OS which duty is to execute tasks. Ok. And OSTaskCreate() takes argument for priority which defines the order in which the tasks are executed (or which task will be next to run). Now, if I make my task not infinite loop, it executes once and "that's it"?
Previously I thought I make it infinite loop to make it semaphore triggered, but that seems to be the common practice with tasks.
Sounds about right to me.
Most embedded OS tasks (as most services and daemons on desktops) run as infinite loops with some kind of wait for the next input to go do something.
And if your task runs just once, it's return will get caught by some code which calls the OS delete task function, and it will duly disappear from the task list.
Thanks Salem :)
Now all I need is to crack the nut about figuring how much stack I should allocate for my task. Guess I can calculate stack needs by following all the function calls in the task. For some reason I wouldnt like to go with "allocate enough stack" since the device might not have too much memory to spare.
Some embedded OS have diagnostic tools to tell you how much stack a task has needed "so far".
So allocating "enough", then running for a while, then picking a tuned size is a reasonable way to go.
Go with as much as you can spare during development, since stack overruns are pretty weird things to debug. If stacks are consecutive in memory, and T1 overruns into T2, then it's usually T2 which dies for no reason which makes any kind of sense :)
Yeah, youre right. I received the book today already.
uC/OS-II has function OSTaskStkChk() function which provides me with this information.
It's just that I need to dig deeper into whole concept of tasks to find out the stack use since the task needs to be created with OSTaskCreateExt(). OSTaskCreateExt() is given stack pointer and bottom of it as argument, so OS knows how much stack the task has. By filling the stack with zeros before creating task, OSTaskStkChk() can be called to calculate how much stack was used.
What OSTaskStkChk() does is loop from stack bottom towards stack start address untill nonzero value is found. Pretty simple ;) Yeah, stack bottom is the end of it... stack in uC/OS-II appears to be from high memory address towards lower memory address. My guess is that there's pretty good reason for that ;)