blob: a1d252a3c1a22a97728c9b22de78aaf52d3ffcd1 [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>BSP Porting - 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="BSP Porting">
<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" >
Version: 1.1.0
</option>
<option value="/v1_0_0/os/introduction" selected="selected" >
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>
</li>
<li ><a href="../port_os/">Porting to your Platform</a>
<ul>
<li class="active">
<a href="./">BSP Porting</a>
</li>
<li >
<a href="../port_mcu/">MCU Porting</a>
</li>
<li >
<a href="../port_cpu/">CPU Porting</a>
</li>
</ul>
</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/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="
../../../../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/core_os/porting/port_os/">Porting to your Platform</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; BSP Porting</li>
</ul>
</div>
</div>
<div class="alert alert-warning">
<p>
Version 1.0.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="create-a-bsp-for-your-target">Create a BSP for your Target</h1>
<h3 id="introduction">Introduction</h3>
<p>If you are using a board or system not currently supported by Mynewt, you will need to
create a BSP for the new target. If another similar BSP exists it is recommended to
copy that BSP as a starting point. For example, if another BSP exists using the same MCU,
start with a copy of that BSP.</p>
<p>Either way, this document describes the steps necessary to create a new BSP from scratch. </p>
<h3 id="keep-your-reference-documents-handy">Keep your Reference Documents handy</h3>
<p>To build a proper BSP, you will typically need the following:</p>
<ul>
<li>The datasheet for the MCU you have chosen</li>
<li>The schematic of your board</li>
<li>The information on the CPU core within your MCU if it is not included in your MCU documentation</li>
<li>This Mynewt documentation</li>
</ul>
<h3 id="name-your-bsp">Name your BSP</h3>
<p>Select a name for your BSP. For the remainder of this document, we'll assume the bsp is named <code>myboard</code>.
In general its best to select a name that describes the board/system you are creating.</p>
<h3 id="create-a-bsp-directory">Create a BSP directory</h3>
<p>Create a directory <code>hw/bsp/myboard</code> using the name chosen above. Within this BSP directory, create the following subdirectories:</p>
<ul>
<li><code>include</code></li>
<li><code>include/bsp</code></li>
<li><code>src</code></li>
</ul>
<h3 id="create-a-target-using-mynewt">Create a Target using Mynewt</h3>
<p>Create a newt target for your test project for the BSP. To learn how to create a target,
see this <strong>howto</strong> <a href="../../get_started/project_create">Tutorial</a>. Once you are familiar
with creating targets, move on below to create a target to use to test your BSP.</p>
<p>It is recommended that you use a simple project like <a href="../../../tutorials/blinky_primo/">blinky</a> to minimize the time
to get a working Mynewt system. For this document, we will assume the <em>target</em> is called <em>myboard_blinky</em>
and uses project <em>blinky</em>. </p>
<p>Set the <code>bsp</code> of the project to <code>/hw/bsp/myboard</code>. While creating your target, you will need to
specify your <code>arch</code>and <code>compiler</code>. If your platform requires an architecture or compiler
that are not defined in Mynewt, you will need to add them first. To add a CPU architecture see <a href="../port_cpu/">CPU Porting</a>.</p>
<p>When this is complete, your <em>target</em> may look similar to this.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code> <span style="color: #000000">$</span> <span style="color: #000000">newt</span> <span style="color: #000000">target</span> <span style="color: #000000">show</span>
<span style="color: #000000">myboard_blinky</span>
<span style="color: #000000">arch=cortex_m0</span>
<span style="color: #000000">bsp=hw/bsp/myboard</span>
<span style="color: #000000">compiler=arm-none-eabi-m0</span>
<span style="color: #000000">compiler_def=debug</span>
<span style="color: #000000">name=myboard_blinky</span>
<span style="color: #000000">project=blinky</span>
</code></pre></div>
<h3 id="create-required-files-for-compilation">Create Required Files For Compilation</h3>
<p>Create the following files within the BSP directory tree. For now, they can be empty files. We will fill them out one at a time.</p>
<table>
<thead>
<tr>
<th><strong>File Path Name</strong></th>
<th><strong>Description</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td>LICENSE</td>
<td>A File to present the source license for your BSP</td>
</tr>
<tr>
<td>README.md</td>
<td>A markdown file to write documentation for your BSP</td>
</tr>
<tr>
<td>pkg.yml</td>
<td>A package file to describe your BSP contents</td>
</tr>
<tr>
<td>include/bsp/bsp.h</td>
<td>A header file to include definitions required by system from the BSP</td>
</tr>
<tr>
<td>include/bsp/bsp_sysid.h</td>
<td>A header file to enumerate the devices in your BSP</td>
</tr>
<tr>
<td>src/os_bsp.c</td>
<td>A C source file to provide functions required by the OS from your BSP</td>
</tr>
<tr>
<td>src/sbrk.c</td>
<td>A C source file to memory from your heap to the OS</td>
</tr>
<tr>
<td>src/libc_stubs.c</td>
<td>A C source file to provide stubs/methods required by libc</td>
</tr>
<tr>
<td>myboard.ld</td>
<td>A linker script to provide the memory map for your linked code</td>
</tr>
</tbody>
</table>
<p>Optionally, create these files as necessary to provide all functionality from Mynewt.</p>
<table>
<thead>
<tr>
<th><strong>File Path Name</strong></th>
<th><strong>Description</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td>myboard_boot.ld</td>
<td>A linker script to provide the memory map for your bootloader</td>
</tr>
<tr>
<td>myboard_download.sh</td>
<td>A bash script to download code into your platform</td>
</tr>
<tr>
<td>myboard_debug.sh</td>
<td>A bash script to intiate a gdb session with your platform</td>
</tr>
<tr>
<td>src/hal_bsp.c</td>
<td>A C source file to provide functions required by the HAL from your BSP</td>
</tr>
</tbody>
</table>
<h3 id="fill-out-your-package-file">Fill Out your Package File</h3>
<p>Edit the package file to describe your BSP.</p>
<p>The package file must contain:</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code> pkg.name: &quot;hw/bsp/myboard&quot;
pkg.linkerscript: &quot;myboard.ld&quot;
</code></pre></div>
<table>
<thead>
<tr>
<th><strong>Attribute</strong></th>
<th><strong>Description</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td><code>pkg.name</code></td>
<td>The name of your bsp package</td>
</tr>
<tr>
<td><code>pkg.linkerscript</code></td>
<td>The linker script that controls the memory placement of the compiled code sections from the Mynewt OS and your applications.</td>
</tr>
</tbody>
</table>
<p>The linker script is a key component of the BSP and specifies where each section of code and data are
stored within your CPU which can vary with the BSP depending on your chosen memory layout.<br />
For a tutorial on writing linker scripts, see <a href="#create-or-copy-linker-script">Create or Copy Linker Script(s)</a>.</p>
<p>The package file typically contains:</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code> pkg.linkerscript.bootloader.OVERWRITE: &quot;myboard_boot.ld&quot;
pkg.downloadscript: &quot;myboard_download.sh&quot;
pkg.debugscript: &quot;myboard_debug.sh&quot;
pkg.deps:
- hw/mcu/mymcu/variant
</code></pre></div>
<p>where <code>mymcu/variant</code> should be replaced with the specific MCU and variant used in your design.</p>
<p>The following table describes additional attributes relevant to the BSP <code>pkg.yml</code> file.</p>
<table>
<thead>
<tr>
<th><strong>Attribute</strong></th>
<th><strong>Description</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td><code>pkg.linkerscript.bootloader.OVERWRITE</code></td>
<td>A special linker for creating a bootloader for Mynewt</td>
</tr>
<tr>
<td><code>pkg.downloadscript</code></td>
<td>A script that can download a flash image into your target platform</td>
</tr>
<tr>
<td><code>pkg.debugscript</code></td>
<td>A script that can run the GDB debugger on your board</td>
</tr>
<tr>
<td><code>pkg.deps</code></td>
<td>Any dependencies on your BSP</td>
</tr>
</tbody>
</table>
<p>The BSP will invariably depend upon an MCU (in this sample it's <code>hw/mcu/mymcu/variant</code>) since the
Mynewt OS runs on an MCU within your target. If your MCU is not supported by Mynewt,
see <a href="../port_mcu/">MCU Porting</a> for details on how to create a new MCU in Mynewt.</p>
<p>The package file may also contain:</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code> pkg.cflags: -D__MY_SPECIAL_BSP_OPTIONS_
pkg.deps:
- libs/cmsis-core
</code></pre></div>
<table>
<thead>
<tr>
<th><strong>Attribute</strong></th>
<th><strong>Description</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td><code>pkg.cflags</code></td>
<td>Any specific compiler flags for your bsp</td>
</tr>
<tr>
<td><code>pkg.deps</code></td>
<td>Any other libraries that may be required. Some architectures (like ARM) have special libraries to make BSP creation easier.</td>
</tr>
</tbody>
</table>
<h3 id="create-or-copy-linker-script">Create or Copy Linker Script</h3>
<p>It's probably best to start with a linker script from another BSP using the same MCU. If this is not available,
consult your MCU documentation and library samples to find a linker script to start with.</p>
<p>Typically, a linker script has to specify the following sections for code:</p>
<ul>
<li>.text -- the location and alignment of the memory section to store your code</li>
<li>.data -- the location and alignment of the memory section to store initialized data</li>
<li>.bss -- the location and alignment of the memory section to store uninitialized data</li>
<li>.heap -- the location and alignment of the memory section to provide system memory</li>
</ul>
<p>The linker script should specify the location and size of the different memory regions
in your BSP and map the code sections described above into these regions. </p>
<p>The linker script should also include an ENTRY point. This is used by the debugger
to know where to start the program counter when the target is debugged.</p>
<p>There may be additional requirements from the MCU or OS that you may find easiest to
place in the linker script. Some specific variables that the OS and MCU depends on are :</p>
<table>
<thead>
<tr>
<th><strong>Variable</strong></th>
<th><strong>Description</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td><code>__bss_start__</code></td>
<td>a variable located at the start of the BSS section</td>
</tr>
<tr>
<td><code>__bss_end__</code></td>
<td>a variable located at the end of the BSS section</td>
</tr>
<tr>
<td><code>__isr_vector</code></td>
<td>Some CPUs map their interrupt vectors. They may need to be specified in the linker</td>
</tr>
<tr>
<td><code>_user_heap_start</code></td>
<td>the start of the heap for unallocated memory</td>
</tr>
<tr>
<td><code>_user_heap_end</code></td>
<td>the end of the heap for unallocated memory</td>
</tr>
</tbody>
</table>
<p>Create an alternate linker script for the bootloader since it is typically linked to use different addresses to boot the main image. </p>
<h3 id="add-functions-and-defines">Add Functions and Defines</h3>
<p>At this point, it will be possible to run the <code>newt</code> tool to build your target.</p>
<p>You may run into complaints from the linker script that a few Mynewt specific functions are missing. We will describe these below.</p>
<table>
<thead>
<tr>
<th><strong>Function</strong></th>
<th><strong>Description</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td><code>os_bsp_init()</code></td>
<td>code to initialize the bsp</td>
</tr>
<tr>
<td><code>os_bsp_systick_init()</code></td>
<td>code to setup the system tick for the OS</td>
</tr>
</tbody>
</table>
<p>There are also several libc definitions that can be stubbed in your first BSP. Examples are <code>_write</code>, <code>_read</code>,
etc. that can be found in <code>libc_stubs.c</code>. But you <em>must</em> implement the following function to provide memory to the OS and system.</p>
<table>
<thead>
<tr>
<th><strong>Function</strong></th>
<th><strong>Description</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td><code>_sbrk</code></td>
<td>Returns memory from heap (used by malloc)</td>
</tr>
</tbody>
</table>
<ul>
<li>Implement <code>_sbrk()</code></li>
</ul>
<p><code>sbrk()</code> is required by libc to get memory from the heap for things like malloc. Although not strongly BSP dependent,
this is currently in the BSP to allow flexibility in providing system memory. See other BSPs for providing <code>sbrk</code> functionality.</p>
<ul>
<li>Implement <code>os_bsp_init()</code></li>
</ul>
<p><code>os_bsp_init</code> should initialize anything required in the OS by the BSP. Typically this is a very small set. </p>
<p><strong>NOTE</strong>: Currently we are making calls to <code>_sbrk()</code> and <code>close(0)</code> from <code>os_bsp_init</code> to get around a
linker issue where some of libc is not getting included. Please include this in your <code>os_bsp_init</code>.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code> <span style="color: #177500">/*</span>
<span style="color: #177500"> * XXX these references are here to keep the functions in for libc to find.</span>
<span style="color: #177500"> */</span>
<span style="color: #000000">_sbrk</span>(<span style="color: #1C01CE">0</span>);
<span style="color: #000000">_close</span>(<span style="color: #1C01CE">0</span>);
</code></pre></div>
<ul>
<li>Other Unresolved Defines or Functions</li>
</ul>
<p>There may be other unresolved defines or functions that are required by the specific MCU within your BSP. Below lists some sample defines.</p>
<table>
<thead>
<tr>
<th><strong>Undefined Variable</strong></th>
<th><strong>Description</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td><code>CONSOLE_UART_PORT</code></td>
<td>Which communications port on your target runs the console</td>
</tr>
<tr>
<td><code>LED_BLINK_PIN</code></td>
<td>which pin on your target runs the blinky LED</td>
</tr>
</tbody>
</table>
<p>The set of missing functionality depends upon the libraries and dependencies you have included in the project.
That's why its best to keep your first project pretty simple then add incrementally.
For example, if you include the Newtron file system, you will need to define a file system map for your BSP.</p>
<p>Missing functionality may take the form of <code>#define</code> items required to compile, or they may take the form of missing functions. </p>
<ul>
<li><code>cmsis_nvic.h</code></li>
</ul>
<p>If you are using an ARM cortex architecture, you need to define the number of interrupts supported by your system.
If you are not using ARM Cortex architecture this may not be required (but something else might be).</p>
<h3 id="add-debug-script">Add Debug Script</h3>
<p>The debug script in the bsp directory allows the newt tool to automatically connect to the debugger
and create a debug session with the target. This requires knowledge of your target debug interface.
Most of the Mynewt BSP targets use <a href="http://openocd.org">openocd</a> to perform debugging.
This script typically creates an openocd connection to the target and then connects a gdb instance
to this openocd connection. There are several examples in existing BSPs to follow.</p>
<p>The script must take a single argument which is the name of the image file minus the '.elf' suffix.</p>
<p>The BSP is complete without this file, but newt will be unable to establish a debug session without it.</p>
<h3 id="add-download-script">Add Download Script</h3>
<p>Similar to the debug script, the download script is a hook for newt to download the image to the target system.
The download script also typically uses the openocd interface to erase flash and progam the code into the device.</p>
<p><strong>NOTE:</strong> The download script needs to command openocd to program the image into the appropriate location
which is typically called <code>FLASH_OFFSET</code> in these scripts. This location has to match the linker script
location of the image link address. For example, if your linker links the code to be run at <code>0xC000</code> your
download script should download the image to the same address in the correct flash. </p>
<h3 id="add-license-and-documentation">Add License and Documentation</h3>
<p>The <code>LICENSE</code> file is an ASCII text file that describes the source license for this
package.</p>
<p>The <code>README.md</code> is a <a href="https://en.wikipedia.org/wiki/Markdown">markdown</a>
file that contains any documentation you
want to provide for the BSP.</p>
<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>