AWS OTA Dummy PAL implementation

Hi All,

I’m using the FreeRTOS demo application for OTA with my custom board.
I want to do OTA, I want to test first simple file downloading from the OTA Job service.

I want to check the PAL invocation before real implementation. I just implemented pseudo pal_stub.c with dummy print statements.

at 3rd “GetPlatformImageState” execution, application getting aborting everytime.

“GetPlatformImageState” just returns “OtaPalImageStateInvalid” all the time and “CreateFileForRx” return pFileContext->pFile = (uint8_t*) 0x1; with dummy value since i’m not downloading anything into file. just want to see “write” call get invokes.

I tried with “OtaPalImageStateValid” in all the APIs return type but it is “Reseting” and no progress of downloading file…

Is there any procedure or document available to implement test OTA implementation ?

Please guide me.
Thanks in advance.
Gnash.

Hello @Gnash,

Welcome to FreeRTOS Forums.

We do have integration tests which can test the PAL layer implementation by doing end to end tests on the code base.

You can find that here: FreeRTOS/FreeRTOS-Libraries-Integration-Tests (github.com).

Let me know if that is something you are looking for.

Thanks,
Aniruddha

Hi Aniruddha,

Thanks for reply,

I understood that is a Unittest cases of PAL testing process, but I m expecting dummy integration with FreeRTOS OTA demo app itself.

I just pasted my dummy implementation as I not able to upload a file.

As while running with AWS OTA service, I’m getting below printf messages from this file,

OTA PAL GetPlatformImage State
OTA PAL GetPlatformImage State
OTA PAL CreateFileForRx is called
OTA PAL GetPlatformImage State
OTA PAL Abort invoked…

Please kindly provide me any procedure or document for implementing the PAL layer for OTA development.

Thanks
Ganesh

#########################ota_pal.c##################################

/**
 * @file ota_pal.c
 * @brief Platform Abstraction layer for AWS OTA based on PSA API
 *
 */

/* OTA PAL Port include. */
#include "ota_pal.h"

/* PSA services. */
//#include "psa/update.h"
//#include "psa/crypto.h"

/***********************************************************************
 *
 * Macros
 *
 **********************************************************************/

/***********************************************************************
 *
 * Structures
 *
 **********************************************************************/

/***********************************************************************
 *
 * Variables
 *
 **********************************************************************/
 /**
 * @brief File Signature Key
 *
 * The OTA signature algorithm we support on this platform.
 */
const char OTA_JsonFileSignatureKey[ OTA_FILE_SIG_KEY_STR_MAX_LENGTH ] = "sig-sha256-rsa";

/**
 * @brief Ptr to system context
 *
 * Keep track of system context between calls from the OTA Agent
 *
 */
const OtaFileContext_t * pxSystemContext = NULL;
//static psa_image_id_t xOTAImageID = TFM_FWU_INVALID_IMAGE_ID;

/* The key handle for OTA image verification. The key should be provisioned
 * before starting an OTA process by the user.
 */
//extern psa_key_handle_t xOTACodeVerifyKeyHandle;

/***********************************************************************
 *
 * Functions
 *
 **********************************************************************/

static unsigned char ota_buffer[10*1024];

OtaPalStatus_t otaPal_Abort( OtaFileContext_t * const pFileContext )
{
	printf( "OTA PAL Abort invoked...\n" );


    return OTA_PAL_COMBINE_ERR( OtaPalSuccess, 0 );
}


OtaPalStatus_t otaPal_CreateFileForRx( OtaFileContext_t * const pFileContext )
{

	printf(( "OTA PAL CreateFileForRx is called \n" ));

    if( pFileContext == NULL || pFileContext->pFilePath == NULL )
    {
        return OTA_PAL_COMBINE_ERR( OtaPalRxFileCreateFailed, 0 );
    }
    printf(( "OTA PAL FileContext %s \n", pFileContext->pFilePath ));

    pFileContext->pFile = (uint8_t*) 0x1011;

    printf(( "OTA PAL Setting dummy file pointer to %u \n", pFileContext->pFile));

    return OTA_PAL_COMBINE_ERR( OtaPalSuccess, 0 );
}

static OtaPalStatus_t otaPal_CheckSignature( OtaFileContext_t * const pFileContext )
{

	printf(( "OTA PAL Check .\n" ));

	return OTA_PAL_COMBINE_ERR( OtaPalSuccess, 0 );
}

OtaPalStatus_t otaPal_CloseFile( OtaFileContext_t * const pFileContext )
{
	printf(( "OTA PAL CloseFile .\n" ));
    /* Check the signature. */
    return otaPal_CheckSignature( pFileContext );
}

int16_t otaPal_WriteBlock( OtaFileContext_t * const pFileContext,
                           uint32_t ulOffset,
                           uint8_t * const pcData,
                           uint32_t ulBlockSize )
{
    uint32_t ulWriteLength, ulDoneLength = 0;

    printf(( "OTA PAL WriteBlock.Offset: [%d] BlockSize [%d] \n", ulOffset, ulBlockSize ));

    if( (pFileContext == NULL) || (pFileContext != pxSystemContext ) )
    {
        return -1;
    }

    //Write into Array.

    return ulDoneLength;
}

OtaPalStatus_t otaPal_ActivateNewImage( OtaFileContext_t * const pFileContext )
{
    //psa_status_t uxStatus;

	printf(( "OTA PAL ActivateNewImage \n" ));

    if( (pFileContext == NULL) || (pFileContext != pxSystemContext ) ) //|| ( xOTAImageID == TFM_FWU_INVALID_IMAGE_ID ) )
    {
        return OTA_PAL_COMBINE_ERR( OtaPalActivateFailed, 0 );
    }

    return OTA_PAL_COMBINE_ERR( OtaPalSuccess, 0 );
}

/**
 */
OtaPalStatus_t otaPal_SetPlatformImageState( OtaFileContext_t * const pFileContext,
                                             OtaImageState_t eState )
{
    //psa_image_id_t ulImageID = TFM_FWU_INVALID_IMAGE_ID;
    //psa_status_t uxStatus;

	printf(( "OTA PAL SetPlatformImage State.\n" ));

    if( pxSystemContext == NULL )
    {
        /* In this case, a reboot should have happened. */
        switch ( eState )
        {
            case OtaImageStateAccepted:

                break;
            case OtaImageStateRejected:
                /* The image is not the running image, the image in the secondary slot will be ereased if
                 * it is not a valid image. */
                break;
            case OtaImageStateTesting:
                break;
            case OtaImageStateAborted:
                /* The image download has been finished or has not been started.*/
                break;
            default:
                return OTA_PAL_COMBINE_ERR( OtaPalBadImageState, 0 );
        }
    }
    else
    {
        if( eState == OtaImageStateAccepted )
        {
            /* The image can only be set as accepted after a reboot. So the pxSystemContext should be NULL. */
            return OTA_PAL_COMBINE_ERR( OtaPalCommitFailed, 0 );
        }

        /* The image is still downloading and the OTA process will not continue. The image is in
         * the secondary slot and does not impact the later update process. So nothing to do in
         * other state.
         */
    }

    return OTA_PAL_COMBINE_ERR( OtaPalSuccess, 0 );
}

/**
 * @brief Get the state of the OTA update image.
 *
 *   NOTE: OtaPalImageStateUnknown should NEVER be returned and indicates an implementation error.
 */
OtaPalImageState_t otaPal_GetPlatformImageState( OtaFileContext_t * const pFileContext )
{
    //psa_status_t uxStatus;

    uint8_t ucSlot;
    printf(( "OTA PAL GetPlatformImage State\n" ));

#if 0
    switch ( xImageInfo.state )
    {
        case PSA_IMAGE_PENDING_INSTALL:
            return OtaPalImageStatePendingCommit;
        case PSA_IMAGE_INSTALLED:
            return OtaPalImageStateValid;
        default:
            return OtaPalImageStateInvalid;
    }
#endif

    /* It should never goes here. But just for coding safety. */
    return OtaPalImageStateInvalid;
}

/**
 * @brief Reset the device.
 *

 */
OtaPalStatus_t otaPal_ResetDevice( OtaFileContext_t * const pFileContext )
{
	printf(( "OTA PAL ResetDevice\n" ));
    //psa_fwu_request_reboot();
    return OTA_PAL_COMBINE_ERR( OtaPalActivateFailed, 0 );
}

#################### ota_pal.c ####################

You probably need to save the state in otaPal_SetPlatformImageState so that you can return correct state in otaPal_GetPlatformImageState. You can take a look at this OTA PAL implementation for Windows Simulator.

Thanks will go through,

Could you please tell me how to Enable log, if it is getting installed through pack procedure in the IDE, though i’ve declared following lines in the ota_config.h file. I don’t see any log from OTA library and want to see where the abort / reset getting called.

/* Include header that defines log levels. */
#include "logging_levels.h"

/* Configure name and log level for the OTA library. */
#ifndef LIBRARY_LOG_NAME
    #define LIBRARY_LOG_NAME     "OTA"
#endif
#ifndef LIBRARY_LOG_LEVEL
    #define LIBRARY_LOG_LEVEL    LOG_DEBUG
#endif

#include "logging_stack.h"

  • Thanks,
    Ganesh

otaPal_SetPlatformImageState

will get call only after downloading the file, is not it ? I mean after calling otaPal_WriteBlock.

I’ve reviewed and understood how to handle the OTA file image downloding and states, (from posix/ota_pa/source/ota_pal_posix.c and , Ota_Windows_Simulator/Common/Ota_PAL/Win32/ota_pal.c )

but i not getting clarity to how to integrate it with demo/ ota_demo_core_mqtt.c application, especially with PAL implementation.

from my application, I m getting only this logs.

OTA PAL GetPlatformImage State
OTA PAL GetPlatformImage State
OTA PAL CreateFileForRx is called
OTA PAL GetPlatformImage State
OTA PAL Aport Invoked…

Do I need to modify anything in the application and configuration ? I don’t see any document for this.

Could you please explain !

Thanks,

Did you see this - Porting the AWS IoT over-the-air (OTA) update library - FreeRTOS

Also, you see this behavior with actual implementation of OTA PAL or your dummy/stub implementation?

Thanks for very much for details and links… able to resolve !