<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Mahavir Jain on Medium]]></title>
        <description><![CDATA[Stories by Mahavir Jain on Medium]]></description>
        <link>https://medium.com/@mahavirj?source=rss-e94f74442319------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*4-yW51bt-rA9cW8_MhdYLw.jpeg</url>
            <title>Stories by Mahavir Jain on Medium</title>
            <link>https://medium.com/@mahavirj?source=rss-e94f74442319------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 22:52:07 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@mahavirj/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Software Bill of Materials]]></title>
            <link>https://medium.com/the-esp-journal/software-bill-of-materials-b1282a58e617?source=rss-e94f74442319------2</link>
            <guid isPermaLink="false">https://medium.com/p/b1282a58e617</guid>
            <category><![CDATA[iot]]></category>
            <category><![CDATA[security]]></category>
            <category><![CDATA[tools]]></category>
            <category><![CDATA[esp-idf]]></category>
            <category><![CDATA[esp32]]></category>
            <dc:creator><![CDATA[Mahavir Jain]]></dc:creator>
            <pubDate>Fri, 03 Nov 2023 09:55:22 GMT</pubDate>
            <atom:updated>2023-11-03T09:55:22.685Z</atom:updated>
            <content:encoded><![CDATA[<h3>Overview</h3><p>The “software bill of materials” (SBOM) has emerged as a key building block in software security and <a href="https://en.wikipedia.org/wiki/Software_supply_chain">software supply chain</a> risk management. An SBOM is a comprehensive list of all the software components, dependencies, and metadata associated with an application.</p><p>Espressif believes that this information is a key step towards ensuring the security of the connected devices. And as such, we have now enabled easy to use tools and solutions to track and analyze this information.</p><p>In this blog post, we shall look through the Espressif’s SBOM generator and analysis tool, <a href="https://github.com/espressif/esp-idf-sbom"><strong>ESP-IDF-SBOM</strong></a>.</p><h3>SBOM</h3><p>According to National Telecommunications and Information Administration’s (NTIA) SBOM FAQ, the official definition of SBOM goes as follows:</p><blockquote>A Software Bill of Materials (SBOM) is a complete, formally structured list of components, libraries, and modules that are required to build (i.e., compile and link) a given piece of software and the supply chain relationships between them. These components can be open source or proprietary, free or paid, and widely available or restricted access.</blockquote><p>Key data fields for each component includes:</p><ul><li>Supplier Name</li><li>Component Name</li><li>Version of the Component</li><li>Other Unique Identifiers</li><li>Dependency Relationship</li><li>Author of SBOM Data</li><li>Timestamp</li></ul><p>SBOM data needs to be presented in consistent and digestible formats. Some formats to handle the data representation are SPDX, CycloneDX etc.</p><p>Simple conceptual SBOM tree for wifi_provisioning component from ESP-IDF looks like below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/709/1*0e3Rufb8-nU-px5RM6htJg.png" /></figure><h3>SPDX</h3><p><a href="https://spdx.github.io/spdx-spec/v2.3/">Software Package Data Exchange</a> (SPDX) is an open standard for communicating software bill of materials (SBOM) information that supports accurate identification of software components, explicit mapping of relationships between components, and the association of security and licensing information with each component.</p><p>The image below outlines what data can be found in an SPDX document.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/383/0*FKOMwJwXJqTbwsRq.png" /><figcaption>Image via <a href="https://spdx.dev/specifications/?ref=fossa.com">SPDX website</a></figcaption></figure><h3>ESP-IDF-SBOM</h3><p><a href="https://github.com/espressif/esp-idf-sbom">ESP-IDF-SBOM</a> is a SBOM generator tool. It generates SPDX format SBOM for ESP-IDF based applications. This tool also allows to check the generated SBOM for known security vulnerabilities against <a href="https://nvd.nist.gov/">National Vulnerabilitiy Database</a> (NVD).</p><h3>SBOM Generator Workflow</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/679/1*gDN-5UHIsn4vxNnwQx2TDg.png" /></figure><p>Brief tool workflow goes like:</p><ul><li>Collect sbom.yml (<a href="https://github.com/espressif/esp-idf-sbom#manifest-file">a manifest file</a>) files from dependant components</li><li>Parse project description file generated by the ESP-IDF build system</li><li>Generate SPDX report</li><li>Scan generated SPDX against the CVE databse to generate final report</li></ul><h3>Getting Started</h3><p>Install the tool and checkout its help:</p><pre>$ pip install esp-idf-sbom<br>$ esp-idf-sbom --help<br><br>usage: esp-idf-sbom [-h] [-q] [-n] [-f] [-v] [-d] [--no-progress] {create,check,manifest} ...<br><br>ESP-IDF SBOM tool<br><br>positional arguments:<br>  {create,check,manifest}<br>                        sub-command help<br>    create              Create SBOM file based on the ESP-IDF project_description.json file.<br>    check               Check components/submodules in the ESP-IDF SBOM file for possible<br>                        vulnerabilities reported in the National Vulnerability Database.<br>    manifest            Commands operating atop of manifest files.<br><br>options:<br>  -h, --help            show this help message and exit<br>  -q, --quiet           By default auxiliary messages like errors, warnings, debug messages<br>                        or progress are reported to the standard error stream. With this<br>                        option set, all such messages are suppressed.<br>  -n, --no-colors       Do not emit color codes. By default color codes are used when stdout<br>                        or stderr is connected to a terminal.<br>  -f, --force-colors    Emit color codes even when stdout or stderr is not connected to a<br>                        terminal.<br>  -v, --verbose         Be verbose. Messages are printed to standard error output.<br>  -d, --debug           Print debug information. Messages are printed to standard error<br>                        output.<br>  --no-progress         Disable progress bar.</pre><p>Generate the SBOM file:</p><pre>$ cd esp-idf/examples/provisioning/wifi_prov_mgr<br>$ idf.py build<br>$ esp-idf-sbom create &lt;project description file&gt; --output-file prj.spdx</pre><p>The project description file is a path to the project_description.json file, which is by default created by the ESP-IDF build system in the project&#39;s build directory.</p><p>Check SBOM against the security vulnerabilities:</p><pre>$ esp-idf-sbom check prj.spdx<br><br>                                        Report summary                                         <br>┌───────────────────────────────────┬─────────────────────────────────────────────────────────┐<br>│ Date:                             │ 2023-10-10T08:21:39Z                                    │<br>│ Project name:                     │ project-wifi_prov_mgr                                   │<br>│ Project version:                  │ v5.2-dev-3250-g7d8f015a4c                               │<br>│ Vulnerability database:           │ NATIONAL VULNERABILITY DATABASE (https://nvd.nist.gov)  │<br>│ Generated by tool:                │ esp-idf-sbom (0.8.0)                                    │<br>│ Generated with command:           │ esp-idf-sbom check prj.spdx                             │<br>│ Number of scanned packages:       │ 57                                                      │<br>├───────────────────────────────────┼─────────────────────────────────────────────────────────┤<br>│ CRITICAL CVEs found:              │                                                         │<br>│ Packages affect by CRITICAL CVEs: │                                                         │<br>│ Number of CRITICAL CVEs:          │ 0                                                       │<br>├───────────────────────────────────┼─────────────────────────────────────────────────────────┤<br>│ HIGH CVEs found:                  │                                                         │<br>│ Packages affect by HIGH CVEs:     │                                                         │<br>│ Number of HIGH CVEs:              │ 0                                                       │<br>├───────────────────────────────────┼─────────────────────────────────────────────────────────┤<br>│ MEDIUM CVEs found:                │                                                         │<br>│ Packages affect by MEDIUM CVEs:   │                                                         │<br>│ Number of MEDIUM CVEs:            │ 0                                                       │<br>├───────────────────────────────────┼─────────────────────────────────────────────────────────┤<br>│ LOW CVEs found:                   │                                                         │<br>│ Packages affect by LOW CVEs:      │                                                         │<br>│ Number of LOW CVEs:               │ 0                                                       │<br>├───────────────────────────────────┼─────────────────────────────────────────────────────────┤<br>│ UNKNOWN CVEs found:               │                                                         │<br>│ Packages affect by UNKNOWN CVEs:  │                                                         │<br>│ Number of UNKNOWN CVEs:           │ 0                                                       │<br>├───────────────────────────────────┼─────────────────────────────────────────────────────────┤<br>│ All CVEs found:                   │                                                         │<br>│ All packages affect by CVEs:      │                                                         │<br>│ Total number of CVEs:             │ 0                                                       │<br>└───────────────────────────────────┴─────────────────────────────────────────────────────────┘<br><br><br>Packages with No Identified Vulnerabilities<br>                        <br>┏━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓<br>┃        Package        ┃          Version          ┃                   CPE                   ┃<br>┡━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩<br>│ project-wifi_prov_mgr │ v5.2-dev-3250-g7d8f015a4c │ cpe:2.3:a:espressif:esp-idf:5.2-dev-325 │<br>│                       │                           │       0-g7d8f015a4c:*:*:*:*:*:*:*       │<br>├───────────────────────┼───────────────────────────┼─────────────────────────────────────────┤<br>│         lwip          │           2.1.3           │ cpe:2.3:a:lwip_project:lwip:2.1.3:*:*:* │<br>│                       │                           │                :*:*:*:*                 │<br>├───────────────────────┼───────────────────────────┼─────────────────────────────────────────┤<br>│         cjson         │          1.7.16           │ cpe:2.3:a:cjson_project:cjson:1.7.16:*: │<br>│                       │                           │               *:*:*:*:*:*               │<br>├───────────────────────┼───────────────────────────┼─────────────────────────────────────────┤<br>│      protobuf-c       │           1.4.1           │ cpe:2.3:a:protobuf-c_project:protobuf-c │<br>│                       │                           │          :1.4.1:*:*:*:*:*:*:*           │<br>├───────────────────────┼───────────────────────────┼─────────────────────────────────────────┤<br>│       mbed_tls        │           3.4.1           │ cpe:2.3:a:arm:mbed_tls:3.4.1:*:*:*:*:*: │<br>│                       │                           │                   *:*                   │<br>├───────────────────────┼───────────────────────────┼─────────────────────────────────────────┤<br>│       freertos        │          10.4.3           │ cpe:2.3:o:amazon:freertos:10.4.3:*:*:*: │<br>│                       │                           │                 *:*:*:*                 │<br>└───────────────────────┴───────────────────────────┴─────────────────────────────────────────┘<br><br>...snip</pre><p>Some highlights from the SBOM vulnerability check:</p><ul><li>wifi_prov_mgr application from ESP-IDF v5.2-dev was used for the exercise</li><li>It is possible to scan the components which are not linked into final executable by adding --check-all-packages in the check command shown above</li><li>It is also possible to generate the SBOM report for the ESP-IDF bootloader. Bootloader specific build description file can be found in the build/bootloader directory inside the project</li><li>Some key components like RTOS, Networking Stack, TLS Stack etc. having <a href="https://nvd.nist.gov/products/cpe/search">Common Platform Enumeration</a> entries have been highlighted in the above output</li><li>Tool also displays information about other component and libraries (not shown in the above log) which are part of the build process</li></ul><h3>Report Format</h3><p>This tool supports multiple formats for the generated output report like JSON, CSV etc. Please refer to the tool help for more details.</p><h3>Compatibility</h3><p>SPDX being a standard format for SBOM, also offers compatibility with the external tools. SBOM files generated from esp-idf-sbom can also be scanned using tools like <a href="https://github.com/intel/cve-bin-tool">cve-bin-tool</a>. This offers an added advantage if you already have any external tools integrated in your system and want to take advantage of its specific features (e.g., more extended scan against different CVE databases).</p><h3>Summary</h3><p>To summarize, some key advantages of SBOM are:</p><ul><li>Forms inventory of the components building the software artifacts</li><li>Lists software licenses, component versions and helps to keep them up-to-date</li><li>Helps to perform security vulnerability analysis</li><li>Becoming a pre-requisite in many security related certifications</li></ul><p><a href="https://github.com/espressif/esp-idf-sbom">ESP-IDF-SBOM</a> tool is useful to generate SBOM for ESP-IDF based projects. The tool can also further help to scan and setup process for continuous security vulnerability scanning of the project.</p><p>We are actively working on to enable wider SBOM coverage across our software solutions and looking for feedback on the <strong>ESP-IDF-SBOM</strong> tool.</p><p>Please do try and share your experience!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b1282a58e617" width="1" height="1" alt=""><hr><p><a href="https://medium.com/the-esp-journal/software-bill-of-materials-b1282a58e617">Software Bill of Materials</a> was originally published in <a href="https://medium.com/the-esp-journal">The ESP Journal</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Secure Signing Using External HSM]]></title>
            <link>https://medium.com/the-esp-journal/secure-signing-using-external-hsm-ebe855a2f2ef?source=rss-e94f74442319------2</link>
            <guid isPermaLink="false">https://medium.com/p/ebe855a2f2ef</guid>
            <category><![CDATA[security]]></category>
            <category><![CDATA[esp32]]></category>
            <category><![CDATA[iot]]></category>
            <category><![CDATA[esptool]]></category>
            <dc:creator><![CDATA[Mahavir Jain]]></dc:creator>
            <pubDate>Fri, 10 Feb 2023 15:44:00 GMT</pubDate>
            <atom:updated>2023-02-10T15:44:00.712Z</atom:updated>
            <content:encoded><![CDATA[<h3>Overview</h3><p>ESP32 series of chips supports secure boot scheme to allow only trusted firmware to execute from its flash storage. However, this requires careful management of the secure signing key, it must be generated and stored in a secure manner by the signing entity.</p><p>External <a href="https://en.wikipedia.org/wiki/Hardware_security_module">HSM</a> (Hardware Security Module) is specially designed cryptographic device that safeguards and manages secrets. HSM also provides specialised cryptographic services like encryption, digital signing etc. Now a days, there are cloud services being offered that provide cloud HSM based solutions.</p><h3>External HSM Signing</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/870/1*jcuWoW6218qkkIMtCb2K0A.png" /><figcaption>Espsecure.py: Signing Using External HSM</figcaption></figure><p>External HSM offers a standard <a href="https://en.wikipedia.org/wiki/PKCS_11">PKCS #11</a> based cryptographic interface for availing various services like signing the firmware. With PKCS #11 interface, external HSM could also be a remote cloud HSM based service over the network.</p><ul><li>Espsecure.py script (part of <a href="https://github.com/espressif/esptool">Esptool</a> project) has been integrated with standard PKCS #11 interface and thus ensures interoperability with any external HSM for getting the ESP32&#39;s firmware signed.</li><li>Please note that, as shown in the above diagram path of the vendor specific PKCS #11 library must be provided in the Espsecure.py configuration to use HSM mode.</li><li>The initial support allows to generate signed application as per our Secure Boot V2 scheme with either RSA-PSS 3072 or ESDSA NISTP256 algorithm.</li></ul><h3>Signing Using YubiKey</h3><p>We will be using <a href="https://www.yubico.com/products/yubikey-5-overview/">YubiKey</a> 5 Series as an external HSM for demonstration here.</p><h4>Installation</h4><p>Please find detailed setup guide for YubiKey host tool and PKCS #11 library setup <a href="https://developers.yubico.com/yubico-piv-tool/">here</a>.</p><p>Note: Following are verified steps for Ubuntu 22.10 OS</p><pre># Install esptool 4.5 release along with HSM dependencies<br>pip install esptool[hsm]==4.5.dev3<br><br># Install tools and PKCS#11 interface library<br>sudo apt install yubico-piv-tool ykcs11<br><br># Generate ECC P256 private key in the 9c (digital signature) slot<br>yubico-piv-tool -a generate -s 9c -A ECCP256</pre><h4>HSM config file</h4><p>Following is a HSM config file that we shall pass to espsecure.py</p><pre>$ cat hsm_cfg.ini<br><br># Config file for the external YubiKey based Hardware Security Module<br>[hsm_config]<br># PKCS11 shared object/library<br>pkcs11_lib = /usr/lib/x86_64-linux-gnu/libykcs11.so<br># HSM login credentials (default YubiKey pin)<br>credentials = 123456<br># Slot number to be used (default YubiKey slot)<br>slot = 0<br># Label of the object used to store the private key (default)<br>label = Private key for Digital Signature<br># Label of the object used to store corresponding public key (default)<br>label_pubkey = Public key for Digital Signature</pre><p><em>Please check directory where </em><em>libykcs11.so is installed on your system and update the path accordingly.</em></p><h4>Generate signature</h4><p>Following command helps to sign the binary using configuration supplied in the hsm_cfg.ini file</p><pre>$ espsecure.py sign_data --version 2 --hsm --hsm-config hsm_cfg.ini --output signed.bin unsigned.bin <br><br>espsecure.py v4.5-dev<br>Trying to establish a session with the HSM.<br>Session creation successful with HSM slot 0.<br>Trying to extract public key from the HSM.<br>Got public key with label Public key for Digital Signature.<br>Connection closed successfully<br>Trying to establish a session with the HSM.<br>Session creation successful with HSM slot 0.<br>Got private key metadata with label Private key for Digital Signature.<br>Signing payload using the HSM.<br>Signature generation successful.<br>Connection closed successfully<br>Pre-calculated signatures found<br>1 signing key(s) found.<br>Signed 65536 bytes of data from unsigned.bin. Signature sector now has 1 signature blocks.</pre><h4>Verify signature</h4><p>For sanity purpose, we can verify the signature using public key from the external HSM</p><pre>$ espsecure.py verify_signature --version 2 --hsm --hsm-config hsm_cfg.ini signed.bin <br><br>espsecure.py v4.5-dev<br>Trying to establish a session with the HSM.<br>Session creation successful with HSM slot 0.<br>Trying to extract public key from the HSM.<br>Got public key with label Public key for Digital Signature.<br>Connection closed successfully<br>Signature block 0 is valid (ECDSA).<br>Signature block 0 verification successful using the supplied key (ECDSA).</pre><h3>Documentation</h3><p>Please refer to the Esptool documentation <a href="https://docs.espressif.com/projects/esptool/en/latest/esp32/espsecure/index.html#remote-signing-using-an-external-hsm">here</a> for more details.</p><p>Please note that this feature shall be available in Esptool v4.5 release. For now, you may use Esptool dev release using pip install esptool[hsm]==4.5.dev3to try out this feature.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ebe855a2f2ef" width="1" height="1" alt=""><hr><p><a href="https://medium.com/the-esp-journal/secure-signing-using-external-hsm-ebe855a2f2ef">Secure Signing Using External HSM</a> was originally published in <a href="https://medium.com/the-esp-journal">The ESP Journal</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[OTA Updates Framework]]></title>
            <link>https://medium.com/the-esp-journal/ota-updates-framework-ab5438e30c12?source=rss-e94f74442319------2</link>
            <guid isPermaLink="false">https://medium.com/p/ab5438e30c12</guid>
            <category><![CDATA[esp-idf]]></category>
            <category><![CDATA[firmware]]></category>
            <category><![CDATA[esp32]]></category>
            <category><![CDATA[iot]]></category>
            <category><![CDATA[embedded-systems]]></category>
            <dc:creator><![CDATA[Mahavir Jain]]></dc:creator>
            <pubDate>Wed, 23 Dec 2020 16:01:51 GMT</pubDate>
            <atom:updated>2020-12-23T16:01:51.265Z</atom:updated>
            <content:encoded><![CDATA[<p>In this post we will discuss the design and internal workings of Over-The-Air (OTA) Updates framework in ESP-IDF.</p><p>We shall also cover some of the features from OTA updates, focused around <strong>reliability</strong> and <strong>security</strong> that can help to build better IoT products with ESP32.</p><h3>Background Information</h3><p>Lets cover some basic information essential for understanding the overall OTA update procedure.</p><h4>Partition Table &amp; Flash Layout</h4><p>The <a href="https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/partition-tables.html">Partition table</a> defines the flash layout on ESP32. Applications can specify its desired flash layout using simple CSV files. A template looks like below:</p><pre># Name,   Type, SubType, Offset,   Size, Flags<br># Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap<br>nvs,      data, nvs,     ,        0x4000,<br>otadata,  data, ota,     ,        0x2000,<br>phy_init, data, phy,     ,        0x1000,<br>ota_0,    app,  ota_0,   ,        1M,<br>ota_1,    app,  ota_1,   ,        1M,</pre><p><strong>Important points to note:</strong></p><ul><li>A binary partition table image is generated using the above CSV file. This occupies 4KiB (single flash sector) and is located at offset 0x9000 in default configuration. First 8 sectors (32KiB), before this, are reserved for the bootloader image.</li><li>If more space is desired for bootloader, then the partition table offset can be adjusted using configuration option CONFIG_PARTITION_TABLE_OFFSET.</li><li>Partitions ota_0 and ota_1 denote active and passive versions for application firmware. Identical copies ensure power safety during OTA updates.</li><li>Application image partitions (ota_0/ota_1) are always adjusted to align on 64 KiB boundary, as that is the page size for flash cache mapping.</li><li>Even though factory partition is supported, we will not be considering it, as that partition is not supported in anti-rollback scheme. If required, that logic can be coupled in primary firmware itself.</li><li>For simplicity we will also not consider multiple firmware partitions (total 16) even though they are supported in ESP-IDF.</li></ul><p>Visual representation of above configuration for 4MiB flash part is shown below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/791/1*QbWq_jQkSgwwwl170AQvuw.png" /><figcaption>Typical application flash layout</figcaption></figure><h4>Application Image Format</h4><p>A detailed documentation can be found <a href="https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/app_image_format.html"><strong>here</strong></a><strong>, </strong>whereas, here we will only consider interesting bits that are applicable for this discussion.</p><p>Following is the application image descriptor (present at offset 0x20 in application image):</p><pre>typedef struct {<br>    uint32_t magic_word;        /*!&lt; Magic word ESP_APP_DESC_MAGIC_WORD */<br>    uint32_t secure_version;    /*!&lt; Secure version */<br>    uint32_t reserv1[2];        /*!&lt; reserv1 */<br>    char version[32];           /*!&lt; Application version */<br>    char project_name[32];      /*!&lt; Project name */<br>    char time[16];              /*!&lt; Compile time */<br>    char date[16];              /*!&lt; Compile date*/<br>    char idf_ver[32];           /*!&lt; Version IDF */<br>    uint8_t app_elf_sha256[32]; /*!&lt; sha256 of elf file */<br>    uint32_t reserv2[20];       /*!&lt; reserv2 */<br>} esp_app_desc_t;</pre><p><strong>Few important fields to note:</strong></p><ul><li>version: Firmware version embedded in image. This can be embedded in firmware image using multiple methods including configuration option or version file. By default its retrieved using command git describe --always --tags command if application is hosted in a git repository.</li><li>secure_version : Security version embedded in image. This can be embedded using configuration option only. This is desired as it groups firmware images based on fixes against security vulnerabilities (e.g. revoked CA certificate) and thus ensuring security. More on this in followup section on anti-rollback feature.</li></ul><h3>Software Architecture</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/501/1*A_G7RgxGdEL2IYSYXWlX2A.png" /><figcaption>OTA Updates Architecture in ESP-IDF</figcaption></figure><p>Above is <strong>simplified</strong> diagram that highlights some key components in an application from ESP-IDF that deals with OTA updates. In most cases, application needs to interact with public interface of <a href="https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/esp_https_ota.html#api-reference"><strong>esp_https_ota</strong></a> and <a href="https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/ota.html#api-reference"><strong>app_update</strong></a><strong> </strong>components only.</p><ul><li><strong>ESP_HTTPS_OTA</strong>: This software component provides simplified API for updating device securely over TLS channel. API accepts two mandatory parameters, HTTPS URL where firmware image is hosted and server certificate to validate server’s identity.</li><li><strong>APP_Update</strong>: This software component abstracts out the complexity of dealing with partition and flash layer operations. It exposes simplified API that can be directly used by an application for programming firmware to device flash. Additionally it also provides some convenience APIs for dealing with rollback and anti-rollback use-cases that we shall cover in the later part of this article.</li></ul><h3>HTTPS OTA API</h3><p>API for secure OTA update is kept very simple and requires 2 mandatory parameters:</p><ul><li>Server (Firmware) URL</li><li>Server Certificate</li></ul><p>Code snippet is as shown below, assuming firmware image is hosted on github.com server:</p><pre>esp_http_client_config_t config = {<br>     .url = &quot;https://raw.githubusercontent.com/path/to/firmware&quot;,<br>     .cert_pem = (char *) github_server_start_pem,<br>};</pre><pre>esp_err_t ret = esp_https_ota(&amp;config);<br>if (ret == ESP_OK) {<br>     esp_restart();<br>} </pre><blockquote>There is also support for advanced APIs which provide more granular control to the application in terms of validation of firmware version, monitoring OTA update progress etc.</blockquote><blockquote>Detailed documentation for this can be found <a href="https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/esp_https_ota.html">here</a>.</blockquote><h3>OTA Update Workflow</h3><p>Simplified workflow for OTA update looks like below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/542/1*YDVZCrhhQ9rxlxAB20VTpg.png" /><figcaption>OTA update workflow</figcaption></figure><ul><li>Server authentication ensures that firmware is downloaded from trusted entity.</li><li>Based on version information in downloaded image header, device can decide to perform upgrade.</li><li>Validation on device side includes header and integrity (SHA256 checksum) related checks. This happens after entire firmware image is written to flash partition.</li><li>If hardware secure boot is enabled then firmware image has signature appended to it. For flash encryption cases, it is entirely handled on device level during flash write stage. More on this in later section.</li></ul><h4>Boot-loader &amp; Application Flowchart</h4><p>Two entities play an important role in OTA update process, the boot-loader and the application.</p><ul><li>The boot-loader and application both rely on the partition table to extract information on various partitions and their offsets in flash.</li><li>Partition otadata is responsible for selection of active firmware (latest updated) based on sequence numbers stored within it.</li><li>otadata partition is allocated with 2 flash sectors (similar to active/passive firmware, 8KiB size) and thus allows for power safety while updating sequence numbers and other parameters during OTA update.</li></ul><p>Following is a simplified flowchart for decision making involved during OTA update in an application. Also it shows how boot-loader picks up newly updated firmware after OTA update.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/512/1*CrF98YOouM4Ka07QmSp2Zw.png" /><figcaption>Simplified OTA update flowchart</figcaption></figure><h4>Flash Layout Transition</h4><p>For normal OTA update scenario, flash layout transition is rather simple. It goes through following stages:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/731/1*tNIPExBvmBgf8vyYazZ48g.png" /><figcaption>Flash layout transition in normal OTA update</figcaption></figure><h4>Stage 1</h4><p>Newly shipped smart light bulb would have functional ota_0 partition and empty ota_1 partition. Boot-loader will always give control to firmware in ota_0 partition.</p><h4>Stage 2</h4><p>Application after performing OTA update will make ota_1 partition as active by updating its sequence number in otadata partition. Thus from subsequent RESET, boot-loader will always give control to firmware in ota_1 partition (till next OTA update).</p><h3>Limitations</h3><p>In the above scenario, if there is some issue (e.g. early firmware bootup crash) in the newly updated firmware from partition ota_1, there is no way the device can fallback to previous known working firmware.</p><h3>Consideration I — Rollback</h3><p>Typically OTA updates are staged and well tested in actual deployment scenarios, e.g. friend-family devices, beta-users and then finally to larger device groups. However this still can not ensure 100% recovery if OTA update goes wrong due to many parameters like variation in hardware attributes of device, or some rare firmware crashes.</p><p>The firmware rollback feature provides an ability to rollback to the previous known working firmware.</p><h4>Boot-loader &amp; Application Flowchart</h4><ul><li>Unlike normal OTA update workflow, rollback case involves few intermittent states before marking firmware as valid.</li><li>Transition from new firmware to valid or invalid is handled by both application and boot-loader.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/782/1*7q7zDTWQVYlyWsfXJkTW1w.png" /><figcaption>Simplified Rollback OTA update flowchart</figcaption></figure><h4>Flash Layout Transition</h4><p>For rollback enabled OTA update scenario, flash layout transition goes through following stages:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/733/1*Jq25sVCtXrv-WUQ0TIg2og.png" /><figcaption>Flash layout transition with rollback OTA update</figcaption></figure><h4>Stage 1</h4><p>Newly shipped smart light bulb would have functional ota_0 partition and empty ota_1 partition. Boot-loader will always give control to firmware in ota_0 partition.</p><h4>Stage 2</h4><p>First OTA update writes new firmware image in passive partition (ota_1) and marks its state as <strong>ESP_OTA_IMG_NEW</strong>. The state is stored in otadata partition along with its sequence number.</p><h4>Stage 3</h4><p>After RESET, boot-loader sees a new firmware with state<strong>ESP_OTA_IMG_NEW</strong>and turns its state to <strong>ESP_IMAGE_PENDING_VERIFY</strong>,<strong> </strong>as its functionality is yet to be validated.</p><h4>Stage 4/4&#39;</h4><p>Once new firmware starts execution, it can set its state to either <strong>ESP_OTA_IMG_VALID</strong> or <strong>ESP_OTA_IMG_INVALID</strong> based on application logic (will come to that in next section). If it fails to update the state of new and first time executing firmware then on subsequent RESET, boot-loader updates its state to <strong>ESP_OTA_IMG_ABORTED</strong> and thus falls back to previous firmware. Following APIs are provided for state transitions:</p><pre>// Mark firmware as valid and cancel rollback process<br>esp_ota_mark_app_valid_cancel_rollback();</pre><pre>// Mark firmware as invalid and rollback to previous firmware<br>esp_ota_mark_app_invalid_rollback_and_reboot();</pre><h4>Firmware Functionality</h4><p>Lets discuss more on transition to “<strong>Stage 4</strong>” from above.</p><p>Firmware functionality can be decided based on various checkpoints within it.</p><ul><li>Successful initialisation</li><li>Connection to WiFi network</li><li>Connection to OTA server</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/502/1*_qCFk0JrgIrqYfhatksx5g.png" /><figcaption>Firmware functionality checkpoints</figcaption></figure><p>Connection to OTA server being the best possible option, as it ensures possibility of next OTA update. However this may need some changes on cloud agent side as well, which can acknowledge communication from device firmware. Once firmware reaches to desired checkpoint successfully, it can invoke earlier mentioned API to cancel rollback process and continue further execution.</p><blockquote>Note: Rollback feature can be enabled through config option, which is discussed in more detail in followup section through working example code.</blockquote><h3>Consideration II — Anti-Rollback</h3><p>Rollback offers an ability to go back to previous working firmware but sometimes this may not be a desired operation. Many times, a device firmware update can also modify some secure credentials (e.g. server’s certificate) embedded within it. This implies that all older firmware images are pretty much obsolete and if executed may posses security risks. “<strong>Firmware Anti-rollback</strong>” feature can help to mitigate such issues.</p><p>Anti-rollback is a feature that allows to execute firmware <strong>only-if </strong>the<strong> </strong><em>security version</em> embedded within it is greater than the one programmed in the device’s EFuse (one-time-programmable memory). Certain bits (up-to 32) can be reserved to store the <em>security version</em> in EFuse. It is ensured that this is kept in sync with the one embedded in the firmware image by both the application and boot-loader during startup.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/576/1*Gt0_-5oyOBHxJKSJrqPsIw.png" /><figcaption>Anti-rollback firmware grouping</figcaption></figure><p>Above image illustrates idea of grouping firmware based on their security versions.</p><ul><li>Each group (G1/G2/G3) has 3 firmware images with different firmware version but same security version.</li><li>If device anti-rollback reserved EFuse has 2 bits set (which means security version 2) then only firmware from G2 and G3 groups will be allowed to execute on device. Firmware images from group G1 having lesser security version will not be allowed to boot.</li><li>Anti-rollback is tightly coupled with rollback, as in version in EFuse is only updated after functionality of new firmware image is confirmed. This can be seen in “Simplified rollback OTA update flowchart” shown earlier.</li></ul><h3>Working Example in ESP-IDF</h3><p>Working example which implements rollback and anti-rollback features can be found <a href="https://github.com/mahavirj/advanced_https_ota"><strong>here</strong></a>. This is slightly modified version of <a href="https://github.com/espressif/esp-idf/tree/78356d1336d23995ee78383d03ba6cac850171cd/examples/system/ota/advanced_https_ota">advanced_https_ota</a> example from ESP-IDF.</p><h4>Configuration Changes</h4><p>Updated sdkconfig.defaults file looks like below:</p><pre># Use custom partition table without factory partition<br>CONFIG_PARTITION_TABLE_CUSTOM=y<br>CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=&quot;partitions_example.csv&quot;</pre><pre># Enable firmware versioning from config option CONFIG_APP_PROJECT_VER_FROM_CONFIG=y<br>CONFIG_APP_PROJECT_VER=&quot;1&quot;</pre><pre># Enable firmware rollback and anti-rollback features<br>CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE=y<br>CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK=y</pre><pre># Set initial secure version to 0 CONFIG_BOOTLOADER_APP_SECURE_VERSION=0</pre><pre># Set secure version eFuse field size CONFIG_BOOTLOADER_APP_SEC_VER_SIZE_EFUSE_FIELD=32</pre><pre># Emulate secure version through flash partition for testing CONFIG_BOOTLOADER_EFUSE_SECURE_VERSION_EMULATE=y</pre><ul><li>Both version and secure_version fields in the firmware image are set through config options itself.</li><li>For testing purpose, we have enabled an option to emulate anti-rollback EFuses through flash partition. For actual product deployment scenario this option should be disabled.</li></ul><h4>Code Changes</h4><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f4c8043c1cb1bd6b6ece51b4540c37a1/href">https://medium.com/media/f4c8043c1cb1bd6b6ece51b4540c37a1/href</a></iframe><ul><li>We have used information from API esp_https_ota_get_img_desc() to decide if OTA update is really required or not. This API retrieves image descriptor part thus its useful to get metadata that involves firmware version and security version. This also prevent further image download from remote server and unnecessary flash program cycles.</li><li>Important point to note is that we are considering successful Wi-Fi connection as a checkpoint within firmware to cancel rollback process and mark image as valid.</li><li>Same API (esp_ota_mark_app_valid_cancel_rollback) is also responsible for updating security version in EFuse matching with current firmware header.</li></ul><h3>Consideration III — Secure Boot &amp; Flash Encryption</h3><p>In this section we will see how OTA updates can be coupled with platform security features (more information covered <a href="https://medium.com/the-esp-journal/understanding-esp32s-security-features-14483e465724">here</a>) in ESP32.</p><ul><li>Secure boot allows only trusted firmware to execute by verifying its signature with public key on device.</li><li>During an OTA update, the firmware image hosted on the server should be signed with ECDSA NIST256p (secure boot v1 scheme) or RSA-3072 (secure boot v2 scheme) based private key. Signature is calculated on SHA256 checksum of firmware image, offering constant time verification, and then it is appended to it.</li><li>As mentioned earlier in the flowchart diagram, the OTA workflow on application side includes image validation stage. For non secure boot enabled cases, validation includes only integrity checks in the form of image header magic bytes and plain SHA256 checksum. For secure boot enabled cases, it involves verification of signature using public key stored in device.</li><li>After the secure boot verification stage, the firmware is marked as valid (non-rollback case) or new (rollback case). If signature is found to be invalid, its marked as invalid right away aborting the OTA update procedure.</li><li>For flash encryption case there are no additional steps are required on server or device side. Firmware image hosted on the server is still in plain text format with (optional) secure boot signature appended to it. During flash write stage on the device, if flash encryption is enabled then firmware gets written in encrypted manner using hardware AES engine and key from EFuse.</li></ul><h3>Important Notes</h3><ul><li>Above discussed features like “rollback” and “anti-rollback” must be enabled before device ships out of factory. Since these features enable certain code path in bootloader, which in itself can not be updated on-field.</li><li>It is recommended that any sort of power save modes (e.g. WiFi modem sleep) should be disabled during OTA update. This allows optimal throughput for data transfer. ESP-IDF provided examples take explicit care for this.</li><li>During OTA update flash goes through programming operations (erase/write) and hence flash cache stays disabled. If there are any interrupts that are required to kept enabled, then they should be registered with their handler in internal code memory (IRAM). More information on this can be found <a href="https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/storage/spi_flash.html#iram-safe-interrupt-handlers">here</a>.</li></ul><p>Getting robust OTA update for IoT product is very essential and some of the considerations mentioned above can be helpful in making right design decisions!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ab5438e30c12" width="1" height="1" alt=""><hr><p><a href="https://medium.com/the-esp-journal/ota-updates-framework-ab5438e30c12">OTA Updates Framework</a> was originally published in <a href="https://medium.com/the-esp-journal">The ESP Journal</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[ESP32 Memory Analysis — Case Study]]></title>
            <link>https://medium.com/the-esp-journal/esp32-memory-analysis-case-study-eacc75fe5431?source=rss-e94f74442319------2</link>
            <guid isPermaLink="false">https://medium.com/p/eacc75fe5431</guid>
            <category><![CDATA[embedded-systems]]></category>
            <category><![CDATA[esp32]]></category>
            <category><![CDATA[memory-optimization]]></category>
            <category><![CDATA[esp-idf]]></category>
            <category><![CDATA[iot]]></category>
            <dc:creator><![CDATA[Mahavir Jain]]></dc:creator>
            <pubDate>Tue, 02 Jun 2020 10:33:19 GMT</pubDate>
            <atom:updated>2020-06-03T12:43:35.395Z</atom:updated>
            <content:encoded><![CDATA[<h3>ESP32 Memory Analysis — Case Study</h3><p>Memory has significant impact on silicon cost as well as die size, hence from hardware perspective having optimal size is important and from software perspective being able to utilise it to fullest is crucial.</p><p>In this post we will discuss some upcoming features and commonly available configuration options (knobs) in ESP-IDF to allow <strong>end</strong> <strong>application</strong> to utilise various internal memory regions in most optimal way.</p><h3>Important Notes</h3><ul><li>We will focus on single core mode of ESP32 here, as that is where more number of memory optimisation features are applicable.</li><li>We will be considering typical IoT use-cases here where gaining memory at the cost of performance is acceptable criteria.</li><li>We will take typical cloud application as case study which requires TLS connection with mutual authentication support.</li><li>ESP-IDF feature branch used here can be found at, <a href="https://github.com/mahavirj/esp-idf/tree/feature/memory_optimizations">https://github.com/mahavirj/esp-idf/tree/feature/memory_optimizations</a></li></ul><h3>ESP32: Internal Memory Breakup</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/745/1*GX1WDpWbR4mdhsF5N1VZdg.png" /><figcaption>ESP32 Memory Layout</figcaption></figure><ul><li>As can be seen from above memory layout, there are various memory regions internal to silicon and of different clock speed.</li><li>For single core use-cases, we get additional 32K of instruction memory, which otherwise would have acted as cache for APP CPU core.</li><li>Instruction RAM access should always be 32-bit address and size aligned.</li><li>For end application business logic, it is always desirable to have more DRAM, which is fastest memory without any access restrictions.</li></ul><h3>Case Study — AWS IoT Sample Application</h3><ul><li>We will be taking subscribe_publish example from ESP-AWS-IoT <a href="https://github.com/espressif/esp-aws-iot/tree/master/examples/subscribe_publish"><strong>here</strong></a> as case study to analyse memory utilisation.</li><li>ESP-IDF provides an API to get minimum free heap or dynamic memory available in system using heap_caps_get_minimum_free_size(). <strong>Our aim would be to maximise this number (for relative analysis) and thus increase the amount of memory available for end application specific business logic (DRAM region to be specific).</strong></li></ul><h3>Default Memory Utilisation</h3><p>We will be using following patch on top of subscribe_publish example to log dynamic memory statistics.</p><ul><li>First we will be logging system level minimum free heap numbers for DRAM and IRAM regions respectively as mentioned earlier.</li><li>Second we will be using heap task tracking feature which provides information on dynamic memory usage on per task basis. This feature is modified to also log peak usage numbers for DRAM and IRAM regions on per task basis.</li><li><strong>We will be logging this information for </strong><strong>aws_iot_task, </strong><strong>tiT (tcpip) and </strong><strong>wifi tasks respectively </strong>(as these tasks define data transfer path from application layer to physical layer and vice-versa). It is also to be noted that there will some variation in peak memory usage of networking tasks based on environmental (like WiFi connection, network latency) factors.</li></ul><p><em>Note: Change in core-id during task creation (from below patch) is for single core configuration that we are using for this particular example.</em></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/bdb678cb11782ff8452c34d32d17d5f2/href">https://medium.com/media/bdb678cb11782ff8452c34d32d17d5f2/href</a></iframe><blockquote>With default configuration (and heap task tracking feature enabled) we get following heap utilisation statistics (all values in bytes):</blockquote><pre>Task Heap Utilisation Stats:<br>||  Task         |  Peak DRAM  |   Peak IRAM ||<br>||  aws_iot_task |   63124     |     0       || <br>||  tiT          |   3840      |     0       || <br>||  wifi         |   31064     |     0       ||</pre><pre>System Heap Utilisation Stats:<br>||   Minimum Free DRAM |   Minimum Free IRAM || <br>||       152976        |        40276        ||</pre><h4>Single Core Config</h4><p>As mentioned earlier we will be using single core configuration for all our experiments. Please note that even in single core mode there is enough processing power available in ESP32 (close to 300 DMIPS), more than sufficient for typical IoT use-cases.</p><blockquote>Corresponding configuration to be enabled in application:</blockquote><pre>CONFIG_FREERTOS_UNICORE=y</pre><blockquote>Updated heap utilisation statistics from application re-run as following:</blockquote><pre>Task Heap Utilisation Stats:<br>||  Task         |  Peak DRAM  |   Peak IRAM ||<br>||  aws_iot_task |   63124     |     0       || <br>||  tiT          |   3892      |     0       || <br>||  wifi         |   31192     |     0       ||</pre><pre>System Heap Utilisation Stats:<br>||   Minimum Free DRAM |   Minimum Free IRAM || <br>||       162980        |        76136        ||</pre><blockquote>As can be seen from above, we have gained ~10KB memory in DRAM, since some of services (e.g. idle, esp_timer tasks etc.) for second CPU core are not required anymore. In addition IPC service for inter processor communication is also no more required, so we gain from stacks and dynamic memory of that service. Increase in IRAM is due to the freeing up of 32KB cache memory of second CPU core and some of code savings due to disablement of above mentioned services.</blockquote><h3>TLS Specific</h3><h4>Asymmetric TLS Content Length</h4><p>This feature has been part of ESP-IDF from v4.0 onwards. This feature allows to enable asymmetric content length for TLS IN/OUT buffers. Thus application has an ability to reduce TLS OUT buffer from its default value of 16KB <strong>(maximum TLS fragment length per specification)</strong> to as small as say 2KB, and thus allowing <strong>14KB of dynamic memory saving</strong>.</p><p>Please note that, it is not possible to reduce TLS IN buffer length from its default 16KB, unless you have direct control over server configuration or sure about server behaviour that it will never send inbound data (during handshake or actual data-transfer phase) over certain threshold.</p><blockquote>Corresponding configuration to be enabled in application:</blockquote><pre># Enable TLS asymmetric in/out content length<br>CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y<br>CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=2048</pre><blockquote>Updated heap utilisation statistics from application re-run as following:</blockquote><pre>Task Heap Utilisation Stats:<br>||  Task         |  Peak DRAM  |   Peak IRAM ||<br>||  aws_iot_task |   48784     |     0       || <br>||  tiT          |   3892      |     0       || <br>||  wifi         |   30724     |     0       ||</pre><pre>System Heap Utilisation Stats:<br>||   Minimum Free DRAM |   Minimum Free IRAM || <br>||       177972        |        76136        ||</pre><blockquote>As can be seen from above, we have gained ~14KB memory from aws_iot_task and thus minimum free DRAM number has increased accordingly.</blockquote><h3>Dynamic Buffer Allocation Feature</h3><p>During TLS connection, mbedTLS stack keeps dynamic allocations active during entire session starting from initial handshake phase. These allocations includes, TLS IN/OUT buffers, peer certificate, client certificate, private keys etc. In this feature (soon to be part of ESP-IDF), mbedTLS internal APIs have been glued (using SHIM layer) and thus it is ensured that whenever resource usage (including data buffers) is complete relevant dynamic memory is immediately freed up.</p><p>This greatly helps to reduce peak heap utilisation for TLS connection. This will have small performance impact due to frequent dynamic memory operations (on-demand resource usage strategy). Moreover since memory related to authentication credentials (certificate, keys etc.) has been freed up, during TLS reconnect attempt (if required), application needs to ensure that mbedTLS SSL context is populated again.</p><blockquote>Corresponding configuration to be enabled in application:</blockquote><pre># Allow to use dynamic buffer strategy for mbedTLS<br>CONFIG_MBEDTLS_DYNAMIC_BUFFER=y<br>CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT=y<br>CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA=y</pre><blockquote>Updated heap utilisation statistics from application re-run as following:</blockquote><pre>Task Heap Utilization Stats:<br>||  Task         |  Peak DRAM  |   Peak IRAM ||<br>||  aws_iot_task |   26268     |     0       || <br>||  tiT          |   3648      |     0       || <br>||  wifi         |   30724     |     0       ||</pre><pre>System Heap Utilization Stats:<br>||   Minumum Free DRAM |   Minimum Free IRAM || <br>||       203648        |        76136        ||</pre><blockquote>As can be seen from above, we have gained ~22KB memory from <em>aws_iot_task</em> and thus minimum free DRAM number has increased accordingly.</blockquote><h3>Networking Specific</h3><h4>WiFi/LwIP Configuration</h4><p>We can further optimise the WiFi and LwIP configuration to reduce memory usage, at the cost of giving away some performance. Primarily we will reduce WiFi TX and RX buffers and try to balance it out by moving some critical code path from networking subsystem to instruction memory (IRAM).</p><p>To give some ballpark on performance aspect, with default networking configuration average TCP throughput is close to ~20Mbps, but with below configuration it will be close to ~4.5Mbps, which is still sufficient to cover typical IoT use-cases.</p><blockquote>Corresponding configuration to be enabled in application:</blockquote><pre># Minimal WiFi/lwIP configuration<br>CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=4<br>CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=16<br>CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=8<br>CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=<br>CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=16<br>CONFIG_LWIP_TCP_SND_BUF_DEFAULT=6144<br>CONFIG_LWIP_TCP_WND_DEFAULT=6144<br>CONFIG_LWIP_TCP_RECVMBOX_SIZE=8<br>CONFIG_LWIP_UDP_RECVMBOX_SIZE=8<br>CONFIG_ESP32_WIFI_IRAM_OPT=y<br>CONFIG_ESP32_WIFI_RX_IRAM_OPT=y<br>CONFIG_LWIP_IRAM_OPTIMIZATION=y</pre><blockquote>Updated heap utilisation statistics from application re-run as following:</blockquote><pre>Task Heap Utilization Stats:<br>||  Task         |  Peak DRAM  |   Peak IRAM ||<br>||  aws_iot_task |   26272     |     0       || <br>||  tiT          |   4108      |     0       || <br>||  wifi         |   19816     |     0       ||</pre><pre>System Heap Utilization Stats:<br>||   Minumum Free DRAM |   Minimum Free IRAM || <br>||       213712        |        62920        ||</pre><blockquote>As can be seen from above log, we have gained roughly ~9KB of additional DRAM for application usage. Impact (reduction) in total IRAM comes because we moved critical code path from networking subsystem to this region.</blockquote><h3>System Specific</h3><h4>Utilising RTC (Fast) Memory (single-core only)</h4><p>As can be seen from earlier memory breakup there is one useful 8KB RTC Fast memory (and reasonably fast) which has been sitting idle and not fully utilised. ESP-IDF will soon have feature to enable RTC Fast memory for dynamic allocation purpose. This option exists in single core configuration, as the RTC Fast memory is accessible to PRO CPU only.</p><p>It has been ensured that RTC Fast memory region will be utilised as first dynamic memory range, and most of startup, pre-scheduler code/services will occupy this range. This will allow to not have any performance impact in application code due to clock speed (slightly on slower side) of this memory.</p><p>Since there are no access restrictions to this region, capability wise we will call it as DRAM henceforth.</p><p>Let’s re-run our application with this feature and gather memory numbers.</p><blockquote>Corresponding configuration to be enabled in application:</blockquote><pre># Add RTC memory to system heap<br>CONFIG_ESP32_ALLOW_RTC_FAST_MEM_AS_HEAP=y</pre><blockquote>Updated heap utilisation statistics from application re-run as following:</blockquote><pre>Task Heap Utilization Stats:<br>||  Task         |  Peak DRAM  |   Peak IRAM ||<br>||  aws_iot_task |   26272     |     0       || <br>||  tiT          |   4096      |     0       || <br>||  wifi         |   19536     |     0       ||</pre><pre>System Heap Utilization Stats:<br>||   Minumum Free DRAM |   Minimum Free IRAM || <br>||       221792        |        62892        ||</pre><blockquote>As can be seen from above log, we have gained 8KB of additional DRAM for application usage.</blockquote><h4>Utilising Instruction Memory (IRAM, single-core only)</h4><p>So far we have seen different configuration options to allow end application to have more memory from DRAM (data memory) region. To continue along similar lines, it should be noted that there is still sufficient IRAM (instruction memory) left but it can not be used as generic purpose due to 32-bit address and size alignment restrictions.</p><ul><li>If access (load or store) is from IRAM region and size is not word-aligned, then processor will generate LoadStoreError(3) exception</li><li>If access (load or store) is from IRAM region and address is not word-aligned then processor will generate LoadStoreAlignmentError(9) exception</li></ul><p>In this particular feature from ESP-IDF, above mentioned unaligned accesses have been fixed through corresponding exception handlers and thus resulting in correct program execution. However, these exception handlers can take up-to 167 CPU cycles for each (restricted) load or store operation. So there could be significant performance penalty (as compared with DRAM access) while using this feature.</p><p>This memory region can be used in following ways:</p><ul><li>First through heap allocator APIs using special capability field known as <strong>MALLOC_CAP_IRAM_8BIT</strong></li><li>Second by redirecting DATA/BSS to this region using provided linker attributes, <strong>IRAM_DATA_ATTR</strong> and <strong>IRAM_BSS_ATTR</strong></li></ul><p>Limitations wise:</p><ul><li>This memory region can be not be used for DMA purpose</li><li>This memory region can not be used for allocating task stacks</li></ul><p>While discussing usage of this memory region with understood performance penalty, TLS IN/OUT (per our configuration value of buffer 16KB/2KB) buffers were found to be one of the potential candidate to allocate from this region. In one of the experiments, for transfer of 1MB file over TLS connection, time increased from ~3 seconds to ~5.2 seconds with TLS IN/OUT buffers moved to IRAM.</p><p>It is also possible to redirect all TLS allocations to IRAM region but that may have larger performance impact and hence this feature redirects only buffers whose size is greater or equal than minimum of TLS IN or OUT buffer (in our case threshold would be 2KB).</p><p>Let’s re-run our application with this feature and gather memory numbers.</p><blockquote>Corresponding configuration to be enabled in application:</blockquote><pre># Allow usage of IRAM as 8bit accessible region<br>CONFIG_ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY=y<br>CONFIG_MBEDTLS_IRAM_8BIT_MEM_ALLOC=y</pre><blockquote>Updated heap utilisation statistics from application re-run as following:</blockquote><pre>Task Heap Utilization Stats:<br>||  Task         |  Peak DRAM  |   Peak IRAM ||<br>||  aws_iot_task |   17960     |     21216   || <br>||  tiT          |   3640      |     0       || <br>||  wifi         |   19536     |     0       ||</pre><pre>System Heap Utilization Stats:<br>||   Minumum Free DRAM |   Minimum Free IRAM || <br>||       228252        |        40432        ||</pre><blockquote>As can be seen from above log, we have gained another ~7KB of additional DRAM for application usage. Please note that, even though we have redirected all allocations above 2KB threshold to IRAM, there are still many smaller (and simultaneous) allocations happening from DRAM region (another local maxima) and hence effective gain is lower than what actually should have been. If additional performance impact is acceptable then it is possible to redirect all TLS allocation to IRAM and gain further at-least ~10–12KB memory from DRAM region.</blockquote><h3>Summary</h3><ul><li>Having complete application control over selection of various features through configuration options is one of the important features in ESP-IDF.</li><li>Through above exercise we have systematically evaluated various features and configuration options within ESP-IDF to <strong>increase DRAM (fastest memory) budget for end application by 63KB</strong> (minimum free DRAM size increased from ~160KB to ~223KB).</li><li>Some of these configuration options are available for single-core configuration only (have been marked as such in title itself) but even in dual-core configuration memory savings are possible with rest of the options.</li><li>It is further possible to utilise instruction memory (IRAM) as 8-bit accessible region for non-performance critical modules like logging and diagnostics by end application.</li><li>It is recommended to disable some of the debugging features that we used in above exercise like heap task tracking to reduce metadata overhead (and further increase memory budget) once required system characterisation is achieved.</li></ul><h3>References</h3><ul><li>Modified subscribe_publish example along with final sdkconfig.defaults file can be found <a href="https://github.com/mahavirj/esp-aws-iot/tree/feature/memory_optimizations/examples/subscribe_publish"><strong>here</strong></a><strong>.</strong></li><li>This application should be built against ESP-IDF fork and feature branch from <a href="https://github.com/mahavirj/esp-idf/tree/feature/memory_optimizations"><strong>here</strong></a><strong>.</strong></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=eacc75fe5431" width="1" height="1" alt=""><hr><p><a href="https://medium.com/the-esp-journal/esp32-memory-analysis-case-study-eacc75fe5431">ESP32 Memory Analysis — Case Study</a> was originally published in <a href="https://medium.com/the-esp-journal">The ESP Journal</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[ESP32 OTA Updates — Amazon FreeRTOS]]></title>
            <link>https://medium.com/the-esp-journal/esp32-ota-updates-amazon-freertos-9ffbbb8f4784?source=rss-e94f74442319------2</link>
            <guid isPermaLink="false">https://medium.com/p/9ffbbb8f4784</guid>
            <category><![CDATA[iot]]></category>
            <category><![CDATA[framework]]></category>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[esp32]]></category>
            <dc:creator><![CDATA[Mahavir Jain]]></dc:creator>
            <pubDate>Mon, 01 Oct 2018 06:21:10 GMT</pubDate>
            <atom:updated>2019-02-07T08:58:11.919Z</atom:updated>
            <content:encoded><![CDATA[<p>ESP32 now supports secure Over-the-Air firmware updates with Amazon FreeRTOS. This enables users of ESP32 with Amazon FreeRTOS to:</p><ul><li>Deploy new firmware on ESP32 in secure manner (single or group of devices, along with dynamic addition of new/re-provisioned device)</li><li>Verify authenticity and integrity of new firmware after its deployed</li><li>Extend OTA update security scheme to take leverage of hardware security features in ESP32</li></ul><h3>Working</h3><p>At a high level,</p><ul><li>The firmware image (or any other partition’s content: filesystem, configuration data), is initially uploaded to an S3 bucket on AWS.</li><li>An AWS OTA Job with the required certificates (for demo purpose can be self-signed) and code-signing profile (security scheme for ESP32 is ECDSA + SHA256) is setup.</li><li>On the device side, the OTA agent from Amazon FreeRTOS needs to be enabled in the firmware, along with the certificate that is responsible for verifying the firmware update image (essentially ECDSA public key).</li><li>The AWS OTA Job then takes the firmware image from the S3 bucket, signs it, and sends it over MQTT+TLS channel in small chunks to the OTA agent on the device.</li><li>The OTA agent on the device then writes the newly received firmware to its storage and manages the state.</li><li>At the end, firmware signature gets validated on the device and it gets approved for boot-up.</li><li>Post boot-up, the OTA agent again interacts with AWS OTA Job for verifying sanity of firmware, and finally the firmware image gets marked as legitimate one, notifying the boot-loader to erase all older firmware instances from the device storage (for not allowing forced rollback).</li></ul><h3>Procedure</h3><p>Lets quickly walk over the steps for getting the OTA update demo functional on ESP32:</p><ul><li>Please follow the Getting Started Guide for some of the prerequisites as documented at, <a href="https://docs.aws.amazon.com/freertos/latest/userguide/ota-prereqs.html"><strong>https://docs.aws.amazon.com/freertos/latest/userguide/ota-prereqs.html</strong></a></li><li>Refer to <a href="https://docs.aws.amazon.com/freertos/latest/userguide/ota-code-sign-cert-esp.html"><strong>https://docs.aws.amazon.com/freertos/latest/userguide/ota-code-sign-cert-esp.html</strong></a> for creating code signing profile for the ESP32 platform</li><li>For downloading firmware to ESP32, refer to <a href="https://docs.aws.amazon.com/freertos/latest/userguide/ota-download-freertos.html#download-freertos-to-port"><strong>https://docs.aws.amazon.com/freertos/latest/userguide/ota-download-freertos.html#download-freertos-to-port</strong></a></li><li>Once the device boots up, the log should look like the one mentioned at, <a href="https://docs.aws.amazon.com/freertos/latest/userguide/burn-initial-firmware-esp.html"><strong>https://docs.aws.amazon.com/freertos/latest/userguide/burn-initial-firmware-esp.html</strong></a></li><li>Create an Amazon FreeRTOS OTA Job (by navigating to IoT Core -&gt; Manage -&gt; Jobs -&gt; Create),</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/982/1*Xx16WJdJZsc0txs9SKt5Og.png" /><figcaption>AFR OTA Job Creation</figcaption></figure><ul><li>Select “Sign a new firmware image for me” option,</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/876/1*v5Ntbw7yC2h3IylKeukRaw.png" /><figcaption>AFR OTA Job Creation</figcaption></figure><ul><li>Create code signing profile, please select ESP32 platform here and provide certificates created earlier,</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/672/1*oTtGcMrg428uljWnD3oCdw.png" /><figcaption>AFR OTA Code Signing Profile</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/673/1*jTXhXvWlx3y4ood-geOGSg.png" /><figcaption>AFR OTA Code Signing Profile</figcaption></figure><h3>Enabling Hardware Security</h3><p>The ESP32 port is so structured that the same secure firmware verification mechanism can be used by the ESP32 chipset for enabling <a href="https://docs.espressif.com/projects/esp-idf/en/latest/security/secure-boot.html"><strong>secure boot</strong></a>.</p><p>ESP32’s secure boot scheme uses the same ECDSA + SHA256 algorithm. Hence the same public key that is used for the OTA firmware image verification can also be used by the bootloader to validate the firmware image on boot-up.</p><p>It is highly recommended that you use secure boot in conjunction with the OTA firmware updates in your products.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9ffbbb8f4784" width="1" height="1" alt=""><hr><p><a href="https://medium.com/the-esp-journal/esp32-ota-updates-amazon-freertos-9ffbbb8f4784">ESP32 OTA Updates — Amazon FreeRTOS</a> was originally published in <a href="https://medium.com/the-esp-journal">The ESP Journal</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Amazon FreeRTOS — ESP32 Support]]></title>
            <link>https://medium.com/the-esp-journal/amazon-freertos-esp32-support-9874a4412a21?source=rss-e94f74442319------2</link>
            <guid isPermaLink="false">https://medium.com/p/9874a4412a21</guid>
            <category><![CDATA[embedded-systems]]></category>
            <category><![CDATA[esp32]]></category>
            <category><![CDATA[iot]]></category>
            <category><![CDATA[framework]]></category>
            <category><![CDATA[microcontrollers]]></category>
            <dc:creator><![CDATA[Mahavir Jain]]></dc:creator>
            <pubDate>Wed, 20 Jun 2018 13:20:45 GMT</pubDate>
            <atom:updated>2018-06-20T13:34:49.317Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*dhVv6pIQdqo3ypiDNMOhzA.png" /></figure><h3>Preface</h3><p><a href="https://aws.amazon.com/freertos/"><strong>Amazon FreeRTOS</strong></a> is the latest offering (after acquisition of FreeRTOS) from Amazon that tries to simplify cloud connectivity with Amazon services (e.g. Shadow, Green-grass etc.) It has support for multiple micro-controller platforms from different vendors. Our <a href="https://www.espressif.com/en/products/hardware/esp32/overview"><strong>ESP32</strong></a> is now officially supported in Amazon FreeRTOS.</p><p>In this article we will discuss about —</p><ul><li>ESP32 integration in Amazon FreeRTOS (using existing <a href="https://github.com/espressif/esp-idf/"><strong>ESP-IDF</strong></a>)</li><li>Getting Started with ESP32 using Amazon FreeRTOS</li></ul><h3>Architecture</h3><p>Let us dig deeper in architecture of this offering in the context of ESP32 -</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/641/1*jCVeIM0_wndMdL9JkJNujw.png" /><figcaption>Amazon FreeRTOS architecture with ESP32</figcaption></figure><ul><li>Upstream or vanilla FreeRTOS had no support for theESP32 architecture (Xtensa LX6 dual core CPU). Support for this architecture is now available in the <a href="https://github.com/aws/amazon-freertos/tree/master/lib/FreeRTOS/portable/ThirdParty/GCC/Xtensa_ESP32"><strong>FreeRTOS V10 kernel</strong></a>. As of now it only supports single core mode of operation.</li><li>A slightly modified version of the <a href="https://github.com/espressif/esp-idf/"><strong>ESP-IDF</strong></a> is part of the Amazon FreeRTOS SDK itself. This IDF has all the required components including, hardware abstraction layer, Wi-Fi driver and other components that <em>do not conflict</em> with the ones already available in Amazon FreeRTOS SDK (e.g. Networking Stack, TLS stack etc.). Such a self contained package allows easier certification process as well.</li><li>Another major change is that this port uses FreeRTOS’ native TCP/IP stack, rather than the LwIP stack from ESP-IDF. This has been enabled using the <a href="https://github.com/aws/amazon-freertos/blob/master/lib/FreeRTOS-Plus-TCP/source/portable/NetworkInterface/esp32/NetworkInterface.c"><strong>network interfacing layer</strong></a> that glues the FreeRTOS TCP/IP stack with ESP32’s Wi-Fi driver. More details about ESP32&#39;s networking architecture have been covered in this <a href="https://medium.com/@mahavirj/esp-idf-wifi-networking-3eaebd11eb43"><strong>post</strong></a>.</li><li>The <a href="https://github.com/aws/amazon-freertos/blob/master/lib/wifi/portable/espressif/esp32_devkitc_esp_wrover_kit/aws_wifi.c"><strong>WiFi portability</strong></a> layer acts as an abstraction, providing consistent application interface between different vendor platforms. Mostly the API for this layer helps in Wi-Fi interface/state management (Station and SoftAP) and power management.</li><li>Another abstration layer is the secure socket layer shown above. It provides consistent application interface between different vendor’s network platforms (some of the vendors use custom Networking Stack) and interfacing with the mbedTLS stack.</li></ul><h3>Qualification</h3><p>The Amazon FreeRTOS Qualification Program (Amazon FQP) is for microcontroller (MCU) vendors for qualifying platforms (not SoC itself), and both ESP32-DevKitC and ESP-WROVER-KIT are certified in the latest release.</p><p>For more information please refer to,<a href="https://aws.amazon.com/freertos/partners/"> https://aws.amazon.com/freertos/partners/</a></p><h3>Getting Started</h3><p>Please refer to the official Getting Started Guide on the AWS website for latest instructions on working with Amazon FreeRTOS: <a href="https://docs.aws.amazon.com/freertos/latest/userguide/getting_started_espressif.html">https://docs.aws.amazon.com/freertos/latest/userguide/getting_started_espressif.html</a></p><h3>Examples</h3><p>Please refer to <a href="https://docs.aws.amazon.com/freertos/latest/userguide/freertos-mds-projects-struct.html">https://docs.aws.amazon.com/freertos/latest/userguide/freertos-mds-projects-struct.html</a> for navigating to examples, primarily includes:</p><ul><li>MQTT — Client that both subscribes to and publishes to the same MQTT topic, as a result of which each time the MQTT client publishes a message to the remote MQTT broker, the broker sends the same message back to the client</li><li>Shadow — Simple lightbulb example to illustrate how client application and things communicate with the Shadow service</li><li>Greengrass — Simple example that performs discovery of AWS greengrass core device</li></ul><h3>Future Road-map (Near Term)</h3><p>Support for secure OTA updates using AWS is in Beta phase, please refer to, <a href="https://docs.aws.amazon.com/freertos/latest/userguide/freertos-ota-dev.html">https://docs.aws.amazon.com/freertos/latest/userguide/freertos-ota-dev.html</a></p><p>This is certainly very important feature and as it evolves, all qualified vendors will support this, including Espressif.</p><p>This is still at early stage, please stay tuned as expecting some exciting road-map (<em>with potential of use-cases it can cover</em>) here!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9874a4412a21" width="1" height="1" alt=""><hr><p><a href="https://medium.com/the-esp-journal/amazon-freertos-esp32-support-9874a4412a21">Amazon FreeRTOS — ESP32 Support</a> was originally published in <a href="https://medium.com/the-esp-journal">The ESP Journal</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[ESP-IDF WiFi Networking]]></title>
            <link>https://medium.com/@mahavirj/esp-idf-wifi-networking-3eaebd11eb43?source=rss-e94f74442319------2</link>
            <guid isPermaLink="false">https://medium.com/p/3eaebd11eb43</guid>
            <category><![CDATA[embedded-systems]]></category>
            <category><![CDATA[networking]]></category>
            <category><![CDATA[esp32]]></category>
            <category><![CDATA[iot]]></category>
            <category><![CDATA[wifi]]></category>
            <dc:creator><![CDATA[Mahavir Jain]]></dc:creator>
            <pubDate>Sat, 21 Apr 2018 11:08:15 GMT</pubDate>
            <atom:updated>2018-04-23T11:52:16.418Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DV0ini7U2qtLMAShINTu8A.jpeg" /></figure><h3>Introduction</h3><p>In this article we will explore WiFi Networking Architecture in <a href="https://github.com/espressif/esp-idf/"><strong>ESP-IDF</strong></a><strong> </strong>(an Internet of Things development framework from <a href="https://www.espressif.com/"><strong>Espressif</strong></a> for <a href="https://www.espressif.com/en/products/hardware/esp32/overview"><strong>ESP32</strong></a> chip).</p><h3>Primary Components</h3><ul><li><strong>TCPIP Stack (</strong><a href="https://savannah.nongnu.org/projects/lwip/"><strong>lwIP</strong></a><strong>):</strong> Embedded networking stack, with POSIX/BSD socket interface to application</li><li><strong>TCPIP Adapter Layer:</strong> Interfacing layer that provides wrappers on TCPIP stack APIs, for default handlers from Event Loop Task</li><li><strong>Event Loop Task:</strong> Task responsible for event dispatching and co-ordination between WiFi driver, TCPIP stack and Application. This has default handlers registered for various system <a href="https://github.com/espressif/esp-idf/blob/043ef32651fada9f66362949deecfe101c636e6c/components/esp32/include/esp_event.h#L29"><strong>events</strong></a></li><li><strong>WiFi Driver:</strong> Acts as MAC layer in networking, with interface for sending/receiving data and WiFi events to higher layers</li></ul><h3>Application workflow</h3><p>We are taking one of ESP-IDF <a href="https://github.com/espressif/esp-idf/blob/043ef32651fada9f66362949deecfe101c636e6c/examples/wifi/power_save/main/power_save.c#L64"><strong>example</strong></a> to demonstrate workflow of WiFi networking. Having said that, best way to represent would be using <a href="http://plantuml.com/sequence-diagram"><strong>plantuml</strong></a> based sequence diagrams, there we go…</p><h4>Part I — Initialization Phase</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/830/1*W6W5tzTUjSSz1pEyz1gGlA.png" /><figcaption>Initialization phase in WiFi Networking</figcaption></figure><p>Typical workflow involves initialization of TCPIP Adapter, Event Loop Task and WiFi driver. Some key points to note here are:</p><ul><li>Application registers its event handler with Event Loop Task, refer <a href="https://github.com/espressif/esp-idf/blob/043ef32651fada9f66362949deecfe101c636e6c/examples/wifi/power_save/main/power_save.c#L65"><strong>here</strong></a></li><li>WiFi driver also needs event handler to send events across to higher layer, that happens during call to esp_wifi_init()using default WiFi configuration from <a href="https://github.com/espressif/esp-idf/blob/043ef32651fada9f66362949deecfe101c636e6c/components/esp32/include/esp_wifi.h#L170"><strong>here</strong></a></li><li>Default event handlers for various system events gets registered during Event Loop initialization, refer <a href="https://github.com/espressif/esp-idf/blob/043ef32651fada9f66362949deecfe101c636e6c/components/esp32/event_default_handlers.c#L408"><strong>here</strong></a></li><li>During last step in above sequence diagram, WiFi driver tx callback, i.e. esp_wifi_internal_tx() gets registered with TCPIP stack, refer <a href="https://github.com/espressif/esp-idf/blob/043ef32651fada9f66362949deecfe101c636e6c/components/tcpip_adapter/tcpip_adapter_lwip.c#L204"><strong>here</strong></a> and <a href="https://github.com/espressif/esp-idf/blob/043ef32651fada9f66362949deecfe101c636e6c/components/lwip/port/netif/wlanif.c#L104"><strong>here</strong></a></li></ul><h4>Part II — Setup Phase</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/888/1*KpOiVBzRUkBa1WoyvBfL0g.png" /><figcaption>Setup phase in WiFi Networking</figcaption></figure><ul><li>On successful WiFi association with access point, TCPIP stack input callback gets registered in WiFi driver, refer <a href="https://github.com/espressif/esp-idf/blob/043ef32651fada9f66362949deecfe101c636e6c/components/esp32/event_default_handlers.c#L202"><strong>here</strong></a></li><li>Once application receives SYSTEM_EVENT_STA_START, it basically starts WiFi connection process using esp_wifi_connect(), followed up by DHCP phase</li></ul><h4>Part III — Data Transfer</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/998/1*o1plkmrWg8xjFFTecx9IAA.png" /><figcaption>Data transfer phase in WiFi Networking</figcaption></figure><p>This is straight forward, once there is acknowledgement for IP connectivity, communication can start with TCPIP stack provided POSIX socket interface</p><h3>Call Graph</h3><p>If you are really interested (not encouraged :P), maybe following call-graph can get more details, basically stripped version that involves only components discussed in above application workflow use-case.</p><blockquote>Generated using GCC -fdump-rtl-expand CFLAG and <a href="https://www.gson.org/egypt/"><strong>egypt</strong></a> call graph tool, also available at <a href="https://raw.githubusercontent.com/mahavirj/misc/master/callgraph.png"><strong>https://raw.githubusercontent.com/mahavirj/misc/master/callgraph.png</strong></a></blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_v5pz219Bes231EG-XmWwQ.png" /><figcaption>Call graph</figcaption></figure><h3>Remarks</h3><ul><li>Architecture looks clean and elegant</li><li>Offers modularity as different components are not tightly coupled</li><li>Application interface is simple and neat</li></ul><h3>What Next</h3><blockquote>So far so good, but can we really do some complex things here?</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/381/1*8GAfnECCWMr3uUdsD6wmZA.png" /></figure><p>Maybe yes, e.g. replacing the entire Networking Stack (marked in blue above), lets explore that in the context of different (and exciting?) project with ESP32…Stay tuned!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3eaebd11eb43" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>