You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ad...@apache.org on 2016/07/06 19:56:21 UTC
[7/9] incubator-mynewt-site git commit: Various changes to task lesson
Various changes to task lesson
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/commit/2b665ab1
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/tree/2b665ab1
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/diff/2b665ab1
Branch: refs/heads/develop
Commit: 2b665ab154fd270b582df25134d5de3ae3fdf7ac
Parents: b773e08
Author: = <=>
Authored: Wed Jul 6 11:00:47 2016 -0700
Committer: = <=>
Committed: Wed Jul 6 11:02:24 2016 -0700
----------------------------------------------------------------------
docs/os/tutorials/pics/task_lesson.png | Bin 12445 -> 12931 bytes
docs/os/tutorials/tasks_lesson.md | 41 +++++++++++++++++-----------
2 files changed, 25 insertions(+), 16 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/2b665ab1/docs/os/tutorials/pics/task_lesson.png
----------------------------------------------------------------------
diff --git a/docs/os/tutorials/pics/task_lesson.png b/docs/os/tutorials/pics/task_lesson.png
index 16cbcd5..0ecb5e8 100644
Binary files a/docs/os/tutorials/pics/task_lesson.png and b/docs/os/tutorials/pics/task_lesson.png differ
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/2b665ab1/docs/os/tutorials/tasks_lesson.md
----------------------------------------------------------------------
diff --git a/docs/os/tutorials/tasks_lesson.md b/docs/os/tutorials/tasks_lesson.md
index 1e9c711..060381b 100644
--- a/docs/os/tutorials/tasks_lesson.md
+++ b/docs/os/tutorials/tasks_lesson.md
@@ -59,8 +59,7 @@ work_task_handler(void *arg)
}
```
-The task function is called when the task is initially put into the
-*running* state by the scheduler. We use an infinite loop to ensure that the task function never returns and assert that the current task\u2019s function is correct before doing any work.
+The task function is called when the task is initially put into the *running* state by the scheduler. We use an infinite loop to ensure that the task function never returns. Our assertion that the current task's handler is the same as our task handler is for illustration purposes only and does not need to be in most task functions.
### Task Priority
As a preemptive, multitasking RTOS, Mynewt decides which tasks to run based on which has a higher priority; the highest priority being 0 and the lowest 255. Thus, before initializing our task, we must choose a priority defined as a macro variable.
@@ -87,34 +86,42 @@ init_tasks(void)
}
```
+And that\u2019s it! Now run your application using the newt run command.
+```
+$ newt run arduino_blinky 0.0.0
+```
+When GDB appears press C then Enter to continue and \u2026 *wait, why doesn't our LED blink anymore?*
+
+
#### Review
-Before we run our new app, let\u2019s review what we need in order to create a task:
+Before we run our new app, let\u2019s review what we need in order to create a task. This is a general case for a new task called mytask:
- **1)** Define a new task, task stack, and priority
+ **1)** Define a new task, task stack, and priority:
```c
/* My Task */
-os_task mytask
+struct os_task mytask
/* My Task Stack */
#define MYTASK_STACK_SIZE OS_STACK_ALIGN(256)
os_stack_t mytask_stack[MYTASK_STACK_SIZE];
/* My Task Priority */
#define MYTASK_PRIO (0)
```
-**2)** Define task function
+**2)** Define task function:
```c
void
mytask_handler(void *arg)
{
- /* ... */
+ while (1) {
+ /* ... */
+ }
}
```
-**3)** Initialize task before calling `os_start()`
+**3)** Initialize task before calling `os_start()`:
```c
os_task_init(&mytask, "mytask", mytask_handler, NULL,
MYTASK_PRIO, OS_WAIT_FOREVER, mytask_stack,
MYTASK_STACK_SIZE);
```
-And that\u2019s it! Run your application and \u2026 *wait, why doesn't our LED blink anymore?*
##Task Priority, Preempting, and Context Switching
A preemptive RTOS is one in which a higher priority task that is *ready to run* will preempt (i.e. take the place of) the lower priority task which is *running*. When a lower priority task is preempted by a higher priority task, the lower priority task\u2019s context data (stack pointer, registers, etc.) is saved and the new task is switched in.
@@ -136,7 +143,7 @@ work_task_handler(void *arg)
/* Do work... */
int i;
for(i = 0; i < 1000000; ++i) {
- //simulate doing a noticeable amount of work
+ /* Simulate doing a noticeable amount of work */
hal_gpio_set(g_led_pin);
}
os_time_delay(3*OS_TICKS_PER_SECOND);
@@ -146,12 +153,12 @@ work_task_handler(void *arg)
In order to notice the LED changing, modify the time delay in `blinky_task_handler()` to blink at a higher frequency.
```c
-os_time_delay(100);
+os_time_delay(OS_TICKS_PER_SEC/10);
```
-Before we run the app, let\u2019s predict the behavior. With the newest
-additions to `work_task_handler()`, our first action will be to sleep for three seconds. This will allow `blinky_task` to take over the CPU and blink to its heart\u2019s content. After three seconds, `work_task` will wake up and be made *ready to run*, causing it to preempt `blinky_task`. The LED will then remain lit for a short period while `work_task` loops, then blink again for another three seconds while `work_task` sleeps.
+Before we run the app, let\u2019s predict the behavior. With the newest additions to `work_task_handler()`, our first action will be to sleep for three seconds. This will allow `blinky_task` to take over the CPU and blink to its heart\u2019s content. After three seconds, `work_task` will wake up and be made *ready to run*, causing it to preempt `blinky_task`. The LED will then remain lit for a short period while `work_task` loops, then blink again for another three seconds while `work_task` sleeps.
+
+Voila, you should see that our prediction was correct!
-Viola, you should see that our prediction was correct! What would happen when both priorities are the same? Try it out for yourself!
###Priority Management Considerations
When projects grow in scope, from blinking LEDs into more sophisticated applications, the number of tasks needed increases alongside complexity. It remains important, then, that each of our tasks is capable of doing its work within a reasonable amount of time.
@@ -164,6 +171,8 @@ The diagram below showcases the different scheduling patterns we. would expect f
In the second case where `blinky_task` has a higher priority, the \u201cwork\u201d done by `work_task` would be executed during the millisecond delays in `blinky_task`, saving us idle time compared to the first case.
+**Note:** Defining the same priority for two tasks leads to somewhat undefined behavior and should be avoided.
+
##Comparing Priority Strategies
Instead of stepping through a bunch of changes to our blinky app, clone my task lesson application from github and copy an existing target.
@@ -227,7 +236,7 @@ If you see minicom welcome you, you\u2019re ready to move on!
### Output Analysis
-Run our new target, task_sim, and you should see an output similar to this:
+Run our new target, task_tgt, and you should see an output similar to this:
```
Starting First Simulation...
@@ -312,4 +321,4 @@ Feel free to play around with the testing parameters to study the different chan
##Conclusion
Moving forward, tasks are just the tip of the iceberg. The [*scheduler*](http://mynewt.apache.org/latest/os/core_os/context_switch/context_switch/), [*event queues*](http://mynewt.apache.org/latest/os/core_os/event_queue/event_queue/), [*semaphores*](http://mynewt.apache.org/latest/os/core_os/semaphore/semaphore/), and [*mutexes*](http://mynewt.apache.org/latest/os/core_os/mutex/mutex/) also add to tasks functionality, increasing our ability as the developer to control greater numbers of tasks more intricately. For example, when we switch the tasks priority, we have to tell the scheduler that our tasks priorities have changed, allowing us us to use priorities dynamically. When running multiple tasks, logging through either the built-in [*Logs*](http://mynewt.apache.org/latest/os/modules/logs/logs/) module (not covered in this lesson) or through the serial console/shell can be very useful for debugging your application. In the end, the way you manage your tasks depends on the context
of your application. You should assign priorities based on execution time, urgency, and frequency, among other things.
-Keep blinking and happy hacking!
+Keep blinking and happy hacking!
\ No newline at end of file