Because of the Thanksgiving holiday in the U.S., TI E2E™ design support forum responses may be delayed from November 25 through December 2. Thank you for your patience.

CC2652R7: OTA implementation under OpenThread protocol of CC2652R7

Part Number: CC2652R7
Other Parts Discussed in Thread: SYSCONFIG

Tool/software:

Hi TI,
My project requires CC2652R7 to perform OTA under OpenThread protocol, but I learned that OpenThread does not have built-in OTA.
The only OTA solution I found is to use CoAP in OpenThread to transfer firmware, and then use MCUboot to update firmware (I don’t know if what ChatGPT said is correct).
I haven’t found any implementation of OTA under OpenThread protocol on the Internet, nor the implementation of CoAP, and I know very little about MCUboot now.
Any suggestions will be appreciated!

  • The SDK and examples I use are as follows:

    SDK: 6.41.00.17
    rtos: temp_sensor
    nortos: mcuboot

    I modified the coapHandleServer method of temp_sensor to look like this:

    #include <ti/devices/cc13x2_cc26x2/driverlib/flash.h>
    #define OTA_BUFFER_SIZE 512  // Define size of each packet
    #define FIRMWARE_MAX_SIZE 0x56000  // Maximum firmware size
    static bool otaInProgress = false;
    static uint32_t firmwareOffset = 0x56000;  // Example starting offset for firmware storage
    static const uint32_t flashPageSize = 4096; // Typical flash page size for CC26x2
    
    // Updated OTA initialization - to start and stop OTA
    static void StartOTA() {
        otaInProgress = true;
        firmwareOffset = 0x56000;  // Reset to initial offset
        // Additional steps to prepare the device for OTA, if necessary
    }
    
    static void StopOTA() {
        otaInProgress = false;
        firmwareOffset = 0;
        // Optional: add post-OTA verification or reset
    }
    
    // Flash write function (replace with actual flash writing logic)
    static otError WriteFirmwareToFlash(const uint8_t *data, uint16_t length) {
        otError error = OT_ERROR_NONE;
    
        if ((firmwareOffset + length) > FIRMWARE_MAX_SIZE) {
            return OT_ERROR_NO_BUFS;
        }
    
        // Erase page if needed
        if (firmwareOffset % flashPageSize == 0) {
            FlashSectorErase(firmwareOffset);
        }
    
        if (FlashProgram((uint32_t *)data, firmwareOffset, length) != FAPI_STATUS_SUCCESS) {
            error = OT_ERROR_FAILED;
        } else {
            firmwareOffset += length;
        }
    
        return error;
    }
    
    void TriggerReboot() {
        SysCtrlSystemReset();  // Trigger a reset to boot into new firmware
    }
    
    static void coapHandleServer(void *aContext, otMessage *aMessage,
                                 const otMessageInfo *aMessageInfo) {
        otError error = OT_ERROR_NONE;
        otMessage *responseMessage = NULL;
        otCoapCode messageCode = otCoapMessageGetCode(aMessage);
    
        if (OT_COAP_CODE_POST == messageCode) {
            if (!otaInProgress) {
                StartOTA();
            }
    
            uint16_t payloadLength = otMessageGetLength(aMessage) - otMessageGetOffset(aMessage);
            uint8_t buffer[OTA_BUFFER_SIZE];
    
            otMessageRead(aMessage, otMessageGetOffset(aMessage), buffer, payloadLength);
    
            error = WriteFirmwareToFlash(buffer, payloadLength);
            otEXPECT(OT_ERROR_NONE == error);
    
            if (firmwareOffset >= FIRMWARE_MAX_SIZE) {
                StopOTA();
    
                responseMessage = otCoapNewMessage((otInstance *)aContext, NULL);
                otEXPECT_ACTION(responseMessage != NULL, error = OT_ERROR_NO_BUFS);
                otCoapMessageInitResponse(responseMessage, aMessage, OT_COAP_TYPE_ACKNOWLEDGMENT, OT_COAP_CODE_CHANGED);
                otCoapMessageSetToken(responseMessage, otCoapMessageGetToken(aMessage), otCoapMessageGetTokenLength(aMessage));
                otCoapMessageSetPayloadMarker(responseMessage);
    
                const char *msg = "OTA Complete";
                otMessageAppend(responseMessage, msg, strlen(msg));
    
                error = otCoapSendResponse((otInstance *)aContext, responseMessage, aMessageInfo);
                otEXPECT(OT_ERROR_NONE == error);
    
                TriggerReboot();
            }
        }
    
        exit:
        if (error != OT_ERROR_NONE && responseMessage != NULL) {
            otMessageFree(responseMessage);
        }
    }
    



    Also defined

    #define MCUBOOT_OVERWRITE_ONLY

    But when I opened mcuboot.syscfg, I got an error: Error parsing CLI arguments in script file: Error: Unrecognized argument: --rtos

    I haven't solved this problem yet, but could anyone tell me if this plan is feasible to implement?

  • Hello,

    Thanks for the question.

    I'll look into it and provide an update within 5 business days.

    Thanks,
    Toby

  • Hello Toby,

    Thank you for letting me know. I look forward to the update.

    Best,

    Gasen

  • Hi Gasen,

    But when I opened mcuboot.syscfg, I got an error: Error parsing CLI arguments in script file: Error: Unrecognized argument: --rtos

    The MCUBoot project doesn't really use SysConfig. SysConfig for MCUBoot is only used for CCFG.

    Any pin modifications, etc, should be done directly in the project.

    Overall, yes, Thread does not specify any OTA mechanism (it only specifies the network layer).

    Are you using Matter? Or is it Thread?

    If you have a non-Matter Thread project, you can start with this:

    doorlock_oad_secure (dev.ti.com/.../node and the BIM

    And refer to this:

    https://dev.ti.com/tirex/explore/node?a=BSEc4rl__6.41.00.17&node=A__APfm9cZhCrJY84-fPJ2IbA__com.ti.SIMPLELINK_CC13XX_CC26XX_SDK__BSEc4rl__6.41.00.17

    Thanks,
    Toby