Hi,
I’ve just started trying to use uC/OS-II on my BL-2600; but can’t seem to get it to make a context switch without manually forcing a task delay using a OSTimeDlyHMSM call – and it seems that this is the case with all of the sample code provided.
Is it actually possible to get pre-emptive multitasking using uC/OS-II, and if so, how do I do it?
–Chris
(P.S. The application that I will be writing using uC/OS-II requires TCP/IP services)
as i know… you have to manually force a task delay either OSTimeDlyHMSM() or OSTimeDly(). Then the OS will automatically do a context switch base on the highest priority task to take over the process.
if you’re talking about a real pre-emptive, i dont think the microC/OS can do that (not sure whether other OS can do).
As for TCP/IP, i remember i read about something saying: all the TCP/IP process have to be put into a single task, not in seperate task. (please correct me if i’m wrong)…
I have only run this on the PC from the samples in the book, but it would seem to me that interrupts are not making higher priority tasks ready to run. I would check the priority of your task, if the priority of your task is higher than anything else ready to run, it won’t pre-empt as the highest priority task is already running. I would then verify that interrupts haven’t been inadvertently disabled. As I remember it was easy to clobber your interrupts with this OS if you call OS_CRITICAL_PROTECT() more than once and the critical protect was level 1 or 2, defined in OS_CFG.h on the PC maybe OS_CFG_LIB for Dynamic C and/or then pended the task without calling OS_CRITICAL_RELEASE(). I don’t have uC/OS-II for the rabbit yet… so I can’t say specifically about the rabbit 2000 version.
Just some thoughts that might help.
In that case, what reason would I have to use uC/OS-II ahead of the built-in co-operative multitasking?
i’ve tried to write some simple program using the built-in co-operative mustitasking, and also using uC/OS.
At the beginning, i also found the different is not much compare to the built-in multitasking. But as your program grows, you will found it easier to have uC/OS to manage the tasks, coz it comes with priority based, semaphore, msg, q, flag, etc. Of course you can still control them using your own written code together with the built-in multitasking.
A lot of libraries in C incorporate the use of uC/OS. so if your program use the uC/OS, then it will ease your work a lot, really!
and if your program is just a very simple one, you can consider sticking onto the built-in multitasking as it save you a lot of code space…
another thing to remember: the dynamic C libraries incorporating uC/OS do not completely bug free! you might encounter bug in the library using the uC/OS… but hey, who can guarantee the program/library he/she wrote is bug free? good luck!
I’m just a junior bunny so I wrote a simple hello world style app with MicroC/OS-II. Because it is supposed to be a “real time” OS I just put a couple of tasks in like this:
#define TASK_STK_SIZE 512 // Size of each task's stacks (# of bytes)
// Redefine uC/OS-II configuration constants as necessary
#define OS_MAX_EVENTS 2 // Maximum number of events (semaphores, queues, mailboxes)
#define OS_MAX_TASKS 11 // Maximum number of tasks system can create (less stat and idle tasks)
#define OS_TASK_STAT_EN 1 // Enable statistics task creation
#define OS_SEM_EN 1 // Enable semaphore usage
#define STACK_CNT_512 13 // number of 512 byte stacks (application tasks + stat task + prog stacks)
#use "ucos2.lib"
void HelloWorldTask(void *data);
void AnotherTask(void* data);
void main(void)
{
OSInit(); // Initialize uC/OS-II
OSTaskCreate(HelloWorldTask, (void *)0, TASK_STK_SIZE, 10);
OSTaskCreate(AnotherTask, (void *)0, TASK_STK_SIZE, 11);
OSStart(); // Start multitasking
}
void HelloWorldTask(void *data)
{
printf("Hello, world
");
while (1)
{
}
}
void AnotherTask(void* data)
{
printf("Hello, from another task
");
while (1)
{
}
}
Suffice to say it didn’t work. It just outputs the following:
Hello, world
AnotherTask isn’t being called. Not very pre-emptive!
I changed the above tasks to the following expectign that they would now work OK given that there is a yield function being called.
void HelloWorldTask(void *data)
{
printf("Hello, world
");
while (1)
{
printf("+");
OSTimeDly(100);
}
}
void AnotherTask(void* data)
{
printf("Hello, from another task
");
while (1)
{
printf("-");
OSTimeDly(100);
}
}
Both tasks have the same priority so I would have assumed that as many + symbols would be printed as - symbols.
Not so folks. The AnotherTask greeting isn’t printed and no - symbols appear. That looks like a bug in my book.
This code works…though for the life of me I don’t know why. if I make both tasks the same priority it still doesn’t work. But if I make the created thread a higher priority than the creator thread then it works as you’d expect.
#define TASK_STK_SIZE 512 // Size of each task's stacks (# of bytes)
// Redefine uC/OS-II configuration constants as necessary
#define OS_MAX_EVENTS 2 // Maximum number of events (semaphores, queues, mailboxes)
#define OS_MAX_TASKS 11 // Maximum number of tasks system can create (less stat and idle tasks)
#define OS_TASK_STAT_EN 1 // Enable statistics task creation
#define OS_SEM_EN 1 // Enable semaphore usage
#define STACK_CNT_512 13 // number of 512 byte stacks (application tasks + stat task + prog stacks)
#use "ucos2.lib"
void HelloWorldTask(void *data);
void AnotherTask(void* data);
void main(void)
{
OSInit(); // Initialize uC/OS-II
OSTaskCreate(HelloWorldTask, (void *)0, TASK_STK_SIZE, 10);
OSStart(); // Start multitasking
}
void HelloWorldTask(void *data)
{
printf("Hello, world
");
OSTaskCreate(AnotherTask, (void *)0, TASK_STK_SIZE, 9);
while (1)
{
printf("+");
OSTimeDly(5);
}
}
void AnotherTask(void* data)
{
printf("Hello, from another task
");
while (1)
{
printf("-");
OSTimeDly(5);
}
}
The output looks like this:
Hello, world
Hello, from another task
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Well Jack,
The first one did not work because neither of the two task yeilds the CPU. So the highest priority task runs indefinetly.
while(1)
{
; // do nothing
}
will never yeild the CPU.
Pre-emption does not mean that each task is called no matter what the priority. Pre-emption means that the highest priority task ready to run will pre-empt a lower priority task provided that pre-emption is not locked due to OSSchedLock(), or interrupt locking etc.
uC/OS-II is a priority based pre-emptive RTOS, however it is not a time-slicing RTOS. Time-slicing means tasks of the same priority that are READY to run each get an equal time-slice whether they yeild the CPU or not. I am pretty sure uC/OS-II does not support multiple tasks at the same priority and does not support time-slicing.
If you make the tasks the same priority the second OS_TASK_CREATE is returning with an error OS_PRIO_EXIT (priority already exists) since uC/OS-II does not support tasks with the same priority (unless this is a Rabbit version change, though, I doubt it. This would be a significant change to the OS scheduler).
Your example two should have worked if the priorities were different. If the priorities were the same then the second OS_TASK_CREATE would have failed. Based on your comments, I suspect that is why example two failed. The code otherwise should have worked. I do not have a Rabbit version to try it with. I haven’t ordered the rabbit version because my project doesn’t need it. I do have the PC-x86 version from the book and it should be fine to verify it.
I don’t think you should have had to implement #3 with the first task creating the second task, although that certainly is a viable way to do it. The rabbit version may have introduced some differences though. Again I suspect that this would not be the case here either.
The book has a really good description of the internals of uC/OS-II. If you are interested, it is a good technical read especially if you are an OS kinda of guy. uC/OS-II is not perfect code. It could have bugs, but I suspect the simple bugs have long since been fixed. There are updates to the rabbit version, the latest being 1.07 for Dynamic C 10.21. Don’t know what has been fixed etc. Just noticed it out there.
Just some thoughts. Hope it helps.
Thanks for replying
Having a startup task create all other tasks seems to be a normal way of going about things on rabbit. 
I’ll check the return codes when creating the tasks to make sure they are being created properly.
uC/OS doesnt support same priority task… max task available will be 64…