| <!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" > |
| 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 class="active"><a href="./">Split Images</a> |
| |
| |
| <ul> |
| |
| |
| |
| </ul> |
| |
| </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/sensor_framework_overview/">Sensor Framework</a> |
| |
| |
| </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>» Split Images</li> |
| |
| |
| |
| <li>» <a href="os/os_user_guide/">OS User Guide</a></li> |
| |
| |
| |
| <li>» <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/modules/split/split.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> |
| |
| |
| |
| <h1 id="split-images">Split Images</h1> |
| <h2 id="description">Description</h2> |
| <p>The split image mechanism divides a target into two separate images: one |
| capable of image upgrade; the other containing application code. By isolating |
| upgrade functionality to a separate image, the application can support |
| over-the-air upgrade without dedicating flash space to network stack and |
| management code. </p> |
| <h2 id="concept">Concept</h2> |
| <p>Mynewt supports three image setups:</p> |
| <table> |
| <thead> |
| <tr> |
| <th>Setup</th> |
| <th>Description</th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr> |
| <td>Single</td> |
| <td>One large image; upgrade not supported.</td> |
| </tr> |
| <tr> |
| <td>Unified</td> |
| <td>Two standalone images.</td> |
| </tr> |
| <tr> |
| <td>Split</td> |
| <td>Kernel in slot 0; application in slot 1.</td> |
| </tr> |
| </tbody> |
| </table> |
| <p>Each setup has its tradeoffs. The Single setup gives you the most flash space, |
| but doesn't allow you to upgrade after manufacturing. The Unified setup allows |
| for a complete failover in case a bad image gets uploaded, but requires a lot |
| of redundancy in each image, limiting the amount of flash available to the |
| application. The Split setup sits somewhere between these two options.</p> |
| <p>Before exploring the split setup in more detail, it might be helpful to get a |
| basic understanding of the Mynewt boot sequence. The boot process is |
| summarized below.</p> |
| <h4 id="boot-sequence-single">Boot Sequence - Single</h4> |
| <p>In the Single setup, there is no boot loader. Instead, the image is placed at |
| address 0. The hardware boots directly into the image code. Upgrade is not |
| possible because there is no boot loader to move an alternate image into place.</p> |
| <h4 id="boot-sequence-unified">Boot Sequence - Unified</h4> |
| <p>In the Unified setup, the boot loader is placed at address 0. At startup, the |
| boot loader arranges for the correct image to be in image slot 0, which may |
| entail swapping the contents of the two image slots. Finally, the boot loader |
| jumps to the image in slot 0.</p> |
| <h4 id="boot-sequence-split">Boot Sequence - Split</h4> |
| <p>The Split setup differs from the other setups mainly in that a target is not |
| fully contained in a single image. Rather, the target is partitioned among two |
| separate images: the <em>loader</em>, and the <em>application</em>. Functionality is divided |
| among these two images as follows:</p> |
| <ol> |
| <li> |
| <p>Loader: </p> |
| <ul> |
| <li>Mynewt OS.</li> |
| <li>Network stack for connectivity during upgrade e.g. BLE stack.</li> |
| <li>Anything else required for image upgrade.</li> |
| </ul> |
| </li> |
| <li> |
| <p>Application:</p> |
| <ul> |
| <li>Parts of Mynewt not required for image upgrade.</li> |
| <li>Application-specific code.</li> |
| </ul> |
| </li> |
| </ol> |
| <p>The loader image serves three purposes:</p> |
| <ol> |
| <li><em>Second-stage boot loader:</em> it jumps into the application image at |
| start up.</li> |
| <li><em>Image upgrade server:</em> the user can upgrade to a new loader + application |
| combo, even if an application image is not currently running.</li> |
| <li><em>Functionality container:</em> the application image can directly access all the |
| code present in the loader image</li> |
| </ol> |
| <p>From the perspective of the boot loader, a loader image is identical to a plain |
| unified image. What makes a loader image different is a change to its start up |
| sequence: rather than starting the Mynewt OS, it jumps to the application image |
| in slot 1 if one is present.</p> |
| <h2 id="tutorial">Tutorial</h2> |
| <h3 id="building-a-split-image">Building a Split Image</h3> |
| <p>We will be referring to the nRF51dk for examples in this document. Let's take |
| a look at this board's flash map (defined in <code>hw/bsp/nrf51dk/bsp.yml</code>):</p> |
| <table> |
| <thead> |
| <tr> |
| <th>Name</th> |
| <th>Offset</th> |
| <th>Size (kB)</th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr> |
| <td>Boot loader</td> |
| <td>0x00000000</td> |
| <td>16</td> |
| </tr> |
| <tr> |
| <td>Reboot log</td> |
| <td>0x00004000</td> |
| <td>16</td> |
| </tr> |
| <tr> |
| <td>Image slot 0</td> |
| <td>0x00008000</td> |
| <td>110</td> |
| </tr> |
| <tr> |
| <td>Image slot 1</td> |
| <td>0x00023800</td> |
| <td>110</td> |
| </tr> |
| <tr> |
| <td>Image scratch</td> |
| <td>0x0003f000</td> |
| <td>2</td> |
| </tr> |
| <tr> |
| <td>Flash file system</td> |
| <td>0x0003f800</td> |
| <td>2</td> |
| </tr> |
| </tbody> |
| </table> |
| <p>The application we will be building is <a href="../../tutorials/bleprph">bleprph</a>. |
| First, we create a target to tie our BSP and application together.</p> |
| <div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>newt target create bleprph-nrf51dk |
| newt target set bleprph-nrf51dk \ |
| app=@apache-mynewt-core/apps/bleprph \ |
| bsp=@apache-mynewt-core/hw/bsp/nrf51dk \ |
| build_profile=optimized \ |
| syscfg=BLE_LL_CFG_FEAT_LE_ENCRYPTION=0:BLE_SM_LEGACY=0 |
| </code></pre></div> |
| |
| <p>The two syscfg settings disable bluetooth security and keep the code size down.</p> |
| <p>We can verify the target using the <code>target show</code> command:</p> |
| <div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>[~/tmp/myproj2]$ newt target show bleprph-nrf51dk |
| targets/bleprph-nrf51dk |
| app=@apache-mynewt-core/apps/bleprph |
| bsp=@apache-mynewt-core/hw/bsp/nrf51dk |
| build_profile=optimized |
| syscfg=BLE_LL_CFG_FEAT_LE_ENCRYPTION=0:BLE_SM_LEGACY=0 |
| </code></pre></div> |
| |
| <p>Next, build the target:</p> |
| <div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>[~/tmp/myproj2]$ newt build bleprph-nrf51dk |
| Building target targets/bleprph-nrf51dk |
| # [...] |
| Target successfully built: targets/bleprph-nrf51dk |
| </code></pre></div> |
| |
| <p>With our target built, we can view a code size breakdown using the <code>newt size <target></code> command. In the interest of brevity, the smaller entries are excluded from the below output:</p> |
| <div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>[~/tmp/myproj2]$ newt size bleprph-nrf51dk |
| Size of Application Image: app |
| FLASH RAM |
| 2446 1533 apps_bleprph.a |
| 1430 104 boot_bootutil.a |
| 1232 0 crypto_mbedtls.a |
| 1107 0 encoding_cborattr.a |
| 2390 0 encoding_tinycbor.a |
| 1764 0 fs_fcb.a |
| 2959 697 hw_drivers_nimble_nrf51.a |
| 4126 108 hw_mcu_nordic_nrf51xxx.a |
| 8161 4049 kernel_os.a |
| 2254 38 libc_baselibc.a |
| 2612 0 libgcc.a |
| 2232 24 mgmt_imgmgr.a |
| 1499 44 mgmt_newtmgr_nmgr_os.a |
| 23918 1930 net_nimble_controller.a |
| 28537 2779 net_nimble_host.a |
| 2207 205 sys_config.a |
| 1074 197 sys_console_full.a |
| 3268 97 sys_log.a |
| 1296 0 time_datetime.a |
| |
| objsize |
| text data bss dec hex filename |
| 105592 1176 13392 120160 1d560 /home/me/tmp/myproj2/bin/targets/bleprph-nrf51dk/app/apps/bleprph/bleprph.elf |
| </code></pre></div> |
| |
| <p>The full image text size is about 103kB (where 1kB = 1024 bytes). With an image slot size of 110kB, |
| this leaves only about 7kB of flash for additional application code and data. |
| Not good. This is the situation we would be facing if we were using the |
| Unified setup.</p> |
| <p>The Split setup can go a long way in solving our problem. Our unified bleprph |
| image consists mostly of components that get used during an image upgrade. By |
| using the Split setup, we turn the unified image into two separate images: the |
| loader and the application. The functionality related to image upgrade can be |
| delegated to the loader image, freeing up a significant amount of flash in the |
| application image slot.</p> |
| <p>Let's create a new target to use with the Split setup. We designate a target |
| as a split target by setting the <code>loader</code> variable. In our example, we are |
| going to use <code>bleprph</code> as the loader, and <code>splitty</code> as the application. |
| <code>bleprph</code> makes sense as a loader because it contains the BLE stack and |
| everything else required for an image upgrade.</p> |
| <div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>newt target create split-nrf51dk |
| newt target set split-nrf51dk \ |
| loader=@apache-mynewt-core/apps/bleprph \ |
| app=@apache-mynewt-core/apps/splitty \ |
| bsp=@apache-mynewt-core/hw/bsp/nrf51dk \ |
| build_profile=optimized \ |
| syscfg=BLE_LL_CFG_FEAT_LE_ENCRYPTION=0:BLE_SM_LEGACY=0 |
| </code></pre></div> |
| |
| <p>Verify that the target looks correct:</p> |
| <div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>[~/tmp/myproj2]$ newt target show split-nrf51dk |
| targets/split-nrf51dk |
| app=@apache-mynewt-core/apps/splitty |
| bsp=@apache-mynewt-core/hw/bsp/nrf51dk |
| build_profile=optimized |
| loader=@apache-mynewt-core/apps/bleprph |
| syscfg=BLE_LL_CFG_FEAT_LE_ENCRYPTION=0:BLE_SM_LEGACY=0 |
| </code></pre></div> |
| |
| <p>Now, let's build the new target:</p> |
| <div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>[~/tmp/myproj2]$ newt build split-nrf51dk |
| Building target targets/split-nrf51dk |
| # [...] |
| Target successfully built: targets/split-nrf51dk |
| </code></pre></div> |
| |
| <p>And look at the size breakdown (again, smaller entries are removed):</p> |
| <div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>[~/tmp/myproj2]$ newt size split-nrf51dk |
| Size of Application Image: app |
| FLASH RAM |
| 3064 251 sys_shell.a |
| |
| objsize |
| text data bss dec hex filename |
| 4680 112 17572 22364 575c /home/me/tmp/myproj2/bin/targets/split-nrf51dk/app/apps/splitty/splitty.elf |
| |
| Size of Loader Image: loader |
| FLASH RAM |
| 2446 1533 apps_bleprph.a |
| 1430 104 boot_bootutil.a |
| 1232 0 crypto_mbedtls.a |
| 1107 0 encoding_cborattr.a |
| 2390 0 encoding_tinycbor.a |
| 1764 0 fs_fcb.a |
| 3168 705 hw_drivers_nimble_nrf51.a |
| 4318 109 hw_mcu_nordic_nrf51xxx.a |
| 8285 4049 kernel_os.a |
| 2274 38 libc_baselibc.a |
| 2612 0 libgcc.a |
| 2232 24 mgmt_imgmgr.a |
| 1491 44 mgmt_newtmgr_nmgr_os.a |
| 25169 1946 net_nimble_controller.a |
| 31397 2827 net_nimble_host.a |
| 2259 205 sys_config.a |
| 1318 202 sys_console_full.a |
| 3424 97 sys_log.a |
| 1053 60 sys_stats.a |
| 1296 0 time_datetime.a |
| |
| objsize |
| text data bss dec hex filename |
| 112020 1180 13460 126660 1eec4 /home/me/tmp/myproj2/bin/targets/split-nrf51dk/loader/apps/bleprph/bleprph.elf |
| </code></pre></div> |
| |
| <p>The size command shows two sets of output: one for the application, and another |
| for the loader. The addition of the split functionality did make bleprph |
| slightly bigger, but notice how small the application is: 4.5 kB! Where before |
| we only had 7 kB left, now we have 105.5 kB. Furthermore, all the |
| functionality in the loader is available to the application at any time. For |
| example, if your application needs bluetooth functionality, it can use the BLE |
| stack present in the loader instead of containing its own copy.</p> |
| <p>Finally, let's deploy the split image to our nRF51dk board. The procedure here |
| is the same as if we were using the Unified setup, i.e., via either the <code>newt load</code> or <code>newt run</code> command.</p> |
| <div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>[~/repos/mynewt/core]$ newt load split-nrf51dk 0 |
| Loading app image into slot 2 |
| Loading loader image into slot 1 |
| </code></pre></div> |
| |
| <h3 id="image-management">Image Management</h3> |
| <h4 id="retrieve-current-state-image-list">Retrieve Current State (image list)</h4> |
| <p>Image management in the split setup is a bit more complicated than in the |
| unified setup. You can determine a device's image management state with the |
| <code>newtmgr image list</code> command. Here is how a device responds to this command |
| after our loader + application combo has been deployed:</p> |
| <div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>[~/tmp/myproj2]$ newtmgr -c A600ANJ1 image list |
| Images: |
| slot=0 |
| version: 0.0.0 |
| bootable: true |
| flags: active confirmed |
| hash: 948f118966f7989628f8f3be28840fd23a200fc219bb72acdfe9096f06c4b39b |
| slot=1 |
| version: 0.0.0 |
| bootable: false |
| flags: |
| hash: 78e4d263eeb5af5635705b7cae026cc184f14aa6c6c59c6e80616035cd2efc8f |
| Split status: matching |
| </code></pre></div> |
| |
| <p>There are several interesting things about this response:</p> |
| <ol> |
| <li><em>Two images:</em> This is expected; we deployed both a loader image and an |
| application image.</li> |
| <li><em>bootable flag:</em> Notice slot 0's bootable flag is set, while slot 1's is |
| not. This tells us that slot 0 contains a loader and slot 1 contains an |
| application. If an image is bootable, it can be booted directly from the boot |
| loader. Non-bootable images can only be started from a loader image.</li> |
| <li><em>flags:</em> Slot 0 is <code>active</code> and <code>confirmed</code>; none of slot 1's flags are set. |
| The <code>active</code> flag indicates that the image is currently running; the |
| <code>confirmed</code> flag indicates that the image will continue to be used on |
| subsequent reboots. Slot 1's lack of enabled flags indicates that the image is |
| not being used at all.</li> |
| <li><em>Split status:</em> The split status field tells you if the loader and |
| application are compatible. A loader + application combo is compatible only if |
| both images were built at the same time with <code>newt</code>. If the loader and |
| application are not compatible, the loader will not boot into the application.</li> |
| </ol> |
| <h3 id="enabling-a-split-application">Enabling a Split Application</h3> |
| <p>By default, the application image in slot 1 is disabled. This is indicated in |
| the <code>image list</code> response above. When you deploy a loader / application combo |
| to your device, the application image won't actually run. Instead, the loader |
| will act as though an application image is not present and remain in "loader |
| mode". Typically, a device in loader mode simply acts as an image management |
| server, listening for an image upgrade or a request to activate the application |
| image.</p> |
| <p>Use the following command sequence to enable the split application image:</p> |
| <ol> |
| <li>Tell device to "test out" the application image on next boot (<code>newtmgr image test <application-image-hash></code>).</li> |
| <li>Reboot device (<code>newtmgr reset</code>).</li> |
| <li>Make above change permanent (<code>newtmgr image confirm</code>).</li> |
| </ol> |
| <p>After the above sequence, a <code>newtmgr image list</code> command elicits the following response:</p> |
| <div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>[~/tmp/myproj2]$ newtmgr -c A600ANJ1 image confirm |
| Images: |
| slot=0 |
| version: 0.0.0 |
| bootable: true |
| flags: active confirmed |
| hash: 948f118966f7989628f8f3be28840fd23a200fc219bb72acdfe9096f06c4b39b |
| slot=1 |
| version: 0.0.0 |
| bootable: false |
| flags: active confirmed |
| hash: 78e4d263eeb5af5635705b7cae026cc184f14aa6c6c59c6e80616035cd2efc8f |
| Split status: matching |
| </code></pre></div> |
| |
| <p>The <code>active confirmed</code> flags value on both slots indicates that both images are |
| permanently running.</p> |
| <h3 id="image-upgrade">Image Upgrade</h3> |
| <p>First, let's review of the image upgrade process for the Unified setup. The |
| user upgrades to a new image in this setup with the following steps:</p> |
| <h4 id="image-upgrade-unified">Image Upgrade - Unified</h4> |
| <ol> |
| <li>Upload new image to slot 1 (<code>newtmgr image upload <filename></code>).</li> |
| <li>Tell device to "test out" the new image on next boot (<code>newtmgr image test <image-hash></code>).</li> |
| <li>Reboot device (<code>newtmgr reset</code>).</li> |
| <li>Make new image permanent (<code>newtmgr image confirm</code>).</li> |
| </ol> |
| <h4 id="image-upgrade-split">Image Upgrade - Split</h4> |
| <p>The image upgrade process is a bit more complicated in the Split setup. It is |
| more complicated because two images need to be upgraded (loader and |
| application) rather than just one. The split upgrade process is described |
| below:</p> |
| <ol> |
| <li>Disable split functionality; we need to deactivate the application image in |
| slot 1 (<code>newtmgr image test <current-loader-hash></code>).</li> |
| <li>Reboot device (<code>newtmgr reset</code>).</li> |
| <li>Make above change permanent (<code>newtmgr image confirm</code>).</li> |
| <li>Upload new loader to slot 1 (<code>newtmgr image upload <filename></code>).</li> |
| <li>Tell device to "test out" the new loader on next boot (<code>newtmgr image test <new-loader-hash></code>).</li> |
| <li>Reboot device (<code>newtmgr reset</code>).</li> |
| <li>Make above change of loader permanent (<code>newtmgr image confirm</code>).</li> |
| <li>Upload new application to slot 1 (<code>newtmgr image upload <filename></code>).</li> |
| <li>Tell device to "test out" the new application on next boot (<code>newtmgr image test <new-application-hash></code>).</li> |
| <li>Reboot device (<code>newtmgr reset</code>).</li> |
| <li>Make above change of application permanent (<code>newtmgr image confirm</code>).</li> |
| </ol> |
| <p>When performing this process manually, it may be helpful to use <code>image list</code> to |
| check the image management state as you go.</p> |
| <h2 id="syscfg">Syscfg</h2> |
| <p>Syscfg is Mynewt's system-wide configuration mechanism. In a split setup, |
| there is a single umbrella syscfg configuration that applies to both the loader |
| and the application. Consequently, overriding a value in an application-only |
| package potentially affects the loader (and vice-versa).</p> |
| <h2 id="loaders">Loaders</h2> |
| <p>The following applications have been enabled as loaders. You may choose to |
| build your own loader application, and these can serve as samples.</p> |
| <ul> |
| <li>@apache-mynewt-core/apps/slinky</li> |
| <li>@apache-mynewt-core/apps/bleprph</li> |
| </ul> |
| <h2 id="split-apps">Split Apps</h2> |
| <p>The following applications have been enabled as split applications. If you |
| choose to build your own split application these can serve as samples. Note |
| that slinky can be either a loader image or an application image.</p> |
| <ul> |
| <li>@apache-mynewt-core/apps/slinky</li> |
| <li>@apache-mynewt-core/apps/splitty</li> |
| </ul> |
| <h2 id="theory-of-operation">Theory of Operation</h2> |
| <p>A split image is built as follows:</p> |
| <p>First newt builds the application and loader images separately to ensure they |
| are consistent (no errors) and to generate elf files which can inform newt of |
| the symbols used by each part.</p> |
| <p>Then newt collects the symbols used by both application and loader in two ways. |
| It collects the set of symbols from the <code>.elf</code> files. It also collects all the |
| possible symbols from the <code>.a</code> files for each application.</p> |
| <p>Newt builds the set of packages that the two applications share. It ensures |
| that all the symbols used in those packages are matching. NOTE: because of |
| features and #ifdefs, its possible for the two package to have symbols that are |
| not the same. In this case newt generates an error and will not build a split |
| image.</p> |
| <p>Then newt creates the list of symbols that the two applications share from |
| those packages (using the .elf files).</p> |
| <p>Newt re-links the loader to ensure all of these symbols are present in the |
| loader application (by forcing the linker to include them in the <code>.elf</code>).</p> |
| <p>Newt builds a special copy of the loader.elf with only these symbols (and the |
| handful of symbols discussed in the linking section above).</p> |
| <p>Finally, newt links the application, replacing the common .a libraries with the |
| special loader.elf image during the link.</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 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> |