Uppsala University
Listen to this web page

Uppsala University Department of Information Technology            

Notes on execi()

The execi call

A task is created by the execi function which as first argument takes the function the newly created task will be executing. If you want to give arguments to your task you most easily do it by using global variables.

If you want to send local arguments to your created tasks you do it by initilizing the argc and *argv[] arguments. argc stands for argument counter and should be an integer holding the number of arguments passed. argv stands for argument vector and is a vector of char pointers (ie. strings). It is your responsibility to create a correct argument vector and set the argc number.

For example a code like:

char * arg_to_foo[2] = {"lego", "mindstorms"};
execi(foo, 2, arg_to_foo, PRIO_NORMAL, DEFAULT_STACK_SIZE);

will create a task executing the function foo. Assuming that foo looks like:

int foo(int argc, char * argv[]) { ... }

we get that argc = 2, argv[0] = "lego" and argv[1] = "mindstorms".

Please note that if you allocate the argc vector in a task which later on dies (eg. in a task running main()) the vector might be deallocated since it vectors are called by call-by-reference in C.

If you don't want to give any arguments to your created task just make a call like:

execi(foo, 0, NULL, PRIO_NORMAL, DEFAULT_STACK_SIZE);

which sets argc = 0 and argv = NULL.

If you would like to give your created tasks arguments which not are char pointers you have to use C:s type casting facilities. Eg. the code:

int nr_of_touch_sensors = 2;
arg_to_foo[2] = (char *) &nr_of_touch_sensors;

will save the address of the integer nr_of_touch_sensors as an char pointer in the arg_to_foo vector. When we later on in the foo function wants to extract the integer we typecast the argument back:

int ts;
ts = *((int *) argv[2]);

ie. reinterpret the char pointer as an integer pointer and save what the integer pointer is pointing at in the integer ts.

The stack size argument to execi() is the amount of bytes that the task will be using when it makes function calls in the program (pushing contexts on the stack). In most cases the DEFAULT_STACK_SIZE value is enough, but if you do a lot a nested function calls you might need to increase the value.

Multitasking in brickOS/legOS

LegOS use pre-emptive multitasking. Shortly it works as follows:

By default a task is executed for 20 ms before being preempted. Every 1 ms a timer interrupt is generated by the hardware. Every time the timer interrupt is generated the current executing task is postponed by the function systime_handler function (defined in systime.c) which runs code which drives the system.

If 20 ms of the current task has elapsed, (ie. 20 timer interrupts has been generated), systime_handler calls tm_switcher, (defined in tm.c), which saves all registers of the current task on its stack, and then call the scheduler. The scheduler designates a new task to execute and returns to tm_switcher which copies the context of the new task into the registers and returns to systime_handler which just returns to the code in the new task.

Ie. system function code is run every 1 ms but the OS only makes preemptive context switches every 20 ms. However, to avoid wasting system resources tasks may voluntarily yield control of the processor by calling the yield() function. This is often indirectly made eg. by calling sleep or wait_event functions.

The scheduler has a queue of all tasks in the system, sorted on priorities. When the scheduler looks for a new task to execute, it always starts with the highest prioritised task which is in a ready-to-execute state. A task is ready to execute when its wait_event function returns a positive value (see the notes_on_wait_event document) or when the task has earlier been preempted by a higher priority task.

Fo more details on how the scheduling of tasks is made in the LegOS kernel see the "Introduction to the LegOS Kernel", (.ps or .pdf), by S. Nilsson.


Last update: Mon, 8 Sep 2003 11:12:21 Responsible: Tobias Amnell. Web: Contact
Copyright © 2004 Uppsala University, Department of Information Technology.
Show printer-friendly page      View this page.      Edit this page.