blob: ee1611edf4adf21bc60208a3766cfdec63e3e6e1 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- This is broken by doc revisioning.
-->
<link rel="shortcut icon" href="../../../img/favicon.ico">
<title>Add task to manage multiple events - Apache Mynewt</title>
<link href="../../../css/bootstrap-3.0.3.min.css" rel="stylesheet">
<link rel="stylesheet" href="../../../css/highlight.css">
<link href="../../../css/base.css" rel="stylesheet">
<link href="../../../css/custom.css" rel="stylesheet">
<link href="../../../css/v2.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
<script>
(function(i, s, o, g, r, a, m) {
i["GoogleAnalyticsObject"] = r;
(i[r] =
i[r] ||
function() {
(i[r].q = i[r].q || []).push(arguments);
}),
(i[r].l = 1 * new Date());
(a = s.createElement(o)), (m = s.getElementsByTagName(o)[0]);
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m);
})(window, document, "script", "//www.google-analytics.com/analytics.js", "ga");
ga("create", "UA-72162311-1", "auto");
ga("send", "pageview");
</script>
</head>
<body class="Add task to manage multiple events">
<div class="container">
<div class="row v2-main-banner">
<a class="logo-cell" href="/">
<img class="logo" src="/img/logo.png">
</a>
<div class="tagline-cell">
<h4 class="tagline">An OS to build, deploy and securely manage billions of devices</h4>
</div>
<div class="news-cell">
<div class="well">
<h4>Latest News:</h4> <a href="/download">Apache Mynewt 1.11.0, Apache NimBLE 1.6.0 </a> released (September 7, 2023)
</div>
</div>
</div>
</div>
<nav id="navbar" class="navbar navbar-inverse affix-top" data-spy="affix" data-offset-top="150" role="navigation">
<div class="container">
<!-- Collapsed navigation -->
<div class="navbar-header">
<!-- Expander button -->
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<!-- Expanded navigation -->
<div class="navbar-collapse collapse">
<!-- Main navigation -->
<ul class="nav navbar-nav navbar-right">
<li
class=""
>
<a href="/"><i class="fa fa-home" style="font-size: larger;"></i></a>
</li>
<li
class="important"
>
<a href="/quick-start/">Quick Start</a>
</li>
<li
class=""
>
<a href="/about/">About</a>
</li>
<li
class=""
>
<a href="/talks/">Talks</a>
</li>
<li
class="active"
>
<a href="/documentation/">Documentation</a>
</li>
<li
class=""
>
<a href="/download/">Download</a>
</li>
<li
class=""
>
<a href="/community/">Community</a>
</li>
<li
class=""
>
<a href="/events/">Events</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="container">
<div class="row">
<div class="col-md-3 v2-sidebar sidebar-container"><div id="docSidebar" class="hidden-print" role="complementary">
<div class="top">
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../../../search.html" method="get">
<div class="form-group">
<input type="text" name="q" class="form-control" placeholder="Search documentation" />
</div>
</form>
</div>
</div>
<ul class="toc-nav">
<li class="doc-version"><select class="form-control" onchange="if (this.value) window.location.href=this.value">
<option value="/latest">
Version: master
</option>
<option value="/v1_11_0/" >
Version: 1.11.0
</option>
<option value="/v1_10_0/" >
Version: 1.10.0
</option>
<option value="/v1_9_0/" >
Version: 1.9.0
</option>
<option value="/v1_8_0/" >
Version: 1.8.0
</option>
<option value="/v1_7_0/" >
Version: 1.7.0
</option>
<option value="/v1_6_0/" >
Version: 1.6.0
</option>
<option value="/v1_5_0/" >
Version: 1.5.0
</option>
<option value="/v1_4_0/" >
Version: 1.4.0
</option>
<option value="/v1_3_0/os/introduction" >
Version: 1.3.0
</option>
<option value="/v1_2_0/os/introduction" >
Version: 1.2.0
</option>
<option value="/v1_1_0/os/introduction" >
Version: 1.1.0
</option>
<option value="/v1_0_0/os/introduction" >
Version: 1.0.0
</option>
<option value="/v0_9_0/os/introduction" selected="selected" >
Version: 0.9.0
</option>
</select></li>
<li ><a href="../../introduction/">Mynewt Documentation</a>
<ul>
<li ><a href="../../get_started/get_started/">Basic Setup</a>
</li>
<li >
<a href="../../get_started/vocabulary/">Concepts</a>
</li>
<li ><a href="../tutorials/">Tutorials</a>
<ul>
<li><a href="
../arduino_zero/
">Project Blinky</a>
</li>
<li ><a href="../repo/add_repos/">Work with repositories</a>
</li>
<li >
<a href="../unit_test/">Write a Test Suite for a Package</a>
</li>
<li >
<a href="../air_quality_sensor/">Air-quality Sensor project</a>
</li>
<li class="active">
<a href="./">Add task to manage multiple events</a>
</li>
<li >
<a href="../project-slinky/">Enable remote comms on sim device</a>
</li>
<li >
<a href="../project-target-slinky/">Enable remote comms on STM32 board</a>
</li>
<li >
<a href="../bletiny_project/">BLE app to check stats via console</a>
</li>
<li ><a href="../bleprph/bleprph-intro/">BLE peripheral project</a>
</li>
<li >
<a href="../ibeacon/">BLE iBeacon</a>
</li>
<li >
<a href="../blehci_project/">BLE HCI interface</a>
</li>
</ul>
</li>
<li ><a href="../../os_user_guide/">OS User Guide</a>
</li>
<li><a href="
../../../network/ble/ble_intro/
">BLE User Guide</a>
</li>
<li ><a href="../../../newt/newt_intro/">Newt Tool Guide</a>
</li>
<li ><a href="../../../newtmgr/overview/">Newt Manager Guide</a>
</li>
<li >
<a href="../../../known_issues/">Known Issues</a>
</li>
</ul>
</li>
<li><a href="
../../../faq/how_to_edit_docs/
">Appendix</a>
</li>
</ul>
</div></div>
<div class="col-md-9" role="main">
<div class="doc-header">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="/documentation/">Docs</a></li>
<li>&raquo; <a href="os/tutorials/tutorials/">Tutorials</a></li>
<li>&raquo; <a href="os/introduction/">Mynewt Documentation</a></li>
<li>&raquo; Add task to manage multiple events</li>
</ul>
</div>
</div>
<div class="alert alert-warning">
<p>
Version 0.9.0 is not the most recent version of the Apache Mynewt
documentation. Click <a href="/latest">here</a> to read the latest
version.
</p>
</div>
<h2 id="how-to-define-a-task-which-uses-event-queues-to-manage-multiple-events">How to define a task which uses event queues to manage multiple events</h2>
<h3 id="introduction">Introduction</h3>
<p>Event queue is a mechanism by which you can serialize incoming events for your task. You can use it to get info about arrived hardware interrupts, callout expirations and messages from other tasks.</p>
<p>The benefit of doing inter-task communication this way is that there should be less resources that need to be locked.</p>
<p>The benefit of doing interrupt processing in a task context instead of inside an interrupt context is that you are not blocking other HW interrupts when doing the work. The same goes for high priority tasks in the system; they're blocked until the interrupt handler returns. From the task context you'll also be able to access other OS facilities; you can sleep while waiting for a lock, for example.</p>
<p><br></p>
<h3 id="example-app">Example app</h3>
<p>Here you are going to write an app which demonstrates the use of event queues for communication between tasks. You will also use OS callouts for timer expiration and another event from a GPIO interrupt.</p>
<p>You will use inputs from 3 sources to toggle 3 GPIO outputs on my STM32F3discovery board.</p>
<p><br></p>
<h4 id="create-project">Create project</h4>
<p>You start by creating a project and populating it with repositories incubator-mynewt-core and mynewt_stm32f3. See <a href="../STM32F303/">STM32F3 tutorial</a> if you need help with this. You can also read the tutorial on <a href="../repo/add_repos/">Additional Repositories</a> for a more thorough understanding. </p>
<p><br> </p>
<h4 id="create-application">Create application</h4>
<p>Here's what the pkg.yml looks for the application.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>[marko@IsMyLaptop:~/src/events]$ cat apps/event_sample/pkg.yml
pkg.name: apps/event_sample
pkg.type: app
pkg.deps:
- &quot;@apache-mynewt-core/libs/os&quot;
- &quot;@apache-mynewt-core/hw/hal&quot;
- &quot;@apache-mynewt-core/libs/console/stub&quot;
</code></pre></div>
<p><br></p>
<h4 id="initialize-the-event-queue-structure">Initialize the event queue structure</h4>
<p>This must be done before anyone tries to place events to the queue. Here it's done before any task gets created. Initialization is done by calling <em>os_eventq_init()</em>.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #633820">#define MY_TASK_PRIO 4</span>
<span style="color: #633820">#define MY_TASK_STACK_SZ 512</span>
<span style="color: #A90D91">static</span> <span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_eventq</span> <span style="color: #000000">my_eventq</span>;
<span style="color: #A90D91">static</span> <span style="color: #000000">os_stack_t</span> <span style="color: #000000">my_task_stack</span>[<span style="color: #000000">MY_TASK_STACK_SZ</span>];
<span style="color: #A90D91">static</span> <span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_task</span> <span style="color: #000000">my_task_str</span>;
<span style="color: #A90D91">void</span>
<span style="color: #000000">init_tasks</span>(<span style="color: #A90D91">void</span>)
{
<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_task</span> <span style="color: #000000">taskid</span>;
<span style="color: #000000">os_eventq_init</span>(<span style="color: #000000">&amp;my_eventq</span>);
<span style="color: #000000">os_task_init</span>(<span style="color: #000000">&amp;my_task_str</span>, <span style="color: #C41A16">&quot;task&quot;</span>, <span style="color: #000000">my_task</span>, <span style="color: #A90D91">NULL</span>, <span style="color: #000000">MY_TASK_PRIO</span>,
<span style="color: #000000">OS_WAIT_FOREVER</span>, <span style="color: #000000">my_task_stack</span>, <span style="color: #000000">MY_TASK_STACK_SZ</span>);
</code></pre></div>
<p><br></p>
<h4 id="processing-events">Processing events</h4>
<p>Here event processing is done inside <em>my_task</em>. The main loop of the task is pulling events from the queue, and then taking action. We look at the type of the event to figure out what to do.</p>
<p>The code snippet shows what the main loop of the event handler looks like. Events are removed from the head of the queue using os_eventq_get</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #A90D91">void</span>
<span style="color: #000000">my_task</span>(<span style="color: #A90D91">void</span> <span style="color: #000000">*arg</span>)
{
<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_event</span> <span style="color: #000000">*ev</span>;
<span style="color: #A90D91">while</span> (<span style="color: #1C01CE">1</span>) {
<span style="color: #000000">ev</span> <span style="color: #000000">=</span> <span style="color: #000000">os_eventq_get</span>(<span style="color: #000000">&amp;my_eventq</span>);
<span style="color: #A90D91">switch</span> (<span style="color: #000000">ev-&gt;ev_type</span>) {
<span style="color: #177500">/* more event types here */</span>
<span style="color: #A90D91">default</span><span style="color: #000000">:</span>
<span style="color: #000000">assert</span>(<span style="color: #1C01CE">0</span>);
}
}
}
</code></pre></div>
<p><br></p>
<h4 id="event-types">Event types</h4>
<p>You can define your own event types. Some numbers are already reserved by the OS, so you should not use those as your own types.</p>
<p>Reserved event types are defined in <em>libs/os/include/os/os_eventq.h</em>. One example of a reserved type is OS_EVENT_T_TIMER, which is used as type in OS callouts.</p>
<p>You should start your event numbers from <em>OS_EVENT_T_PERUSER</em>, and go higher.</p>
<p>You are going to generate events from GPIO interrupt handler, from another task as well as from a callout. OS callout already has a type, but you'll need to define types for the other uses.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #633820">#define MY_TASK_GPIO_EVENT (OS_EVENT_T_PERUSER)</span>
<span style="color: #633820">#define MY_TASK_TASK_EVENT (OS_EVENT_T_PERUSER + 1)</span>
</code></pre></div>
<p><br></p>
<h4 id="posting-events-from-another-task">Posting events from another task</h4>
<p>Events are posted to a queue by calling <em>os_eventq_put()</em>. You need to preallocate memory for the event structure. Here it's done by declaring the event structure as a global variable.</p>
<p>Note that you can call <em>os_eventq_put()</em> with an event which has already been queued. In that case, the call has no effect; the position of the event is not changed within the queue.</p>
<p>In the code snippet we declare the os_event structure, and initialize it. We also create the event generating task, and periodically post event to the event queue.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #633820">#define GEN_TASK_PRIO 3</span>
<span style="color: #633820">#define GEN_TASK_STACK_SZ 512</span>
<span style="color: #A90D91">static</span> <span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_event</span> <span style="color: #000000">gen_task_ev</span>;
<span style="color: #A90D91">static</span> <span style="color: #000000">os_stack_t</span> <span style="color: #000000">gen_task_stack</span>[<span style="color: #000000">GEN_TASK_STACK_SZ</span>];
<span style="color: #A90D91">static</span> <span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_task</span> <span style="color: #000000">gen_task_str</span>;
<span style="color: #A90D91">void</span>
<span style="color: #000000">gen_task</span>(<span style="color: #A90D91">void</span> <span style="color: #000000">*arg</span>)
{
<span style="color: #A90D91">while</span> (<span style="color: #1C01CE">1</span>) {
<span style="color: #000000">os_time_delay</span>(<span style="color: #000000">OS_TICKS_PER_SEC</span> <span style="color: #000000">/</span> <span style="color: #1C01CE">4</span>);
<span style="color: #000000">os_eventq_put</span>(<span style="color: #000000">&amp;my_eventq</span>, <span style="color: #000000">&amp;gen_task_ev</span>);
}
}
<span style="color: #A90D91">void</span>
<span style="color: #000000">init_tasks</span>(<span style="color: #A90D91">void</span>)
{
<span style="color: #177500">/* .... */</span>
<span style="color: #000000">gen_task_ev</span>.<span style="color: #000000">ev_type</span> <span style="color: #000000">=</span> <span style="color: #000000">MY_TASK_TASK_EVENT</span>;
<span style="color: #000000">os_task_init</span>(<span style="color: #000000">&amp;gen_task_str</span>, <span style="color: #C41A16">&quot;gen_task&quot;</span>, <span style="color: #000000">gen_task</span>, <span style="color: #A90D91">NULL</span>, <span style="color: #000000">GEN_TASK_PRIO</span>,
<span style="color: #000000">OS_WAIT_FOREVER</span>, <span style="color: #000000">gen_task_stack</span>, <span style="color: #000000">GEN_TASK_STACK_SZ</span>);
}
</code></pre></div>
<p><br></p>
<h4 id="callout-events">Callout events</h4>
<p>You can get timer events delivered to your task's event queue with OS callout. Check <a href="../../core_os/callout/callout/">callout documentation</a> for description on how to use the API.</p>
<p>For this example, you'll use only one type of callout; so you can use the simpler structure.</p>
<p>In the code snippet we declare the os_callout structure and initialize it. Then we arm the timer.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #A90D91">static</span> <span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_callout</span> <span style="color: #000000">my_callout</span>;
<span style="color: #A90D91">void</span>
<span style="color: #000000">init_tasks</span>(<span style="color: #A90D91">void</span>)
{
<span style="color: #177500">/* .... */</span>
<span style="color: #000000">os_callout_init</span>(<span style="color: #000000">&amp;my_callout</span>, <span style="color: #000000">&amp;my_eventq</span>, <span style="color: #A90D91">NULL</span>);
<span style="color: #000000">os_callout_reset</span>(<span style="color: #000000">&amp;my_callout</span>, <span style="color: #000000">OS_TICKS_PER_SEC</span>);
}
</code></pre></div>
<p><br></p>
<h4 id="posting-events-from-interrupt-handler">Posting events from interrupt handler</h4>
<p>Another place where posting events makes sense is from an interrupt handler. In this tutorial you will do it when GPIO changes state.</p>
<p>You'll use HAL GPIO interface to register a routine which is getting called from the interrupt handler context. This routine will then post event to your queue.</p>
<p>On STM32F3Discovery board, there is a button connected to PA0. The identifier for this GPIO pin is 0.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #A90D91">static</span> <span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_event</span> <span style="color: #000000">gpio_ev</span>;
<span style="color: #A90D91">void</span>
<span style="color: #000000">init_tasks</span>(<span style="color: #A90D91">void</span>)
{
<span style="color: #177500">/* .... */</span>
<span style="color: #000000">gpio_ev</span>.<span style="color: #000000">ev_type</span> <span style="color: #000000">=</span> <span style="color: #000000">MY_TASK_GPIO_EVENT</span>;
<span style="color: #000000">hal_gpio_irq_init</span>(<span style="color: #1C01CE">0</span>, <span style="color: #000000">my_gpio_irq</span>, <span style="color: #A90D91">NULL</span>, <span style="color: #000000">GPIO_TRIG_RISING</span>,
<span style="color: #000000">GPIO_PULL_NONE</span>);
<span style="color: #000000">hal_gpio_irq_enable</span>(<span style="color: #1C01CE">0</span>);
}
<span style="color: #A90D91">static</span> <span style="color: #A90D91">void</span>
<span style="color: #000000">my_gpio_irq</span>(<span style="color: #A90D91">void</span> <span style="color: #000000">*arg</span>)
{
<span style="color: #000000">os_eventq_put</span>(<span style="color: #000000">&amp;my_eventq</span>, <span style="color: #000000">&amp;gpio_ev</span>);
}
</code></pre></div>
<p><br></p>
<h4 id="event-processing-finalized">Event processing finalized</h4>
<p>Now that you are posting events from different sources, you will fill in the parts in the task main loop to trigger different behaviors depending on event type.</p>
<p>You'll drive different LEDs depending on what type of event arrived. LEDs on this board are connected to PE8, PE9, PE10 and so on. These have GPIO identifiers starting from 72 onwards.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #633820">#define TASK_LED 72</span>
<span style="color: #633820">#define CALLOUT_LED 73</span>
<span style="color: #633820">#define GPIO_LED 74</span>
<span style="color: #A90D91">void</span>
<span style="color: #000000">init_tasks</span>(<span style="color: #A90D91">void</span>)
{
<span style="color: #177500">/* .... */</span>
<span style="color: #000000">hal_gpio_init_out</span>(<span style="color: #000000">TASK_LED</span>, <span style="color: #1C01CE">1</span>);
<span style="color: #000000">hal_gpio_init_out</span>(<span style="color: #000000">CALLOUT_LED</span>, <span style="color: #1C01CE">1</span>);
<span style="color: #000000">hal_gpio_init_out</span>(<span style="color: #000000">GPIO_LED</span>, <span style="color: #1C01CE">1</span>);
}
</code></pre></div>
<p>And here is the new main loop for your task. Note that when callout event arrives, we re-arm the callout.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #A90D91">void</span>
<span style="color: #000000">my_task</span>(<span style="color: #A90D91">void</span> <span style="color: #000000">*arg</span>)
{
<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_event</span> <span style="color: #000000">*ev</span>;
<span style="color: #A90D91">while</span> (<span style="color: #1C01CE">1</span>) {
<span style="color: #000000">ev</span> <span style="color: #000000">=</span> <span style="color: #000000">os_eventq_get</span>(<span style="color: #000000">&amp;my_eventq</span>);
<span style="color: #A90D91">switch</span> (<span style="color: #000000">ev-&gt;ev_type</span>) {
<span style="color: #A90D91">case</span> <span style="color: #000000">MY_TASK_TASK_EVENT</span>:
<span style="color: #000000">hal_gpio_toggle</span>(<span style="color: #000000">TASK_LED</span>);
<span style="color: #A90D91">break</span>;
<span style="color: #A90D91">case</span> <span style="color: #000000">OS_EVENT_T_TIMER</span>:
<span style="color: #000000">hal_gpio_toggle</span>(<span style="color: #000000">CALLOUT_LED</span>);
<span style="color: #000000">os_callout_reset</span>(<span style="color: #000000">&amp;my_callout</span>, <span style="color: #000000">OS_TICKS_PER_SEC</span> <span style="color: #000000">/</span> <span style="color: #1C01CE">2</span>);
<span style="color: #A90D91">break</span>;
<span style="color: #A90D91">case</span> <span style="color: #000000">MY_TASK_GPIO_EVENT</span>:
<span style="color: #000000">hal_gpio_toggle</span>(<span style="color: #000000">GPIO_LED</span>);
<span style="color: #A90D91">break</span>;
<span style="color: #A90D91">default</span><span style="color: #000000">:</span>
<span style="color: #000000">assert</span>(<span style="color: #1C01CE">0</span>);
}
}
}
</code></pre></div>
<p><br></p>
<p>Now you're done. Once you load this to your board, the task LED will blink at an interval of 250ms, the callout LED with an interval of 500ms, and the GPIO LED every time you press the button.</p>
<p><br></p>
<h3 id="code-for-the-example">Code for the example</h3>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #633820">#include</span> <span style="color: #177500">&lt;os/os.h&gt;</span>
<span style="color: #633820">#include</span> <span style="color: #177500">&lt;bsp/bsp.h&gt;</span>
<span style="color: #633820">#include</span> <span style="color: #177500">&lt;hal/hal_gpio.h&gt;</span>
<span style="color: #633820">#include</span> <span style="color: #177500">&lt;assert.h&gt;</span>
<span style="color: #633820">#define MY_TASK_PRIO 4</span>
<span style="color: #633820">#define MY_TASK_STACK_SZ 512</span>
<span style="color: #633820">#define GEN_TASK_PRIO 3</span>
<span style="color: #633820">#define GEN_TASK_STACK_SZ 512</span>
<span style="color: #633820">#define MY_TASK_GPIO_EVENT (OS_EVENT_T_PERUSER)</span>
<span style="color: #633820">#define MY_TASK_TASK_EVENT (OS_EVENT_T_PERUSER + 1)</span>
<span style="color: #633820">#define TASK_LED 72</span>
<span style="color: #633820">#define CALLOUT_LED 73</span>
<span style="color: #633820">#define GPIO_LED 74</span>
<span style="color: #A90D91">static</span> <span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_eventq</span> <span style="color: #000000">my_eventq</span>;
<span style="color: #A90D91">static</span> <span style="color: #000000">os_stack_t</span> <span style="color: #000000">my_task_stack</span>[<span style="color: #000000">MY_TASK_STACK_SZ</span>];
<span style="color: #A90D91">static</span> <span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_task</span> <span style="color: #000000">my_task_str</span>;
<span style="color: #A90D91">static</span> <span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_event</span> <span style="color: #000000">gen_task_ev</span>;
<span style="color: #A90D91">static</span> <span style="color: #000000">os_stack_t</span> <span style="color: #000000">gen_task_stack</span>[<span style="color: #000000">GEN_TASK_STACK_SZ</span>];
<span style="color: #A90D91">static</span> <span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_task</span> <span style="color: #000000">gen_task_str</span>;
<span style="color: #A90D91">static</span> <span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_callout</span> <span style="color: #000000">my_callout</span>;
<span style="color: #A90D91">static</span> <span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_event</span> <span style="color: #000000">gpio_ev</span>;
<span style="color: #A90D91">void</span>
<span style="color: #000000">my_task</span>(<span style="color: #A90D91">void</span> <span style="color: #000000">*arg</span>)
{
<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_event</span> <span style="color: #000000">*ev</span>;
<span style="color: #A90D91">while</span> (<span style="color: #1C01CE">1</span>) {
<span style="color: #000000">ev</span> <span style="color: #000000">=</span> <span style="color: #000000">os_eventq_get</span>(<span style="color: #000000">&amp;my_eventq</span>);
<span style="color: #A90D91">switch</span> (<span style="color: #000000">ev-&gt;ev_type</span>) {
<span style="color: #A90D91">case</span> <span style="color: #000000">MY_TASK_TASK_EVENT</span>:
<span style="color: #000000">hal_gpio_toggle</span>(<span style="color: #000000">TASK_LED</span>);
<span style="color: #A90D91">break</span>;
<span style="color: #A90D91">case</span> <span style="color: #000000">OS_EVENT_T_TIMER</span>:
<span style="color: #000000">hal_gpio_toggle</span>(<span style="color: #000000">CALLOUT_LED</span>);
<span style="color: #000000">os_callout_reset</span>(<span style="color: #000000">&amp;my_callout</span>, <span style="color: #000000">OS_TICKS_PER_SEC</span> <span style="color: #000000">/</span> <span style="color: #1C01CE">2</span>);
<span style="color: #A90D91">break</span>;
<span style="color: #A90D91">case</span> <span style="color: #000000">MY_TASK_GPIO_EVENT</span>:
<span style="color: #000000">hal_gpio_toggle</span>(<span style="color: #000000">GPIO_LED</span>);
<span style="color: #A90D91">break</span>;
<span style="color: #A90D91">default</span><span style="color: #000000">:</span>
<span style="color: #000000">assert</span>(<span style="color: #1C01CE">0</span>);
}
}
}
<span style="color: #A90D91">static</span> <span style="color: #A90D91">void</span>
<span style="color: #000000">my_gpio_irq</span>(<span style="color: #A90D91">void</span> <span style="color: #000000">*arg</span>)
{
<span style="color: #000000">os_eventq_put</span>(<span style="color: #000000">&amp;my_eventq</span>, <span style="color: #000000">&amp;gpio_ev</span>);
}
<span style="color: #A90D91">void</span>
<span style="color: #000000">gen_task</span>(<span style="color: #A90D91">void</span> <span style="color: #000000">*arg</span>)
{
<span style="color: #A90D91">while</span> (<span style="color: #1C01CE">1</span>) {
<span style="color: #000000">os_time_delay</span>(<span style="color: #000000">OS_TICKS_PER_SEC</span> <span style="color: #000000">/</span> <span style="color: #1C01CE">4</span>);
<span style="color: #000000">os_eventq_put</span>(<span style="color: #000000">&amp;my_eventq</span>, <span style="color: #000000">&amp;gen_task_ev</span>);
}
}
<span style="color: #A90D91">void</span>
<span style="color: #000000">init_tasks</span>(<span style="color: #A90D91">void</span>)
{
<span style="color: #000000">os_eventq_init</span>(<span style="color: #000000">&amp;my_eventq</span>);
<span style="color: #000000">os_task_init</span>(<span style="color: #000000">&amp;my_task_str</span>, <span style="color: #C41A16">&quot;task&quot;</span>, <span style="color: #000000">my_task</span>, <span style="color: #A90D91">NULL</span>, <span style="color: #000000">MY_TASK_PRIO</span>,
<span style="color: #000000">OS_WAIT_FOREVER</span>, <span style="color: #000000">my_task_stack</span>, <span style="color: #000000">MY_TASK_STACK_SZ</span>);
<span style="color: #000000">gen_task_ev</span>.<span style="color: #000000">ev_type</span> <span style="color: #000000">=</span> <span style="color: #000000">MY_TASK_TASK_EVENT</span>;
<span style="color: #000000">os_task_init</span>(<span style="color: #000000">&amp;gen_task_str</span>, <span style="color: #C41A16">&quot;gen_task&quot;</span>, <span style="color: #000000">gen_task</span>, <span style="color: #A90D91">NULL</span>, <span style="color: #000000">GEN_TASK_PRIO</span>,
<span style="color: #000000">OS_WAIT_FOREVER</span>, <span style="color: #000000">gen_task_stack</span>, <span style="color: #000000">GEN_TASK_STACK_SZ</span>);
<span style="color: #000000">os_callout_init</span>(<span style="color: #000000">&amp;my_callout</span>, <span style="color: #000000">&amp;my_eventq</span>, <span style="color: #A90D91">NULL</span>);
<span style="color: #000000">os_callout_reset</span>(<span style="color: #000000">&amp;my_callout</span>, <span style="color: #000000">OS_TICKS_PER_SEC</span>);
<span style="color: #000000">gpio_ev</span>.<span style="color: #000000">ev_type</span> <span style="color: #000000">=</span> <span style="color: #000000">MY_TASK_GPIO_EVENT</span>;
<span style="color: #000000">hal_gpio_irq_init</span>(<span style="color: #1C01CE">0</span>, <span style="color: #000000">my_gpio_irq</span>, <span style="color: #A90D91">NULL</span>, <span style="color: #000000">GPIO_TRIG_RISING</span>,
<span style="color: #000000">GPIO_PULL_NONE</span>);
<span style="color: #000000">hal_gpio_irq_enable</span>(<span style="color: #1C01CE">0</span>);
<span style="color: #000000">hal_gpio_init_out</span>(<span style="color: #000000">TASK_LED</span>, <span style="color: #1C01CE">1</span>);
<span style="color: #000000">hal_gpio_init_out</span>(<span style="color: #000000">CALLOUT_LED</span>, <span style="color: #1C01CE">1</span>);
<span style="color: #000000">hal_gpio_init_out</span>(<span style="color: #000000">GPIO_LED</span>, <span style="color: #1C01CE">1</span>);
}
<span style="color: #A90D91">int</span>
<span style="color: #000000">main</span>(<span style="color: #A90D91">int</span> <span style="color: #000000">argc</span>, <span style="color: #A90D91">char</span> <span style="color: #000000">**argv</span>)
{
<span style="color: #000000">os_init</span>();
<span style="color: #000000">init_tasks</span>();
<span style="color: #000000">os_start</span>();
<span style="color: #000000">assert</span>(<span style="color: #1C01CE">0</span>);
<span style="color: #A90D91">return</span> <span style="color: #1C01CE">0</span>;
}
</code></pre></div>
<div class="row">
<ul class="nav nav-pills" style="margin-bottom: 10px">
<li>
</li>
<li class="pull-right">
</li>
</ul>
</div>
<footer class="row">
<div class="col-xs-12">
<p class="copyright">Apache Mynewt (incubating) is available under Apache License, version 2.0.</p>
</div>
<div class="col-xs-12">
<div class="logos">
<a href="https://www.apache.org/">
<img src="/img/asf_logo_wide_small.png" alt="Apache" title="Apache">
</a>
<p>
Copyright © 2015-2021 The Apache Software Foundation.<br>
<small class="footnote">
Apache Mynewt, Mynewt, Apache, the Apache feather logo, and the Apache Mynewt
project logo are either registered trademarks or trademarks of the Apache
Software Foundation in the United States and other countries.
</small>
</p>
<a href="">
<img src="https://www.countit.com/images/add_to_slack.png" alt="Slack Icon" title="Join our Slack Community" />
</a>
</div>
</div>
<a href="https://www.apache.org/licenses/">
<button class="button-footer-asf">
License
</button>
</a>
<a href="https://www.apache.org/foundation/sponsorship.html">
<button class="button-footer-asf">
Sponsorship
</button>
</a>
<a href="https://www.apache.org/foundation/thanks.html">
<button class="button-footer-asf">
Thanks
</button>
</a>
<a href="https://www.apache.org/security/">
<button class="button-footer-asf">
Security
</button>
</a>
<a href="https://apache.org/events/current-event">
<button class="button-footer-asf">
ASF Events
</button>
</a>
</footer>
</div>
</div>
</div>
<script src="../../../js/jquery-1.10.2.min.js"></script>
<script src="../../../js/bootstrap-3.0.3.min.js"></script>
<script src="../../../js/highlight.pack.js"></script>
<script src="../../../js/base.js"></script>
<script src="../../../js/custom.js"></script>
<script src="search/main.js"></script>
</body>
</html>