1.5.5.2 Using The Library

The PRIME Firmware Upgrade service library is used by the PRIME Library as well as by the user application.

The following examples illustrate how the Firmware Upgrade service can be used.

Examples of PRIME Firmware Upgrade library usage

Example of PRIME version switching when a network is detected in a different version:


PRIME_API newPrimeApi;
bool VersionSwapEnd = false;

static void lAPP_PrimeVersionSwapRequest(SRV_FU_TRAFFIC_VERSION traffic)
{
    /* Compare current PRIME pointer with detected traffic */
    if (traffic == SRV_FU_TRAFFIC_VER_PRIME_1_4) 
    {
        newPrimeApi = (PRIME_API *)PRIME_SN_FWSTACK14_ADDRESS;
        versionSwapEn = true;

    } 
    else if (traffic == SRV_FU_TRAFFIC_VER_PRIME_1_3) 
    {
        newPrimeApi = (PRIME_API *)PRIME_SN_FWSTACK13_ADDRESS;
        versionSwapEn = true;
    }
    else
    {
        // Do nothing
    }
}

void lAPP_SwapStackVersion(void)
{
    /* Initialize PRIME stack with the new pointer */
    if (newPrimeApi == (PRIME_API *)PRIME_SN_FWSTACK14_ADDRESS)
    {
        PRIME_Restart((uint32_t *)newPrimeApi, PRIME_VERSION_1_4);
    } 
    else
    {
        PRIME_Restart((uint32_t *)newPrimeApi, PRIME_VERSION_1_3);
    }
}


void APP_Tasks ( void )
{
    /* Check the application's current state. */
    switch ( appData.state )
    {
        /* Application's initial state. */
        case APP_STATE_INIT:
        {
            /* Initialize result callback for version swap request */
            SRV_FU_RegisterCallbackSwapVersion(lAPP_PrimeVersionSwapRequest);
            break;
        }

        case APP_STATE_SERVICE_TASKS:
        {
            /* Check if stack must be swapped */
            if (versionSwapEn == APP_VERSION_ENABLE_SWAP)
            {
                versionSwapEn = 0;
                lAPP_SwapStackVersion();
            }

            break;
        }

        /* The default state should never be executed. */
        default:
        {
            break;
        }
    }
}

Example to set the public key for ECDSA signature verification:


/* Public Key for FU Signature */
static uint8_t pubECDSAKey[LENGTH_ECDSA_KEY] =
    {0x04,0x26,0x6f,0xfe,0x08,0x07,0x51,0xbf,0xd6,0xef,0xd6,0xde,0xf4,0x74,0xc5,
     0x1a,0x5e,0x1a,0x10,0xbb,0x07,0xd0,0x0a,0x0a,0x4f,0x8a,0x4e,0xab,0x59,0x66,
     0x7a,0xbb,0xd9,0xd2,0x90,0x60,0xdb,0xc7,0x95,0x16,0xab,0xfb,0x2c,0xfe,0xa0,
     0xd4,0x7b,0xc7,0x0f,0xe8,0x2f,0x97,0xe7,0xd0,0xaa,0x4e,0x20,0x4b,0x00,0xc2,
     0x90,0x23,0x88,0xd3,0xc8};

void APP_Tasks ( void )
{
    /* Check the application's current state. */
    switch ( appData.state )
    {
        /* Application's initial state. */
        case APP_STATE_INIT:
        {
            /* Pass the public key to FU module */
            SRV_FU_SetECDSAPublicKey(pubECDSAKey, LENGTH_ECDSA_KEY);
            break;
        }

        case APP_STATE_SERVICE_TASKS:
        {
            break;
        }

        /* The default state should never be executed. */
        default:
        {
            break;
        }
    }
}

Example of a Service Node restart after a successful firmware upgrade:


static uint32_t volatile fuSwapEn;

static void lAPP_SwapFirmware(void)
{
    /* Swap firmware */
    if (SRV_FU_SwapFirmware() == true)
    {
        /* Trigger reset to launch bootloader */
        SRV_RESET_HANDLER_RestartSystem(RESET_HANDLER_FU_RESET);
    }
}

static void lAPP_PrimeFuResultHandler(SRV_FU_RESULT fuResult)
{
    switch (fuResult) 
    {
        case SRV_FU_RESULT_SUCCESS:
            /* Update FU pointer */
            fuSwapEn = APP_FU_ENABLE_SWAP;
            break;

        case SRV_FU_RESULT_CRC_ERROR:
            /* Nothing to do - FU will restart automatically */
            break;

        case SRV_FU_RESULT_CANCEL:
            /* Nothing to do */
            break;

        case SRV_FU_RESULT_FW_CONFIRM:
            /* Nothing to do */
            break;

        case SRV_FU_RESULT_FW_REVERT:
            /* Revert FU pointer */
            fuSwapEn = APP_FU_ENABLE_SWAP;
            break;

        case SRV_FU_RESULT_ERROR:
            /* Nothing to do */
            break;

        case SRV_FU_RESULT_SIGNATURE_ERROR:
            /* Nothing to do */
            break;

        case SRV_FU_RESULT_IMAGE_ERROR:
            /* Nothing to do */
            break;

        default:
            break;
    }
}

void APP_Tasks ( void )
{
    /* Check the application's current state. */
    switch ( appData.state )
    {
        /* Application's initial state. */
        case APP_STATE_INIT:
        {
            /* Initialize FU result callback */
            SRV_FU_RegisterCallbackFuResult(lAPP_PrimeFuResultHandler);
            break;
        }

        case APP_STATE_SERVICE_TASKS:
        {
            /* Check if FU location must be swapped */
            if (fuSwapEn == APP_FU_ENABLE_SWAP)
            {
                fuSwapEn = 0;
                lAPP_SwapFirmware();
            }
            breakM
        }

        /* The default state should never be executed. */
        default:
        {
            break;
        }
    }
}