Start
Task
Function
Scheduling
and Timeslice
Task
Context
Task
Control Block
Global
Variables
Memory
Management
API
Assembly
Functions
Give
it a Try
Enhancements
References,
Sources & PDF
GLOBAL
VARIABLES
As most programmers have
learned, global variables are generally not part of
good code design. But, there are situations where
their use is warranted.
For example, under µexec,
we use two global variables to pass information between
C and assembly routines. The alternative is to use
normal argument passing between the routines, but
that would be compiler and microcontroller dependent,
making it difficult to port µexec using other compilers
or to other microcontrollers:
void (*uexc_current_func)(void);
unsigned char *uexc_current_sp;
uexc_current_func is
the pointer to the function for the current task and
is needed only to start a new task. uexc_current_sp
is the current stack pointer or the address of the
sp field of the current task. The latter is used by
UEXC_Defer to tell the assembly routine where to store
the stack pointer after the interrupt frame is created.
µexec uses a few other
global variables and macros, such as static TaskControlBlock
*current_ task;. This global variable points to the
task-control block of the current task. All the tasks
are linked in a circular list, so the next task to
execute is given by current_task->next.
void (*UEXC_InterruptDriver)
(void); contains the address of a function to call
whenever the timer interrupt triggers. If you have
more than one function to call, you can chain them
together.
The NUM_TASKS macro is
the maximum number of task-control blocks that can
be allocated. You should change this to match the
number of tasks you have in your system.
The macro UEXC_MIN_STACK_SIZE
defines the minimum stack size for a task. If your
task function invokes other functions or uses local
variables, you should allocate a bigger stack.