blob: 0df872d15aab4e2528b7a83cd1e11f443c21538f [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>Sensor Device Driver - 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="Sensor Device Driver">
<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" >
Version: 1.2.0
</option>
<option value="/v1_1_0/os/introduction" selected="selected" >
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="../../../core_os/mynewt_os/">OS Core</a>
</li>
<li ><a href="../../../core_os/porting/port_os/">Porting to your Platform</a>
</li>
<li ><a href="../../console/console/">Console</a>
</li>
<li ><a href="../../shell/shell/">Shell</a>
</li>
<li ><a href="../../split/split/">Split Images</a>
</li>
<li ><a href="../../bootloader/bootloader/">Bootloader</a>
</li>
<li><a href="
../../fs/fs/fs/
">File System</a>
</li>
<li ><a href="../../hal/hal/">Hardware Abstraction Layer</a>
</li>
<li ><a href="../sensor_framework_overview/">Sensor Framework</a>
<ul>
<li><a href="
../sensor_api/
">API</a>
</li>
<li >
<a href="../sensor_shell/">Sensor Shell</a>
</li>
<li class="active">
<a href="./">Sensor Device Driver</a>
</li>
<li >
<a href="../sensor_create/">Creating and Configuring Sensor Devices</a>
</li>
</ul>
</li>
<li ><a href="../../drivers/driver/">Drivers</a>
</li>
<li ><a href="../../testutil/testutil/">Test Utilities</a>
</li>
<li ><a href="../../devmgmt/newtmgr/">Device Management with Newt Manager</a>
</li>
<li ><a href="../../imgmgr/imgmgr/">Image Manager</a>
</li>
<li >
<a href="../../baselibc/">Baselibc library</a>
</li>
<li ><a href="../../json/json/">JSON</a>
</li>
<li ><a href="../../fcb/fcb/">Flash Circular Buffer</a>
</li>
<li ><a href="../../stats/stats/">Stats</a>
</li>
<li ><a href="../../logs/logs/">Logs</a>
</li>
<li ><a href="../../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="
../../../../faq/go_env/
">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/modules/sensor_framework/sensor_framework_overview/">Sensor Framework</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>&raquo; Sensor Device Driver</li>
<li class="wy-breadcrumbs-aside">
<a href="https://github.com/apache/mynewt-site/blob/master/docs/os/modules/sensor_framework/sensor_driver.md"
class="icon icon-github"> Edit on GitHub</a>
</li>
</ul>
</div>
</div>
<div class="alert alert-warning">
<p>
Version 1.1.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="sensor-device-driver">Sensor Device Driver</h2>
<p>A Mynewt sensor device driver uses the sensor framework abstraction and API to enable applications to access sensor data from any Mynewt sensor device using a common interface. The sensor device driver must also use the Mynewt HAL interface to communicate with and control a sensor device.</p>
<p>This guide describes what a sensor device driver must implement to enable a sensor device within the sensor framework. For information on using the HAL API to communicate with a sensor device, see the <a href="/os/modules/hal/hal.md">Hardware Layer Abstraction Guide</a>.</p>
<p>The <code>hw/drivers/sensors/&lt;sensorname&gt;</code> package implements the device driver for the sensor named <code>SENSORNAME</code>.</p>
<p><strong>Note:</strong> All example excerpts are from the BNO055 sensor device driver package.</p>
<p><br></p>
<h3 id="initializing-and-configuring-a-sensor-device">Initializing and Configuring a Sensor Device</h3>
<p>A driver package for a sensor named <code>SENSORNAME</code> must define and export the following data structures and functions to initialize and configure a device: </p>
<ul>
<li>
<p><code>struct &lt;sensorname&gt;</code>: This data structure represents a sensor device. The structure must include a <code>dev</code> field of type <code>struct os_dev</code> and a <code>sensor</code> field of type <code>struct sensor</code>. For example: </p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>struct bno055 {
struct os_dev dev;
struct sensor sensor;
struct bno055_cfg cfg;
os_time_t last_read_time;
};
</code></pre></div>
</li>
<li>
<p><code>struct &lt;sensorname&gt;_cfg</code>: This data structure defines the configuration for a sensor device. The structure fields are specific to the device. This is the data structure that a BSP, the sensor creator package, or an application sets to configure a sensor device. For example: </p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>struct bno055_cfg {
uint8_t bc_opr_mode;
uint8_t bc_pwr_mode;
uint8_t bc_units;
uint8_t bc_placement;
uint8_t bc_acc_range;
uint8_t bc_acc_bw;
...
uint32_t bc_mask;
};
</code></pre></div>
</li>
<li>
<p><code>&lt;sensorname&gt;_init()</code>: This is the os device initialization callback of type <code>int (*os_dev_init_func_t)(struct os_dev *, void *)</code> that the <code>os_dev_create()</code> function calls to initialize the device. For example, the bno055 device driver package defines the following function:</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>int bno055_init(struct os_dev *dev, void *arg)
</code></pre></div>
<p>The BSP, which creates a device for an onboard sensor, and the sensor creator package, which creates a device for an off-board sensor, calls the <code>os_dev_create()</code> function and passes:</p>
<ul>
<li>A pointer to a <code>struct &lt;sensorname&gt;</code> variable. </li>
<li>The <code>&lt;sensorname&gt;_init()</code> function pointer.</li>
<li>A pointer to a <code>struct sensor_itf</code> variable that specifies the interface the driver uses to communicate with the sensor device. </li>
</ul>
<p>See the <a href="/os/modules/sensor_framework/sensor_create.md">Creating Sensor Devices</a> page for more details.</p>
<p>The <code>os_dev_create()</code> function calls the <code>&lt;sensorname&gt;_init()</code> function with a pointer to the <code>struct &lt;sensorname&gt;</code> for the <code>dev</code> parameter and a pointer to the <code>struct sensor_itf</code> for the <code>arg</code> parameter.</p>
</li>
<li>
<p><code>&lt;sensorname&gt;_config()</code>: This is the sensor configuration function that the BSP, sensor creator package, or an application calls to configure the sensor device. For example:</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>int bno055_config(struct bno055 *bno055, struct bno055_cfg *cfg)
</code></pre></div>
</li>
</ul>
<p><br></p>
<h3 id="defining-functions-to-read-sensor-data-and-get-sensor-value-type">Defining Functions to Read Sensor Data and Get Sensor Value Type</h3>
<p>A device driver must implement the following functions that the sensor API uses to read sensor data and to get the configuration value type for a sensor: </p>
<ul>
<li>
<p>A function of type <code>int (*sensor_read_func_t)(struct sensor *, sensor_type_t, sensor_data_func_t, void *, uint32_t)</code> that the sensor framework uses to read a single value from a sensor for the specified sensor types. The device driver must implement this function such that it reads, for each sensor type set in the bit mask, a single value from the sensor and calls the <code>sensor_data_funct_t</code> callback with the opaque callback argument , the sensor data, and the sensor type.</p>
</li>
<li>
<p>A function of type <code>int (*sensor_get_config_func_t)(struct sensor *, sensor_type_t, struct sensor_cfg *)</code> that returns the value type for the specified sensor type. For example, the value type for a <code>SENSOR_VALUE_TYPE_TEMPERATURE</code> sensor might be <code>SENSOR_VALUE_TYPE_FLOAT</code> and the value type for a <code>SENSOR_TYPE_ACCELEROMETER</code> sensor might be <code>SENSOR_VALUE_TYPE_FLOAT_TRIPLET</code>. </p>
</li>
</ul>
<p>The driver initializes a <code>sensor_driver</code> structure, shown below, with the pointers to these functions:</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">sensor_driver</span> {
<span style="color: #000000">sensor_read_func_t</span> <span style="color: #000000">sd_read</span>;
<span style="color: #000000">sensor_get_config_func_t</span> <span style="color: #000000">sd_get_config</span>;
};
</code></pre></div>
<p>For example:</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">int</span> <span style="color: #000000">bno055_sensor_read</span>(<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">sensor</span> <span style="color: #000000">*</span>, <span style="color: #000000">sensor_type_t</span>,
<span style="color: #000000">sensor_data_func_t</span>, <span style="color: #A90D91">void</span> <span style="color: #000000">*</span>, <span style="color: #A90D91">uint32_t</span>);
<span style="color: #A90D91">static</span> <span style="color: #A90D91">int</span> <span style="color: #000000">bno055_sensor_get_config</span>(<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">sensor</span> <span style="color: #000000">*</span>, <span style="color: #000000">sensor_type_t</span>,
<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">sensor_cfg</span> <span style="color: #000000">*</span>);
<span style="color: #A90D91">static</span> <span style="color: #A90D91">const</span> <span style="color: #A90D91">struct</span> <span style="color: #3F6E75">sensor_driver</span> <span style="color: #000000">g_bno055_sensor_driver</span> <span style="color: #000000">=</span> {
<span style="color: #000000">bno055_sensor_read</span>,
<span style="color: #000000">bno055_sensor_get_config</span>
};
</code></pre></div>
<p><br></p>
<h3 id="registering-the-sensor-in-the-sensor-framework">Registering the Sensor in the Sensor Framework</h3>
<p>The device driver must initialize and register a <code>struct sensor</code> object with the sensor manager. See the <a href="/os/modules/sensor_framework/sensor_api.md">Sensor API</a> and the <a href="/os/modules/sensor_framework/sensor_manager_api.md">Sensor Manager API</a> pages for more details.</p>
<p>The device driver <code>&lt;sensorname&gt;_init()</code> function initializes and registers a sensor object as follows:</p>
<ul>
<li>
<p>Calls the <code>sensor_init()</code> function to initialize the <code>struct sensor</code> object.</p>
</li>
<li>
<p>Calls the <code>sensor_set_driver()</code> function to specify the sensor types that the sensor device supports, and the pointer to the <code>struct sensor_driver</code> variable that specifies the driver functions to read the sensor data and to get the value type for a sensor.</p>
</li>
<li>
<p>Calls the <code>sensor_set_interface()</code> function to set the interface that the device driver uses to communicate with the sensor device. The BSP, or sensor creator package for an off-board sensors, sets up the <code>sensor_itf</code> and passes it to the <code>&lt;sensorname&gt;_init()</code> function. The <code>sensor_set_interface()</code> functions saves this information in the sensor object. The device driver uses the <code>SENSOR_GET_ITF()</code> macro to retrieve the sensor_itf when it needs to communicate with the sensor device.</p>
</li>
<li>
<p>Calls the <code>sensor_mgr_register()</code> function to register the sensor with the sensor manager.</p>
</li>
</ul>
<p>For example:</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>int
bno055_init(struct os_dev *dev, void *arg)
{
struct bno055 *bno055;
struct sensor *sensor;
int rc;
if (!arg || !dev) {
rc = SYS_ENODEV;
goto err;
}
<span style="background-color: #ffffcc"> bno055 = (struct bno055 *) dev;
</span>
rc = bno055_default_cfg(&amp;bno055-&gt;cfg);
if (rc) {
goto err;
}
<span style="background-color: #ffffcc"> sensor = &amp;bno055-&gt;sensor;
</span>
/* Code to setup logging and stats may go here */
....
<span style="background-color: #ffffcc"> rc = sensor_init(sensor, dev);
</span> if (rc != 0) {
goto err;
}
/* Add the accelerometer/magnetometer driver */
<span style="background-color: #ffffcc"> rc = sensor_set_driver(sensor, SENSOR_TYPE_ACCELEROMETER |
</span><span style="background-color: #ffffcc"> SENSOR_TYPE_MAGNETIC_FIELD | SENSOR_TYPE_GYROSCOPE |
</span><span style="background-color: #ffffcc"> SENSOR_TYPE_TEMPERATURE | SENSOR_TYPE_ROTATION_VECTOR |
</span><span style="background-color: #ffffcc"> SENSOR_TYPE_GRAVITY | SENSOR_TYPE_LINEAR_ACCEL |
</span><span style="background-color: #ffffcc"> SENSOR_TYPE_EULER, (struct sensor_driver *) &amp;g_bno055_sensor_driver);
</span> if (rc != 0) {
goto err;
}
/* Set the interface */
<span style="background-color: #ffffcc"> rc = sensor_set_interface(sensor, arg);
</span> if (rc) {
goto err;
}
<span style="background-color: #ffffcc"> rc = sensor_mgr_register(sensor);
</span> if (rc != 0) {
goto err;
}
return (0);
err:
return (rc);
}
</code></pre></div>
<p><br></p>
<h3 id="configuring-the-sensor-device-and-setting-the-configured-sensor-types">Configuring the Sensor Device and Setting the Configured Sensor Types</h3>
<p>After the BSP, or the sensor creator package for an off-board sensor, creates the OS device for a sensor, it calls the <code>&lt;sensorname&gt;_config()</code> function to configure sensor device information such as mode, power mode, and to set the configured sensor types. The <code>&lt;sensorname&gt;_config()</code> function configures the settings on the sensor device. It must also call the <code>sensor_set_type_mask()</code> function to set the configured sensor types in the sensor object. The configured sensor types are a subset of the sensor types that the sensor device supports and the sensor framework only reads sensor data for configured sensor types.</p>
<p><strong>Notes:</strong> </p>
<ul>
<li>
<p>The device driver uses the <code>SENSOR_GET_ITF()</code> macro to retrieve the sensor interface to communicate with the sensor.</p>
</li>
<li>
<p>If a sensor device has a chip ID that can be queried, we recommend that the device driver read and verify the chip ID with the data sheet.</p>
</li>
<li>
<p>An application may call the <code>&lt;sensorname&gt;_config()</code> function to configure the sensor device.</p>
</li>
</ul>
<p>For example:</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>int
bno055_config(struct bno055 *bno055, struct bno055_cfg *cfg)
{
int rc;
uint8_t id;
uint8_t mode;
<span style="background-color: #ffffcc"> struct sensor_itf *itf;
</span>
<span style="background-color: #ffffcc"> itf = SENSOR_GET_ITF(&amp;(bno055-&gt;sensor));
</span>
<span style="background-color: #ffffcc"> /* Check if we can read the chip address */
</span><span style="background-color: #ffffcc"> rc = bno055_get_chip_id(itf, &amp;id);
</span><span style="background-color: #ffffcc"> if (rc) {
</span><span style="background-color: #ffffcc"> goto err;
</span><span style="background-color: #ffffcc"> }
</span><span style="background-color: #ffffcc">
</span><span style="background-color: #ffffcc"> if (id != BNO055_ID) {
</span><span style="background-color: #ffffcc"> os_time_delay((OS_TICKS_PER_SEC * 100)/1000 + 1);
</span><span style="background-color: #ffffcc">
</span><span style="background-color: #ffffcc"> rc = bno055_get_chip_id(itf, &amp;id);
</span><span style="background-color: #ffffcc"> if (rc) {
</span><span style="background-color: #ffffcc"> goto err;
</span><span style="background-color: #ffffcc"> }
</span><span style="background-color: #ffffcc">
</span><span style="background-color: #ffffcc"> if(id != BNO055_ID) {
</span><span style="background-color: #ffffcc"> rc = SYS_EINVAL;
</span><span style="background-color: #ffffcc"> goto err;
</span><span style="background-color: #ffffcc"> }
</span><span style="background-color: #ffffcc"> }
</span>
....
/* Other code to set the configuration on the sensor device. */
....
<span style="background-color: #ffffcc"> rc = sensor_set_type_mask(&amp;(bno055-&gt;sensor), cfg-&gt;bc_mask);
</span><span style="background-color: #ffffcc"> if (rc) {
</span><span style="background-color: #ffffcc"> goto err;
</span><span style="background-color: #ffffcc"> }
</span><span style="background-color: #ffffcc">
</span><span style="background-color: #ffffcc"> bno055-&gt;cfg.bc_mask = cfg-&gt;bc_mask;
</span>
return 0;
err:
return rc;
}
</code></pre></div>
<p><br></p>
<h3 id="implementing-a-sensor-device-shell-command">Implementing a Sensor Device Shell Command</h3>
<p>A sensor device driver package may optionally implement a sensor device shell command that retrieves and sets sensor device information to aid in testing and debugging. While the sensor framework <a href="/os/modules/sensor_framework/sensor_shell.md">sensor shell command</a> reads sensor data for configured sensor types and is useful for testing an application, it does not access low level device information, such as reading register values and setting hardware configurations, that might be needed to test a sensor device or to debug the sensor device driver code. A sensor device shell command implementation is device specific but should minimally support reading sensor data for all the sensor types that the device supports because the sensor framework <code>sensor</code> shell command only reads sensor data for configured sensor types.</p>
<p>The package should: </p>
<ul>
<li>
<p>Name the sensor device shell command <code>&lt;sensorname&gt;</code>. For example, the sensor device shell command for the BNO055 sensor device is <code>bno055</code>.</p>
</li>
<li>
<p>Define a <code>&lt;SENSORNAME&gt;_CLI</code> syscfg setting to specify whether the shell command is enabled and disable the setting by default.</p>
</li>
<li>
<p>Export a <code>&lt;sensorname&gt;_shell_init()</code> function that an application calls to initialize the sensor shell command when the <code>SENSORNAME_CLI</code> setting is enabled.</p>
</li>
</ul>
<p>For an example on how to implement a sensor device shell command, see the <a href="https://github.com/apache/mynewt-core/blob/master/hw/drivers/sensors/bno055/src/bno055_shell.c">bno055 shell command</a> source code. See the <a href="/os/tutorials/sensors/sensor_nrf52_bno055.md">Enabling an Off-Board Sensor in an Existing Application Tutorial</a> for examples of the bno055 shell command.</p>
<p><br></p>
<h3 id="defining-logs">Defining Logs</h3>
<p>A sensor device driver should define logs for testing purposes. See the <a href="os/modules/logs/logs.md">Log OS Guide</a> for more details on how to add logs. The driver should define a <code>&lt;SENSORNAME&gt;_LOG</code> syscfg setting to specify whether logging is enabled and disable the setting by default.</p>
<p>Here is an example from the BNO055 sensor driver package:</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="background-color: #ffffcc">#if MYNEWT_VAL(BNO055_LOG)
</span><span style="background-color: #ffffcc">#include &quot;log/log.h&quot;
</span><span style="background-color: #ffffcc">#endif
</span>
<span style="background-color: #ffffcc">if MYNEWT_VAL(BNO055_LOG)
</span><span style="background-color: #ffffcc">#define LOG_MODULE_BNO055 (305)
</span><span style="background-color: #ffffcc">#define BNO055_INFO(...) LOG_INFO(&amp;_log, LOG_MODULE_BNO055, __VA_ARGS__)
</span><span style="background-color: #ffffcc">#define BNO055_ERR(...) LOG_ERROR(&amp;_log, LOG_MODULE_BNO055, __VA_ARGS__)
</span><span style="background-color: #ffffcc">static struct log _log;
</span><span style="background-color: #ffffcc">#else
</span><span style="background-color: #ffffcc">#define BNO055_INFO(...)
</span><span style="background-color: #ffffcc">#define BNO055_ERR(...)
</span><span style="background-color: #ffffcc">#endif
</span><span style="background-color: #ffffcc">
</span> ...
int
bno055_init(struct os_dev *dev, void *arg)
{
...
rc = bno055_default_cfg(&amp;bno055-&gt;cfg);
if (rc) {
goto err;
}
<span style="background-color: #ffffcc">#if MYNEWT_VAL(BNO055_LOG)
</span><span style="background-color: #ffffcc"> log_register(dev-&gt;od_name, &amp;_log, &amp;log_console_handler, NULL, LOG_SYSLEVEL);
</span><span style="background-color: #ffffcc">#endif
</span>
...
}
</code></pre></div>
<p><br></p>
<h3 id="defining-stats">Defining Stats</h3>
<p>A sensor device driver may also define stats for the sensor. See the <a href="os/modules/stats/stats.md">Stats OS Guide</a> for more details on how to add stats. The driver should define a <code>&lt;SENSORNAME&gt;_STATS</code> syscfg setting to specify whether stats is enabled and disable the setting by default.</p>
<p>Here is an example from the BNO055 sensor driver package:</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="background-color: #ffffcc">#if MYNEWT_VAL(BNO055_STATS)
</span><span style="background-color: #ffffcc">#include &quot;stats/stats.h&quot;
</span><span style="background-color: #ffffcc">#endif
</span>
<span style="background-color: #ffffcc">#if MYNEWT_VAL(BNO055_STATS)
</span><span style="background-color: #ffffcc">/* Define the stats section and records */
</span><span style="background-color: #ffffcc">STATS_SECT_START(bno055_stat_section)
</span><span style="background-color: #ffffcc"> STATS_SECT_ENTRY(errors)
</span><span style="background-color: #ffffcc">STATS_SECT_END
</span>
<span style="background-color: #ffffcc">/* Define stat names for querying */
</span><span style="background-color: #ffffcc">STATS_NAME_START(bno055_stat_section)
</span><span style="background-color: #ffffcc"> STATS_NAME(bno055_stat_section, errors)
</span><span style="background-color: #ffffcc">STATS_NAME_END(bno055_stat_section)
</span>
<span style="background-color: #ffffcc">/* Global variable used to hold stats data */
</span><span style="background-color: #ffffcc">STATS_SECT_DECL(bno055_stat_section) g_bno055stats;
</span><span style="background-color: #ffffcc">#endif
</span>
...
int
bno055_init(struct os_dev *dev, void *arg)
{
...
<span style="background-color: #ffffcc">#if MYNEWT_VAL(BNO055_STATS)
</span><span style="background-color: #ffffcc"> /* Initialise the stats entry */
</span><span style="background-color: #ffffcc"> rc = stats_init(
</span><span style="background-color: #ffffcc"> STATS_HDR(g_bno055stats),
</span><span style="background-color: #ffffcc"> STATS_SIZE_INIT_PARMS(g_bno055stats, STATS_SIZE_32),
</span><span style="background-color: #ffffcc"> STATS_NAME_INIT_PARMS(bno055_stat_section));
</span><span style="background-color: #ffffcc"> SYSINIT_PANIC_ASSERT(rc == 0);
</span><span style="background-color: #ffffcc"> /* Register the entry with the stats registry */
</span><span style="background-color: #ffffcc"> rc = stats_register(dev-&gt;od_name, STATS_HDR(g_bno055stats));
</span><span style="background-color: #ffffcc"> SYSINIT_PANIC_ASSERT(rc == 0);
</span><span style="background-color: #ffffcc">#endif
</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>