Over the Air Download (OAD)

This section serves as a guide to the Texas Instruments Over-the-Air Download (OAD) ecosystem including the custom profile specification, application architecture, drivers, and middleware. OAD is a device firmware upgrade method that allows the firmware image running on a device to be updated over the air using a Bluetooth low energy connection while providing power loss protection.

The guide will cover the principles of the OAD process, the out of the box examples included in the SimpleLink CC2640R2 SDK, and the process for adding OAD to an existing project.

Warning

Updating the device firmware over serial (UART or SPI) connection from a host MCU using the CC26xx embedded ROM Serial Bootloader (SBL) is covered in application note CC2538/CC26xx Bootloader Interface (SWRA466).

Scope

The OAD guide section will cover:

  • OAD theory of operation and architecture
  • How to run the OAD examples included in the SimpleLink CC2640R2 SDK
  • How to add OAD to an existing sample application

The supported development kit for OAD is the CC2640R2 Launchpad. To follow the procedures listed in this guide, two CC2640R2 Launchpad development kits are required.

Read this Section First

Document Updates/Errata

This document is constantly being improved. For the best user experience, please ensure that you are using the latest version. Newer revisions will be posted online on the OAD User’s Guide wiki page.

OAD Concept Overview

This section aims to explain the major concepts involved in the OAD process from a high level. The concepts here will be expanded upon further in the following sections. Some concepts, such as the Boot Image Manager (BIM), may vary in their implementation details. Wherever possible, the concepts will be covered in this chapter with their implementation details covered in the following chapters.

OAD Types

There are two methods of implementing an over the air download update: On-chip and Off-chip. The key difference between the two methods is where the downloaded image is to be stored during the OAD process. During on-chip OAD, the downloaded image is written to internal flash, allowing for a single chip OAD solution. Off-Chip OAD stores the downloaded image in an external flash part, requiring a two chip OAD solution. Figure 74. shows a comparison of different OAD methods. Each type of OAD has associated trade offs and benefits which will be discussed in their respective sections. Despite their differences, both OAD methods share the same over the air profile and metadata vector described in this section

../_images/image1.png

Figure 74. OAD Types Overview

Table 17. OAD Types Overview.
OAD Type Advantages Limitations
On-chip No external flash required Application size restriction Stack image not upgraded
Off-chip Ability to store multiple / backup images Full application + stack upgrade,Maximum application size Low power external flash required

OAD Topology Overview

Two BLE capable devices are required for implementing the OAD custom GATT service. The terms for the devices involved in an OAD exchange are listed below:

The OAD Target is always the device that implements the OAD service GATT server. Typically this is the peripheral device that is being updated. The OAD Target uses a Boot Image Manager (BIM) to facilitate the application of a new firmware update image. The BIM executes on a device reset and determines if a firmware update is to be applied. If no update is being applied, then the BIM will transfer program execution to the main application image. The behavior of the BIM is dependent upon the selected OAD type and further described in the respective off-chip and on-chip sections below

The OAD Downloader is always the device that implements the OAD service GATT client. Typically this is the central device that is supplying the firmware update image. Figure 75. shows a graphical relationship of the devices required for an OAD transfer. The OAD Downloader can be any compliant BLE device that meets the minimum requirements needed to implement the OAD service (e.g, a smartphone).

../_images/image2.png

Figure 75. OAD Downloader and Target

All provided TI example applications (BTool, mobile applications, etc.) are implemented such that the OAD Target is a peripheral device, and the OAD Downloader is a central device. Other configurations are outside of the scope of this document.

OAD Image Metadata

All firmware images delivered via OAD are in binary format and contain an image metadata header The information in the metadata header is used by the OAD service to determine whether or not an image is acceptable for download or by the BIM to determine which image should be loaded/executed in the main system flash. In order to prevent this information from being calculated multiple times all TI OAD images use a standard 16-byte metadata vector. This metadata vector is embedded at the beginning of the image, occupying the first 16 bytes before the application code firmware content.

This section explains the various fields within the metadata vector and what they mean. The following sections will describe how each field is used specifically for On-chip and Off-chip OAD.

Most metadata checking is done in OADTarget_validateNewImage().

TI provides a tool to generate an OAD ready image, which contains a metadata vector called the OAD Image Tool. See Generating Metadata Vector for OAD Image.

Table 18. below shows a description of the metadata vector.

Table 18. Description of the metadata vector.
Field Size (in bytes) Description
CRC 2 Cyclic Redundancy Check
CRC Shadow 2 Place holder for CRC
Version 2 Version
Length 2 Length of the image in words*
UID 4 User Identification
Start Address 2 The destination address of the image in words*
Image Type 1 The type of image to be downloaded
State 1 The status of this image
[*]

These fields are measured in 32-bit words.

For example, an image length of 0x100 describes an image that is 1024 bytes in size. This OAD word size is defined by EFL_OAD_ADDR_RESOLUTION for off-chip OAD and by HAL_FLASH_WORD_SIZE for on-chip OAD.

CRC and CRC Shadow

The cyclic redundancy check (CRC) is a means to check the integrity of an image. This must be done in two steps. First the CRC must be calculated when the image is generated from the toolchain, this will be stored in the CRC field within the metadata vector.

This initial CRC will be sent over the air via the OAD service (see OAD Service (0xFFC0) section).

Later, once the target has received the OAD image, CRC shadow will be calculated to determine if the image has been corrupted during transfer. The target will re-calculate the CRC of the downloaded image and store the result in the CRC shadow field of the metadata vector.

If the CRC and CRC shadow are equivalent, the target can assume that the image was not corrupted while sending over the air.

The algorithm selected for CRC calculations is the CRC-16-CCITT, it is a 16 bit CRC calculation that has a 99.9984% error detection rate in the worst case. In addition to this CRC, all data transfers in BLE are protected by a CRC on the link layer so the risk of an undetected data corruption is even further reduced.

Version

The image version field is used to track revisions of images and ensure upgrade compatibility. Customers may implement their own versioning scheme; however, there are additional checks imposed by the TI OAD profile. See the function OADTarget_validateNewImage() within oad_target_external_flash.c or oad_target_internal_flash.c how these version checks are done in Off-chip and On-chip OAD, respectively.

Note

For On-chip OAD solutions, the LSB of the version field is reserved to designate if the image is of type A or B. Image A’s version field must always be 0 while Image B’s version field must always be 1. See the OAD_IMG_ID macro within oad_target.h. Image validation is performed in OADTarget_validateNewImage().

Length

The length field is the length of the image in words, where the word size is defined by EFL_OAD_ADDR_RESOLUTION and HAL_FLASH_WORD_SIZE for On-chip and Off-chip OAD respectively. Off-chip OAD customers who are using different external flash parts may need to modify EFL_OAD_ADDR_RESOLUTION to match the word size of their part. For On-chip OAD, the word size of the CC2640R2F is fixed.

User Identification (UID)

This field is un-used by the TI OAD profile, but the hooks are in place for a customer to add their own implementation of verifying images based on UID.

For on-chip OAD, the convention is that Image A will embed ‘A’, ‘A’, ‘A’, ‘A’ and Image B will embed ‘B’, ‘B’, ‘B’, ‘B’. off-chip images use ‘E’, ‘E’, ‘E’, ‘E’ by default.

Start Address

The start address is the first address where the proposed image is to be stored in internal flash. Similar to the length field, this is calculated in words. Off-chip OAD solutions put restrictions on the start address based on image type (more on this in the next section).

Note

For On-chip OAD solutions, this field is reserved in the metadata as they use a fixed start address that is based on the internal flash memory map.

Image Type

In Off-chip OAD systems with external flash, there are multiple types of images that can be uploaded. These image types include:

  • App + Stack
  • App only
  • Network Processor
  • Stack only

Warning

While stack only upgrades are possible with off-chip OAD, the user must be sure that the App/Stack boundary RAM and flash addresses have not changed between the current firmware image and the proposed OAD image. Since there are no runtime checks on the App/Stack boundary, a stack only OAD will overwrite the resident application if the boundary has grown. Users should exercise care when using this option. TI recommends performing a app + stack upgrade when using the off-chip OAD method.

If a boundary address change is required (i.e. stack is growing or shrinking), it is required that a user perform a merged update (App+Stack) to ensure that the OAD image is ready to run.

Note

On-chip OAD solutions determine this image type based on the LSB of the image version field. The image type field is not used (reserved for future use).

The supported image types are listed below:

Table 19. Off-chip OAD Image Types.
Image Type Value Description
EFL_OAD_IMG_TYPE_APP 1 An application or application + stack merged update
EFL_OAD_IMG_TYPE_STACK 2 A stack only update
EFL_OAD_IMG_TYPE_NP 3
A network processor update.
This only applies to the SimpleAP + SimpleNP demo
EFL_OAD_IMG_TYPE_FACTORY 4 Describes the permanently resident production image that runs on the device before any OTA updates.

Image State

The image state is a one byte metadata field that is used only by Off-chip OAD solutions. The state informs the BIM whether or not the image is ready to run or currently running. This prevents the BIM from copying the same image from external to internal flash on every boot.

Note

For On-chip OAD solutions this field is reserved in the metadata as the OAD reset service handles switching between images in the bootloader.

OAD Service (0xFFC0)

The OAD service has been designed to provide a simple and customizable implementation for the customer. In its most rudimentary form, this service is responsible for accepting/rejecting an OAD interaction based on image header criteria, storing the image in its appropriate location, and causing a device reset if the download is successful so that the downloaded application image is run by the BIM.

A screenshot of BTool displaying the OAD service is shown below:

../_images/image3.png

Figure 76. OAD Service Overview

The OAD service is a primary service with four characteristics. The characteristics of the OAD service, their UUIDs, and descriptions are listed in Figure 76.

Note

The characteristics use the 128-bit TI base UUID of the format F000XXXX-0451-4000-B000-000000000000 where XXXX is their shortened 16bit UUID. For brevity, this document will refer to the characteristics by their 16-bit short UUID.

Table 20. OAD Service Description.
UUID Name Description
0xFFC0 OAD Service OAD service declaration
0xFFC1 Image Identify Used to send image metadata over the air so that the OAD Target device can determine if it should accept or reject the proposed image
0xFFC2 Image Block Actual block of image data along with offset into the image.
0xFFC3 Image Count Number of complete images to be downloaded in the OAD session
0xFFC4 Image Status Status of current OAD download

The primary method for sending data from the OAD Downloader to the OAD target is the GATT writes with no response message. GATT notifications are the primary method used to send status data from the target to the downloader. This communication scheme was selected to prevent the target device from having to include the GATT client code required in order to receive notifications from the downloader. The OAD Downloader shall register for notifications from any characteristic with a CCCD (by writing 01:00 to the CCCD).

Note

Both GATT notifications and GATT write without response are non-acknowledged message types. To ensure reliability, it is recommended to limit OAD payload transfers to one procedure per connection event.

For a message sequence chart describing the OAD process in terms OAD service messages exchanged between the target and OAD Downloader please see Figure 81..

OAD Image Identify (0xFFC1)

The Image Identify characteristic is used to exchange image metadata between OAD Downloader and target. The OAD process begins when the OAD Downloader sends the 16 byte metadata of the proposed OAD image to the target. Upon receiving the candidate metadata, the target will do some calculations to determine whether or not the proposed image should be downloaded. “01:00” shall be written to the CCCD of this characteristic so that notification for metadata rejection is enabled.

Note

The conditions under which an OAD is accepted vary slightly between the on and off-chip methods. Please see OADTarget_validateNewImage() in oad_target_external_flash.c for off-chip OAD and oad_target_internal_flash.c for on-chip OAD. These functions implement the image reject conditions.

If the target accepts the image it will continue the OAD process by sending a notification on the Image Block characteristic requesting the first block. Otherwise the target will reject the image by sending back a portion the currently resident image’s metadata. The reject metadata contains the Image version, and User ID fields. For more information about these fields, please refer to OAD Image Metadata.

A sniffer capture of the image identify characteristic being used to reject a candidate OAD image is shown below. Note that only image version, length, and user ID are contained in the reject notification.

../_images/image4.png

Figure 77. Reject Notification in Sniffer Capture

Alternatively, a successful OAD initiation is shown in below:

../_images/image5.png

Figure 78. Successful OAD Initiation Sniffer Capture

OAD Image Block Characteristic (0xFFC2)

The OAD Image Block characteristic is used to request and transfer a block of the OAD image. “01:00” shall be written to the CCCD of this characteristic so that notification for block request is enabled. The target requests the next block of the image by sending a GATT notification to the OAD Downloader with the requested block number. The OAD Downloader will respond (GATT write no response) with the block number and a 16 byte OAD image block. The image block contains the actual binary data from OAD image offset by the block number. Figure 79. shows a block request/response sniffer capture.

../_images/image6.png

Figure 79. Block Request/Response Sniffer Capture

In Figure 79. above, the block number field is 2 bytes (little endian) and highlighted in red. The OAD image block is 16 bytes and highlighted in purple.

OAD Image Count Characteristic (0xFFC3)

The OAD Image Count characteristic is used to set the number of OAD images to be downloaded. This is used for only Off-chip OAD and the default value of the characteristic is 1. Note On-chip OAD only supports one image download per session. See On-Chip OAD for details.

OAD Image Status (0xFFC4)

The OAD image status characteristic is used to report various failures that may occur during the OAD process. The OAD Downloader may use this information to determine why an OAD failed, so that it may correct for the errors and try again. To enable notifications on this characteristic “01:00” shall be written to the CCCD of this characteristic. There are four OAD status messages that are defined by default. The OAD status codes are listed in the table below:

Table 21. OAD Status Codes
OAD Status Code Value Description
OAD_SUCCESS 0 OAD succeeded
OAD_CRC_ERR 1 The downloaded image’s CRC doesn’t match the one expected from the metadata
OAD_FLASH_ERR 2 The external flash cannot be opened
OAD_BUFFER_OFL 3 The block number of the received packet doesn’t match the one requested. An overflow has occurred.

The customer may extend these values as needed, and use the OAD_sendStatus() function to send updates to the downloader.

OAD Reset Service (0xFFD0)

The OAD reset service is only used by on-chip OAD solutions. It implements a method for invalidating the currently running image and resetting the device. This must occur because in on-chip solutions the currently running image cannot update itself. More information about the on-chip OAD process will be covered in the on-chip OAD chapter. Figure 80. shows an overview of the OAD reset service and it’s characteristic. Like the OAD service, the reset service uses the 128 bit TI base UUID with a 16 bit short UUID of 0xFFD0.

../_images/btool_oad_reset_service.png

Figure 80. OAD Reset Service

OAD Reset (0xFFD1)

The OAD reset is accomplished by invalidating Image B, which forces the BIM to revert to Image A until another successful OAD of Image B has occurred. Image B is invalidated by corrupting its CRC. After the corruption, the reset service immediately invokes a HAL reset to jump to the BIM. Note that a GATT write of any value to the reset service will trigger a reset of the device/invalidation of Image B.

OAD Process

This Profile has been designed to provide a simple and customizable OAD Profile for the customer. In its most rudimentary form, for both On-chip and Off-chip OAD, this profile is responsible for accepting an OAD interaction based on image header criteria, storing the image onto the flash and causing a device reset if the download is successful so that the downloaded application image is run by the BIM. The OAD Downloader and OAD Target perform Client role and Server role respectively.

Initiation of the OAD Process

After establishing a new connection, updating the connection interval for a faster OAD and enabling notifications of OAD Image Identify and OAD Image Block characteristics on the OAD Target, the OAD Downloader shall write to the Image Identify characteristic of the OAD Target. The message data will be the header retrieved from the OAD Image available for OAD.

@startuml
Downloader <- Target: Advertisements
Downloader -> Target: Connect Req
Downloader <-> Target: OAD Service Discovery

Downloader -> Target: Enable Notifications on Img Notify Char
Downloader -> Target: Enable Notifications on Img Block Char
Downloader -> Target: Enable Notifications on Img Status Char

group Optional for Network Processor OAD
Downloader -> Target: Write to Img Count Char
end

note left of Downloader
Generate metadata
end note

Downloader -> Target: Write metadata to Image Identify Char

note right of Target
Target validates metadata
end note

alt Image is rejected by Target
Downloader <- Target: Notification on Image Identify Char of current metadata
note over Downloader, Target
  OAD process terminates in the case of rejected metadata
end note

else Image is accepted by Target
Downloader <- Target: Notification on Image Block Char requesting 1st block
end

note left of Downloader
Read requested block
from image file
end note

Downloader -> Target: Write 1st block with block num to Image Block Char

group Repeat For Each Block In the Image

Downloader <- Target: Notification on Image Block Char requesting next block
note left of Downloader
Read requested block
from image file
end note

Downloader -> Target: Write requested block with block num to Image Block Char

note right of Target
Write block to flash
end note
end

...Repeat above until all blocks are sent...

Target -> Target: Validate Received Image
alt Image fails post download checks

Downloader <- Target: Notification on Image Status Char: FAILURE_CODE
note over Downloader, Target
  OAD process terminates in the case of rejected image, never jump to BIM
end note
else Image passes post download checks
Downloader <- Target: Notification on Image Status Char: SUCCESS
note right of Target
 Write metadata to flash
end note
note right of Target
 Reset Device
end note
note left of Downloader
 Terminate connection
 (Supervision timeout)
end note
end


@enduml

Figure 81. Sequence diagram for OAD process

Upon receiving the write request to the Image Identify characteristic, the OAD Target will compare the image available for OAD to its own running image. OADTarget_validateNewImage() in the OAD profile is responsible for determining the acceptance of the new image.

If the OAD Target determines that the image available for OAD is acceptable, the OAD Target will initiate the OAD process by notifying the Image Block Transfer characteristic to the OAD Downloader requesting the first block of the new image. Otherwise, if the OAD Target finds that the new image does not meet its criteria to begin the OAD process, it shall respond by notifying the Image Identify characteristic with its own Image Header data as sign of rejection. In that case, the OAD procedure will end immediately as depicted in Figure 81..

Image Block Transfers

The Image Block Transfer characteristic allows the two devices to request and respond with the OAD image, one block at a time. The image block size is defined to be 16 bytes – see OAD_BLOCK_SIZE in oad.h. The OAD Target will request an image block from the OAD Downloader by notifying the OAD Image Block characteristic with the correct block index. The OAD Downloader shall then respond by writing to the OAD Image Block characteristic. The message’s data will be the requested block’s index followed by the corresponding 16-byte block of the image. Whenever the OAD Target is ready to digest another block of the OAD image, it will notify the Image Block Transfer characteristic with the index of the desired image block. The OAD Downloader will then respond.

Completion of the OAD Process

After the OAD Target has received the final image block, it will verify that the image is correctly received and stored by calculating the CRC over the stored OAD image.

The OAD Target will then reset so that the bootloader (BIM) can verify and boot the new image downloaded.

The burden of verification is then on the Downloader, which will lose BLE connection to the OAD Target during this verification and instantiation process, to restart scanning and the to reestablish a connection and verify that the new image is indeed running.

Handling Errors During the OAD Process

To ensure reliability, any error or faults that occurs during an OAD transfer requires the OAD Downloader to restart the OAD transfer procedure from the beginning. Errors may be reported through the OAD Image Status characteristic if notifications have been enabled

Boot Image Manager (BIM)

Since a running image cannot update itself, both On-chip and Off-chip OAD methods must employ a boot image manager (BIM). The BIM is a lightweight section of code that is designed to run every time the device resets, check the validity of newly downloaded images, and if necessary, load the new image into internal flash.

BIM’s implementation varies slightly for On-chip and Off-chip OAD solutions, thus there is a separate BIM project for each.

Note

As of BLE-Stack 3.00.01 BIM is always linked to page 31 of internal flash, and will always link the CCFG section with it. Thus the OAD application will not need its own CCFG.

Linker Responsibilities

In general, there are a few bare requirements that the linker command file must have to support the TI OAD Profile, TI Tools, and TI BIM (The TI OAD Ecosystem):

These requirements are critical; not just to be supported in the TI OAD Ecosystem but for stability of application as discussed in earlier sections.

The SimpleLink CC2640R2 SDK provides cc26xx_app_oad.cmd (CCS) and cc26xx_app_oad.icf (IAR) linker command files to show these requirements for compatibility with TI OAD Ecosystem. Example modifications to an existing linker command file to make an Library OAD off-chip possible is shown in :ref:sec-generating-library-oad-linker-file.

Generally, the TI Image Tool will handle page alignment of OAD images, no linker intervention is required. However, if desired, some stack side changes can be done to make the stack entry point page aligned, see Stack Side Changes for OAD Project.

Off-Chip OAD

This section describes the off-chip OAD process as well as an overview of the differences between Split Image Off-Chip OAD and Library Off-Chip OAD. Off-chip OAD utilizes an external memory component (Flash) to store the new image during download and image selection/update.

The following procedures are unique to off-chip OAD:

For information about the OAD profile and metadata, please see OAD Concept Overview.

Supported Stack Image Types

Off-chip OAD supports the split image and stack library build configurations. This means that the user can update both the application and stack during the same OAD session. Stack and stack_library image types are supported by off-chip OAD, see the following sections for an explanation of the merits of each.

For more information about the stack image types (stack, stack_library) please. see Protocol Stack Build Configurations.

Split Image Off-Chip OAD

Split Image Off-Chip OAD has following benefits that an application developer would find useful:

  • Flexibility of OAD Image & Transfer Time

    The developer can choose what type of OAD Image makes the best sense to perform OAD with. If decreased OAD transfer time, the developer can choose to generate an App Only OAD Image. If the developer wants to upgrade the application as well as the stack at the cost of additional transfer time, an App+Stack OAD Image can be generated.

  • SimpleLink CC2640R2 SDK Examples for Reference

    Contained within SimpleLink CC2640R2 SDK the simple_peripheral_oad_offchip project has an implementation of App Only Off-Chip OAD for reference. See Out of the Box Demo (Off-Chip App Only OAD).

However, Split Image Off-Chip OAD has the following drawbacks:

  • Increased Flash Usage

    The introduction of the page aligned image boundary can potentially remove up to nearly a page of flash. Global linking of application and stack is also disabled for Split Image Off-Chip OAD, further reducing flash availability.

Library Off-Chip OAD

Library Off-Chip OAD, or StackLibrary Off-Chip OAD has the following benefits that an application developer would find useful:

  • Additional Flash for Application

    The developer will be able to get all the benefits related to the Library build configuration outlined in the CC2640 to CC2640R2F.

However, Library Off-Chip OAD has the following drawbacks:

  • OAD Transfer Time and Image is Large

    The Library Off-Chip configuration requires the developer to transfer an image containing both the application and the stack, always. If SNV is included, it’s possible trim out excess padded data to the nearest page. (This step would also remove the SNV from the OAD image as well). See the SNV section within Add Off-chip OAD to an existing project for more information on preserving SNV

  • No Reference Example in SimpleLink CC2640R2 SDK

    Although there’s no example to reference, the same procedure outlined in this guide cane be used to generate a Library Off-chip OAD project from a Library Project:

    1. Conversion of cc26xx_app_and_stack.icf to be OAD enabled

      Following the steps outlined in Generating Linker Command File for OAD Off-chip convert the SimpleLink CC2640R2 SDK provided cc26xx_app_and_stack.icf to be OAD enabled.

      All Library projects in SimpleLink CC2640R2 SDK utilize cc26xx_app_and_stack.icf for the applications FlashROM_StackLibrary configuration.

    2. Adding Off-chip OAD Functionality to an existing Library configuration project

      With the Off-chip OAD enabled cc26xx_app_and_stack.icf from the previous step, follow the steps outlined in Add Off-chip OAD to an existing project with any library enabled project in SimpleLink CC2640R2 SDK. (for example, simple_peripheral or simple_central)

Constraints and Requirements for Off-chip OAD

In order to perform off-chip OAD the target system must contain have:

  • An external storage device such as serial flash memory with at least 128kB of space. Support of multiple OAD images requires n * 128kB + (n * EXT_FL_PAGE_SIZE ) of external memory storage. Where n is the number of images to be stored in external flash. n must be >= 1.
  • Free GPIO pins to interface to the external memory (i.e. 4 wires for SPI)
  • Enough free code space to reserve the entire contents of pg 31 (4kB) for BIM

Off-chip OAD Memory layout

The memory maps for both internal and external flash are detailed below.

../_images/offchip_oad_mem_layout.png

Figure 82. Off-Chip OAD Memory Layout

Off-chip OAD applications use the both internal flash memory and an off-chip flash memory device. The internal flash memory contains the Interrupt Vectors, the Application where OAD Profile is embedded, the BLE stack image, the NV Storage Area, the BIM and the CCFG.

The off-chip flash memory on the CC2640R2 Launchpad contains up to 3 OAD Images and up to 3 metadata vectors corresponding to the OAD Images. The memory map layout of the external flash part is defined in ext_flash_layout.h. The size of each OAD Image placeholder is 128kB. The memory partition of the application for Off-chip OAD is depicted in Figure 82.. Each OAD image, either App only or App+Stack, must support OAD Profile so that further OAD is enabled after it is downloaded to the off-chip memory, copied to the on-chip memory, and executed.

The sectors in Figure 82. in red are designed to be permanently resident on the device. The BIM and CCFG are not intended to be upgraded via OAD. The OAD design was selected this way so that a failure during the OAD process does not yield a bricked device.

BIM for Off-chip OAD

Warning

The BIM will link the resident CCFG sector. Furthermore, this is a custom CCFG, with the IMAGE_VALID_CONF field set to 0x1F000. This means that the boot ROM of the device will automatically execute BIM code instead of application code at startup. BIM will handle starting the application. OAD applications will not need to include a CCFG. This is a feature of CC2640R2F, and not compatible with CC2650 devices.

The OAD solution requires that permanently resident boot code, the BIM, exists in order to provide a fail-safe mechanism for determining whether to run the existing application image or to copy a new image or images from off-chip flash to internal flash (code) memory. It is assumed that a valid image exists either in off-chip flash ready to be copied or already placed in on-chip flash at any given time. Given this assumption, the initial image placed in internal flash which does not exist in external flash will have invalid external image metadata, and so the BIM will choose to jump to the existing image’s entry point.

At startup, BIM checks if the application image metadata in off-chip flash has a status indicating that the image is to be copied to the on-chip flash. If the status is 0xFF, copies the image to internal flash and performs CRC validations. If any other status value is found the image will not be verified or copied to internal flash.

If the status field indicates that the image is ready for copying then the CRC validation will be performed as described below:

If a 2 byte value is found that is neither 0x0000 nor 0xFFFF, but a 0xFFFF shadow checksum is found, the BIM computes the CRC over the image. Image length is determined by the metadata that is also stored contiguous with the CRC in on-chip flash that was copied over during the original write of the image from the off-chip flash.

If off-chip flash contains an image to be copied to internal flash, but this image is undesirable, the BIM can be programmed with symbol NO_COPY to skip image checking and jump directly into the image already placed in internal flash; at which point the on-chip flash image could invalidate the bad image’s metadata or OAD a new image in its place. BIM will not be able to load any new images while NO_COPY is defined in the build.

BIM is only responsible for making an application image failsafe upon entry. BIM has exactly one entrance to the application image.

The BIM occupies the last flash page with CCFG and uses the interrupt vectors at the start of flash where the Reset Interrupt Vector calls the BIM startup routine to ensure its control of the system upon a device reset.

../_images/offchip_oad_bim.png

Figure 83. Functional Overview of Off-chip BIM

Out of the Box Demo (Off-Chip App Only OAD)

The SimpleLink CC2640R2 SDK includes demo projects that are setup to use OAD in advance. These build configurations may be flashed onto the device out of the box. All out of the box demos use BTool as the OAD Downloader. Please see OAD Topology Overview for more information. Ensure that BTool is setup correctly first. See BTool Setup for steps on how to do so. The steps listed below assume that a CC2640R2 Launchpad is being used. Additional steps may be required for custom hardware.

Furthermore, the steps in this section are referring to the OAD Target device, the images referenced below should be flashed onto that device.

Using CCS

Warning

If both the OAD Target and the OAD Downloader are connected at the same time, CCS may load the image to the wrong device. This is because CCS will select the first XDS110 it finds. This behavior can be avoided by unplugging the OAD Target device, or by setting a multi emulator debug session using CCS. See the wiki Debug with Multiple Emulators for more information.

The steps below will describe how to run the out of the box demo for OAD on CCS.

  1. Import the bim_oad_offchip, stack, and app projects into the workspace.

    ../_images/offchip_oad_workspace_ccs.png

    Figure 84. Offchip OAD CCS Workspace

  2. Build and load the BIM project onto the CC2640R2 Launchpad

  3. Build and load the simple_peripheral_cc2640r2lp_stack_oad_offchip project onto the CC2640R2 Launchpad

  4. Build the and load the simple_peripheral_cc2640r2lp_app_oad_offchip project

    • Note that a special post build step will run and generate a new app image file called simple_peripheral_cc2640r2lp_app_oad_offchip.bin. This is the file to be provided to BTool and sent over the air.
  5. You should now be able to observe that the device is advertising using BTool.

  6. Make your application level changes that are intended for OAD update. Follow steps in Changing Application Data to Verify an OAD for a trivial way to change app to verify the OAD. Build the application with changes.

  7. Use BTool to OAD your modified application file following the steps detailed in BTool OAD Procedure

    • Make sure you are using the *_oad_offchip.bin file with BTool as this file contains the metadata.

Attention

After a successful OAD, you may need to re-start your CC2640R2F in order for it to advertise again. This is because the XDS110 driver may be still attached from previous debug sessions.

Using IAR

The steps below will describe how to run the out of the box demo for OAD on IAR.

  1. Open the bim_oad_offchip project, build and load it onto the CC2640R2 Launchpad using the debugger.

  2. Open the simple_peripheral_oad_offchip workspace from the simple_peripheral_oad_offchip folder within the BLE-stack examples.

    • Build and load the stack project.
    • Be sure to use the FlashROM build configuration for the stack. This configuration corresponds to the ICall split image architecture required by OAD.
  3. Build and load the simple_peripheral application project using the FlashROM_OAD_Offchip build config.

  4. You should now be able to observe that the device is advertising via BTool.

  5. Make your application level changes that are intended for OAD update. Follow steps in Changing Application Data to Verify an OAD for a trivial way to change app to verify the OAD. Build the application with changes.

  6. Use BTool to OAD your modified application file following the steps detailed in BTool OAD Procedure

    • Make sure you are using the *_oad.bin file with BTool as this file contains the metadata. By default these images can be found at: \examples\rtos\CC2640R2_LAUNCHXL\blestack\simple_peripheral_oad_offchip\tirtos\iar\app\FlashROM_OAD_Offchip\Exe

Attention

After a successful OAD, you may need to re-start your CC2640R2F in order for it to advertise again. This is because the XDS110 driver may be still attached from previous debug sessions.

Add Off-chip OAD to an existing project

Note

All the following changes get applied to the application side. Stack side should remain untouched for all OAD configurations. For more information see Stack Side Changes for OAD Project.

  1. Use bim_oad_offchip project, as is. No change is required.

  2. Add OAD profile code to the application project:

    • The required files can be found in \source\ti\blestack\profiles\oad\cc26xx
      • oad.c
      • oad.h
      • oad_target.h
      • oad_target_external_flash.c
  3. Add External Flash middleware to application project

    • oad_target_external_flash.c relies on the ExtFlash module from the middleware folder \source\ti\mw\extflash. Add these files to the application project.
      • ExtFlash.c
      • ExtFlash.h
  4. Add the necessary include paths to the project:

    • The OAD profile code can be found at \source\ti\blestack\profiles\oad\cc26xx
  5. Use the proper off-chip OAD linker file and configure it properly.

    • IAR projects should use:
      cc26xx_app_oad.icf for App Only, App + Stack
    • CCS projects should use:
      cc26xx_app_oad.cmd for App Only, App + Stack, Library

    For information on how to modify an existing linker command file for OAD see Generating Linker Command File for OAD Off-chip.

  6. Add the following preprocessor defines to your application:

    • FEATURE_OAD
    • HAL_IMAGE_E
  7. Add necessary code to your high level application file to include OAD.

    • Add the following defines to your application file (i.e. simple_peripheral)

      #include "oad_target.h"
      #include "oad.h"
      // ...
      #define OAD_PACKET_SIZE                       ((OAD_BLOCK_SIZE) + 2)
      // ...
      #define SBP_QUEUE_PING_EVT                    Event_Id_02
      
      #define SBP_ALL_EVENTS                        (SBP_ICALL_EVT        | \
                                                     SBP_QUEUE_EVT        | \
                                                     SBP_PERIODIC_EVT     | \
                                                     SBP_CONN_EVT_END_EVT | \
                                                     SBP_QUEUE_PING_EVT)
      
    • Add the following TI-RTOS Queue structures in your application:

      // Event data from OAD profile.
      static Queue_Struct oadQ;
      static Queue_Handle hOadQ;
      
    • Add a callback to your application

      void SimpleBLEPeripheral_processOadWriteCB(uint8_t event, uint16_t connHandle,
                                                 uint8_t *pData);\
      // ...
      static oadTargetCBs_t simpleBLEPeripheral_oadCBs =
      {
        SimpleBLEPeripheral_processOadWriteCB // Write Callback.
      };
      
    • Register the OAD service, initialize Queues.

      VOID OAD_addService();                 // OAD Profile
      OAD_register((oadTargetCBs_t *)&simpleBLEPeripheral_oadCBs);
      hOadQ = Util_constructQueue(&oadQ);
      
    • Add the OAD Queue processing code to your application

      if (events & SBP_QUEUE_PING_EVT)
      {
        while (!Queue_empty(hOadQ))
        {
          oadTargetWrite_t *oadWriteEvt = Queue_get(hOadQ);
      
          // Identify new image.
          if (oadWriteEvt->event == OAD_WRITE_IDENTIFY_REQ)
          {
            OAD_imgIdentifyWrite(oadWriteEvt->connHandle, oadWriteEvt->pData);
          }
          // Write a next block request.
          else if (oadWriteEvt->event == OAD_WRITE_BLOCK_REQ)
          {
            OAD_imgBlockWrite(oadWriteEvt->connHandle, oadWriteEvt->pData);
          }
      
          // Free buffer.
          ICall_free(oadWriteEvt);
        }
      }
      
    • Add an application layer OAD callback

      void SimpleBLEPeripheral_processOadWriteCB(uint8_t event, uint16_t connHandle,
                                                 uint8_t *pData)
      {
        oadTargetWrite_t *oadWriteEvt = ICall_malloc( sizeof(oadTargetWrite_t) + \
                                                   sizeof(uint8_t) * OAD_PACKET_SIZE);
      
        if ( oadWriteEvt != NULL )
        {
          oadWriteEvt->event = event;
          oadWriteEvt->connHandle = connHandle;
      
          oadWriteEvt->pData = (uint8_t *)(&oadWriteEvt->pData + 1);
          memcpy(oadWriteEvt->pData, pData, OAD_PACKET_SIZE);
      
          Queue_put(hOadQ, (Queue_Elem *)oadWriteEvt);
      
          // Post the application's event.  For OAD, no event flag is used.
          Event_post(syncEvent, SBP_QUEUE_PING_EVT);
        }
      }
      
  8. Add the necessary arguments to your configuro script to relocate your app’s reset vector address.

  9. [Optional] On custom hardware, you may need to change the pinout of the external flash part. This can be done in two steps:

    • First, change the application layer code.

      • The application interfaces to the external SPI flash via ExtFlash.c

      • By default, the ExtFlash module uses Board_SPI0, this can be changed to Board_SPI0

        Listing 84. ExtFlash.c interface to SPI
        /* Attempt to open SPI. */
        spiHandle = SPI_open(Board_SPI0, &spiParams);
        
      • The pins used by the Board_SPIX group can be set in the board file, i.e. CC2640R2_LAUNCHXL.c

        Listing 85. CC2640R2_LAUNCHXL.c SPI1 Pins
        .mosiPin            = CC2640R2_LAUNCHXL_SPI1_MOSI,
        .misoPin            = CC2640R2_LAUNCHXL_SPI1_MISO,
        .clkPin             = CC2640R2_LAUNCHXL_SPI1_CLK,
        .csnPin             = CC2640R2_LAUNCHXL_SPI1_CSN
        
      • The defines above can be set in CC2640R2_LAUNCHXL.h

    • Second, change the pins that the BIM uses to access the SPI flash. This can be done in the bim_oad_offchip project. Since BIM is a bare metal program (no-RTOS). It doesn’t use the TI-RTOS SPI driver like the application does. BIM SPI pins are set in \examples\rtos\CC2640R2_LAUNCHXL\blestack\bim_oad_offchip\src\bsp.h

      Listing 86. Off-chip OAD BIM interface to SPI
      // Board external flash defines
      #define BSP_IOID_FLASH_CS       IOID_20
      #define BSP_SPI_MOSI            IOID_9
      #define BSP_SPI_MISO            IOID_8
      #define BSP_SPI_CLK_FLASH       IOID_10
      
  10. [Optional] For App+Stack or Library OAD Images, trim SNV/Unused Space

    Library and App+Stack can generate large OAD images especially if the end application utilizes SNV. (App + Stack will always be large)

    SNV can be preserved on the OAD Target device by applying the ‘-r’ command to the OAD Image Tool. The ‘-r’ command will limit the output image to within the range specified. Page alignment must still be preserved, so some 0xFFs may be kept in the image.

    For example, to preserve page 31, or a 1 page SNV: the -r :1e000 command can be appended to the post build step:

    Listing 87. Modified IAR post-build step to remove SNV from an App+Stack OAD image
    "$TOOLS_BLE$\oad\oad_image_tool.exe" "$PROJ_DIR$\FlashROM_OAD_Offchip\Exe\simple_peripheral_cc2640r2lp_app.hex" "$PROJ_DIR$\..\stack\FlashROM\Exe\simple_peripheral_cc2640r2lp_stack.hex" -t offchip -i app --imgVer 0 -ob "$PROJ_DIR$\FlashROM_OAD_Offchip\Exe\simple_peripheral_cc2640r2lp_app_oad.bin" -m 0x0000 -r :0x1e000
    

    The result will be am OAD image file that will not overwrite a target’s 31st page (if used for SNV, adjust as necessary for 2 SNV pages)

    Lastly, for Library builds, there will be 0xFFs between the end of the Application + Stack merged section and the SNV. If SNV is being preserved then it is safe to also trim the OAD image to the nearest page.

    For example, if a Library OAD image is produced, only takes up the first 15 pages and the SNV does not need to preserved, then append -r :0x0F000 to the post-build step:

    Listing 88. Modified IAR post-build step to remove SNV and 0xFFs from a Library OAD image.
    "$TOOLS_BLE$\oad\oad_image_tool.exe" "$PROJ_DIR$\FlashROM_StackLibrary_OAD_Offchip\Exe\hid_adv_remote_cc2640r2rc_app.hex" -t offchip -i app --imgVer 0 -ob "$PROJ_DIR$\FlashROM_StackLibrary_OAD_Offchip\Exe\hid_adv_remote_cc2640r2rc_app.bin" -m 0x0000 -r :0xF000
    

On-Chip OAD

This section describes the on-chip OAD process. On-chip OAD uses only internal flash to update the user application. No external memory components are required to implement on-chip OAD. This section aims to address the following procedures that are unique to on-chip OAD:

For information about the OAD profile and metadata, please see OAD Concept Overview

Note

The terms OAD Target App and Image A are synonymous. Both refer to the image that is permanently resident during on-chip OAD operations. The OAD Target App runs on the OAD Target and contains the minimum system software device for the purposes of updating the user image (Image B).

Constraints and Requirements for On-chip OAD

In order to perform on-chip OAD the target system meet the following requirements:

  • Enough free flash space to fit the user application within the 16 pages of internal flash allocated to it.
  • The application and stack must use the split image ICall (FlashROM) architecture to ensure that the OAD Target App, customer Image B application and BLE protocol stack do not contain overlapping flash pages

The OAD Image to be downloaded is, by default, allocated 16 flash pages. Because page 1 cannot be updated, an application must include its own TI-RTOS instance in flash without dependence on the TI-RTOS ROM implementation. This image also shares the CCFG referenced in the above paragraph. For reliability reasons, it is not possible to update the CCFG parameters via an OAD.

The OAD Target App and the OAD image B share the same RAM range as only one image is executed. The OAD Image B must be a complete application image, capable of running independently of the permanently resident OAD Target App.

The BLE protocol stack defaults to a range of 8 flash pages, ranging from address 0x17000 to 0x1EFFF and one SNV page is used by default. If the OAD Image is too large to fit in its allocated space, consider removing some features of the BLE stack to reduce its size.

The OAD Target App, or the Image A, and the Image B shall share the same BLE stack image. It is not possible to perform an on-chip OAD of the BLE Stack image.

Warning

On-chip OAD projects are unique in that two applications share the same protocol stack image. This protocol stack is built the oad_target_stack project. Both image A ( oad_target_cc2640r2lp_app ) and image B ( simple_peripheral_cc2640r2lp_app_oad_onchip ) share the generated oad_target_stack boundary files. See Frontier Tool Operation for more information on boundary files. In other words, the Image B project ( simple_peripheral_cc2640r2lp_app_oad_onchip ) shares the oad_target_stack with Image A.

On-chip OAD deals with four images. The table below shows the corresponding project associated with each image. Furthermore the terms OAD Target Image and Image A are synonymous, they will be used interchangeably in this document.

Image Name IAR Project CCS Project
Image A (Target Image) oad_target/cc2640r2lp_app oad_target_cc2640r2lp_app
Image B (User Image) simple_peripheral_oad_onchip/cc2640r2lp_app simple_peripheral_cc2640r2lp_app_oad_onchip
BLE Protocol Stack image (shared between Image A and B) oad_target/cc2640r2lp_stack oad_target_cc2640r2lp_stack
BIM for on-chip OAD bim_oad_onchip/cc2640r2lp_app bim_oad_onchip_cc2640r2lp_app

On-Chip OAD Memory layout

The memory map for CC2640R2F internal flash in an on-chip OAD configuration is shown below.

../_images/onchip_oad_mem_layout.png

Figure 85. On-Chip OAD Memory Layout

BIM for On-chip OAD

Warning

The BIM will link the resident CCFG sector. Furthermore, this is a custom CCFG, with the IMAGE_VALID_CONF field set to 0x1F000. This means that the boot ROM of the device will automatically execute BIM code instead of application code at startup. BIM will handle starting the application. OAD applications will not need to include a CCFG. This is a feature of CC2640R2F, and not compatible with R1 devices.

The OAD solution requires that permanently resident boot code, the BIM, exists in order to provide a fail-safe mechanism for determining (in preferential order) the image which is ready to run. When a valid image is found, the BIM jumps to that image at which point the image takes over execution. Either Image A or Image B must implement the proprietary TI OAD Profile. By default, this is Image A’s role. When an image with the OAD Profile downloads a new image, a system reset can be executed to return to BIM to verify the correctness of the download and begin execution.

../_images/onchip_oad_bim.png

Figure 86. Functional Overview of On-chip BIM

As the permanent owner of the flash interrupt vectors, BIM provides a fail-safe mechanism for intercepting the reset vector, putting the hardware into a safe state, and taking the most appropriate action by reading the headers of Image A and Image B.

By default, BIM gives precedence to Image B, as Image A is only expected to be run when a newer instance of Image B is ready to OAD or no valid Image B exists in the internal flash memory. If the preferred image is not ready to run, then the other image is checked. If neither image is ready to run – an unlikely scenario because Image A, the OAD Target App, need not ever be erased – then BIM puts the device into a low power Standby mode. Also by default, a CRC check is not performed on Image A because it is expected that the OAD Target App will be used as a fixed image. The check on Image A will only read the checksum placed by IAR to see if an image exists, it will not calculate the CRC shadow.

In order to verify that an image is valid, a fixed 4-byte area known as the CRC and CRC-shadow will be queried. If the 2-byte CRC16 output calculated at build time matches the 2-byte CRC16 shadow calculated by BIM, then the image is commissioned to run immediately. If the CRC is not zero and not the erased-flash value of 0xFFFF and the CRC-shadow is the erased-flash value of 0xFFFF, then the CRC can be calculated over the entire image (not including this 4-byte area) and the result can be compared to the valid CRC to determine whether the image should be commissioned as ready to run.

Out of the Box Demo (On-Chip OAD)

The SimpleLink CC2640R2 SDK includes demo projects that are setup to use OAD in advance. These build configurations may be flashed onto the device out of the box. All out of the box demos use BTool as the OAD Downloader. Please see OAD Topology Overview for more information. Ensure that BTool is setup correctly first. See BTool Setup for steps on how to do so. The steps listed below assume that a CC2640R2 Launchpad is being used. Additional steps may be required for custom hardware.

Furthermore, the steps in this section are referring to the OAD Target device, the images referenced below should be flashed onto that device.

Using CCS

Warning

If both the OAD Target and the OAD Downloader are connected at the same time, CCS may load the image to the wrong device. This is because CCS will select the first XDS110 it finds. This behavior can be avoided by unplugging the OAD Target device, or by setting a multi emulator debug session using CCS. See the wiki Debug with Multiple Emulators for more information.

  1. Import the bim_oad_onchip, oad_target_cc2640r2lp_stack, oad_target_cc2640r2lp_app, and simple_peripheral_cc2640r2lp_app_oad_onchip projects into the workspace.

    ../_images/onchip_oad_workspace_ccs.png

    Figure 87. On-chip OAD CCS Workspace

  2. Build the bim_oad_onchip and oad_target_cc2640r2lp_stack projects.

  3. Build the oad_target_cc2640r2lp_app project, this will generate a production (superbin) file as discussed in Generating a Production Image for OAD. By default the superbin is generated in the project’s build folder.

  4. Load the superbin created in the previous step onto the CC2640R2 Launchpad using Smart RF Flash Programmer 2.

    • Make sure you are using the *_oad.bin file with BTool as this file contains the metadata. By default these images can be found at: \workspace_v7\oad_target_cc2640r2lp_app
    • Make sure to erase all unprotected pages so any old code in the image B region is removed.
  5. You should now be able to observe that the device is advertising via BTool.

    • The OAD Target App (Image A) advertises as “OAD Target”, it’s device addr is 0A:D0:AD:0A:D0:AD.
    • See BTool OAD Verify Advertising for steps.
  6. Make your application level changes that are intended for OAD update. Follow steps in Changing Application Data to Verify an OAD for a trivial way to change app to verify the OAD. Build the application with changes.

    • Remember that with the ImageA/ImageB architecture of on-chip OAD, the user space application is simple_peripheral_cc2640r2lp_app_oad_onchip changes should be made to this application as Image A is permanently resident and cannot be updated.
  7. Use BTool to OAD your modified application file following the steps detailed in BTool OAD Procedure

    • Make sure you are using the *_oad.bin file with BTool as this file contains the metadata. By default these images can be found at: \workspace_v7\simple_peripheral_cc2640r2lp_app_oad_onchip

Attention

After a successful OAD, you may need to re-start your CC2640R2F in order for it to advertise again. This is because the XDS110 driver may be still attached from previous debug sessions.

Using IAR

  1. Open bim_oad_onchip workspace, build the project.

  2. Open oad_target workspace, build the stack project.

  3. Build the oad_target_cc2640r2lp_app project, this will generate a production (superbin) file as discussed in Generating a Production Image for OAD. By default the superbin is generated in the project’s build folder.

  4. Load the superbin created in the previous step onto the CC2640R2 Launchpad using Smart RF Flash Programmer 2.

    • Make sure you are using the *_oad.bin file with BTool as this file contains the metadata. By default these images can be found at: \examples\rtos\CC2640R2_LAUNCHXL\blestack\oad_target\tirtos\iar\app\FlashROM\Exe
    • Make sure to erase all unprotected pages so any old code in the image B region is removed.
  5. You should now be able to observe that the device is advertising via BTool.

    • The OAD Target App (Image A) advertises as “OAD Target”, it’s device addr is 0A:D0:AD:0A:D0:AD.
    • See BTool OAD Verify Advertising for steps.
  6. Make your application level changes that are intended for OAD update. Follow steps in Changing Application Data to Verify an OAD for a trivial way to change app to verify the OAD. Build the application with changes.

    • Remember that with the ImageA/ImageB architecture of on-chip OAD, the user space application is simple_peripheral_oad_onchip with the FlashOnly_OAD_ImgB build config. Changes should be made to this application as Image A is permanently resident and cannot be updated.
  7. Use BTool to OAD your modified application file following the steps detailed in BTool OAD Procedure

    • Make sure you are using the *_oad.bin file with BTool as this file contains the metadata. By default these images can be found at: \examples\rtos\CC2640R2_LAUNCHXL\blestack\simple_peripheral_oad_onchip\tirtos\iar\app\FlashOnly_OAD_ImgB\Exe
    • The simple_peripehral app (Image B) advertises as “Simple BLE Peripheral”, it’s device addr is the default burned into the device during production.

Attention

After a successful OAD, you may need to re-start your CC2640R2F in order for it to advertise again. This is because the XDS110 driver may be still attached from previous debug sessions.

Add On-Chip OAD to an existing project

Note

All the following changes get applied to the application side. Stack side should remain untouched for all OAD configurations. For more information see Stack Side Changes for OAD Project.

  1. Use OAD Target/ ImageA Project, as is. No change is required. This includes:

    • bim_oad_onchip
    • oad_target_cc2640r2lp_stack
    • oad_target_cc2640r2lp_app
  2. Add OAD profile code to the application project:

    • The required files can be found in \source\ti\blestack\profiles\oad\cc26xx
      • oad.c
      • oad.h
      • oad_target.h
      • oad_target_internal_flash.c
      • oad_reset_service.c
  3. Add the necessary include paths to the project:

    • The OAD profile code can be found at \source\ti\blestack\profiles\oad\cc26xx
  4. Add the following defines to your application:

    • IMAGE_INVALIDATE
    • HAL_IMAGE_B
  5. Add the OAD Target Stack’s boundary definition See screen shots below.

    • IAR
      ../_images/iar_onchip_compiler_opts.png
    • CCS
      ../_images/ccs_onchip_compiler_opts.png
  6. Use the proper on-chip OAD linker file and configure it properly.

    • IAR projects should use cc26xx_app_oad.icf

      • Pass in the following defines to the linker:

        • CC2650=2
        • FLASH_ONLY_BUILD=2
      • Add the OAD Target Stack’s boundary definition See screen shot below.

        ../_images/iar_onchip_linker_opts.png
    • CCS projects should use cc26xx_app_oad_onchip.cmd

      • Pass in the following defines to the linker:
        • R2=1
    • Add the OAD Target Stack’s boundary definition See screenshot below.

      ../_images/ccs_onchip_linker_opts.png
  7. Add necessary code to your high level application file to include the OAD reset service. This service is used to invalidate Image B and jump back to Image A for further upgrades to Image B.

    • Add the following defines to your application file (i.e. simple_peripheral)

      #include "oad_target.h"
      #include "oad.h"
      ...
      
    • Within the application’s init routine, add the OAD reset service.

      Reset_addService();
      
  8. Add the necessary arguments to your configuro script to relocate your app’s reset vector address.

Troubleshooting Guide

This guide seeks to address many of the common issues encountered during OAD.

General Troubleshooting Guide Prior to BIM

There are various places where OAD can fail; use the following steps to determine where the issue is occurring during the interaction:

  • Use a BLE Packet Sniffer and Record the OAD Transaction

    This will verify that the profile is implemented correctly and a valid image was transferred over the air.

    • Look for a OAD Initiation

      Notifications from OAD Image Notify should be requested – and the appropriate response from the OAD Target after a GATT Write of the Candidate metadata.

    • Look for OAD Image Status Characteristic

      This will contain the status of the image prior to BIM launching the image.

  • Read external/internal flash to ensure CRC Shadow is valid and matches CRC field

    • This will verify that the image was received fully without errors by the OAD Target

      • For Internal, various tools can be used. SmartRF Programmer 2 or using a jtag debugger and connecting to running target and utilizing a memory viewer are possible options.
      • For External, interface another MCU or another serial device to dump out the Flash.

Downloaded OAD Image Isn’t Starting

If the application doesn’t start running the downloaded firmware after a successful download, it’s a BIM issue.

Depending on OAD type, on-chip or off-chip, refer to sections BIM for On-chip OAD or BIM for Off-chip OAD respectively. Utilize how BIM operates and a debugger to find where the issue is occurring.

Should External Flash be Used During OAD?

No, External flash should not be utilized while OAD Profile is active; the Profile is designed to have uninterrupted exclusive access to Flash, in Off-Chip configurations.

Building Super Hex Files

To build merged hexfiles, there are various methods to do this. One option is to utilize the TI OAD Image Tool (Python). See Generating a Production Image for OAD for more information. Hex files can be converted to binary using any tool that supports the Intel extended hex format.

Mobile Application Can’t Perform OAD

Ensure the latest version of the Application is downloaded from your Phone’s Application Store and try again.

If problem persists, please post your Phone’s Model and OS Version number along with details to reproduce your setup on our Support Forums. Utilize BTool and verify that the OAD works correctly.

OAD Target device doesn’t reset after successful OAD

IThis usually occurs when the JTAG debugger (e.g., XDS110) is connected. Disconnect and remove the debugger prior to performing OAD.

This issue should not be appearing in field devices, or devices that are powered through a battery or other means.

Can’t connect via BTool After successful OAD

  • Try resetting the host_test device attached to BTool.
  • Close and re-open BTool.
  • Verify target is advertising using a mobile app.

OAD Target App Doesn’t Advertise out of the Box

Likely the image metadata is not embedded in the image, or there is a corrupted image that is causing problems.

Appendix

This section will cover various tutorials that are helpful throughout the OAD process. It is not intended to be read sequentially, but instead referenced from other sections.

Generating Linker Command File for OAD Off-chip

Understanding of OAD Concept Overview, particularly what are the Linker Responsibilities is recommended.

This section describes how to convert a standard SDK linker command file to be compatible with the TI OAD Ecosystem for both CCS and IAR linkers.

Modifications for CCS (cc26xx_app.cmd)

  1. Allocation of Flash for Metadata Vector and App Start

    FLASH_APP_BASE defines where the linker begin to place read and execute application code and data because of the following section:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    /* System memory map */
    MEMORY
    {
        /* EDITOR'S NOTE:
         * the FLASH and SRAM lengths can be changed by defining
         * ICALL_STACK0_START or ICALL_RAM0_START in
         * Properties->ARM Linker->Advanced Options->Command File Preprocessing.
         */
    
        /* Application stored in and executes from internal flash */
        /* Flash Size 128 KB */
        #ifdef ICALL_STACK0_START
            FLASH (RX) : origin = FLASH_APP_BASE, length = ADJ_ICALL_STACK0_START - FLASH_APP_BASE
        #else // default
            FLASH (RX) : origin = FLASH_APP_BASE, length = FLASH_LEN - FLASH_PAGE_LEN
        #endif
    

    Instead of origin being assigned to FLASH_APP_BASE, assign to a new undefined symbol FLASH_OAD_IMG_START.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    /* System memory map */
    MEMORY
    {
        /* EDITOR'S NOTE:
         * the FLASH and SRAM lengths can be changed by defining
         * ICALL_STACK0_START or ICALL_RAM0_START in
         * Properties->ARM Linker->Advanced Options->Command File Preprocessing.
         */
    
        /* Application stored in and executes from internal flash */
        /* Flash Size 128 KB */
        #ifdef ICALL_STACK0_START
            FLASH (RX) : origin = FLASH_OAD_IMG_START, length = ADJ_ICALL_STACK0_START - FLASH_APP_BASE
        #else // default
            FLASH (RX) : origin = FLASH_OAD_IMG_START, length = FLASH_LEN - FLASH_PAGE_LEN
        #endif
    

    Now to define the symbol, we need to shift the starting point over 16 bytes. The original linker file code is:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    /* The starting address of the application.  Normally the interrupt vectors  */
    /* must be located at the beginning of the application. Flash is 128KB, with */
    /* sector length of 4KB                                                      */
    #define FLASH_APP_BASE          0x00000000
    #define FLASH_LEN               0x20000
    #define FLASH_PAGE_LEN          0x1000
    #define FLASH_PAGE_MASK         0xFFFFF000
    
    /* Last page of Flash is allocated to App: 0x1F000 - 0x1FFFF */
    #define FLASH_LAST_PAGE_START   (FLASH_LEN - FLASH_PAGE_LEN)
    
    #ifdef ICALL_STACK0_START
    #ifdef PAGE_ALIGN
    #define ADJ_ICALL_STACK0_START (ICALL_STACK0_START & FLASH_PAGE_MASK)
    #else /* !PAGE_ALIGN */
    #define ADJ_ICALL_STACK0_START ICALL_STACK0_START
    #endif /* PAGE_ALIGN */
    #endif /* ICALL_STACK0_START */
    

    Replace with the following which defines FLASH_OAD_IMG_START relative to the symbol FLASH_OAD_IMG_HDR_SIZE, or 16 bytes.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    /* The starting address of the application.  Normally the interrupt vectors  */
    /* must be located at the beginning of the application.                      */
    #ifndef FLASH_APP_BASE
    #define FLASH_APP_BASE          0x00000000
    #endif /* FLASH_APP_BASE */
    
    #define FLASH_OAD_IMG_HDR_SIZE  0x10  /* header size (hex) in bytes */
    #define FLASH_OAD_IMG_START     (FLASH_APP_BASE + FLASH_OAD_IMG_HDR_SIZE)
    
    #define FLASH_LEN               0x20000
    #define FLASH_PAGE_LEN          0x1000
    #define FLASH_PAGE_MASK         0xFFFFF000
    
    #ifdef ICALL_STACK0_START
    #define ADJ_ICALL_STACK0_START (ICALL_STACK0_START & FLASH_PAGE_MASK)
    #endif /* ICALL_STACK0_START */
    
  2. Preservation of Page 31 (BIM + CCFGs)

    Due to the previous step, we can violate this rule. Look at the following:

    1
    2
    3
    4
    5
    6
    7
    /* Application stored in and executes from internal flash */
    /* Flash Size 128 KB */
    #ifdef ICALL_STACK0_START
        FLASH (RX) : origin = FLASH_OAD_IMG_START, length = ADJ_ICALL_STACK0_START - FLASH_APP_BASE
    #else // default
        FLASH (RX) : origin = FLASH_OAD_IMG_START, length = FLASH_LEN - FLASH_PAGE_LEN
    #endif
    

    For example, if ICALL_STACK0_START isn’t defined (for a Library build) then the starting address FLASH_OAD_IMG_START but the length is FLASH_LEN - FLASH_PAGE_LEN which is 128 kB - 4 kB. The problem is there is actually less space available and we are over allocating. Rewritten, the starting address for FLASH is 0x010, the ending address is 0x1F010, cutting into the last page, violating this rule.

    To fix this, simply subtract off the size of the meta data vector by using the previously defined FLASH_OAD_IMG_HDR_SIZE.

    The fix will look like:

    1
    2
    3
    4
    5
    6
    7
    /* Application stored in and executes from internal flash */
    /* Flash Size 128 KB */
    #ifdef ICALL_STACK0_START
        FLASH (RX) : origin = FLASH_OAD_IMG_START, length = ADJ_ICALL_STACK0_START - FLASH_OAD_IMG_HDR_SIZE
    #else // default
        FLASH (RX) : origin = FLASH_OAD_IMG_START, length = FLASH_LEN - FLASH_PAGE_LEN - FLASH_OAD_IMG_HDR_SIZE
    #endif
    

    The final range for FLASH if ICALL_STACK0_START isn’t defined (like in a Library build), will be 0x010 to 0x1F000. In other words, all the way until the last page.

    Warning

    For App only OAD or App + Stack non-library OAD, you will have to build the stack image first or manually define ICALL_STACK0_START so the stack image’s entry point doesn’t get corrupted.

    Note

    SNV flash range is automatically accounted for if ICALL_STACK0_START is defined.

    SNV flash range does not need to accounted for in library builds, as long FLASH range extends to right up to the last page, the SNV sectors will get linked in.

  3. Alignment of Interrupt Vector Table see Using a custom reset vector address for your application

    This is already handled by the existing linker file with:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    /* Retain interrupt vector table variable                                    */
    --retain=g_pfnVectors
    /* Override default entry point.                                             */
    --entry_point ResetISR
    /* Suppress warnings and errors:                                             */
    /* - 10063: Warning about entry point not being _c_int00                     */
    /* - 16011, 16012: 8-byte alignment errors. Observed when linking in object  */
    /*   files compiled using Keil (ARM compiler)                                */
    --diag_suppress=10063,16011,16012
    
  4. Page Alignment of OAD Image

    The OAD image for a library OAD build with SNV will always be 31 pages. No page alignment is necessary. OAD Image Tool also will pad with 0xFF to the next page when producing an output binary.

Modifications for IAR (cc26xx_app_and_stack.icf)

  1. Allocation of Flash for Metadata Vector and App Start

    We want the FLASH region to defines where the linker should place application and stack code and data.

    Replace:

    1
    2
    // Code and RO Data
    place in FLASH_ALL { readonly };
    

    With:

    1
    2
    // Code and RO Data
    place in FLASH { readonly };
    

    Next redefine FLASH such that it goes from a undefined symbol OAD_FLASH_START to FLASH_END which is defined to the end of page 30. OAD_FLASH_START will represent where application/stack code may begin, after the header

    1
    define region FLASH = mem:[from OAD_FLASH_START to FLASH_END];
    

    Then define the symbols that accounts for the OAD metadata:

    1
    2
    3
    4
    // OAD specific
    define symbol OAD_HDR_SIZE  = 16; // Size of metadata vector
    define symbol OAD_HDR_START   = FLASH_START;
    define symbol OAD_HDR_END     = OAD_HDR_START + OAD_HDR_SIZE - 1;
    

    Lastly define OAD_FLASH_START, accounting for the metadata vector as well as the interrupt table:

    1
    define symbol OAD_FLASH_START = INT_VEC_START + INT_VEC_SIZE;
    

    Note

    To fully define OAD_FLASH_START, the interrupt vector table needs to be accounted for. See the next step.

  2. Alignment of Interrupt Vector Table see Using a custom reset vector address for your application

    The Interrupt Vector Table needs to be placed in order for the application to function correctly. Normally, the table would start at the beginning of flash; however, due to the metadata vector, the table needs to be moved.

    First define symbols to account for the table:

    1
    2
    3
    define symbol INT_VEC_SIZE    = 64;
    define symbol INT_VEC_START   = OAD_HDR_START + OAD_HDR_SIZE;
    define symbol INT_VEC_END     = INT_VEC_START + INT_VEC_SIZE - 1;
    

    Note

    Symbols OAD_HDR_START and OAD_HDR_SIZE are defined in the previous step.

    Next define the region based off the symbols defined:

    1
    define region INT_VEC   = mem:[from INT_VEC_START to INT_VEC_END];
    

    Lastly, for memory placement, the following needs to be added so the .intvec section gets placed correctly:

    1
    2
    3
    // Interrupt Vector Table
    place at start of INT_VEC       { readonly section .intvec };
    keep                            { readonly section .intvec };
    
  3. Preservation of Page 31 (BIM + CCFGs)

    Although the project shouldn’t be building the ccfg_app_ble.c file, thus there shouldn’t be anything to link, removal of the following lines is recommended:

    1
    2
    3
    // CCFG
    place at end of FLASH_LAST_PAGE { readonly section .ccfg };
    keep { section .ccfg };
    

    BIM should be building and linking the CCFGs.

    The previous steps ensure that page 31 isn’t used by linker.

  4. Page Alignment of OAD Image

    The OAD image for a library OAD build with SNV will always be 31 pages. No page alignment is necessary. OAD Image Tool also will pad with 0xFF to the next page when producing an output binary.

Stack Side Changes for OAD Project

Generally, no stack side changes to enable OAD are required. However, if desired, depending on the OAD configuration type, stack side changes may be done in the project.

The configurations that may a stack side change are configurations where the stack image is separate from the application image. In other words, App only and Stack only for Off-chip, and (Img_B) App only for On-chip. No changes on stack project in Library OAD configurations should be done.

One possible change is to page align the stack, such that the entry point is always the same address at the beginning of a page. To force the linker to be page aligned, simply add PAGE_ALIGN=1 to the linker defines on the stack project.

In the case of a Stack only OAD configuration, the stack OAD project can be page aligned to allow for the additional features (up to the boundary). As long as the entry point is the same, the application will function normally.

Note

Modifying the Stack project to meet your applications needs is highly encouraged. For example, adding/removing SNV Using Simple NV for Flash Storage or changing Stack Configurations, should be done to meet application needs.

This topic of this section is stack side changes in order to work with the TI OAD ecosystem.

Generating Metadata Vector for OAD Image

The OAD_Image_Tool is designed to generate a metadata vector and insert it into a given image, to produce an OAD ready image. An OAD ready image can be a hex file or a binary that contains metadata for the target to interpret.

The OAD_Image_Tool can be found as a Python script or as a binary inside SimpleLink CC2640R2 SDK installation. It is located in BLE Examples Support Files in the Tools folder.

To view usage instructions for the tool, run the Python script or the binary with the -h argument passed in.

For example, to generate an OAD ready application image, invoke the tool with:

1
./oad_image_tool.exe -t offchip -o out.hex -m 0x0000 -i app in.hex

The out.hex file will be an OAD ready image with the metadata to tell the OAD Target that it’s an Application image for Off-chip OAD.

Generating a Production Image for OAD

A production image is one that contains the app, stack, and BIM images combined into a single file. Production images are generally used when an OAD enabled device is initially programmed at the manufacturing facility. Production images can also be useful for debugging as all of the information is contained in a single file.

TI has included a Python based OAD_Image_Tool that can perform a variety of operations on OAD ready hex files in the SimpleLink CC2640R2 SDK. It will be used to generate a production OAD image.

Currently, the oad_image_tool is already being invoked as a post build step on oad_target_app, and simple_peripheral builds for on and off-chip OAD.

CCS Update OAD Image Tool Build Step

The image below shows how to edit the CCS post build step for the OAD image tool. This menu can be accessed by right clicking the project –> properties.

../_images/oad_image_tool_ccs_postbuild.png

Figure 92. Update OAD Image Tool Post Build Step CCS

IAR Update OAD Image Tool Build Step

The image below shows how to edit the IAR post build step for the OAD image tool. This menu can be accessed by right clicking the project –> options.

../_images/oad_image_tool_iar_postbuild.png

Figure 93. Update OAD Image Tool Post Build Step IAR

Generate production On-Chip (Image A) using CCS or IAR

This is done as part of the oad_target project within the SimpleLink CC2640R2 SDK, see the post build steps of oad_target_app for more details.

Generate production Off-Chip using CCS

The following steps detail how to generate an on-chip OAD production image which contains Image A and the on-chip BIM.

Warning

The following steps assume you have already followed the steps 1-2 of the Out of the Box Demo (On-Chip OAD) for CCS.

  • Add the following code to the oad_target_cc2640r2lp_app project’s post build steps.

    "${TI_BLE_SDK_BASE}/tools/blestack/oad/oad_image_tool.exe" "${ProjName}.hex" "${PROJECT_LOC}/../simple_peripheral_cc2640r2lp_stack_oad_offchip/FlashROM/      simple_peripheral_cc2640r2lp_stack_oad_offchip.hex" "${PROJECT_LOC}/../bim_oad_offchip_cc2640r2lp_app/FlashOnly/bim_oad_offchip_cc2640r2lp_app.hex" -t onchip -i production -v 0 -m 0x0000 --r 0x0000 -ob "${ProjName}_oad.bin"
    

Generate production Off-Chip Image using IAR

The following steps detail how to generate an on-chip OAD production image which contains Image A and the on-chip BIM.

Warning

The following steps assume you have already followed the steps 1-2 of the Out of the Box Demo (On-Chip OAD) for IAR.

  • Add the following code to the oad_target_cc2640r2lp_app project’s post build steps.

    "$TOOLS_BLE$\oad\oad_image_tool.exe" "$PROJ_DIR$\..\..\..\..\bim_oad_offchip\tirtos\iar\app\FlashOnly\Exe\bim_oad_offchip.hex" "$PROJ_DIR$\..\stack\FlashROM\Exe\simple_peripheral_cc2640r2lp_stack.hex" "$PROJ_DIR$\FlashROM_OAD_Offchip\Exe\simple_peripheral_cc2640r2lp_app.hex" -t onchip -i production -v 0 -m 0x0000 -ob "$PROJ_DIR$\FlashROM_OAD_Offchip\Exe\simple_peripheral_cc2640r2lp_app_oad.bin"
    

Using a custom reset vector address for your application

The projects within the SimpleLink CC2640R2 SDK will build the TI-RTOS kernel as a pre-build step within the application. This prebuild step is called configuro. During the configuro stage it is possible to relocate your reset vectors. This is required for OAD applications to make room for the metadata vector at the beginning of the image space. For more information about configuro, please see RTSC Configuro Page.

Note

You may need to change OAD_IMG_E=1 in the images below to OAD_IMG_A=1 or OAD_IMG_B=1 depending on your use case.

Change Reset Vector Address in IAR

IAR treats configuro as a prebuild action. These actions can be found by right clicking the project –> Build Actions –> Pre-build command line. See the image below for more information.

../_images/configuro_iar_oad.png

Change Reset Vector Address in CCS

CCS has native RTSC/Configuro support built into the project. These actions can be found by right clicking the project –> Build –> XDCtools –> Advanced Options. See the image below for more information.

../_images/configuro_iar_ccs.png

Changing Application Data to Verify an OAD

It can be difficult to verify OAD without making application changes. A quick and easy way to change your application image before sending over the air is to change it’s scan response data.

This way, a successful OAD can be observed via the change in scan response data. See below for steps on how to change this.

  • A good test is to change the scan response data as below in simple_peripheral.c
Listing 89. Changing SBP advertisement data
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// GAP - SCAN RSP data (max size = 31 bytes)
static uint8_t scanRspData[] =
{
  // complete name
  0x14,   // length of this data
  GAP_ADTYPE_LOCAL_NAME_COMPLETE,
  'S',
  'i',
  'm',
  'p',
  'l',
  'e',
  'B',
  'L',
  'E',
  'P',
  'e',
  'r',
  'i',
  'p',
  'h',
  'e',
  'r',
  'a',
  '2',
  //...
}

Warning

If you change of scan response data you must also change it’s length. See line 5 of the code snippet above.

Using BTool and CC2640R2 Launchpad as an OAD Downloader

This section will describe how to use setup and use BTool, to perform an OAD. These steps are independent of OAD type and can be used to perform on-chip or off-chip OAD.

Tip

BTool is a very feature-rich application. This guide only seeks to document the OAD functionality of BTool.

Warning

Use the BTool included with SimpleLink CC2640R2 SDK, older versions may not have support for OAD.

BTool Setup

BTool requires a CC2640R2 Launchpad running the host_test application with POWER_SAVING disabled connected to the PC. Steps on how to setup a CC2640R2 Launchpad to work with BTool are listed below. See OAD Topology Overview for more information.

  1. Navigate to the install location of the SimpleLink CC2640R2 SDK.
  2. Within the SimpleLink CC2640R2 SDK open the \examples\rtos\CC2640R2_LAUNCHXL\blestack\hexfiles folder.
  3. Open Smart RF Flash Programmer 2.
  4. Load the OAD Downloader CC2640R2 Launchpad with the cc2640r2lp_host_test.hex image.

BTool OAD Verify Advertising

BTool can be used to scan and discover OAD device. You can verify your device is advertising by following one of the options below.

  • Advertisement can be verified in one of two ways:
    • If you know your device’s address (can be checked via Smart RF Flash Programmer 2) you can click the scan button and verify it appears in the “Slave BDA” combo box.
    • If you don’t know your device’s address, you can change it’s advertisement data (described in Changing Application Data to Verify an OAD). From there, scan the scan button and look in the BTool log window during scanning to verify the device with the custom advertising data appears.

BTool OAD Procedure

  1. Open BTool, and connect to your device. See the image below for steps.

    ../_images/connect_via_btool.png

    Figure 96. Connecting to a device using BTool

  2. Select to the OAD tab in BTool and initiate the OAD process. See the image below for instructions

    Attention

    Be sure to point BTool to the *_oad.bin file generated by the oad image tool post build step. This file contains the metadata.

    ../_images/btool_oad_init.png

    Figure 97. Initiating an OAD transfer via BTool

    Note

    If BTool from another Software Development Kit is used then the OAD Transfer Tab may not exist. Use the BTool that is included with SimpleLink CC2640R2 SDK

  3. OAD process will continue as below

    ../_images/btool_oad_in_progress.png

    Figure 98. OAD transfer via BTool

  4. BTool will report success

    ../_images/btool_oad_success.png

    Figure 99. Successful OAD transfer using BTool