--- /dev/null
+title: RGB Lamp Tasks
+linktitle: rgb-task
+parent: rgb-code
+ctime: 2012-03-10
+mtime: 2012-03-10
+
+# Tasks
+
+A task implements an application behavior in response to an event. Tasks are
+executed to completion without pre-emption. Task start requests are queued if
+another task is already executing. A task start request when that task is
+already queued to start is effectively a null operation. However, a task start
+request for a task that is not queued but currently running will queue the task
+for a subsequent execution. This very simple task design is more than
+sufficient for the needs of the lamp application.
+
+One key decision under such a task architecture is which task to run next if
+multiple tasks are queued. This code selects the task with the highest priority
+in such a case. Application code must be cognizant of this fact, as a
+perpetually queueing high priority task will prevent execution of a queued lower
+priority task. This behavior is similar to hardware interrupt dispatch in many
+processor architectures, so most developers should already be familiar with its
+pitfalls.
+
+# Task implementation
+
+Tasks are implemented in the task.c, task.h and task_defs.h files,
+as found in the [repository](http://oss/gitweb?p=rgblamp.git;a=summary).
+
+Task identifiers are defind in the task_defs.h file. Each task id is an
+enumeration, with the highest priority task given the value of zero, and
+successively lower priority tasks having incrementally larger numbers. Since
+the task queue is implemented as bits in a variable, the width of the task_id_t
+structure defines the maximum number of supported tasks.
+
+Before using, initialize the task subsystem:
+
+ task_init();
+
+To queue a task for execution, post it. Tasks can be posted from within an ISR
+or from without. A task can post itself as well.
+
+ task_post(TASK_ID);
+
+Task dispatch is constructed from the task_get() function, which atomically gets
+and clears the next task (bit). The user application code then constructs a
+switch statement or similar structure to call a function associated with each
+task id. The lamp code implements this behavior in the user_tasks() function
+in main.c. Check it out in the
+[repository](http://oss/gitweb?p=rgblamp.git;a=summary). A short version:
+
+ void user_tasks(unsigned char block)
+ {
+ task_id_t tid;
+
+ while ((tid = task_get(block)) >= 0) {
+ switch (tid) {
+ case TASK_BTN_PB:
+ pb_task();
+ break;
+ ...
+ }
+ }
+ }
+