AVED Programming Control (APC) Proxy Driver

Overview

The APC proxy driver binds in the FAL provided in initialization. Internally, it also creates a number of resources including two mutexes for protection, a mailbox to handle asynchronous responses, and a task to handle the interaction with the FAL.

The APC task will:

  • Pend to its mailbox, and handle the incoming messages.

  • Download new images to flash and update metadata.

  • Copy images from one partition to another.

  • Select partition to boot from next.

The API consists of a number of functions to download/copy an image to a location in flash memory, select boot partition and receive Flash Partition Table (FPT) data. The flash APIs will post an internal message with the required data onto the mailbox. The APC proxy task will service this mailbox and make the appropriate calls to the FAL to download/copy an image or select a new boot partition.

The API also provides two debug functions to display and clear of the stat/error counters.

API

Initialise the APC proxy driver

This will open the FAL using the provided handle and make use of the OSAL to create two mutexes, a mailbox, and the proxy task.

iAPC_Initialise

/**
 * @brief   Main initialisation point for the APC Proxy Driver
 *
 * @param   ucProxyId   Unique ID for this Proxy driver
 * @param   pxFwIf      Handle to the Firmware Interface to use
 * @param   ulTaskPrio  Priority of the Proxy driver task (if RR disabled)
 * @param   ulTaskStack Stack size of the Proxy driver task
 *
 * @return  OK          Proxy driver initialised correctly
 *          ERROR       Proxy driver not initialised, or was already initialised
 *
 */
int iAPC_Initialise( uint8_t ucProxyId, FW_IF_CFG *pxFwIf,
                     uint32_t ulTaskPrio, uint32_t ulTaskStack );

Bind Callbacks

This API can be used to bind into a callback to be notified of events generated by the APC proxy using the EVL library. The current supported events are:

  • APC_PROXY_DRIVER_E_DOWNLOAD_STARTED

  • APC_PROXY_DRIVER_E_DOWNLOAD_COMPLETE

  • APC_PROXY_DRIVER_E_DOWNLOAD_BUSY

  • APC_PROXY_DRIVER_E_DOWNLOAD_FAILED

  • APC_PROXY_DRIVER_E_COPY_STARTED

  • APC_PROXY_DRIVER_E_COPY_COMPLETE

  • APC_PROXY_DRIVER_E_COPY_BUSY

  • APC_PROXY_DRIVER_E_COPY_FAILED

  • APC_PROXY_DRIVER_E_PARTITION_SELECTED

  • APC_PROXY_DRIVER_E_PARTITION_SELECTION_FAILED


iAPC_BindCallback

/**
 * @brief   Bind into this proxy driver
 *
 * @param   pxCallback  Callback to bind into the proxy driver
 *
 * @return  OK          Callback successfully bound
 *          ERROR       Callback not bound
 *
 */
int iAPC_BindCallback( EVL_CALLBACK *pxCallback );

Download Image

This will post a message (APC_MSG_TYPE_DOWNLOAD_PDI) onto the APC mailbox to be handled within the internal APC task to download an image to a location in NV memory.

iAPC_DownloadImage

/**
 * @brief   Download an image to a location in NV memory
 *
 * @param   pxSignal    Current event occurance (used for tracking)
 * @param   iPartition  The partition in the FPT to store this image in
 * @param   ulSrcAddr   Address (in RAM) to read the image from
 * @param   ulImageSize Size of image (in bytes)
 *
 * @return  OK          Image downloaded successfully
 *          ERROR       Image not downloaded successfully
 *
 */
int iAPC_DownloadImage( EVL_SIGNAL *pxSignal, int iPartition, uint32_t ulSrcAddr, uint32_t ulImageSize );

Update FPT

This will post a message (APC_MSG_TYPE_DOWNLOAD_PDI) onto the APC mailbox to be handled within the internal APC task to download an image to a location in NV memory and update the FPT.

iAPC_UpdateFpt

/**
 * @brief Download an image with an FPT to a location in NV memory
 *
 * @param pxSignal Current event occurance (used for tracking)
 * @param ulSrcAddr Address (in RAM) to read the image from
 * @param ulImageSize Size of image (in bytes)
 * @param usPacketNum Image packet number
 * @param usPacketSize Size of image packet (in KB)
 * @param iLastPacket Boolean indicating if this is the last data packet
 *
 * @return OK Image downloaded successfully
 * ERROR Image not downloaded successfully
 *
 */
int iAPC_UpdateFpt( EVL_SIGNAL *pxSignal, uint32_t ulSrcAddr, uint32_t ulImageSize,
uint16_t usPacketNum, uint16_t usPacketSize, int iLastPacket );

Copy Image

This will post a message (APC_MSG_TYPE_COPY_PDI) onto the APC mailbox to be handled within the internal APC task to copy an image from one partition to another.

iAPC_CopyImage

/**
 * @brief   Copy an image from one partition to another
 *
 * @param   pxSignal        Current event occurance (used for tracking)
 * @param   iSrcPartition   The partition in the FPT to copy this image from
 * @param   iDestPartition  The partition in the FPT to copy this image to
 * @param   ulCpyAddr       Address (in RAM) to copy the source partition to before writing it
 * @param   ulAllocatedSize Maximum size available to copy
 *
 * @return  OK          Image copied successfully
 *          ERROR       Image not copied successfully
 *
 */
int iAPC_CopyImage( EVL_SIGNAL *pxSignal, int iSrcPartition, int iDestPartition, uint32_t ulCpyAddr, uint32_t ulAllocatedSize );

Set Next Partition

This will post a message (APC_MSG_TYPE_PARTITION_SELECT) onto the APC mailbox to be handled within the internal APC task to select which partition to boot from.

iAPC_SetNextPartition

/**
 * @brief   Select which partition to boot from
 *
 * @param   pxSignal    Current event occurance (used for tracking)
 * @param   iPartition  The partition to boot from on the next reset
 *
 * @return  OK          Partition successfully selected
 *          ERROR       Partition not selected
 */
int iAPC_SetNextPartition( EVL_SIGNAL *pxSignal, int iPartition );

Enable Hot Reset

This will post a message (APC_MSG_TYPE_ENABLE_HOT_RESET) onto the APC mailbox to be handled within the internal APC task to enable the hot reset capability.

iAPC_EnableHotReset

/**
 * @brief   Enable the hot reset capability
 *
 * @param   pxSignal    Current event occurance (used for tracking)
 *
 * @return  OK          Hot reset successfully enabled
 *          ERROR       Hot reset not enabled
 */
int iAPC_EnableHotReset( EVL_SIGNAL *pxSignal );

Get FPT Header

This will copy the locally stored Flash Partition Table (FPT) header data into the passed FPT header struct. This process is mutex protected.

iAPC_GetFptHeader

/**
 * @brief   Get the Flash Partition Table (FPT) Header
 *
 * @param   pxFptHeader     Pointer to the FPT header data
 *
 * @return  OK              FPT header retrieved successfully
 *          ERROR           FPT header not retrieved successfully
 *
 */
int iAPC_GetFptHeader( APC_PROXY_DRIVER_FPT_HEADER *pxFptHeader );

Get FPT Partition

This will copy the locally stored Flash Partition Table (FPT) partition data into the passed FPT partition struct. This process is mutex protected.

iAPC_GetFptPartition

/**
 * @brief   Get a Flash Partition Table (FPT) Partition
 *
 * @param   iPartition      Index of partition to retrieve (0 is the 1st partition)
 * @param   pxFptPartition  Pointer to the FPT partition data
 *
 * @return  OK              FPT partition retrieved successfully
 *          ERROR           FPT partition not retrieved successfully
 *
 */
int iAPC_GetFptPartition( int iPartition, APC_PROXY_DRIVER_FPT_PARTITION *pxFptPartition );

Clear Statistics

Debug function used to clear the all statistics counters back to zero.

iAPC_ClearStatistics

/**
 * @brief   Clear all the stats in the proxy driver
 *
 * @return  OK          Stats cleared successfully
 *          ERROR       Stats not cleared successfully
 *
 */
int iAPC_ClearStatistics( void );

Sequence Diagrams

APC Proxy Initialization

Two APC API functions are called from the AMC main task (iAPC_Initialise and iAPC_BindCallback), in order to initialize the proxy.

iAPC_Initialise will call into the FAL to open with the provided handle, create two shared proxy mutexes, create a proxy mailbox and create the proxy task.

iAPC_BindCallback will bind the appropriate top-level callback function.

image1

APC Proxy Task

The Task within APC has a number of responsibilities:

  • Pend to its mailbox, and handle the incoming messages.

  • Download new image to flash and update metadata.

  • Copy image from one partition to another.

  • Select partition to boot from next.

The sequence flow diagram below outline the top-level functionality of the APC proxy task. Some complexity has been hidden within local functions, namely iDownloadImage(), iCopyImage() and iSelectPartition().

image2

Examples

Initialize Driver

This function should only be called once. It requires an unique ID for the proxy, used for signaling new events from the proxy, along with a handle to a FW_IF (already created and initialized), proxy driver task priority and stack size.

iAPC_Initialise Example

if( OK == iAPC_Initialise( AMC_EVENT_UNIQUE_ID_APC, &xOspiIf, AMC_TASK_PRIO_DEFAULT, AMC_APC_TASK_STACK ) )
{
    AMC_PRINTF( "APC Proxy Driver initialised\r\n" );
}
else
{
    AMC_PRINTF( "Error initialising APC Proxy Driver\r\n" );
}

Register For Callback

Define a function based on the function pointer prototype and bind in using the API.

iAPC_BindCallback Example

/* Define a callback to handle the events */
static int iApcCallback( EVL_SIGNAL *pxSignal )
{
    int iStatus = ERROR;

    if( ( NULL != pxSignal ) && ( AMC_EVENT_UNIQUE_ID_APC == pxSignal->ucModule ) )
    {
        switch( pxSignal->ucEventType )
        {
            case APC_PROXY_DRIVER_E_DOWNLOAD_STARTED:
            case APC_PROXY_DRIVER_E_DOWNLOAD_COMPLETE:
            case APC_PROXY_DRIVER_E_DOWNLOAD_FAILED:
            case APC_PROXY_DRIVER_E_DOWNLOAD_BUSY:
            case APC_PROXY_DRIVER_E_COPY_STARTED:
            case APC_PROXY_DRIVER_E_COPY_COMPLETE:
            case APC_PROXY_DRIVER_E_COPY_FAILED:
            case APC_PROXY_DRIVER_E_COPY_BUSY:
            case APC_PROXY_DRIVER_E_PARTITION_SELECTED:
            case APC_PROXY_DRIVER_E_PARTITION_SELECTION_FAILED:
                /* TODO: handle events */
                iStatus = OK;
                break;

            default:
                break;
        }
    }

    return iStatus;
}


/* Bind into the callback during the application initialisation */
if( OK == iAPC_BindCallback( &iApcCallback ) )
{
    AMC_PRINTF( "APC Proxy Driver initialised and bound\r\n" );
}
else
{
    AMC_PRINTF( "Error binding to Proxy Driver\r\n" );
}

Download image

Example of downloading an image to flash.

iAPC_DownloadImage Example

int iInstance      = 0; /* set to desired request instance */
int iPartition     = 0; /* set to desired partition number */
int iImageSize     = 0; /* set to desired image size (bytes) */
uint32_t ulSrcAddr = 0; /* set to desired source (RAM) address */

EVL_SIGNAL xSignal = { 0 };
xSignal.ucInstance = iInstance;

if( OK != iAPC_DownloadImage( &xSignal, iPartition, ulSrcAddr, ( uint32_t )iImageSize ) )
{
    APC_DBG_PRINTF( "Error writing %d bytes to partition %d\r\n", iImageSize, iPartition );
}
else
{
    APC_DBG_PRINTF( "%d bytes written from 0x%08X to partition %d\r\n",
                    iImageSize, ulSrcAddr, iPartition );
}

Copy image

Example of copying an image to flash.

iAPC_CopyImage Example

int iInstance      = 0; /* set to desired request instance */
int iSrcPartition  = 0; /* set to desired source partition number */
int iDestPartition = 0; /* set to desired destination partition number */
int iImageSize     = 0; /* set to desired image size (max num bytes) */
uint32_t ulSrcAddr = 0; /* set to desired source (RAM) address */

EVL_SIGNAL xSignal = { 0 };
xSignal.ucInstance = iInstance;

if( OK != iAPC_CopyImage( &xSignal, iSrcPartition, iDestPartition, ulSrcAddr, ( uint32_t )iImageSize ) )
{
    APC_DBG_PRINTF( "Error copying partition %d partition %d\r\n", iSrcPartition, iDestPartition );
}
else
{
    APC_DBG_PRINTF( "Partition %d copied to partition %d\r\n",
                    iSrcPartition, iDestPartition );
}

Sets

Set next partition

Example of selecting the next boot partition.

iAPC_SetNextPartition Example

int iInstance  = 0; /* set to desired request instance */
int iPartition = 0; /* set to desired partition number */

EVL_SIGNAL xSignal = { 0 };
xSignal.ucInstance = iInstance;

if( OK != iAPC_SetNextPartition( &xSignal, iPartition ) )
{
    APC_DBG_PRINTF( "Error selecting partition %d\r\n", iPartition );
}
else
{
    APC_DBG_PRINTF( "Selected partition %d\r\n", iPartition );
}

Enable hot reset

Example of enabling hot rest capability.

iAPC_EnableHotReset Example

int iInstance  = 0; /* set to desired request instance */

EVL_SIGNAL xSignal = { 0 };
xSignal.ucInstance = iInstance;

if( OK != iAPC_EnableHotReset( &xSignal ) )
{
    PLL_DAL( APC_DBG_NAME, "Error enabling hot reset\r\n" );
}
else
{
    PLL_DAL( APC_DBG_NAME, "Hot reset enabled\r\n" );
}

Gets

Get FPT header

Example of retrieving the FPT header.

iAPC_GetFptHeader Example

APC_PROXY_DRIVER_FPT_HEADER xFptHeader = { 0 };

if( OK != iAPC_GetFptHeader( &xFptHeader ) )
{
    APC_DBG_PRINTF( "Error retrieving FPT header\r\n" );
}
else
{
    APC_DBG_PRINTF( "======================================================================\r\n" );
    APC_DBG_PRINTF( "FPT header:\r\n" );
    APC_DBG_PRINTF( "\tMagic number . . . . . : 0x%08X\r\n", xFptHeader.ulMagicNum );
    APC_DBG_PRINTF( "\tFPT version. . . . . . : 0x%02X\r\n", xFptHeader.ucFptVersion );
    APC_DBG_PRINTF( "\tFPT header size. . . . : 0x%02X\r\n", xFptHeader.ucFptHeaderSize );
    APC_DBG_PRINTF( "\tEntry size . . . . . . : 0x%02X\r\n", xFptHeader.ucEntrySize );
    APC_DBG_PRINTF( "\tNum entries. . . . . . : 0x%02X\r\n", xFptHeader.ucNumEntries );
    APC_DBG_PRINTF( "======================================================================\r\n" );
}

Get FPT partition

Example of retrieving an FPT partition.

iAPC_GetFptPartition Example

int iPartition = 0; /* set to desired partition number */

APC_PROXY_DRIVER_FPT_PARTITION xFptPartition = { 0 };

if( OK != iAPC_GetFptPartition( iPartition, &xFptPartition ) )
{
    APC_DBG_PRINTF( "Error retrieving FPT Partition %d\r\n", iPartition );
}
else
{
    APC_DBG_PRINTF( "======================================================================\r\n" );
    APC_DBG_PRINTF( "FPT partition %d:\r\n", iPartition );
    APC_DBG_PRINTF( "\tPartition type . . . . : 0x%08X\r\n", xFptPartition.ulPartitionType );
    APC_DBG_PRINTF( "\tPartition base address : 0x%08X\r\n", xFptPartition.ulPartitionBaseAddr );
    APC_DBG_PRINTF( "\tPartition size . . . . : 0x%08X\r\n", xFptPartition.ulPartitionSize );
    APC_DBG_PRINTF( "======================================================================\r\n" );
}

Page Revision: v. 28