blob: 7f612d3a198541e11e6fa0fc5d983b7a3b3d3ede [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>Events and Event Queues - 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="Events and Event Queues">
<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.12.0, Apache NimBLE 1.7.0 </a> released (April 4, 2024)
</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_12_0/" >
Version: 1.12.0
</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" selected="selected" >
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" >
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="../blinky/">Project Blinky</a>
</li>
<li ><a href="../repo/add_repos/">Work with repositories</a>
</li>
<li ><a href="../project-slinky/">Project Slinky for Remote Comms</a>
</li>
<li><a href="
../ble_bare_bones/
">Bluetooth Low Energy</a>
</li>
<li><a href="
../lora/lorawanapp/
">LoRa</a>
</li>
<li><a href="
./
">OS Fundamentals</a>
<ul>
<li class="active">
<a href="./">Events and Event Queues</a>
</li>
<li >
<a href="../tasks_lesson/">Tasks and Priority Management</a>
</li>
</ul>
</li>
<li><a href="
../add_newtmgr/
">Remote Device Management</a>
</li>
<li><a href="
../sensors/sensors/
">Sensors</a>
</li>
<li><a href="
../segger_rtt/
">Tooling</a>
</li>
<li><a href="
../codesize/
">Other</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="
../../../newt/install/prev_releases/
">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; OS Fundamentals</li>
<li>&raquo; <a href="os/tutorials/tutorials/">Tutorials</a></li>
<li>&raquo; <a href="os/introduction/">Mynewt Documentation</a></li>
<li>&raquo; Events and Event Queues</li>
<li class="wy-breadcrumbs-aside">
<a href="https://github.com/apache/mynewt-site/blob/master/docs/os/tutorials/event_queue.md"
class="icon icon-github"> Edit on GitHub</a>
</li>
</ul>
</div>
</div>
<div class="alert alert-warning">
<p>
Version 1.3.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-use-event-queues-to-manage-multiple-events">How to Use Event Queues to Manage Multiple Events</h2>
<h3 id="introduction">Introduction</h3>
<p>The event queue mechanism allows you to serialize incoming events for your task. You can use it to get information about hardware interrupts, callout expirations, and messages from other tasks.</p>
<p>The benefit of using events for inter-task communication is that it can reduce the number of resources that need to be shared and locked. </p>
<p>The benefit of processing interrupts in a task context instead of the interrupt context is that other interrupts and high priority tasks are not blocked waiting for the interrupt handler to complete processing. A task can also access other OS facilities and sleep.</p>
<p>This tutorial assumes that you have read about <a href="../../core_os/event_queue/event_queue/">Event Queues</a>, the <a href="../../modules/hal/hal/">Hardware Abstraction Layer</a>, and <a href="../../core_os/callout/callout/">OS Callouts</a> in the OS User's Guide. </p>
<p>This tutorial shows you how to create an application that uses events for: </p>
<ul>
<li>Inter-task communication </li>
<li>OS callouts for timer expiration </li>
<li>GPIO interrupts </li>
</ul>
<p>It also shows you how to:</p>
<ul>
<li>Use the Mynewt default event queue and application main task to process your events. </li>
<li>Create a dedicated event queue and task for your events. </li>
</ul>
<p>To reduce an application's memory requirement, we recommend that you use the Mynewt default event queue if your application or package does not have real-time timing requirements. </p>
<h3 id="prerequisites">Prerequisites</h3>
<p>Ensure that you have met the following prerequisites before continuing with this tutorial:</p>
<ul>
<li>Install the newt tool.</li>
<li>Install the newtmgr tool.</li>
<li>Have Internet connectivity to fetch remote Mynewt components.</li>
<li>Install the compiler tools to support native compiling to build the project this tutorial creates.</li>
<li>Have a cable to establish a serial USB connection between the board and the laptop.</li>
</ul>
<h3 id="example-application">Example Application</h3>
<p>In this example, you will write an application, for the Nordic nRF52 board, that uses events from three input sources to toggle three GPIO outputs and light up the LEDs. If you are using a different board, you will need to adjust the GPIO pin numbers in the code example.</p>
<p>The application handles events from three sources on two event queues:</p>
<ul>
<li>Events generated by an application task at periodic intervals are added to the Mynewt default event queue. </li>
<li>OS callouts for timer events are added to the <code>my_timer_interrupt_eventq</code> event queue. </li>
<li>GPIO interrupt events are added to the <code>my_timer_interrupt_eventq</code> event queue.
<br></li>
</ul>
<h4 id="create-the-project">Create the Project</h4>
<p>Follow the instructions in the <a href="../nRF52/">nRF52 tutorial</a> to create a project.
<br></p>
<h4 id="create-the-application">Create the Application</h4>
<p>Create the <code>pkg.yml</code> file for the application:</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>pkg.name: apps/eventq_example
pkg.type: app
pkg.deps:
- kernel/os
- hw/hal
- sys/console/stub
</code></pre></div>
<p><br></p>
<h4 id="application-task-generated-events">Application Task Generated Events</h4>
<p>The application creates a task that generates events, at periodic intervals, to toggle the LED at pin <code>TASK_LED</code>. The event is queued on the Mynewt default event queue and is processed in the context of the application main task. </p>
<p>Declare and initialize the <code>gen_task_ev</code> event with the <code>my_ev_cb()</code> callback function to process the event:</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #177500">/* Callback function for application task event */</span>
<span style="color: #A90D91">static</span> <span style="color: #A90D91">void</span> <span style="color: #000000">my_ev_cb</span>(<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_event</span> <span style="color: #000000">*</span>);
<span style="color: #177500">/* Initialize the event with the callback function */</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: #000000">=</span> {
.<span style="color: #000000">ev_cb</span> <span style="color: #000000">=</span> <span style="color: #000000">my_ev_cb</span>,
};
</code></pre></div>
<p><br>
Implement the <code>my_ev_cb()</code> callback function to process a task generated event and toggle the LED at pin <code>TASK_LED</code>:</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #177500">/* LED 1 (P0.17 on the board) */</span>
<span style="color: #633820">#define TASK_LED 17</span>
<span style="color: #177500">/*</span>
<span style="color: #177500"> * Event callback function for events generated by gen_task. It toggles </span>
<span style="color: #177500"> * the LED at pin TASK_LED.</span>
<span style="color: #177500"> */</span>
<span style="color: #A90D91">static</span> <span style="color: #A90D91">void</span> <span style="color: #000000">my_ev_cb</span>(<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_event</span> <span style="color: #000000">*ev</span>)
{
<span style="color: #000000">assert</span>(<span style="color: #000000">ev</span>);
<span style="color: #000000">hal_gpio_toggle</span>(<span style="color: #000000">TASK_LED</span>);
<span style="color: #A90D91">return</span>;
}
</code></pre></div>
<p><br>
Create a task that generates an event at periodic intervals and adds, using the <code>os_eventq_put()</code> function, the event to the Mynewt default 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: #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: #177500">/* </span>
<span style="color: #177500"> * Task handler to generate an event to toggle the LED at pin TASK_LED. </span>
<span style="color: #177500"> * The event is added to the Mynewt default event queue. </span>
<span style="color: #177500"> */</span>
<span style="color: #A90D91">static</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">os_eventq_dflt_get</span>(), <span style="color: #000000">&amp;gen_task_ev</span>);
}
}
<span style="color: #A90D91">static</span> <span style="color: #A90D91">void</span>
<span style="color: #000000">init_tasks</span>(<span style="color: #A90D91">void</span>)
{
<span style="color: #177500">/* Create a task to generate events to toggle the LED at pin TASK_LED */</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>
Implement the application <code>main()</code> function to call the <code>os_eventq_run()</code> function to dequeue an event from the Mynewt default event queue and call the callback function to process the event. </p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><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">sysinit</span>();
<span style="color: #000000">init_tasks</span>();
<span style="color: #A90D91">while</span> (<span style="color: #1C01CE">1</span>) {
<span style="color: #000000">os_eventq_run</span>(<span style="color: #000000">os_eventq_dflt_get</span>());
}
<span style="color: #000000">assert</span>(<span style="color: #1C01CE">0</span>);
}
</code></pre></div>
<p><br></p>
<h4 id="os-callout-timer-events">OS Callout Timer Events</h4>
<p>Set up OS callout timer events. For this example, we use a dedicated event queue for timer events to show you how to create a dedicated event queue and a task to process the events.</p>
<p>Implement the <code>my_timer_ev_cb()</code> callback function to process a timer event and toggle the LED at pin <code>CALLOUT_LED</code>:</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #177500">/* LED 2 (P0.18 on the board) */</span>
<span style="color: #633820">#define CALLOUT_LED 18</span>
<span style="color: #177500">/* The timer callout */</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: #177500">/*</span>
<span style="color: #177500"> * Event callback function for timer events. It toggles the LED at pin CALLOUT_LED.</span>
<span style="color: #177500"> */</span>
<span style="color: #A90D91">static</span> <span style="color: #A90D91">void</span> <span style="color: #000000">my_timer_ev_cb</span>(<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_event</span> <span style="color: #000000">*ev</span>)
{
<span style="color: #000000">assert</span>(<span style="color: #000000">ev</span> <span style="color: #000000">!=</span> <span style="color: #A90D91">NULL</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>);
}
</code></pre></div>
<p><br>
In the <code>init_tasks()</code> function, initialize the <code>my_timer_interrupt_eventq</code> event queue, create a task to process events from the queue, and initialize the OS callout for the timer: </p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #633820">#define MY_TIMER_INTERRUPT_TASK_PRIO 4</span>
<span style="color: #633820">#define MY_TIMER_INTERRUPT_TASK_STACK_SZ 512</span>
<span style="color: #A90D91">static</span> <span style="color: #000000">os_stack_t</span> <span style="color: #000000">my_timer_interrupt_task_stack</span>[<span style="color: #000000">MY_TIMER_INTERRUPT_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_timer_interrupt_task_str</span>;
<span style="color: #A90D91">static</span> <span style="color: #A90D91">void</span>
<span style="color: #000000">init_tasks</span>(<span style="color: #A90D91">void</span>)
{
<span style="color: #177500">/* Use a dedicate event queue for timer and interrupt events */</span>
<span style="color: #000000">os_eventq_init</span>(<span style="color: #000000">&amp;my_timer_interrupt_eventq</span>);
<span style="color: #177500">/* </span>
<span style="color: #177500"> * Create the task to process timer and interrupt events from the</span>
<span style="color: #177500"> * my_timer_interrupt_eventq event queue.</span>
<span style="color: #177500"> */</span>
<span style="color: #000000">os_task_init</span>(<span style="color: #000000">&amp;my_timer_interrupt_task_str</span>, <span style="color: #C41A16">&quot;timer_interrupt_task&quot;</span>,
<span style="color: #000000">my_timer_interrupt_task</span>, <span style="color: #A90D91">NULL</span>,
<span style="color: #000000">MY_TIMER_INTERRUPT_TASK_PRIO</span>, <span style="color: #000000">OS_WAIT_FOREVER</span>,
<span style="color: #000000">my_timer_interrupt_task_stack</span>,
<span style="color: #000000">MY_TIMER_INTERRUPT_TASK_STACK_SZ</span>);
<span style="color: #177500">/* </span>
<span style="color: #177500"> * Initialize the callout for a timer event. </span>
<span style="color: #177500"> * The my_timer_ev_cb callback function processes the timer events.</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_timer_interrupt_eventq</span>,
<span style="color: #000000">my_timer_ev_cb</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>
Implement the <code>my_timer_interrupt_task()</code> task handler to dispatch events from the <code>my_timer_interrupt_eventq</code> event queue:</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">void</span>
<span style="color: #000000">my_timer_interrupt_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_eventq_run</span>(<span style="color: #000000">&amp;my_timer_interrupt_eventq</span>);
}
}
</code></pre></div>
<p><br></p>
<h4 id="interrupt-events">Interrupt Events</h4>
<p>The application toggles the LED each time button 1 on the board is pressed. The interrupt handler generates an event when the GPIO for button 1 (P0.13) changes state. The events are added to the <code>my_timer_interrupt_eventq</code> event queue, the same queue as the timer events.</p>
<p>Declare and initialize the <code>gpio_ev</code> event with the <code>my_interrupt_ev_cb()</code> callback function to process the event:</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: #000000">ev_cb</span> <span style="color: #000000">=</span> <span style="color: #000000">my_interrupt_ev_cb</span>,
};
</code></pre></div>
<p><br>
Implement the <code>my_interrupt_ev_cb()</code> callback function to process an interrupt event and toggle the LED at pin <code>GPIO_LED</code>:</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #177500">/* LED 3 (P0.19 on the board) */</span>
<span style="color: #633820">#define GPIO_LED 19</span>
<span style="color: #177500">/*</span>
<span style="color: #177500"> * Event callback function for interrupt events. It toggles the LED at pin GPIO_LED.</span>
<span style="color: #177500"> */</span>
<span style="color: #A90D91">static</span> <span style="color: #A90D91">void</span> <span style="color: #000000">my_interrupt_ev_cb</span>(<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_event</span> <span style="color: #000000">*ev</span>)
{
<span style="color: #000000">assert</span>(<span style="color: #000000">ev</span> <span style="color: #000000">!=</span> <span style="color: #A90D91">NULL</span>);
<span style="color: #000000">hal_gpio_toggle</span>(<span style="color: #000000">GPIO_LED</span>);
}
</code></pre></div>
<p><br></p>
<p>Implement the <code>my_gpio_irq()</code> handler to post an interrupt event to the <code>my_timer_interrupt_eventq</code> event queue:</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">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_timer_interrupt_eventq</span>, <span style="color: #000000">&amp;gpio_ev</span>);
}
</code></pre></div>
<p><br></p>
<p>In the <code>init_tasks()</code> function, add the code to set up and enable the GPIO input pin for the button and initialize the GPIO output pins for the LEDs:</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #177500">/* LED 1 (P0.17 on the board) */</span>
<span style="color: #633820">#define TASK_LED 17 </span>
<span style="color: #177500">/* 2 (P0.18 on the board) */</span>
<span style="color: #633820">#define CALLOUT_LED 18 </span>
<span style="color: #177500">/* LED 3 (P0.19 on the board) */</span>
<span style="color: #633820">#define GPIO_LED 19</span>
<span style="color: #177500">/* Button 1 (P0.13 on the board) */</span>
<span style="color: #633820">#define BUTTON1_PIN 13</span>
<span style="color: #A90D91">void</span>
<span style="color: #000000">init_tasks</span>()
<span style="color: #177500">/* Initialize OS callout for timer events. */</span>
....
<span style="color: #177500">/* </span>
<span style="color: #177500"> * Initialize and enable interrupts for the pin for button 1 and </span>
<span style="color: #177500"> * configure the button with pull up resistor on the nrf52dk.</span>
<span style="color: #177500"> */</span>
<span style="color: #000000">hal_gpio_irq_init</span>(<span style="color: #000000">BUTTON1_PIN</span>, <span style="color: #000000">my_gpio_irq</span>, <span style="color: #A90D91">NULL</span>, <span style="color: #000000">HAL_GPIO_TRIG_RISING</span>, <span style="color: #000000">HAL_GPIO_PULL_UP</span>);
<span style="color: #000000">hal_gpio_irq_enable</span>(<span style="color: #000000">BUTTON1_PIN</span>);
<span style="color: #177500">/* Initialize the GPIO output pins. Value 1 is off for these LEDs. */</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><br></p>
<h3 id="putting-it-all-together">Putting It All Together</h3>
<p>Here is the complete <code>main.c</code> source for your application. Build the application and load it on your board. The task LED (LED1) blinks at an interval of 250ms, the callout LED (LED2) blinks at an interval of 500ms, and the GPIO LED (LED3) toggles on or off each time you press Button 1.</p>
<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">#include</span> <span style="color: #177500">&lt;sysinit/sysinit.h&gt;</span>
<span style="color: #633820">#define MY_TIMER_INTERRUPT_TASK_PRIO 4</span>
<span style="color: #633820">#define MY_TIMER_INTERRUPT_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: #177500">/* LED 1 (P0.17 on the board) */</span>
<span style="color: #633820">#define TASK_LED 17</span>
<span style="color: #177500">/* LED 2 (P0.18 on the board) */</span>
<span style="color: #633820">#define CALLOUT_LED 18</span>
<span style="color: #177500">/* LED 3 (P0.19 on the board) */</span>
<span style="color: #633820">#define GPIO_LED 19</span>
<span style="color: #177500">/* Button 1 (P0.13 on the board) */</span>
<span style="color: #633820">#define BUTTON1_PIN 13</span>
<span style="color: #A90D91">static</span> <span style="color: #A90D91">void</span> <span style="color: #000000">my_ev_cb</span>(<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_event</span> <span style="color: #000000">*</span>);
<span style="color: #A90D91">static</span> <span style="color: #A90D91">void</span> <span style="color: #000000">my_timer_ev_cb</span>(<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_event</span> <span style="color: #000000">*</span>);
<span style="color: #A90D91">static</span> <span style="color: #A90D91">void</span> <span style="color: #000000">my_interrupt_ev_cb</span>(<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_event</span> <span style="color: #000000">*</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_timer_interrupt_eventq</span>;
<span style="color: #A90D91">static</span> <span style="color: #000000">os_stack_t</span> <span style="color: #000000">my_timer_interrupt_task_stack</span>[<span style="color: #000000">MY_TIMER_INTERRUPT_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_timer_interrupt_task_str</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_event</span> <span style="color: #000000">gen_task_ev</span> <span style="color: #000000">=</span> {
.<span style="color: #000000">ev_cb</span> <span style="color: #000000">=</span> <span style="color: #000000">my_ev_cb</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: #000000">=</span> {
.<span style="color: #000000">ev_cb</span> <span style="color: #000000">=</span> <span style="color: #000000">my_interrupt_ev_cb</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: #177500">/*</span>
<span style="color: #177500"> * Task handler to generate an event to toggle the LED at pin TASK_LED.</span>
<span style="color: #177500"> * The event is added to the Mynewt default event queue.</span>
<span style="color: #177500"> */</span>
<span style="color: #A90D91">static</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">os_eventq_dflt_get</span>(), <span style="color: #000000">&amp;gen_task_ev</span>);
}
}
<span style="color: #177500">/*</span>
<span style="color: #177500"> * Event callback function for events generated by gen_task. It toggles the LED at pin TASK_LED. </span>
<span style="color: #177500"> */</span>
<span style="color: #A90D91">static</span> <span style="color: #A90D91">void</span> <span style="color: #000000">my_ev_cb</span>(<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_event</span> <span style="color: #000000">*ev</span>)
{
<span style="color: #000000">assert</span>(<span style="color: #000000">ev</span>);
<span style="color: #000000">hal_gpio_toggle</span>(<span style="color: #000000">TASK_LED</span>);
<span style="color: #A90D91">return</span>;
}
<span style="color: #177500">/*</span>
<span style="color: #177500"> * Event callback function for timer events. It toggles the LED at pin CALLOUT_LED.</span>
<span style="color: #177500"> */</span>
<span style="color: #A90D91">static</span> <span style="color: #A90D91">void</span> <span style="color: #000000">my_timer_ev_cb</span>(<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_event</span> <span style="color: #000000">*ev</span>)
{
<span style="color: #000000">assert</span>(<span style="color: #000000">ev</span> <span style="color: #000000">!=</span> <span style="color: #A90D91">NULL</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: #177500">/*</span>
<span style="color: #177500"> * Event callback function for interrupt events. It toggles the LED at pin GPIO_LED.</span>
<span style="color: #177500"> */</span>
<span style="color: #A90D91">static</span> <span style="color: #A90D91">void</span> <span style="color: #000000">my_interrupt_ev_cb</span>(<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_event</span> <span style="color: #000000">*ev</span>)
{
<span style="color: #000000">assert</span>(<span style="color: #000000">ev</span> <span style="color: #000000">!=</span> <span style="color: #A90D91">NULL</span>);
<span style="color: #000000">hal_gpio_toggle</span>(<span style="color: #000000">GPIO_LED</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_timer_interrupt_eventq</span>, <span style="color: #000000">&amp;gpio_ev</span>);
}
<span style="color: #A90D91">static</span> <span style="color: #A90D91">void</span>
<span style="color: #000000">my_timer_interrupt_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_eventq_run</span>(<span style="color: #000000">&amp;my_timer_interrupt_eventq</span>);
}
}
<span style="color: #A90D91">void</span>
<span style="color: #000000">init_tasks</span>(<span style="color: #A90D91">void</span>)
{
<span style="color: #177500">/* Create a task to generate events to toggle the LED at pin TASK_LED */</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: #177500">/* Use a dedicate event queue for timer and interrupt events */</span>
<span style="color: #000000">os_eventq_init</span>(<span style="color: #000000">&amp;my_timer_interrupt_eventq</span>);
<span style="color: #177500">/* </span>
<span style="color: #177500"> * Create the task to process timer and interrupt events from the</span>
<span style="color: #177500"> * my_timer_interrupt_eventq event queue.</span>
<span style="color: #177500"> */</span>
<span style="color: #000000">os_task_init</span>(<span style="color: #000000">&amp;my_timer_interrupt_task_str</span>, <span style="color: #C41A16">&quot;timer_interrupt_task&quot;</span>,
<span style="color: #000000">my_timer_interrupt_task</span>, <span style="color: #A90D91">NULL</span>,
<span style="color: #000000">MY_TIMER_INTERRUPT_TASK_PRIO</span>, <span style="color: #000000">OS_WAIT_FOREVER</span>,
<span style="color: #000000">my_timer_interrupt_task_stack</span>,
<span style="color: #000000">MY_TIMER_INTERRUPT_TASK_STACK_SZ</span>);
<span style="color: #177500">/* </span>
<span style="color: #177500"> * Initialize the callout for a timer event. </span>
<span style="color: #177500"> * The my_timer_ev_cb callback function processes the timer event.</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_timer_interrupt_eventq</span>,
<span style="color: #000000">my_timer_ev_cb</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: #177500">/* </span>
<span style="color: #177500"> * Initialize and enable interrupt for the pin for button 1 and </span>
<span style="color: #177500"> * configure the button with pull up resistor on the nrf52dk.</span>
<span style="color: #177500"> */</span>
<span style="color: #000000">hal_gpio_irq_init</span>(<span style="color: #000000">BUTTON1_PIN</span>, <span style="color: #000000">my_gpio_irq</span>, <span style="color: #A90D91">NULL</span>, <span style="color: #000000">HAL_GPIO_TRIG_RISING</span>, <span style="color: #000000">HAL_GPIO_PULL_UP</span>);
<span style="color: #000000">hal_gpio_irq_enable</span>(<span style="color: #000000">BUTTON1_PIN</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">sysinit</span>();
<span style="color: #000000">init_tasks</span>();
<span style="color: #A90D91">while</span> (<span style="color: #1C01CE">1</span>) {
<span style="color: #000000">os_eventq_run</span>(<span style="color: #000000">os_eventq_dflt_get</span>());
}
<span style="color: #000000">assert</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 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>