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 );
Print Statistics¶
Debug function used to display the statistic counters and errors.
iAPC_PrintStatistics
/**
* @brief Print all the stats gathered by the proxy driver
*
* @return OK Stats retrieved from proxy driver successfully
* ERROR Stats not retrieved successfully
*
*/
int iAPC_PrintStatistics( void );
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.
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().
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