mm-iot-sdk/framework/doc/html/bootloader_8c.html
Morse Micro 4f4eb7fc7a Morse Micro MM-IoT-SDK release 2.9.7
This commit introduces version 2.9.7 of the Morse Micro MM-IoT-SDK
for ARM microcontroller base platforms.
2025-10-04 02:04:28 +10:00

739 lines
40 KiB
HTML

<!-- HTML header for doxygen 1.8.17-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.9.4"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Morse Micro IoT SDK: bootloader.c File Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="style.css" rel="stylesheet" type="text/css"/>
<link rel="shortcut icon" href="favicon.svg" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectlogo"><img alt="Logo" src="logo.png"/></td>
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">Morse Micro IoT SDK
&#160;<span id="projectnumber">2.9.7</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.4 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search",'Search','.html');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
<div id="nav-tree">
<div id="nav-tree-contents">
<div id="nav-sync" class="sync"></div>
</div>
</div>
<div id="splitbar" style="-moz-user-select:none;"
class="ui-resizable-handle">
</div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(document).ready(function(){initNavTree('bootloader_8c.html',''); initResizable(); });
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div class="header">
<div class="summary">
<a href="#define-members">Macros</a> &#124;
<a href="#enum-members">Enumerations</a> &#124;
<a href="#func-members">Functions</a> &#124;
<a href="#var-members">Variables</a> </div>
<div class="headertitle"><div class="title">bootloader.c File Reference</div></div>
</div><!--header-->
<div class="contents">
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p >Example bootloader to boot and update application securely. </p>
<h1><a class="anchor" id="autotoc_md17"></a>
Firmware Update Procedure</h1>
<p >The software update is done in 2 stages.</p>
<h2><a class="anchor" id="autotoc_md18"></a>
Stage 1: Software download and Authentication</h2>
<p >This step is performed by the application and is application specific. The application downloads the software image using any means possible and then authenticates it using any means possible - this is all application specific. The update image is in the morse <code>MBIN</code> file format. Once the software image has been successfully downloaded and authenticated, the application software needs to signal the bootloader that a new image is available for flashing. it does so by simply writing the path of the software image to config store key UPDATE_IMAGE. For added security the application also writes a SHA256 hash of the image to IMAGE_SIGNATURE key. Once this is done, the application simply reboots the CPU which causes the bootloader to execute.</p>
<p >To build a .mbin file for any application simply issue the following make command in the applications folder: </p><div class="fragment"><div class="line">make mbin -j4</div>
</div><!-- fragment --><p> The result of the above command will be a .mbin file in the <code>build/</code> directory for the application in addition to the .elf file. </p><dl class="section note"><dt>Note</dt><dd>You cannot generate a .mbin file for the bootloader itself.</dd></dl>
<h2><a class="anchor" id="autotoc_md19"></a>
Stage 2: Flashing the Software image</h2>
<p >This code implements stage 2. Once rebooted by the application, the CPU automatically executes the bootloader (this program) which is in the boot region of flash. The bootloader sees that there is an UPDATE_IMAGE key in config store and proceeds to verify the image pointed to by the key using the SHA256 algorithm and compares the result with the hash in the IMAGE_SIGNATURE key. If the hash matches it then proceeds with flashing the image into the application code area of the flash. In case the checksum does not match the bootloader writes an error code into the config store and jumps back into the old application image without performing the software update. Once the image has been successfully flashed the bootloader transfers control to the new application image.</p>
<p >If no UPDATE_IMAGE key was found, the bootloader simply jumps to the current application image in flash.</p>
<p >In addition to the above the bootloader performs some sanity checks like checking how many times the update was attempted and failed in order to prevent the bootloader from getting stuck in an infinite update loop in the event of a faulty hardware (or software image). </p>
<p class="definition">Definition in file <a class="el" href="bootloader_8c_source.html">bootloader.c</a>.</p>
</div><div class="textblock"><code>#include &lt;stdio.h&gt;</code><br />
<code>#include &lt;stdint.h&gt;</code><br />
<code>#include &lt;stdbool.h&gt;</code><br />
<code>#include &lt;string.h&gt;</code><br />
<code>#include &lt;endian.h&gt;</code><br />
<code>#include &lt;sys/unistd.h&gt;</code><br />
<code>#include &lt;sys/fcntl.h&gt;</code><br />
<code>#include &lt;sys/errno.h&gt;</code><br />
<code>#include &quot;sha256.h&quot;</code><br />
<code>#include &quot;mmhal_flash.h&quot;</code><br />
<code>#include &quot;mmconfig.h&quot;</code><br />
<code>#include &quot;mmhal.h&quot;</code><br />
<code>#include &quot;mmosal.h&quot;</code><br />
<code>#include &quot;puff.h&quot;</code><br />
<code>#include &quot;mbin.h&quot;</code><br />
</div><div class="textblock"><div class="dynheader">
Include dependency graph for bootloader.c:</div>
<div class="dyncontent">
<div class="center"><img src="bootloader_8c__incl.png" border="0" usemap="#abootloader_8c" alt=""/></div>
<map name="abootloader_8c" id="abootloader_8c">
<area shape="rect" title="Example bootloader to boot and update application securely." alt="" coords="798,5,901,32"/>
<area shape="rect" title=" " alt="" coords="1155,453,1221,480"/>
<area shape="rect" title=" " alt="" coords="651,453,722,480"/>
<area shape="rect" title=" " alt="" coords="313,453,396,480"/>
<area shape="rect" title=" " alt="" coords="1055,453,1126,480"/>
<area shape="rect" title=" " alt="" coords="462,80,541,107"/>
<area shape="rect" title=" " alt="" coords="565,80,665,107"/>
<area shape="rect" title=" " alt="" coords="689,80,778,107"/>
<area shape="rect" title=" " alt="" coords="802,80,897,107"/>
<area shape="rect" title=" " alt="" coords="921,80,1002,107"/>
<area shape="rect" href="mmhal__flash_8h_source.html" title=" " alt="" coords="217,304,335,331"/>
<area shape="rect" href="mmconfig_8h_source.html" title=" " alt="" coords="43,304,141,331"/>
<area shape="rect" href="mmhal_8h_source.html" title=" " alt="" coords="357,80,437,107"/>
<area shape="rect" href="mmosal_8h_source.html" title=" " alt="" coords="771,379,858,405"/>
<area shape="rect" title=" " alt="" coords="1229,80,1288,107"/>
<area shape="rect" href="mbin_8h_source.html" title=" " alt="" coords="1312,80,1379,107"/>
<area shape="rect" title=" " alt="" coords="368,379,443,405"/>
<area shape="rect" title=" " alt="" coords="368,229,432,256"/>
<area shape="rect" href="mmhal__wlan_8h_source.html" title=" " alt="" coords="461,155,579,181"/>
<area shape="rect" href="mmpkt_8h_source.html" title=" " alt="" coords="518,304,599,331"/>
<area shape="rect" href="mmwlan_8h_source.html" title=" " alt="" coords="717,229,808,256"/>
<area shape="rect" title=" " alt="" coords="861,453,931,480"/>
<area shape="rect" title=" " alt="" coords="750,453,837,480"/>
<area shape="rect" title=" " alt="" coords="725,304,800,331"/>
</map>
</div>
</div>
<p><a href="bootloader_8c_source.html">Go to the source code of this file.</a></p>
<table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="define-members" name="define-members"></a>
Macros</h2></td></tr>
<tr class="memitem:a6cc84937ff76b5c7eafccff861c09110"><td class="memItemLeft" align="right" valign="top">#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="bootloader_8c.html#a6cc84937ff76b5c7eafccff861c09110">MAX_UPDATE_ATTEMPTS</a>&#160;&#160;&#160;10</td></tr>
<tr class="memdesc:a6cc84937ff76b5c7eafccff861c09110"><td class="mdescLeft">&#160;</td><td class="mdescRight">Maximum number of times we attempt to update before giving up. <a href="bootloader_8c.html#a6cc84937ff76b5c7eafccff861c09110">More...</a><br /></td></tr>
<tr class="separator:a6cc84937ff76b5c7eafccff861c09110"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a79f8ce89914364edcd444bad719e909d"><td class="memItemLeft" align="right" valign="top">#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="bootloader_8c.html#a79f8ce89914364edcd444bad719e909d">MAX_SEGMENT_SIZE</a>&#160;&#160;&#160;32768</td></tr>
<tr class="memdesc:a79f8ce89914364edcd444bad719e909d"><td class="mdescLeft">&#160;</td><td class="mdescRight">Maximum size of a segment, set to 32768. <a href="bootloader_8c.html#a79f8ce89914364edcd444bad719e909d">More...</a><br /></td></tr>
<tr class="separator:a79f8ce89914364edcd444bad719e909d"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="enum-members" name="enum-members"></a>
Enumerations</h2></td></tr>
<tr class="memitem:a9c2734c8641676d2dcc02b82fc9a25a3"><td class="memItemLeft" align="right" valign="top">enum &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="bootloader_8c.html#a9c2734c8641676d2dcc02b82fc9a25a3">bootloader_return_codes</a> { <br />
&#160;&#160;<b>BOOTLOADER_OK</b> = 0
, <b>BOOTLOADER_ERR_FILE_NOT_FOUND</b>
, <b>BOOTLOADER_ERR_SIGNATURE_NOT_FOUND</b>
, <b>BOOTLOADER_ERR_FILE_VERIFICATION_FAILED</b>
, <br />
&#160;&#160;<b>BOOTLOADER_ERR_INVALID_FILE</b>
, <b>BOOTLOADER_ERR_FILE_CORRUPT</b>
, <b>BOOTLOADER_ERR_ERASE_FAILED</b>
, <b>BOOTLOADER_ERR_PROGRAM_FAILED</b>
, <br />
&#160;&#160;<b>BOOTLOADER_ERR_TOO_MANY_ATTEMPTS</b>
, <b>BOOTLOADER_ERR_FILE_DECOMPRESSION</b>
<br />
}</td></tr>
<tr class="memdesc:a9c2734c8641676d2dcc02b82fc9a25a3"><td class="mdescLeft">&#160;</td><td class="mdescRight">Bootloader return codes. <a href="bootloader_8c.html#a9c2734c8641676d2dcc02b82fc9a25a3">More...</a><br /></td></tr>
<tr class="separator:a9c2734c8641676d2dcc02b82fc9a25a3"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="func-members" name="func-members"></a>
Functions</h2></td></tr>
<tr class="memitem:ad7adf72f0188214738b18073dbf9a0df"><td class="memItemLeft" align="right" valign="top">static void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="bootloader_8c.html#ad7adf72f0188214738b18073dbf9a0df">delay_ms</a> (uint32_t approx_delay_ms)</td></tr>
<tr class="memdesc:ad7adf72f0188214738b18073dbf9a0df"><td class="mdescLeft">&#160;</td><td class="mdescRight">Implements a delay of approximately the duration specified. <a href="bootloader_8c.html#ad7adf72f0188214738b18073dbf9a0df">More...</a><br /></td></tr>
<tr class="separator:ad7adf72f0188214738b18073dbf9a0df"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a4216c0860ba47882f9a2dc002bcff4d5"><td class="memItemLeft" align="right" valign="top">static void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="bootloader_8c.html#a4216c0860ba47882f9a2dc002bcff4d5">blink_error_code</a> (int code)</td></tr>
<tr class="memdesc:a4216c0860ba47882f9a2dc002bcff4d5"><td class="mdescLeft">&#160;</td><td class="mdescRight">Blinks the hardware error LED to indicate the error code. <a href="bootloader_8c.html#a4216c0860ba47882f9a2dc002bcff4d5">More...</a><br /></td></tr>
<tr class="separator:a4216c0860ba47882f9a2dc002bcff4d5"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aee64527bc3ac3493e545088bfddd20dd"><td class="memItemLeft" align="right" valign="top">static void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="bootloader_8c.html#aee64527bc3ac3493e545088bfddd20dd">update_failed</a> (int code)</td></tr>
<tr class="memdesc:aee64527bc3ac3493e545088bfddd20dd"><td class="mdescLeft">&#160;</td><td class="mdescRight">Called when multiple attempts to update failed, must not return. <a href="bootloader_8c.html#aee64527bc3ac3493e545088bfddd20dd">More...</a><br /></td></tr>
<tr class="separator:aee64527bc3ac3493e545088bfddd20dd"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a3fff6197c0b420e41cb8c6ca32b58bbe"><td class="memItemLeft" align="right" valign="top">static void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="bootloader_8c.html#a3fff6197c0b420e41cb8c6ca32b58bbe">erase_application_area</a> (void)</td></tr>
<tr class="memdesc:a3fff6197c0b420e41cb8c6ca32b58bbe"><td class="mdescLeft">&#160;</td><td class="mdescRight">This function erases the entire application flash region. <a href="bootloader_8c.html#a3fff6197c0b420e41cb8c6ca32b58bbe">More...</a><br /></td></tr>
<tr class="separator:a3fff6197c0b420e41cb8c6ca32b58bbe"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a39140ce852070800f265073418f49fad"><td class="memItemLeft" align="right" valign="top">static int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="bootloader_8c.html#a39140ce852070800f265073418f49fad">read_segment_header</a> (int fd, struct <a class="el" href="structmbin__tlv__hdr.html">mbin_tlv_hdr</a> *seg_hdr)</td></tr>
<tr class="memdesc:a39140ce852070800f265073418f49fad"><td class="mdescLeft">&#160;</td><td class="mdescRight">Loads the segment header from file. <a href="bootloader_8c.html#a39140ce852070800f265073418f49fad">More...</a><br /></td></tr>
<tr class="separator:a39140ce852070800f265073418f49fad"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ae056e191483eb2bd384b33251e74ab98"><td class="memItemLeft" align="right" valign="top">static int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="bootloader_8c.html#ae056e191483eb2bd384b33251e74ab98">read_uint32</a> (int fd, uint32_t *val)</td></tr>
<tr class="memdesc:ae056e191483eb2bd384b33251e74ab98"><td class="mdescLeft">&#160;</td><td class="mdescRight">Loads a 32 bit integer from file and converts to host endian. <a href="bootloader_8c.html#ae056e191483eb2bd384b33251e74ab98">More...</a><br /></td></tr>
<tr class="separator:ae056e191483eb2bd384b33251e74ab98"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aa561c09fdf6feb3346f48f9925cc822e"><td class="memItemLeft" align="right" valign="top">static int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="bootloader_8c.html#aa561c09fdf6feb3346f48f9925cc822e">load_and_flash_mbin</a> (const char *fname, bool make_changes)</td></tr>
<tr class="memdesc:aa561c09fdf6feb3346f48f9925cc822e"><td class="mdescLeft">&#160;</td><td class="mdescRight">Loads and flashes the image. <a href="bootloader_8c.html#aa561c09fdf6feb3346f48f9925cc822e">More...</a><br /></td></tr>
<tr class="separator:aa561c09fdf6feb3346f48f9925cc822e"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a7cf929399abd068757e3d916ca9e034e"><td class="memItemLeft" align="right" valign="top">static int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="bootloader_8c.html#a7cf929399abd068757e3d916ca9e034e">verify_signature</a> (const char *fname)</td></tr>
<tr class="memdesc:a7cf929399abd068757e3d916ca9e034e"><td class="mdescLeft">&#160;</td><td class="mdescRight">Verifies the signature of the file. <a href="bootloader_8c.html#a7cf929399abd068757e3d916ca9e034e">More...</a><br /></td></tr>
<tr class="separator:a7cf929399abd068757e3d916ca9e034e"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a38b339ba5e30f1e04eb52e3fcae416a2"><td class="memItemLeft" align="right" valign="top">static void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="bootloader_8c.html#a38b339ba5e30f1e04eb52e3fcae416a2">check_update</a> ()</td></tr>
<tr class="memdesc:a38b339ba5e30f1e04eb52e3fcae416a2"><td class="mdescLeft">&#160;</td><td class="mdescRight">Check for an update, if an update is found, perform it. <a href="bootloader_8c.html#a38b339ba5e30f1e04eb52e3fcae416a2">More...</a><br /></td></tr>
<tr class="separator:a38b339ba5e30f1e04eb52e3fcae416a2"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a840291bc02cba5474a4cb46a9b9566fe"><td class="memItemLeft" align="right" valign="top">int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="bootloader_8c.html#a840291bc02cba5474a4cb46a9b9566fe">main</a> (void)</td></tr>
<tr class="memdesc:a840291bc02cba5474a4cb46a9b9566fe"><td class="mdescLeft">&#160;</td><td class="mdescRight">The bootloader entry point. <a href="bootloader_8c.html#a840291bc02cba5474a4cb46a9b9566fe">More...</a><br /></td></tr>
<tr class="separator:a840291bc02cba5474a4cb46a9b9566fe"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="var-members" name="var-members"></a>
Variables</h2></td></tr>
<tr class="memitem:a37d4a9c3115f43a3e2b3e102bc81b48f"><td class="memItemLeft" align="right" valign="top"><a id="a37d4a9c3115f43a3e2b3e102bc81b48f" name="a37d4a9c3115f43a3e2b3e102bc81b48f"></a>
uint8_t&#160;</td><td class="memItemRight" valign="bottom"><b>application_start</b></td></tr>
<tr class="memdesc:a37d4a9c3115f43a3e2b3e102bc81b48f"><td class="mdescLeft">&#160;</td><td class="mdescRight">Start of Application region in flash. <br /></td></tr>
<tr class="separator:a37d4a9c3115f43a3e2b3e102bc81b48f"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aaaf4eda13ed1d5a1e8fcefbc9d9f4bd6"><td class="memItemLeft" align="right" valign="top"><a id="aaaf4eda13ed1d5a1e8fcefbc9d9f4bd6" name="aaaf4eda13ed1d5a1e8fcefbc9d9f4bd6"></a>
uint8_t&#160;</td><td class="memItemRight" valign="bottom"><b>application_end</b></td></tr>
<tr class="memdesc:aaaf4eda13ed1d5a1e8fcefbc9d9f4bd6"><td class="mdescLeft">&#160;</td><td class="mdescRight">End of Application region in flash. <br /></td></tr>
<tr class="separator:aaaf4eda13ed1d5a1e8fcefbc9d9f4bd6"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a83329d26ababd34a8e4a2af7df10e35a"><td class="memItemLeft" align="right" valign="top">static uint8_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="bootloader_8c.html#a83329d26ababd34a8e4a2af7df10e35a">segment_buffer</a> [<a class="el" href="bootloader_8c.html#a79f8ce89914364edcd444bad719e909d">MAX_SEGMENT_SIZE</a>]</td></tr>
<tr class="memdesc:a83329d26ababd34a8e4a2af7df10e35a"><td class="mdescLeft">&#160;</td><td class="mdescRight">Temporary buffer for loading segments. <a href="bootloader_8c.html#a83329d26ababd34a8e4a2af7df10e35a">More...</a><br /></td></tr>
<tr class="separator:a83329d26ababd34a8e4a2af7df10e35a"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aac44c88f1f923d025044ec2bd6740e20"><td class="memItemLeft" align="right" valign="top">static uint8_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="bootloader_8c.html#aac44c88f1f923d025044ec2bd6740e20">deflate_buffer</a> [<a class="el" href="bootloader_8c.html#a79f8ce89914364edcd444bad719e909d">MAX_SEGMENT_SIZE</a>]</td></tr>
<tr class="memdesc:aac44c88f1f923d025044ec2bd6740e20"><td class="mdescLeft">&#160;</td><td class="mdescRight">Temporary buffer for deflating segments. <a href="bootloader_8c.html#aac44c88f1f923d025044ec2bd6740e20">More...</a><br /></td></tr>
<tr class="separator:aac44c88f1f923d025044ec2bd6740e20"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
<h2 class="groupheader">Macro Definition Documentation</h2>
<a id="a79f8ce89914364edcd444bad719e909d" name="a79f8ce89914364edcd444bad719e909d"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a79f8ce89914364edcd444bad719e909d">&#9670;&nbsp;</a></span>MAX_SEGMENT_SIZE</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">#define MAX_SEGMENT_SIZE&#160;&#160;&#160;32768</td>
</tr>
</table>
</div><div class="memdoc">
<p>Maximum size of a segment, set to 32768. </p>
<p class="definition">Definition at line <a class="el" href="bootloader_8c_source.html#l00078">78</a> of file <a class="el" href="bootloader_8c_source.html">bootloader.c</a>.</p>
</div>
</div>
<a id="a6cc84937ff76b5c7eafccff861c09110" name="a6cc84937ff76b5c7eafccff861c09110"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a6cc84937ff76b5c7eafccff861c09110">&#9670;&nbsp;</a></span>MAX_UPDATE_ATTEMPTS</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">#define MAX_UPDATE_ATTEMPTS&#160;&#160;&#160;10</td>
</tr>
</table>
</div><div class="memdoc">
<p>Maximum number of times we attempt to update before giving up. </p>
<p class="definition">Definition at line <a class="el" href="bootloader_8c_source.html#l00075">75</a> of file <a class="el" href="bootloader_8c_source.html">bootloader.c</a>.</p>
</div>
</div>
<h2 class="groupheader">Enumeration Type Documentation</h2>
<a id="a9c2734c8641676d2dcc02b82fc9a25a3" name="a9c2734c8641676d2dcc02b82fc9a25a3"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a9c2734c8641676d2dcc02b82fc9a25a3">&#9670;&nbsp;</a></span>bootloader_return_codes</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">enum <a class="el" href="bootloader_8c.html#a9c2734c8641676d2dcc02b82fc9a25a3">bootloader_return_codes</a></td>
</tr>
</table>
</div><div class="memdoc">
<p>Bootloader return codes. </p>
<p class="definition">Definition at line <a class="el" href="bootloader_8c_source.html#l00081">81</a> of file <a class="el" href="bootloader_8c_source.html">bootloader.c</a>.</p>
</div>
</div>
<h2 class="groupheader">Function Documentation</h2>
<a id="a4216c0860ba47882f9a2dc002bcff4d5" name="a4216c0860ba47882f9a2dc002bcff4d5"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a4216c0860ba47882f9a2dc002bcff4d5">&#9670;&nbsp;</a></span>blink_error_code()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">static void blink_error_code </td>
<td>(</td>
<td class="paramtype">int&#160;</td>
<td class="paramname"><em>code</em></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">static</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Blinks the hardware error LED to indicate the error code. </p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">code</td><td>The error code to blink. </td></tr>
</table>
</dd>
</dl>
<p class="definition">Definition at line <a class="el" href="bootloader_8c_source.html#l00130">130</a> of file <a class="el" href="bootloader_8c_source.html">bootloader.c</a>.</p>
</div>
</div>
<a id="a38b339ba5e30f1e04eb52e3fcae416a2" name="a38b339ba5e30f1e04eb52e3fcae416a2"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a38b339ba5e30f1e04eb52e3fcae416a2">&#9670;&nbsp;</a></span>check_update()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">static void check_update </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">static</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Check for an update, if an update is found, perform it. </p>
<p class="definition">Definition at line <a class="el" href="bootloader_8c_source.html#l00550">550</a> of file <a class="el" href="bootloader_8c_source.html">bootloader.c</a>.</p>
</div>
</div>
<a id="ad7adf72f0188214738b18073dbf9a0df" name="ad7adf72f0188214738b18073dbf9a0df"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ad7adf72f0188214738b18073dbf9a0df">&#9670;&nbsp;</a></span>delay_ms()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">static void delay_ms </td>
<td>(</td>
<td class="paramtype">uint32_t&#160;</td>
<td class="paramname"><em>approx_delay_ms</em></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">static</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Implements a delay of approximately the duration specified. </p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">approx_delay_ms</td><td>The delay in ms. </td></tr>
</table>
</dd>
</dl>
<p class="definition">Definition at line <a class="el" href="bootloader_8c_source.html#l00113">113</a> of file <a class="el" href="bootloader_8c_source.html">bootloader.c</a>.</p>
</div>
</div>
<a id="a3fff6197c0b420e41cb8c6ca32b58bbe" name="a3fff6197c0b420e41cb8c6ca32b58bbe"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a3fff6197c0b420e41cb8c6ca32b58bbe">&#9670;&nbsp;</a></span>erase_application_area()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">static void erase_application_area </td>
<td>(</td>
<td class="paramtype">void&#160;</td>
<td class="paramname"></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">static</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>This function erases the entire application flash region. </p>
<p >We erase everything in one go as we don't want to deal with overlapping segments in the MBIN file. If a segment overlaps we need to take care that we don't erase the same flash block twice (or we lose the data data for the previous segment due to the overlap). We avoid this issue by erasing everything in one go at the start. </p>
<p class="definition">Definition at line <a class="el" href="bootloader_8c_source.html#l00184">184</a> of file <a class="el" href="bootloader_8c_source.html">bootloader.c</a>.</p>
</div>
</div>
<a id="aa561c09fdf6feb3346f48f9925cc822e" name="aa561c09fdf6feb3346f48f9925cc822e"></a>
<h2 class="memtitle"><span class="permalink"><a href="#aa561c09fdf6feb3346f48f9925cc822e">&#9670;&nbsp;</a></span>load_and_flash_mbin()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">static int load_and_flash_mbin </td>
<td>(</td>
<td class="paramtype">const char *&#160;</td>
<td class="paramname"><em>fname</em>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype">bool&#160;</td>
<td class="paramname"><em>make_changes</em>&#160;</td>
</tr>
<tr>
<td></td>
<td>)</td>
<td></td><td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">static</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Loads and flashes the image. </p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">fname</td><td>MBIN file to load </td></tr>
<tr><td class="paramname">make_changes</td><td>If make_changes is false then flash will not be written to </td></tr>
</table>
</dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>BOOTLOADER_OK on success, else error code </dd></dl>
<p class="definition">Definition at line <a class="el" href="bootloader_8c_source.html#l00263">263</a> of file <a class="el" href="bootloader_8c_source.html">bootloader.c</a>.</p>
</div>
</div>
<a id="a840291bc02cba5474a4cb46a9b9566fe" name="a840291bc02cba5474a4cb46a9b9566fe"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a840291bc02cba5474a4cb46a9b9566fe">&#9670;&nbsp;</a></span>main()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">int main </td>
<td>(</td>
<td class="paramtype">void&#160;</td>
<td class="paramname"></td><td>)</td>
<td></td>
</tr>
</table>
</div><div class="memdoc">
<p>The bootloader entry point. </p>
<dl class="section return"><dt>Returns</dt><dd>Does not return </dd></dl>
<p class="definition">Definition at line <a class="el" href="bootloader_8c_source.html#l00620">620</a> of file <a class="el" href="bootloader_8c_source.html">bootloader.c</a>.</p>
</div>
</div>
<a id="a39140ce852070800f265073418f49fad" name="a39140ce852070800f265073418f49fad"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a39140ce852070800f265073418f49fad">&#9670;&nbsp;</a></span>read_segment_header()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">static int read_segment_header </td>
<td>(</td>
<td class="paramtype">int&#160;</td>
<td class="paramname"><em>fd</em>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype">struct <a class="el" href="structmbin__tlv__hdr.html">mbin_tlv_hdr</a> *&#160;</td>
<td class="paramname"><em>seg_hdr</em>&#160;</td>
</tr>
<tr>
<td></td>
<td>)</td>
<td></td><td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">static</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Loads the segment header from file. </p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">fd</td><td>The file descriptor to read from </td></tr>
<tr><td class="paramname">seg_hdr</td><td>Pointer to segment header to read data into </td></tr>
</table>
</dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>BOOTLOADER_OK on success, else error code </dd></dl>
<p class="definition">Definition at line <a class="el" href="bootloader_8c_source.html#l00218">218</a> of file <a class="el" href="bootloader_8c_source.html">bootloader.c</a>.</p>
</div>
</div>
<a id="ae056e191483eb2bd384b33251e74ab98" name="ae056e191483eb2bd384b33251e74ab98"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ae056e191483eb2bd384b33251e74ab98">&#9670;&nbsp;</a></span>read_uint32()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">static int read_uint32 </td>
<td>(</td>
<td class="paramtype">int&#160;</td>
<td class="paramname"><em>fd</em>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype">uint32_t *&#160;</td>
<td class="paramname"><em>val</em>&#160;</td>
</tr>
<tr>
<td></td>
<td>)</td>
<td></td><td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">static</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Loads a 32 bit integer from file and converts to host endian. </p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">fd</td><td>The file descriptor to read from </td></tr>
<tr><td class="paramname">val</td><td>Pointer to variable to read data into </td></tr>
</table>
</dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>BOOTLOADER_OK on success, else error code </dd></dl>
<p class="definition">Definition at line <a class="el" href="bootloader_8c_source.html#l00241">241</a> of file <a class="el" href="bootloader_8c_source.html">bootloader.c</a>.</p>
</div>
</div>
<a id="aee64527bc3ac3493e545088bfddd20dd" name="aee64527bc3ac3493e545088bfddd20dd"></a>
<h2 class="memtitle"><span class="permalink"><a href="#aee64527bc3ac3493e545088bfddd20dd">&#9670;&nbsp;</a></span>update_failed()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">static void update_failed </td>
<td>(</td>
<td class="paramtype">int&#160;</td>
<td class="paramname"><em>code</em></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">static</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Called when multiple attempts to update failed, must not return. </p>
<p >This function <em>could</em> try rebooting after a fixed delay and the update process can be retried by the bootloader. However the delay should be sufficiently large (several minutes at least) as it is likely that whatever caused us to fail will happen again, so spamming the flash with multiple attempts is not a good idea.</p>
<p >We usually end up in this function if we had a hardware failure, like a flash failure. So the problem is likely to happen again and will possibly get worse with each attempt.</p>
<p >We do not end up in this function if sanity checks (Like image checksum) prior to updating failed. If that happens we simply continue to the existing application with an error code stored in config store. Once the flash is erased, any failure will get us here.</p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">code</td><td>The error code, gets written to config store and blinked. </td></tr>
</table>
</dd>
</dl>
<p class="definition">Definition at line <a class="el" href="bootloader_8c_source.html#l00164">164</a> of file <a class="el" href="bootloader_8c_source.html">bootloader.c</a>.</p>
</div>
</div>
<a id="a7cf929399abd068757e3d916ca9e034e" name="a7cf929399abd068757e3d916ca9e034e"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a7cf929399abd068757e3d916ca9e034e">&#9670;&nbsp;</a></span>verify_signature()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">static int verify_signature </td>
<td>(</td>
<td class="paramtype">const char *&#160;</td>
<td class="paramname"><em>fname</em></td><td>)</td>
<td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">static</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Verifies the signature of the file. </p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">fname</td><td>MBIN file to verify </td></tr>
</table>
</dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>BOOTLOADER_OK on success, else error code </dd></dl>
<p class="definition">Definition at line <a class="el" href="bootloader_8c_source.html#l00501">501</a> of file <a class="el" href="bootloader_8c_source.html">bootloader.c</a>.</p>
</div>
</div>
<h2 class="groupheader">Variable Documentation</h2>
<a id="aac44c88f1f923d025044ec2bd6740e20" name="aac44c88f1f923d025044ec2bd6740e20"></a>
<h2 class="memtitle"><span class="permalink"><a href="#aac44c88f1f923d025044ec2bd6740e20">&#9670;&nbsp;</a></span>deflate_buffer</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">uint8_t deflate_buffer[<a class="el" href="bootloader_8c.html#a79f8ce89914364edcd444bad719e909d">MAX_SEGMENT_SIZE</a>]</td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">static</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Temporary buffer for deflating segments. </p>
<p class="definition">Definition at line <a class="el" href="bootloader_8c_source.html#l00105">105</a> of file <a class="el" href="bootloader_8c_source.html">bootloader.c</a>.</p>
</div>
</div>
<a id="a83329d26ababd34a8e4a2af7df10e35a" name="a83329d26ababd34a8e4a2af7df10e35a"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a83329d26ababd34a8e4a2af7df10e35a">&#9670;&nbsp;</a></span>segment_buffer</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">uint8_t segment_buffer[<a class="el" href="bootloader_8c.html#a79f8ce89914364edcd444bad719e909d">MAX_SEGMENT_SIZE</a>]</td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">static</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Temporary buffer for loading segments. </p>
<p class="definition">Definition at line <a class="el" href="bootloader_8c_source.html#l00102">102</a> of file <a class="el" href="bootloader_8c_source.html">bootloader.c</a>.</p>
</div>
</div>
</div><!-- contents -->
</div><!-- doc-content -->
<!-- HTML footer for doxygen 1.8.17-->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
<ul>
<li class="navelem"><a class="el" href="dir_91b8f418cff946e8d8b598a9068417a8.html">examples</a></li><li class="navelem"><a class="el" href="dir_12cf38ffbeb76538c5f7506fe6735d1c.html">bootloader</a></li><li class="navelem"><a class="el" href="dir_cefeded39835002f59726db72b8a31dd.html">src</a></li><li class="navelem"><a class="el" href="bootloader_8c.html">bootloader.c</a></li>
<li class="footer">Copyright 2021 Morse Micro </li>
</ul>
</div>
</body>
</html>