]> oss.titaniummirror.com Git - oss-web.git/blobdiff - in/projects/rgblamp/task.md
Website document reorganization
[oss-web.git] / in / projects / rgblamp / task.md
diff --git a/in/projects/rgblamp/task.md b/in/projects/rgblamp/task.md
new file mode 100644 (file)
index 0000000..4c29f6c
--- /dev/null
@@ -0,0 +1,65 @@
+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;
+          ...
+        }
+      }
+    }
+