blob: a26330500287f7efe0101672a08b661d66bebbd1 [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>toc - 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="toc">
<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" >
Version: 1.3.0
</option>
<option value="/v1_2_0/os/introduction" selected="selected" >
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/">Tutorials</a>
</li>
<li ><a href="../../../os_user_guide/">OS User Guide</a>
<ul>
<li ><a href="../../mynewt_os/">OS Core</a>
<ul>
<li><a href="
../../os_started/
">Functions</a>
</li>
<li ><a href="../../context_switch/context_switch/">Scheduler</a>
</li>
<li ><a href="../../cputime/os_cputime/">CPU Time</a>
</li>
<li ><a href="../../time/os_time/">OS Time</a>
</li>
<li ><a href="../../task/task/">Tasks</a>
</li>
<li class="active"><a href="./">Event Queues</a>
<ul>
<li><a href="
../os_eventq_init/
">Functions</a>
</li>
</ul>
</li>
<li ><a href="../../semaphore/semaphore/">Semaphores</a>
</li>
<li ><a href="../../mutex/mutex/">Mutexes</a>
</li>
<li ><a href="../../memory_pool/memory_pool/">Memory Pools</a>
</li>
<li ><a href="../../heap/heap/">Heap</a>
</li>
<li><a href="
../../mbuf/mbuf/
">Memory Buffers</a>
</li>
<li ><a href="../../sanity/sanity/">Sanity</a>
</li>
<li ><a href="../../callout/callout/">Callouts</a>
</li>
</ul>
</li>
<li ><a href="../../porting/port_os/">Porting to your Platform</a>
</li>
<li ><a href="../../../modules/console/console/">Console</a>
</li>
<li ><a href="../../../modules/shell/shell/">Shell</a>
</li>
<li ><a href="../../../modules/split/split/">Split Images</a>
</li>
<li ><a href="../../../modules/bootloader/bootloader/">Bootloader</a>
</li>
<li><a href="
../../../modules/fs/fs/fs/
">File System</a>
</li>
<li ><a href="../../../modules/hal/hal/">Hardware Abstraction Layer</a>
</li>
<li ><a href="../../../modules/sensor_framework/sensor_framework_overview/">Sensor Framework</a>
</li>
<li ><a href="../../../modules/drivers/driver/">Drivers</a>
</li>
<li ><a href="../../../modules/testutil/testutil/">Test Utilities</a>
</li>
<li ><a href="../../../modules/devmgmt/newtmgr/">Device Management with Newt Manager</a>
</li>
<li ><a href="../../../modules/imgmgr/imgmgr/">Image Manager</a>
</li>
<li >
<a href="../../../modules/baselibc/">Baselibc library</a>
</li>
<li ><a href="../../../modules/json/json/">JSON</a>
</li>
<li ><a href="../../../modules/fcb/fcb/">Flash Circular Buffer</a>
</li>
<li ><a href="../../../modules/stats/stats/">Stats</a>
</li>
<li ><a href="../../../modules/logs/logs/">Logs</a>
</li>
<li ><a href="../../../modules/sysinitconfig/sysinitconfig/">System Configuration And Initialization</a>
</li>
</ul>
</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; Event Queues</li>
<li>&raquo; <a href="os/core_os/mynewt_os/">OS Core</a></li>
<li>&raquo; <a href="os/os_user_guide/">OS User Guide</a></li>
<li>&raquo; <a href="os/introduction/">Mynewt Documentation</a></li>
<li class="wy-breadcrumbs-aside">
<a href="https://github.com/apache/mynewt-site/blob/master/docs/os/core_os/event_queue/event_queue.md"
class="icon icon-github"> Edit on GitHub</a>
</li>
</ul>
</div>
</div>
<div class="alert alert-warning">
<p>
Version 1.2.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>
<h1 id="event-queues">Event Queues</h1>
<p>An event queue allows a task to serialize incoming events and simplify event processing. Events are stored in a queue and a task removes and processes an event from the queue. An event is processed in the context of this task. Events may be generated by <a href="../../callout/callout/">OS callouts</a>, interrupt handlers, and other tasks. </p>
<h3 id="description">Description</h3>
<p>Mynewt's event queue model uses callback functions to process events. Each event is associated with a callback function that is called to process the event. This model enables a library package, that uses events in its implementation but does not have real-time timing requirements, to use an application event queue instead of creating a dedicated event queue and task to process its events. The callback function executes in the context of the task that the application creates to manage the event queue. This model reduces an application's memory requirement because memory must be allocated for the task's stack when a task is created. A package that has real-time timing requirements and must run at a specific task priority should create a dedicated event queue and task to process its events.</p>
<p>In the Mynewt model, a package defines its events and implements the callback functions for the events. A package that does not have real-time timing requirements should use Mynewt's default event queue for its events. The callback function for an event from the Mynewt default event queue is executed in the context of the application main task. A package can, optionally, export a function that allows an application to specify the event queue for the package to use. (See the example in the <code>os_eventq_designate()</code> function description on how to write such a function.) The application task handler that manages the event queue simply pulls events from the event queue and executes the event's callback function in its context. </p>
<p>A common way that Mynewt applications or packages process events from an event queue is to have a task that executes in an infinite loop and calls the <code>os_eventq_get()</code> function to dequeue and return the event from the head of the event queue. The task then calls the event callback function to process the event. The <code>os_eventq_get()</code> function puts the task in to the <code>sleeping</code> state when there are no events on the queue. (See <a href="../../context_switch/context_switch/">Scheduler</a> for more information on task execution states.) Other tasks (or interrupts) call the <code>os_eventq_put()</code> function to add an event to the queue. The <code>os_eventq_put()</code> function determines whether a task is blocked waiting for an event on the queue and puts the task into the <code>ready-to-run</code> state. </p>
<p>A task can use the <code>os_eventq_run()</code> wrapper function that calls the <code>os_eventq_get()</code> function to dequeue an event from the queue and then calls the event callback function to process the event.</p>
<p>Note:</p>
<ul>
<li>Only one task should consume or block waiting for events from an event queue.</li>
<li>The <a href="../../callout/callout/">os_callout</a> subsystem uses events for timer expiration notification.</li>
</ul>
<h3 id="data-structures">Data structures</h3>
<p>The <code>os_event</code> structure defines an event and has the following fields:</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_event</span> {
<span style="color: #A90D91">uint8_t</span> <span style="color: #000000">ev_queued</span>;
<span style="color: #000000">os_event_fn</span> <span style="color: #000000">*ev_cb</span>;
<span style="color: #A90D91">void</span> <span style="color: #000000">*ev_arg</span>;
<span style="color: #000000">STAILQ_ENTRY</span>(<span style="color: #000000">os_event</span>) <span style="color: #000000">ev_next</span>;
};
</code></pre></div>
<table>
<thead>
<tr>
<th>Element</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>ev_queued</code></td>
<td>Internal field that indicates whether this event is currently linked to an event queue</td>
</tr>
<tr>
<td><code>ev_cb</code></td>
<td>Pointer to the callback function to call to process this event</td>
</tr>
<tr>
<td><code>ev_arg</code></td>
<td>Pointer to an optional opaque data that the callback function uses to process this event</td>
</tr>
<tr>
<td><code>ev_next</code></td>
<td>Linkage attaching this event to an event queue</td>
</tr>
</tbody>
</table>
<p>An event callback function has the following function prototype:</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #A90D91">typedef</span> <span style="color: #A90D91">void</span> <span style="color: #000000">os_event_fn</span>(<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_event</span> <span style="color: #000000">*ev</span>);
</code></pre></div>
<p>A pointer to the <code>os_event</code> structure for the event is passed as an argument to the callback function. </p>
<p>Notes: If the memory for the <code>os_event</code> structure is dynamically allocated: </p>
<ul>
<li>You must not free the memory for an event that is currently on an event queue.</li>
<li>You must free the memory in the callback function after it completes processing the event.</li>
</ul>
<p>You must set the callback function for an event when you initialize the event. For example, here is an example of a statically-initialized event in the NimBLE host:</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">ble_hs_event_tx_notify</span>(<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_event</span> <span style="color: #000000">*ev</span>);
<span style="color: #177500">/** OS event - triggers tx of pending notifications and indications. */</span>
<span style="color: #A90D91">static</span> <span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_event</span> <span style="color: #000000">ble_hs_ev_tx_notifications</span> <span style="color: #000000">=</span> {
.<span style="color: #000000">ev_cb</span> <span style="color: #000000">=</span> <span style="color: #000000">ble_hs_event_tx_notify</span>,
};
</code></pre></div>
<p><br> <br />
The <code>os_eventq</code> structure defines an event queue and has the following fields: </p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_eventq</span> {
<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_task</span> <span style="color: #000000">*evq_task</span>;
<span style="color: #000000">STAILQ_HEAD</span>(, <span style="color: #000000">os_event</span>) <span style="color: #000000">evq_list</span>;
};
</code></pre></div>
<table>
<thead>
<tr>
<th>Element</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>evq_task</code></td>
<td>Pointer to the task, if any, that is waiting (in the <code>sleeping</code> state) for the <code>os_eventq_get()</code> function to return an event</td>
</tr>
<tr>
<td><code>evq_list</code></td>
<td>Head of the list of events in this queue</td>
</tr>
</tbody>
</table>
<p>You must call the <code>os_eventq_init()</code> function to initialize an event queue before you can add events to the queue.</p>
<h3 id="list-of-functions">List of Functions</h3>
<p>The functions available in the Event Queue feature are:</p>
<table>
<thead>
<tr>
<th><strong>Function</strong></th>
<th><strong>Description</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="../os_eventq_init/"><code>os_eventq_init</code></a></td>
<td>Initializes an event queue.</td>
</tr>
<tr>
<td><a href="../os_eventq_inited/"><code>os_eventq_inited</code></a></td>
<td>Indicates whether an event queue has been initialized.</td>
</tr>
<tr>
<td><a href="../os_eventq_get/"><code>os_eventq_get</code></a></td>
<td>Dequeues an event from the head of an event queue. The calling task blocks (in the <code>sleeping</code> state) when the event queue is empty.</td>
</tr>
<tr>
<td><a href="../os_eventq_put/"><code>os_eventq_put</code></a></td>
<td>Enqueues an event at the tail of an event queue and puts a task waiting for an event on the queue into the <code>ready-to-run</code> state.</td>
</tr>
<tr>
<td><a href="../os_eventq_remove/"><code>os_eventq_remove</code></a></td>
<td>Removes an event from an event queue.</td>
</tr>
<tr>
<td><a href="../os_eventq_dflt_get/"><code>os_eventq_dflt_get</code></a></td>
<td>Gets the default event queue.</td>
</tr>
<tr>
<td><a href="../os_eventq_designate/"><code>os_eventq_designate</code></a></td>
<td>Reassigns a package's current event queue to a new event queue.</td>
</tr>
<tr>
<td><a href="../os_eventq_run/"><code>os_eventq_run</code></a></td>
<td>Wrapper function that dequeues an event from an event queue and calls the callbck function for the event.</td>
</tr>
</tbody>
</table>
<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>