Creating an OTAP Image Preserving the Memory Content for KW36

Document created by Edgar Eduardo Lomeli Gonzalez Employee on Mar 2, 2020Last modified by Edgar Eduardo Lomeli Gonzalez Employee on Mar 13, 2020
Version 7Show Document
  • View in full screen mode

Introduction

When a software update is requested by an OTAP Client (a device that receives a software update, commonly Bluetooth LE Peripheral) from the OTAP Server (a device that sends a software update, commonly Bluetooth LE Central), you may want to preserve some data previously acquired, such as bonding information, trimming values for the system oscillators, or probably NVM data for your application. This document guides you in performing OTAP updates preserving the flash data content of your interest. This document is intended for developers familiarized with OTAP custom Bluetooth LE service, for more information, you can take a look at the following post: Reprogramming a KW36 device using the OTAP Client Software.  

 

OTAP Header and Sub-elements

OTAP Protocol implements a format for the software update that is composed of a header and a defined number of sub-elements. The OTAP Header describes general information about the software update and it has a defined format shown in the following figure. For more information about the header fields, you can go to 11.4.1 Bluetooth Low Energy OTAP header chapter of the Bluetooth Low Energy Application Developer's Guide document included in the SDK at <SDK_2.2.X_FRDM-KW36_Download_Path>\docs\wireless\Bluetooth

 

                                       

 

Each Sub-element contains information for a specific purpose. You could implement your proprietary fields for your application (For more information about sub-element fields, you can go to 11.4.1 Bluetooth Low Energy OTAP header chapter of the Bluetooth Low Energy Application Developer's Guide document included in the SDK at <SDK_2.2.X_FRDM-KW36_Download_Path>\docs\wireless\Bluetooth).

OTAP includes the following sub-elements:

 

Image File Sub-elementValue Field Lenght (bytes)Description
Upgrade Image VariableThis sub-element contains the actual binary executable image which is copied into the flash memory of the OTAP Client device. The maximum size of this sub-element depends on the target hardware.
Sector Bitmap32This sub-element contains a sector bitmap of the flash memory of the target device which tells the bootloader which sectors should be overwritten and which leave intact. The format of this field is the least-significant bit first for each byte with the least significant bytes and bits standing for the lowest memory sections of the flash. 
Image File CRC2This is a 16-bit CRC calculated over all elements of the image file except this field itself. This element must be the last sub-element in an image file sent over the air.

 

OTAP Sector Bitmap Sub-element Field

The KW36 Flash is partitioned into:

  • One 256 KB Program Flash (P-Flash) array divided into 2 KB sectors with a flash address range from 0x0000_0000 to 0x0003_FFFF.
  • One 256 KB FlexNVM array divided in 2 KB sectors, flash address ranges from 0x1000_0000 to 0x1003_FFFF with an Alias memory with address range 0x0004_0000 to 0x0007_FFFF.

 

The Bitmap sub-element is 256 bits of length, in terms of the KW36 flash, each bit represents a 2KB sector covering the address range from 0x0 - 0x0007_FFFF (P-Flash to FlexNVM Alias address range), where 1 means that such sector should be erased and 0 means that such sector should be preserved. The Bitmap field is used by the OTAP Bootloader to obtain the address range which should be erased before programming the KW36 with the software update, so it must be configured before sending a software update to leave intact the address range of memory that contain data of your interest and erase only the address range that will be overwritten by the software update.       

 

 

For example: Suppose that a developer wants to preserve the address range between 0x7D800 - 0x7FFFF and the address range between 0x0 - 0x1FFF, and the left memory must be erased. The address range between 0x7D800 - 0x7FFFF corresponds to the 5 top flash sectors and the address range between 0x0 - 0x1FFF are the lowest 4 sectors.

So, it means that bits between 256 and 252 (256, 255, 254, 253 and 252) and bits between 4 and 1 (4,3,2 and 1) should be set to 0, that way OTAP Bitmap for this example is:

 

0x07FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0

 

Configuring OTAP Bitmap to Protect an Address Range Using OTAP Server Software with NXP Test Tool

  • Download and install Test Tool for Connectivity products in NXP's web site

  • Flash a KW36 with OTAP Server software included in your SDK in wireless_examples->bluetooth->otas. Open Test Tool in your PC and go to OTA Updates - > OTAP Bluetooth LE

 

 

  • Choose the port attached to the OTAP Server and click on the "Connect to OTAP Server Device" button. Then browse the SREC file for the software update. You can configure the OTAP Bitmap, selecting the "Override sector bitmap" checkbox and changing it to your value.  

 

 

Configuring OTAP Bitmap to Protect an Address Range Using IOT Toolbox

For the moment, there is no way to configure the OTAP Bitmap using IoT Toolbox, however, you can fill the bitmapBuffer according to your needs under the OTAP Bootloader code. You can find the OTAP Bootloader code in wireless_examples->framework->bootloader_otap.

 

The patch must be implemented in the "Boot_LoadImage" function located in "source->OtapBootloader.c" file. According to the example of "OTAP Sector Bitmap Sub-element field" section, you could fill "bitmapBuffer" at the top of the function and remove the portion of the code which read the bitmap array from the OTAP Server (which is set to 0xFF bytes using IoT Toolbox and there is no way to change it, that's why we have to write directly in the OTAP Bootloader code), see the following example:

 

void Boot_LoadImage (void)
{
uint8_t status = kStatus_FLASH_Success;
/* Bitmap Buffer of the example of "OTAP Sector Bitmap Sub-element field" section */
uint8_t bitmapBuffer[gBootData_SectorsBitmap_Size_c] = {0xF0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x07};
uint8_t bootProcessCompleteFlag[FSL_FEATURE_FLASH_PFLASH_BLOCK_WRITE_UNIT_SIZE] = {0};
uint8_t buffer[gFlashErasePage_c];
uint32_t remaingImgSize, len, i;
uint32_t flashAddr = gUserFlashStart_d;
uint8_t bitMask;
uint8_t *pBitmap;

...
...
...

/* Read sector bitmap */ /* Comment this portion of code */
// if (Boot_ReadExternalStorage(gBootData_SectorsBitmap_Size_c, gBootData_SectorsBitmap_Offset_c, bitmapBuffer))
// {
// gHandleBootError_d();
// }

...
...
...
}

Attachments

    Outcomes