1429 lines
67 KiB
C
1429 lines
67 KiB
C
|
|
/***********************************************************************************************************************
|
||
|
|
* FILE DESCRIPTION
|
||
|
|
* ------------------------------------------------------------------------------------------------------------------*/
|
||
|
|
/** \file
|
||
|
|
* \brief Interface layer for accessing the logical block table (LBT)
|
||
|
|
*
|
||
|
|
* --------------------------------------------------------------------------------------------------------------------
|
||
|
|
* COPYRIGHT
|
||
|
|
* --------------------------------------------------------------------------------------------------------------------
|
||
|
|
* \par Copyright
|
||
|
|
* \verbatim
|
||
|
|
* Copyright (c) 2023 by Vector Informatik GmbH. All rights reserved.
|
||
|
|
*
|
||
|
|
* This software is copyright protected and proprietary to Vector Informatik GmbH.
|
||
|
|
* Vector Informatik GmbH grants to you only those rights as set out in the license conditions.
|
||
|
|
* All other rights remain with Vector Informatik GmbH.
|
||
|
|
* \endverbatim
|
||
|
|
*/
|
||
|
|
/**********************************************************************************************************************/
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* REVISION HISTORY
|
||
|
|
* --------------------------------------------------------------------------------------------------------------------
|
||
|
|
* Version Date Author Change Id Description
|
||
|
|
* --------------------------------------------------------------------------------------------------------------------
|
||
|
|
* 01.00.00 2018-05-24 visci - Initial version
|
||
|
|
* 01.01.00 2018-11-27 visshs ESCAN00101459 Add Support for Secure Boot
|
||
|
|
* 01.02.00 2019-02-26 visrie ESCAN00102278 Added additional getter functions
|
||
|
|
* 01.02.01 2019-09-05 visrcn ESCAN00103604 Modified memory qualifiers
|
||
|
|
* 01.03.00 2022-03-31 visstn FBL-4366 Perform MISRA 2012 migration
|
||
|
|
* 01.04.00 2022-10-17 visjns FBL-4925 Change LBT access to use RAM
|
||
|
|
* 01.04.01 2023-04-24 vismix ESCAN00113819 Incorrect assertion expression in FblLbtActivateLbtBlockByAddress()
|
||
|
|
* 01.05.00 2023-12-14 vistbe FBL-7967 Add new filename attribute for LBT
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
|
||
|
|
#define FBL_LBT_ACCESS_SOURCE
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* INCLUDES
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
|
||
|
|
#include "fbl_inc.h"
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* VERSION
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
|
||
|
|
#if ( FBLLIB_LBT_VERSION != 0x0105u ) || \
|
||
|
|
( FBLLIB_LBT_RELEASE_VERSION != 0x00u )
|
||
|
|
# error "Error in fbl_lbt_access.c: Source and header file are inconsistent!"
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#if ( FBLLIB_LBT_VERSION != _FBLLIB_LBT_VERSION ) || \
|
||
|
|
( FBLLIB_LBT_RELEASE_VERSION != _FBLLIB_LBT_RELEASE_VERSION )
|
||
|
|
# error "Error in fbl_lbt_access.c: Source and v_ver.h are inconsistent!"
|
||
|
|
#endif
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* DEFINES
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
|
||
|
|
/* Access of LBT in RAM */
|
||
|
|
#if defined(FBL_LBT_ENABLE_RAM_BUFFER)
|
||
|
|
# define FBL_LBT_RAM_BUF_SIZE sizeof(tLogicalBlockTable)
|
||
|
|
#endif /* FBL_LBT_ENABLE_RAM_BUFFER */
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* TYPEDEFS
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
|
||
|
|
#if defined(FBL_LBT_ENABLE_RAM_BUFFER)
|
||
|
|
typedef const V_MEMRAM1 tLogicalBlockTable V_MEMRAM2 V_MEMRAM3 * tLogicalBlockTableConstPointer;
|
||
|
|
#endif /* FBL_LBT_ENABLE_RAM_BUFFER */
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* LOCAL DATA
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
|
||
|
|
#define FBLLBT_START_SEC_VAR
|
||
|
|
#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */
|
||
|
|
|
||
|
|
V_MEMRAM0 static V_MEMRAM1 tFblLbtBlockNr V_MEMRAM2 fblLbtBlockIteratorNr;
|
||
|
|
V_MEMRAM0 static V_MEMRAM1 tFblLbtBlockFilter V_MEMRAM2 fblLbtBlockIteratorFilter;
|
||
|
|
V_MEMRAM0 static V_MEMRAM1 boolean V_MEMRAM2 fblLbtBlockIteratorDone;
|
||
|
|
#if defined(FBL_LBT_ENABLE_RAM_BUFFER)
|
||
|
|
V_MEMRAM0 static V_MEMRAM1 tLogicalBlockTable V_MEMRAM2 fblLbtRamBuffer;
|
||
|
|
V_MEMROM0 static tLogicalBlockTableConstPointer V_MEMROM1 V_MEMROM2 fblLbtActive = &fblLbtRamBuffer;
|
||
|
|
#else
|
||
|
|
V_MEMRAM0 static V_MEMROM1 tLogicalBlockTable V_MEMROM2 V_MEMROM3 * V_MEMRAM1 V_MEMRAM2 fblLbtActive;
|
||
|
|
#endif /* FBL_LBT_ENABLE_RAM_BUFFER */
|
||
|
|
|
||
|
|
#define FBLLBT_STOP_SEC_VAR
|
||
|
|
#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* LOCAL FUNCTION PROTOTYPES
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
|
||
|
|
#define FBLLBT_START_SEC_CODE
|
||
|
|
#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */
|
||
|
|
|
||
|
|
static boolean FblLbtBlockFilterHit(const V_MEMRAM1 tFblLbtBlockFilter V_MEMRAM2 V_MEMRAM3 * blockFilter,
|
||
|
|
const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor);
|
||
|
|
#if defined( FBL_LBT_ENABLE_REPROGRAMMABLE_LBT )
|
||
|
|
static tFblResult FblLbtBlockCompare(const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * block1,
|
||
|
|
const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * block2);
|
||
|
|
static tFblResult FblLbtCheckReferences(void);
|
||
|
|
#endif /* FBL_LBT_ENABLE_REPROGRAMMABLE_LBT */
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* LOCAL FUNCTIONS
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtBlockFilterHit
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Check whether a certain block matches the filter settings
|
||
|
|
* \param[in] blockFilter Block filter settings
|
||
|
|
* \param[in] blockDescriptor Structure with block information
|
||
|
|
* \return Possible return values:
|
||
|
|
* - TRUE if the block matches the filter criteria
|
||
|
|
* - FALSE otherwise
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
static boolean FblLbtBlockFilterHit(const V_MEMRAM1 tFblLbtBlockFilter V_MEMRAM2 V_MEMRAM3 * blockFilter,
|
||
|
|
const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor)
|
||
|
|
{
|
||
|
|
/* Default setting: open filter */
|
||
|
|
boolean result = TRUE;
|
||
|
|
|
||
|
|
/* Check if mandatory/optional filter is enabled */
|
||
|
|
if (blockFilter->mandatoryType.enabled == TRUE)
|
||
|
|
{
|
||
|
|
/* Check if this is a mandatory block */
|
||
|
|
if (blockDescriptor->mandatoryType == TRUE)
|
||
|
|
{
|
||
|
|
/* Block is mandatory: compare against filter value */
|
||
|
|
result = (blockFilter->mandatoryType.value == TRUE) ? TRUE : FALSE;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
/* Block is optional: compare against filter value */
|
||
|
|
result = (blockFilter->mandatoryType.value == FALSE) ? TRUE : FALSE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#if defined( FBL_LBT_ENABLE_BLOCK_TYPE )
|
||
|
|
/* Check if block type filter is enabled */
|
||
|
|
if (blockFilter->blockType.enabled == TRUE)
|
||
|
|
{
|
||
|
|
/* AND logic: check if filter is still 'open' */
|
||
|
|
if (result == TRUE)
|
||
|
|
{
|
||
|
|
result = (boolean)((blockDescriptor->blockType == blockFilter->blockType.value) ? TRUE : FALSE);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
#endif /* FBL_LBT_ENABLE_BLOCK_TYPE */
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
#if defined( FBL_LBT_ENABLE_REPROGRAMMABLE_LBT )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtBlockCompare
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Compare the parameters of two blocks (member-compare)
|
||
|
|
* \param[in] block1 Structure with parameters of first block
|
||
|
|
* \param[in] block2 Structure with parameters of second block
|
||
|
|
* \return Possible return values:
|
||
|
|
* - kFblOk if the two blocks are equal
|
||
|
|
* - kFblFailed otherwise
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
static tFblResult FblLbtBlockCompare(const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * block1,
|
||
|
|
const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * block2)
|
||
|
|
{
|
||
|
|
tFblResult result = kFblOk;
|
||
|
|
|
||
|
|
if ( (block1->blockNr != block2->blockNr)
|
||
|
|
|| (block1->mandatoryType != block2->mandatoryType)
|
||
|
|
|| (block1->blockStartAddress != block2->blockStartAddress)
|
||
|
|
|| (block1->blockLength != block2->blockLength)
|
||
|
|
#if defined( FBL_LBT_ENABLE_BLOCK_INDEX )
|
||
|
|
|| (block1->blockIndex != block2->blockIndex)
|
||
|
|
#endif
|
||
|
|
#if defined( FBL_LBT_ENABLE_BLOCK_TYPE )
|
||
|
|
|| (block1->blockType != block2->blockType)
|
||
|
|
#endif
|
||
|
|
#if defined( FBL_LBT_ENABLE_HEADER_ADDRESS )
|
||
|
|
|| (block1->headerAddress != block2->headerAddress)
|
||
|
|
#endif
|
||
|
|
#if defined( FBL_LBT_ENABLE_BM_HEADER_ADDRESS )
|
||
|
|
|| (block1->bmHeaderAddress != block2->bmHeaderAddress)
|
||
|
|
#endif
|
||
|
|
#if defined( FBL_LBT_ENABLE_MAX_PROG_ATTEMPTS )
|
||
|
|
|| (block1->maxProgAttempts != block2->maxProgAttempts)
|
||
|
|
#endif
|
||
|
|
#if defined( FBL_LBT_ENABLE_VERIFY_INPUT )
|
||
|
|
|| (block1->verifyInput != block2->verifyInput)
|
||
|
|
#endif
|
||
|
|
#if defined( FBL_LBT_ENABLE_VERIFY_PROCESSED )
|
||
|
|
|| (block1->verifyProcessed != block2->verifyProcessed)
|
||
|
|
#endif
|
||
|
|
#if defined( FBL_LBT_ENABLE_VERIFY_PIPELINED )
|
||
|
|
|| (block1->verifyPipelined != block2->verifyPipelined)
|
||
|
|
#endif
|
||
|
|
#if defined( FBL_LBT_ENABLE_VERIFY_OUTPUT )
|
||
|
|
|| (block1->verifyOutput != block2->verifyOutput)
|
||
|
|
#endif
|
||
|
|
)
|
||
|
|
{
|
||
|
|
/* At least one of the block descriptor parameters doesn't match */
|
||
|
|
result = kFblFailed;
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtCheckReferences
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Check if the references which are used in the reprogrammable LBT are valid with the bootloader
|
||
|
|
* \return Possible return values:
|
||
|
|
* - kFblOk if all references are valid
|
||
|
|
* - kFblFailed otherwise
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
static tFblResult FblLbtCheckReferences(void)
|
||
|
|
{
|
||
|
|
tFblResult result = kFblOk;
|
||
|
|
tFblLbtBlockFilter blockFilter = {0};
|
||
|
|
tBlockDescriptor newLbtBlock = {0};
|
||
|
|
vuint8 tableIdx = 0u;
|
||
|
|
|
||
|
|
FblLbtBlockFilterInit(&blockFilter);
|
||
|
|
|
||
|
|
newLbtBlock = FblLbtBlockFirst(&blockFilter);
|
||
|
|
while ( FblLbtBlockDone() == FALSE )
|
||
|
|
{
|
||
|
|
#if defined( FBL_LBT_ENABLE_BLOCK_TYPE )
|
||
|
|
/* Compare actual block type against pre-defined list */
|
||
|
|
result = kFblFailed;
|
||
|
|
for (tableIdx = 0u; tableIdx < fblLbtBlockTypes.typeCount; tableIdx++)
|
||
|
|
{
|
||
|
|
if (newLbtBlock.blockType == fblLbtBlockTypes.type[tableIdx])
|
||
|
|
{
|
||
|
|
result = kFblOk;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
#endif /* FBL_LBT_ENABLE_BLOCK_TYPE */
|
||
|
|
|
||
|
|
#if defined( FBL_LBT_ENABLE_VERIFY_INPUT )
|
||
|
|
if (result == kFblOk)
|
||
|
|
{
|
||
|
|
/* Compare actual verification function against pre-defined list */
|
||
|
|
result = kFblFailed;
|
||
|
|
for (tableIdx = 0u; tableIdx < fblLbtVerificationFunc.funcCount; tableIdx++)
|
||
|
|
{
|
||
|
|
if (newLbtBlock.verifyInput == fblLbtVerificationFunc.func[tableIdx])
|
||
|
|
{
|
||
|
|
result = kFblOk;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
#endif /* FBL_LBT_ENABLE_VERIFY_INPUT */
|
||
|
|
#if defined( FBL_LBT_ENABLE_VERIFY_PROCESSED )
|
||
|
|
if (result == kFblOk)
|
||
|
|
{
|
||
|
|
/* Compare actual verification function against pre-defined list */
|
||
|
|
result = kFblFailed;
|
||
|
|
for (tableIdx = 0u; tableIdx < fblLbtVerificationFunc.funcCount; tableIdx++)
|
||
|
|
{
|
||
|
|
if (newLbtBlock.verifyProcessed == fblLbtVerificationFunc.func[tableIdx])
|
||
|
|
{
|
||
|
|
result = kFblOk;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
#endif /* FBL_LBT_ENABLE_VERIFY_PROCESSED */
|
||
|
|
#if defined( FBL_LBT_ENABLE_VERIFY_PIPELINED )
|
||
|
|
if (result == kFblOk)
|
||
|
|
{
|
||
|
|
/* Compare actual verification function against pre-defined list */
|
||
|
|
result = kFblFailed;
|
||
|
|
for (tableIdx = 0u; tableIdx < fblLbtVerificationFunc.funcCount; tableIdx++)
|
||
|
|
{
|
||
|
|
if (newLbtBlock.verifyPipelined == fblLbtVerificationFunc.func[tableIdx])
|
||
|
|
{
|
||
|
|
result = kFblOk;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
#endif /* FBL_LBT_ENABLE_VERIFY_PIPELINED */
|
||
|
|
#if defined( FBL_LBT_ENABLE_VERIFY_OUTPUT )
|
||
|
|
if (result == kFblOk)
|
||
|
|
{
|
||
|
|
/* Compare actual verification function against pre-defined list */
|
||
|
|
result = kFblFailed;
|
||
|
|
for (tableIdx = 0u; tableIdx < fblLbtVerificationFunc.funcCount; tableIdx++)
|
||
|
|
{
|
||
|
|
if (newLbtBlock.verifyOutput == fblLbtVerificationFunc.func[tableIdx])
|
||
|
|
{
|
||
|
|
result = kFblOk;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
#endif /* FBL_LBT_ENABLE_VERIFY_OUTPUT */
|
||
|
|
|
||
|
|
if (result != kFblOk)
|
||
|
|
{
|
||
|
|
/* Unknown reference used: abort */
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
newLbtBlock = FblLbtBlockNext();
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
#endif /* FBL_LBT_ENABLE_REPROGRAMMABLE_LBT */
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* GLOBAL FUNCTIONS
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtInitPowerOn
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Power-on initialization of the LBT access module
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
void FblLbtInitPowerOn(void)
|
||
|
|
{
|
||
|
|
#if defined(FBL_LBT_ENABLE_RAM_BUFFER)
|
||
|
|
/* Initialize pointer with built-in LBT copied into RAM buffer */ /* PRQA S 0306 1 */ /* MD_FblLib_Lbt_0306 */
|
||
|
|
(void)FblReadBlock((tFblAddress)&FblLogicalBlockTable, (vuint8*)&fblLbtRamBuffer, FBL_LBT_RAM_BUF_SIZE);
|
||
|
|
#else
|
||
|
|
/* Initialize pointer with built-in LBT */
|
||
|
|
fblLbtActive = &FblLogicalBlockTable;
|
||
|
|
#endif /* FBL_LBT_ENABLE_RAM_BUFFER */
|
||
|
|
}
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtBlockFilterInit
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Initialize/reset the block filter structure
|
||
|
|
* \param[out] blockFilter Structure with block filter parameters
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
void FblLbtBlockFilterInit(V_MEMRAM1 tFblLbtBlockFilter V_MEMRAM2 V_MEMRAM3 * blockFilter)
|
||
|
|
{
|
||
|
|
blockFilter->mandatoryType.enabled = FALSE;
|
||
|
|
#if defined( FBL_LBT_ENABLE_BLOCK_TYPE )
|
||
|
|
blockFilter->blockType.enabled = FALSE;
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtBlockFilterSetMandatoryType
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Set and enable the filter for the mandatory type
|
||
|
|
* \param[out] blockFilter Structure with block filter parameters
|
||
|
|
* \param[in] mandatoryType The mandatory type value which shall be filtered (optional/mandatory)
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
void FblLbtBlockFilterSetMandatoryType(V_MEMRAM1 tFblLbtBlockFilter V_MEMRAM2 V_MEMRAM3 * blockFilter,
|
||
|
|
tFblLbtMandatoryType mandatoryType)
|
||
|
|
{
|
||
|
|
blockFilter->mandatoryType.value = mandatoryType;
|
||
|
|
blockFilter->mandatoryType.enabled = TRUE;
|
||
|
|
}
|
||
|
|
|
||
|
|
#if defined( FBL_LBT_ENABLE_BLOCK_TYPE )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtBlockFilterSetBlockType
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Set and enable the filter for the block type
|
||
|
|
* \param[out] blockFilter Structure with block filter parameters
|
||
|
|
* \param[in] blockType The block type value which shall be filtered
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
void FblLbtBlockFilterSetBlockType(V_MEMRAM1 tFblLbtBlockFilter V_MEMRAM2 V_MEMRAM3 * blockFilter,
|
||
|
|
tFblLbtBlockType blockType)
|
||
|
|
{
|
||
|
|
blockFilter->blockType.value = blockType;
|
||
|
|
blockFilter->blockType.enabled = TRUE;
|
||
|
|
}
|
||
|
|
#endif /* FBL_LBT_ENABLE_BLOCK_TYPE */
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtBlockFirst
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Initialization/start function of the block iterator
|
||
|
|
* \param[in] blockFilter Structure with block filter parameters
|
||
|
|
* \return First block which matches the given filter settings
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tBlockDescriptor FblLbtBlockFirst(const V_MEMRAM1 tFblLbtBlockFilter V_MEMRAM2 V_MEMRAM3 * blockFilter)
|
||
|
|
{
|
||
|
|
fblLbtBlockIteratorNr = 0u;
|
||
|
|
fblLbtBlockIteratorFilter = *blockFilter;
|
||
|
|
fblLbtBlockIteratorDone = FALSE;
|
||
|
|
|
||
|
|
return FblLbtBlockNext();
|
||
|
|
}
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtBlockNext
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Continue/next function of the block iterator
|
||
|
|
* \return Next block which matches the filter settings which have been passed to FblLbtBlockFirst
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tBlockDescriptor FblLbtBlockNext(void)
|
||
|
|
{
|
||
|
|
tBlockDescriptor blockDescriptor = {0};
|
||
|
|
boolean filterResult = FALSE;
|
||
|
|
|
||
|
|
/* Initialize block descriptor to avoid compiler warning (invalid descriptor will NOT be used, loop is aborted before) */
|
||
|
|
blockDescriptor = FblLogicalBlockTable.logicalBlock[0u];
|
||
|
|
|
||
|
|
while (fblLbtBlockIteratorNr < fblLbtActive->noOfBlocks)
|
||
|
|
{
|
||
|
|
/* Retrieve next block from LBT */
|
||
|
|
blockDescriptor = fblLbtActive->logicalBlock[fblLbtBlockIteratorNr];
|
||
|
|
|
||
|
|
/* Increment iterator */
|
||
|
|
fblLbtBlockIteratorNr++;
|
||
|
|
|
||
|
|
/* Test block descriptor against filter settings */
|
||
|
|
filterResult = FblLbtBlockFilterHit(&fblLbtBlockIteratorFilter, &blockDescriptor);
|
||
|
|
if (filterResult == TRUE)
|
||
|
|
{
|
||
|
|
/* Current block descriptor matches the filter settings, return to caller */
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if ((fblLbtBlockIteratorNr >= fblLbtActive->noOfBlocks) && (filterResult == FALSE))
|
||
|
|
{
|
||
|
|
/* No more blocks found, abort iteration */
|
||
|
|
fblLbtBlockIteratorDone = TRUE;
|
||
|
|
}
|
||
|
|
|
||
|
|
return blockDescriptor;
|
||
|
|
}
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtBlockDone
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Implementation of the exit condition of the block iterator
|
||
|
|
* \return Boolean value which reflects the exit condition
|
||
|
|
* - FALSE: Last block not reached yet
|
||
|
|
* - TRUE : Last block has been reached
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
boolean FblLbtBlockDone(void)
|
||
|
|
{
|
||
|
|
return fblLbtBlockIteratorDone;
|
||
|
|
}
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtGetBlockCount
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Getter function for the actual block count of the active LBT
|
||
|
|
* \return Number of blocks in the active LBT
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblLbtBlockCount FblLbtGetBlockCount(void)
|
||
|
|
{
|
||
|
|
return (tFblLbtBlockCount)fblLbtActive->noOfBlocks;
|
||
|
|
}
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtGetMagicFlag
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Getter function to read the magic flag
|
||
|
|
* \return Magic flag value
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblLbtMagicFlag FblLbtGetMagicFlag(void)
|
||
|
|
{
|
||
|
|
return (tFblLbtMagicFlag)fblLbtActive->magicFlag;
|
||
|
|
}
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtGetBlockNrByAddressLength
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Look up and return the block number for a given memory range
|
||
|
|
* \param[in] address Start address of the memory range
|
||
|
|
* \param[in] length Length of the memory range
|
||
|
|
* \param[out] Block number of the respective block (if found)
|
||
|
|
* \return Possible return values:
|
||
|
|
* - kFblOk if block number could be retrieved successfully
|
||
|
|
* - kFblFailed otherwise
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblResult FblLbtGetBlockNrByAddressLength(tFblAddress address, tFblLength length,
|
||
|
|
V_MEMRAM1 tFblLbtBlockNr V_MEMRAM2 V_MEMRAM3 * blockNr)
|
||
|
|
{
|
||
|
|
tFblResult result = kFblFailed;
|
||
|
|
tBlockDescriptor localBlockDescriptor = {0};
|
||
|
|
tFblLbtBlockFilter blockFilter = {0};
|
||
|
|
|
||
|
|
/* Configure block filter (clear all filter settings) */
|
||
|
|
FblLbtBlockFilterInit(&blockFilter);
|
||
|
|
|
||
|
|
localBlockDescriptor = FblLbtBlockFirst(&blockFilter);
|
||
|
|
while (FblLbtBlockDone() == FALSE)
|
||
|
|
{
|
||
|
|
result = FblLbtCheckRangeContained(address, length,
|
||
|
|
localBlockDescriptor.blockStartAddress,
|
||
|
|
localBlockDescriptor.blockLength);
|
||
|
|
if (result == kFblOk)
|
||
|
|
{
|
||
|
|
*blockNr = localBlockDescriptor.blockNr;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
localBlockDescriptor = FblLbtBlockNext();
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtGetBlockDescriptorByNr
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Look up and return the block descriptor with a certain block number value
|
||
|
|
* \param[in] blockNr Block number value of the block to be retrieved
|
||
|
|
* \param[out] blockDescriptor Parameter structure with the information of the respective block
|
||
|
|
* \return Possible return values:
|
||
|
|
* - kFblOk if descriptor could be retrieved successfully
|
||
|
|
* - kFblFailed otherwise
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblResult FblLbtGetBlockDescriptorByNr(tFblLbtBlockNr blockNr,
|
||
|
|
V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor)
|
||
|
|
{
|
||
|
|
tFblResult result = kFblFailed;
|
||
|
|
|
||
|
|
if (blockNr < fblLbtActive->noOfBlocks)
|
||
|
|
{
|
||
|
|
*blockDescriptor = fblLbtActive->logicalBlock[blockNr];
|
||
|
|
result = kFblOk;
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtGetBlockDescriptorByAddressLength
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Look up and return the block descriptor for a given memory range
|
||
|
|
* \param[in] address Start address of the memory range
|
||
|
|
* \param[in] length Length of the memory range
|
||
|
|
* \param[out] blockDescriptor Parameter structure with the information of the respective block
|
||
|
|
* \return Possible return values:
|
||
|
|
* - kFblOk if block descriptor could be retrieved successfully
|
||
|
|
* - kFblFailed otherwise
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblResult FblLbtGetBlockDescriptorByAddressLength(tFblAddress address, tFblLength length,
|
||
|
|
V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor)
|
||
|
|
{
|
||
|
|
tFblResult result = kFblFailed;
|
||
|
|
tFblLbtBlockNr localBlockNr = 0u;
|
||
|
|
|
||
|
|
result = FblLbtGetBlockNrByAddressLength(address, length, &localBlockNr);
|
||
|
|
|
||
|
|
if (result == kFblOk)
|
||
|
|
{
|
||
|
|
result = FblLbtGetBlockDescriptorByNr(localBlockNr, blockDescriptor);
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
#if defined( FBL_LBT_ENABLE_BLOCK_TYPE )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtGetBlockDescriptorByType
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Look up and return the first block descriptor with a certain block type value
|
||
|
|
* \param[in] blockType Type value of the block to be retrieved
|
||
|
|
* \param[out] blockDescriptor Parameter structure with the information of the respective block
|
||
|
|
* \return Possible return values:
|
||
|
|
* - kFblOk if descriptor could be retrieved successfully
|
||
|
|
* - kFblFailed otherwise
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblResult FblLbtGetBlockDescriptorByType(tFblLbtBlockType blockType,
|
||
|
|
V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor)
|
||
|
|
{
|
||
|
|
tFblResult result = kFblFailed;
|
||
|
|
tBlockDescriptor localBlockDescriptor = {0};
|
||
|
|
tFblLbtBlockFilter blockFilter = {0};
|
||
|
|
|
||
|
|
/* Configure block filter (clear all filter settings) */
|
||
|
|
FblLbtBlockFilterInit(&blockFilter);
|
||
|
|
|
||
|
|
localBlockDescriptor = FblLbtBlockFirst(&blockFilter);
|
||
|
|
while ( FblLbtBlockDone() == FALSE )
|
||
|
|
{
|
||
|
|
if (localBlockDescriptor.blockType == blockType)
|
||
|
|
{
|
||
|
|
*blockDescriptor = localBlockDescriptor;
|
||
|
|
result = kFblOk;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
localBlockDescriptor = FblLbtBlockNext();
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
#endif /* FBL_LBT_ENABLE_BLOCK_TYPE */
|
||
|
|
|
||
|
|
#if defined( FBL_LBT_ENABLE_BLOCK_TYPE )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtGetBlockTypeByNr
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Look up and return the block type with a certain block index value
|
||
|
|
* \param[in] blockNr Block number value of the block to be retrieved
|
||
|
|
* \param[out] blockType Type of the respective block
|
||
|
|
* \return Possible return values:
|
||
|
|
* - kFblOk if block type could be retrieved successfully
|
||
|
|
* - kFblFailed otherwise
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblResult FblLbtGetBlockTypeByNr(tFblLbtBlockNr blockNr,
|
||
|
|
V_MEMRAM1 tFblLbtBlockType V_MEMRAM2 V_MEMRAM3 * blockType)
|
||
|
|
{
|
||
|
|
tFblResult result = kFblFailed;
|
||
|
|
tBlockDescriptor blockDescriptor = {0};
|
||
|
|
|
||
|
|
/* Initialize block type to resolve MISRA finding (blockDescriptor is only valid in case 'kFblOk' is returned) */
|
||
|
|
blockDescriptor.blockType = 0uL;
|
||
|
|
|
||
|
|
if (FblLbtGetBlockDescriptorByNr(blockNr, &blockDescriptor) == kFblOk)
|
||
|
|
{
|
||
|
|
*blockType = blockDescriptor.blockType;
|
||
|
|
result = kFblOk;
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
#endif /* FBL_LBT_ENABLE_BLOCK_TYPE */
|
||
|
|
|
||
|
|
#if defined( FBL_LBT_ENABLE_BLOCK_INDEX )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtGetBlockIndexByNr
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Look up and return the block index with a certain block index value
|
||
|
|
* \param[in] blockNr Block number value of the block to be retrieved
|
||
|
|
* \param[out] blockIndex Index of the respective block
|
||
|
|
* \return Possible return values:
|
||
|
|
* - kFblOk if block type could be retrieved successfully
|
||
|
|
* - kFblFailed otherwise
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblResult FblLbtGetBlockIndexByNr(tFblLbtBlockNr blockNr, V_MEMRAM1 tFblLbtBlockIndex V_MEMRAM2 V_MEMRAM3 * blockIndex)
|
||
|
|
{
|
||
|
|
tFblResult result = kFblFailed;
|
||
|
|
tBlockDescriptor blockDescriptor = {0};
|
||
|
|
|
||
|
|
/* Initialize block type to resolve MISRA finding (blockDescriptor is only valid in case 'kFblOk' is returned) */
|
||
|
|
blockDescriptor.blockIndex = 0uL;
|
||
|
|
|
||
|
|
if (FblLbtGetBlockDescriptorByNr(blockNr, &blockDescriptor) == kFblOk)
|
||
|
|
{
|
||
|
|
*blockIndex = blockDescriptor.blockIndex;
|
||
|
|
result = kFblOk;
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
#endif /* FBL_LBT_ENABLE_BLOCK_INDEX */
|
||
|
|
|
||
|
|
#if defined( FBL_LBT_ENABLE_HEADER_ADDRESS )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtGetBlockHeaderAddressByNr
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Look up and return the block header address with a certain block index value
|
||
|
|
* \param[in] blockNr Block number value of the block to be retrieved
|
||
|
|
* \param[out] blockHeaderAddress Header address of the respective block
|
||
|
|
* \return Possible return values:
|
||
|
|
* - kFblOk if header address could be retrieved successfully
|
||
|
|
* - kFblFailed otherwise
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblResult FblLbtGetBlockHeaderAddressByNr(tFblLbtBlockNr blockNr,
|
||
|
|
V_MEMRAM1 tFblAddress V_MEMRAM2 V_MEMRAM3 * blockHeaderAddress)
|
||
|
|
{
|
||
|
|
tFblResult result = kFblFailed;
|
||
|
|
tBlockDescriptor blockDescriptor = {0};
|
||
|
|
|
||
|
|
/* Initialize header address to resolve MISRA finding (blockDescriptor is only valid in case 'kFblOk' is returned) */
|
||
|
|
blockDescriptor.headerAddress = 0uL;
|
||
|
|
|
||
|
|
if (FblLbtGetBlockDescriptorByNr(blockNr, &blockDescriptor) == kFblOk)
|
||
|
|
{
|
||
|
|
*blockHeaderAddress = blockDescriptor.headerAddress;
|
||
|
|
result = kFblOk;
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
#endif /* FBL_LBT_ENABLE_BLOCK_HEADER_ADDRESS */
|
||
|
|
|
||
|
|
#if defined( FBL_LBT_ENABLE_BM_HEADER_ADDRESS )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtGetBlockBmHeaderAddressByNr
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Look up and return the bootmanager header address with a certain block index value
|
||
|
|
* \param[in] blockNr Block number value of the block to be retrieved
|
||
|
|
* \param[out] bmHeaderAddress BM Header address of the respective block
|
||
|
|
* \return Possible return values:
|
||
|
|
* - kFblOk if header address could be retrieved successfully
|
||
|
|
* - kFblFailed otherwise
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblResult FblLbtGetBlockBmHeaderAddressByNr(tFblLbtBlockNr blockNr,
|
||
|
|
V_MEMRAM1 tFblAddress V_MEMRAM2 V_MEMRAM3 * bmHeaderAddress)
|
||
|
|
{
|
||
|
|
tFblResult result = kFblFailed;
|
||
|
|
tBlockDescriptor blockDescriptor = {0};
|
||
|
|
|
||
|
|
/* Initialize BM header address to resolve MISRA finding (blockDescriptor is only valid in case 'kFblOk' is returned) */
|
||
|
|
blockDescriptor.bmHeaderAddress = 0uL;
|
||
|
|
|
||
|
|
if (FblLbtGetBlockDescriptorByNr(blockNr, &blockDescriptor) == kFblOk)
|
||
|
|
{
|
||
|
|
*bmHeaderAddress = blockDescriptor.bmHeaderAddress;
|
||
|
|
result = kFblOk;
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
#endif /* FBL_LBT_ENABLE_BM_HEADER_ADDRESS */
|
||
|
|
|
||
|
|
#if defined( FBL_LBT_ENABLE_MAX_PROG_ATTEMPTS )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtGetBlockMaxProgAttemptsByNr
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Look up and return the maximum programming attempts with a certain block index value
|
||
|
|
* \param[in] blockNr Block number value of the block to be retrieved
|
||
|
|
* \param[out] maxProgAttempts Maxmimum programming attempts of the respective block
|
||
|
|
* \return Possible return values:
|
||
|
|
* - kFblOk if maximum programming attempts could be retrieved successfully
|
||
|
|
* - kFblFailed otherwise
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblResult FblLbtGetBlockMaxProgAttemptsByNr(tFblLbtBlockNr blockNr,
|
||
|
|
V_MEMRAM1 tFblLbtMaxProgAttempts V_MEMRAM2 V_MEMRAM3 * maxProgAttempts)
|
||
|
|
{
|
||
|
|
tFblResult result = kFblFailed;
|
||
|
|
tBlockDescriptor blockDescriptor = {0};
|
||
|
|
|
||
|
|
/* Initialize maximum programming attempts to resolve MISRA finding (blockDescriptor is only valid in case 'kFblOk' is returned) */
|
||
|
|
blockDescriptor.maxProgAttempts = 0u;
|
||
|
|
|
||
|
|
if (FblLbtGetBlockDescriptorByNr(blockNr, &blockDescriptor) == kFblOk)
|
||
|
|
{
|
||
|
|
*maxProgAttempts = blockDescriptor.maxProgAttempts;
|
||
|
|
result = kFblOk;
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
#endif /* FBL_LBT_ENABLE_MAX_PROG_ATTEMPTS */
|
||
|
|
|
||
|
|
#if defined( FBL_LBT_ENABLE_VERIFY_INPUT )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtGetBlockVerifyInputFuncByNr
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Look up and return the verification function
|
||
|
|
* \param[in] blockNr Block number value of the block to be retrieved
|
||
|
|
* \param[out] blockVerifyFunc Address of the block specific verification function
|
||
|
|
* \return Possible return values:
|
||
|
|
* - kFblOk if verification function could be retrieved successfully
|
||
|
|
* - kFblFailed otherwise
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblResult FblLbtGetBlockVerifyInputFuncByNr(tFblLbtBlockNr blockNr,
|
||
|
|
V_MEMRAM1 tExportFct V_MEMRAM2 V_MEMRAM3 * blockVerifyFunc)
|
||
|
|
{
|
||
|
|
tFblResult result = kFblFailed;
|
||
|
|
tBlockDescriptor blockDescriptor = {0};
|
||
|
|
|
||
|
|
/* Initialize verify function to resolve MISRA finding (blockDescriptor is only valid in case 'kFblOk' is returned) */
|
||
|
|
blockDescriptor.verifyInput = (tExportFct)0;
|
||
|
|
|
||
|
|
if (FblLbtGetBlockDescriptorByNr(blockNr, &blockDescriptor) == kFblOk)
|
||
|
|
{
|
||
|
|
*blockVerifyFunc = blockDescriptor.verifyInput;
|
||
|
|
result = kFblOk;
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
#endif /* FBL_LBT_ENABLE_VERIFY_INPUT */
|
||
|
|
|
||
|
|
#if defined( FBL_LBT_ENABLE_VERIFY_PROCESSED )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtGetBlockVerifyProcessedFuncByNr
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Look up and return the verification function
|
||
|
|
* \param[in] blockNr Block number value of the block to be retrieved
|
||
|
|
* \param[out] blockVerifyFunc Address of the block specific verification function
|
||
|
|
* \return Possible return values:
|
||
|
|
* - kFblOk if verification function could be retrieved successfully
|
||
|
|
* - kFblFailed otherwise
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblResult FblLbtGetBlockVerifyProcessedFuncByNr(tFblLbtBlockNr blockNr,
|
||
|
|
V_MEMRAM1 tExportFct V_MEMRAM2 V_MEMRAM3 * blockVerifyFunc)
|
||
|
|
{
|
||
|
|
tFblResult result = kFblFailed;
|
||
|
|
tBlockDescriptor blockDescriptor = {0};
|
||
|
|
|
||
|
|
/* Initialize verify function to resolve MISRA finding (blockDescriptor is only valid in case 'kFblOk' is returned) */
|
||
|
|
blockDescriptor.verifyProcessed = (tExportFct)0;
|
||
|
|
|
||
|
|
if (FblLbtGetBlockDescriptorByNr(blockNr, &blockDescriptor) == kFblOk)
|
||
|
|
{
|
||
|
|
*blockVerifyFunc = blockDescriptor.verifyProcessed;
|
||
|
|
result = kFblOk;
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
#endif /* FBL_LBT_ENABLE_VERIFY_PROCESSED */
|
||
|
|
|
||
|
|
#if defined( FBL_LBT_ENABLE_VERIFY_PIPELINED )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtGetBlockVerifyPipelinedFuncByNr
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Look up and return the verification function
|
||
|
|
* \param[in] blockNr Block number value of the block to be retrieved
|
||
|
|
* \param[out] blockVerifyFunc Address of the block specific verification function
|
||
|
|
* \return Possible return values:
|
||
|
|
* - kFblOk if verification function could be retrieved successfully
|
||
|
|
* - kFblFailed otherwise
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblResult FblLbtGetBlockVerifyPipelinedFuncByNr(tFblLbtBlockNr blockNr,
|
||
|
|
V_MEMRAM1 tExportFct V_MEMRAM2 V_MEMRAM3 * blockVerifyFunc)
|
||
|
|
{
|
||
|
|
tFblResult result = kFblFailed;
|
||
|
|
tBlockDescriptor blockDescriptor = {0};
|
||
|
|
|
||
|
|
/* Initialize verify function to resolve MISRA finding (blockDescriptor is only valid in case 'kFblOk' is returned) */
|
||
|
|
blockDescriptor.verifyPipelined = (tExportFct)0;
|
||
|
|
|
||
|
|
if (FblLbtGetBlockDescriptorByNr(blockNr, &blockDescriptor) == kFblOk)
|
||
|
|
{
|
||
|
|
*blockVerifyFunc = blockDescriptor.verifyPipelined;
|
||
|
|
result = kFblOk;
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
#endif /* FBL_LBT_ENABLE_VERIFY_PIPELINED */
|
||
|
|
|
||
|
|
#if defined( FBL_LBT_ENABLE_VERIFY_OUTPUT )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtGetBlockVerifyOutputFuncByNr
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Look up and return the block header address with a certain block index value
|
||
|
|
* \param[in] blockNr Block number value of the block to be retrieved
|
||
|
|
* \param[out] blockVerifyFunc Address of the block specific verification function
|
||
|
|
* \return Possible return values:
|
||
|
|
* - kFblOk if verification function could be retrieved successfully
|
||
|
|
* - kFblFailed otherwise
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblResult FblLbtGetBlockVerifyOutputFuncByNr(tFblLbtBlockNr blockNr,
|
||
|
|
V_MEMRAM1 tExportFct V_MEMRAM2 V_MEMRAM3 * blockVerifyFunc)
|
||
|
|
{
|
||
|
|
tFblResult result = kFblFailed;
|
||
|
|
tBlockDescriptor blockDescriptor = {0};
|
||
|
|
|
||
|
|
/* Initialize verify function to resolve MISRA finding (blockDescriptor is only valid in case 'kFblOk' is returned) */
|
||
|
|
blockDescriptor.verifyOutput = (tExportFct)0uL;
|
||
|
|
|
||
|
|
if (FblLbtGetBlockDescriptorByNr(blockNr, &blockDescriptor) == kFblOk)
|
||
|
|
{
|
||
|
|
*blockVerifyFunc = blockDescriptor.verifyOutput;
|
||
|
|
result = kFblOk;
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
#endif /* FBL_LBT_ENABLE_VERIFY_OUTPUT */
|
||
|
|
|
||
|
|
#if defined( FBL_LBT_ENABLE_BLOCK_INDEX )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtGetBlockDescriptorByIndex
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Look up and return the block descriptor with a certain block index value
|
||
|
|
* \param[in] blockIndex Index value of the block to be retrieved
|
||
|
|
* \param[out] blockDescriptor Parameter structure with the information of the respective block
|
||
|
|
* \return Possible return values:
|
||
|
|
* - kFblOk if descriptor could be retrieved successfully
|
||
|
|
* - kFblFailed otherwise
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblResult FblLbtGetBlockDescriptorByIndex(tFblLbtBlockIndex blockIndex,
|
||
|
|
V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor)
|
||
|
|
{
|
||
|
|
tFblResult result = kFblFailed;
|
||
|
|
tBlockDescriptor localBlockDescriptor = {0};
|
||
|
|
tFblLbtBlockFilter blockFilter = {0};
|
||
|
|
|
||
|
|
/* Configure block filter (clear all filter settings) */
|
||
|
|
FblLbtBlockFilterInit(&blockFilter);
|
||
|
|
|
||
|
|
localBlockDescriptor = FblLbtBlockFirst(&blockFilter);
|
||
|
|
while ( FblLbtBlockDone() == FALSE )
|
||
|
|
{
|
||
|
|
if (localBlockDescriptor.blockIndex == blockIndex)
|
||
|
|
{
|
||
|
|
*blockDescriptor = localBlockDescriptor;
|
||
|
|
result = kFblOk;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
localBlockDescriptor = FblLbtBlockNext();
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtGetBlockNrByIndex
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Look up and return the block number with a certain block index value
|
||
|
|
* \param[in] blockIndex Index value of the block to be retrieved
|
||
|
|
* \param[out] blockNr Number of the respective block
|
||
|
|
* \return Possible return values:
|
||
|
|
* - kFblOk if block number could be retrieved successfully
|
||
|
|
* - kFblFailed otherwise
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblResult FblLbtGetBlockNrByIndex(tFblLbtBlockIndex blockIndex,
|
||
|
|
V_MEMRAM1 tFblLbtBlockNr V_MEMRAM2 V_MEMRAM3 * blockNr)
|
||
|
|
{
|
||
|
|
tFblResult result = kFblFailed;
|
||
|
|
tBlockDescriptor blockDescriptor = {0};
|
||
|
|
|
||
|
|
/* Initialize block number to resolve MISRA finding (blockDescriptor is only valid in case 'kFblOk' is returned) */
|
||
|
|
blockDescriptor.blockNr = 0u;
|
||
|
|
|
||
|
|
if (FblLbtGetBlockDescriptorByIndex(blockIndex, &blockDescriptor) == kFblOk)
|
||
|
|
{
|
||
|
|
*blockNr = blockDescriptor.blockNr;
|
||
|
|
result = kFblOk;
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
# if defined( FBL_LBT_ENABLE_BLOCK_TYPE )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtGetBlockTypeByIndex
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Look up and return the block type with a certain block index value
|
||
|
|
* \param[in] blockIndex Index value of the block to be retrieved
|
||
|
|
* \param[out] blockType Type of the respective block
|
||
|
|
* \return Possible return values:
|
||
|
|
* - kFblOk if block type could be retrieved successfully
|
||
|
|
* - kFblFailed otherwise
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblResult FblLbtGetBlockTypeByIndex(tFblLbtBlockIndex blockIndex,
|
||
|
|
V_MEMRAM1 tFblLbtBlockType V_MEMRAM2 V_MEMRAM3 * blockType)
|
||
|
|
{
|
||
|
|
tFblResult result = kFblFailed;
|
||
|
|
tBlockDescriptor blockDescriptor = {0};
|
||
|
|
|
||
|
|
/* Initialize block type to resolve MISRA finding (blockDescriptor is only valid in case 'kFblOk' is returned) */
|
||
|
|
blockDescriptor.blockType = 0uL;
|
||
|
|
|
||
|
|
if (FblLbtGetBlockDescriptorByIndex(blockIndex, &blockDescriptor) == kFblOk)
|
||
|
|
{
|
||
|
|
*blockType = blockDescriptor.blockType;
|
||
|
|
result = kFblOk;
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
# endif /* FBL_LBT_ENABLE_BLOCK_TYPE */
|
||
|
|
|
||
|
|
# if defined( FBL_LBT_ENABLE_HEADER_ADDRESS )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtGetBlockHeaderAddressByIndex
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Look up and return the block header address with a certain block index value
|
||
|
|
* \param[in] blockIndex Index value of the block to be retrieved
|
||
|
|
* \param[out] blockHeaderAddress Header address of the respective block
|
||
|
|
* \return Possible return values:
|
||
|
|
* - kFblOk if header address could be retrieved successfully
|
||
|
|
* - kFblFailed otherwise
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblResult FblLbtGetBlockHeaderAddressByIndex(tFblLbtBlockIndex blockIndex,
|
||
|
|
V_MEMRAM1 tFblAddress V_MEMRAM2 V_MEMRAM3 * blockHeaderAddress)
|
||
|
|
{
|
||
|
|
tFblResult result = kFblFailed;
|
||
|
|
tBlockDescriptor blockDescriptor = {0};
|
||
|
|
|
||
|
|
/* Initialize header address to resolve MISRA finding (blockDescriptor is only valid in case 'kFblOk' is returned) */
|
||
|
|
blockDescriptor.headerAddress = 0uL;
|
||
|
|
|
||
|
|
if (FblLbtGetBlockDescriptorByIndex(blockIndex, &blockDescriptor) == kFblOk)
|
||
|
|
{
|
||
|
|
*blockHeaderAddress = blockDescriptor.headerAddress;
|
||
|
|
result = kFblOk;
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
# endif /* FBL_LBT_ENABLE_BLOCK_HEADER_ADDRESS */
|
||
|
|
|
||
|
|
# if defined( FBL_LBT_ENABLE_BM_HEADER_ADDRESS )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtGetBlockBmHeaderAddressByIndex
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Look up and return the bootmanager header address with a certain block index value
|
||
|
|
* \param[in] blockIndex Index value of the block to be retrieved
|
||
|
|
* \param[out] bmHeaderAddress BM Header address of the respective block
|
||
|
|
* \return Possible return values:
|
||
|
|
* - kFblOk if header address could be retrieved successfully
|
||
|
|
* - kFblFailed otherwise
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblResult FblLbtGetBlockBmHeaderAddressByIndex(tFblLbtBlockIndex blockIndex,
|
||
|
|
V_MEMRAM1 tFblAddress V_MEMRAM2 V_MEMRAM3 * bmHeaderAddress)
|
||
|
|
{
|
||
|
|
tFblResult result = kFblFailed;
|
||
|
|
tBlockDescriptor blockDescriptor = {0};
|
||
|
|
|
||
|
|
/* Initialize BM header address to resolve MISRA finding (blockDescriptor is only valid in case 'kFblOk' is returned) */
|
||
|
|
blockDescriptor.bmHeaderAddress = 0uL;
|
||
|
|
|
||
|
|
if (FblLbtGetBlockDescriptorByIndex(blockIndex, &blockDescriptor) == kFblOk)
|
||
|
|
{
|
||
|
|
*bmHeaderAddress = blockDescriptor.bmHeaderAddress;
|
||
|
|
result = kFblOk;
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
# endif /* FBL_LBT_ENABLE_BM_HEADER_ADDRESS */
|
||
|
|
|
||
|
|
# if defined( FBL_LBT_ENABLE_MAX_PROG_ATTEMPTS )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtGetBlockMaxProgAttemptsByIndex
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Look up and return the maximum programming attempts with a certain block index value
|
||
|
|
* \param[in] blockIndex Index value of the block to be retrieved
|
||
|
|
* \param[out] maxProgAttempts Maxmimum programming attempts of the respective block
|
||
|
|
* \return Possible return values:
|
||
|
|
* - kFblOk if maximum programming attempts could be retrieved successfully
|
||
|
|
* - kFblFailed otherwise
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblResult FblLbtGetBlockMaxProgAttemptsByIndex(tFblLbtBlockIndex blockIndex,
|
||
|
|
V_MEMRAM1 tFblLbtMaxProgAttempts V_MEMRAM2 V_MEMRAM3 * maxProgAttempts)
|
||
|
|
{
|
||
|
|
tFblResult result = kFblFailed;
|
||
|
|
tBlockDescriptor blockDescriptor = {0};
|
||
|
|
|
||
|
|
/* Initialize maximum programming attempts to resolve MISRA finding (blockDescriptor is only valid in case 'kFblOk' is returned) */
|
||
|
|
blockDescriptor.maxProgAttempts = 0u;
|
||
|
|
|
||
|
|
if (FblLbtGetBlockDescriptorByIndex(blockIndex, &blockDescriptor) == kFblOk)
|
||
|
|
{
|
||
|
|
*maxProgAttempts = blockDescriptor.maxProgAttempts;
|
||
|
|
result = kFblOk;
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
# endif /* FBL_LBT_ENABLE_MAX_PROG_ATTEMPTS */
|
||
|
|
|
||
|
|
# if defined( FBL_LBT_ENABLE_VERIFY_INPUT )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtGetBlockVerifyInputFuncByIndex
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Look up and return the verification function
|
||
|
|
* \param[in] blockIndex Index value of the block to be retrieved
|
||
|
|
* \param[out] blockVerifyFunc Address of the block specific verification function
|
||
|
|
* \return Possible return values:
|
||
|
|
* - kFblOk if verification function could be retrieved successfully
|
||
|
|
* - kFblFailed otherwise
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblResult FblLbtGetBlockVerifyInputFuncByIndex(tFblLbtBlockIndex blockIndex,
|
||
|
|
V_MEMRAM1 tExportFct V_MEMRAM2 V_MEMRAM3 * blockVerifyFunc)
|
||
|
|
{
|
||
|
|
tFblResult result = kFblFailed;
|
||
|
|
tBlockDescriptor blockDescriptor = {0};
|
||
|
|
|
||
|
|
/* Initialize verify function to resolve MISRA finding (blockDescriptor is only valid in case 'kFblOk' is returned) */
|
||
|
|
blockDescriptor.verifyInput = (tExportFct)0;
|
||
|
|
|
||
|
|
if (FblLbtGetBlockDescriptorByIndex(blockIndex, &blockDescriptor) == kFblOk)
|
||
|
|
{
|
||
|
|
*blockVerifyFunc = blockDescriptor.verifyInput;
|
||
|
|
result = kFblOk;
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
# endif /* FBL_LBT_ENABLE_VERIFY_INPUT */
|
||
|
|
|
||
|
|
# if defined( FBL_LBT_ENABLE_VERIFY_PROCESSED )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtGetBlockVerifyProcessedFuncByIndex
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Look up and return the verification function
|
||
|
|
* \param[in] blockIndex Index value of the block to be retrieved
|
||
|
|
* \param[out] blockVerifyFunc Address of the block specific verification function
|
||
|
|
* \return Possible return values:
|
||
|
|
* - kFblOk if verification function could be retrieved successfully
|
||
|
|
* - kFblFailed otherwise
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblResult FblLbtGetBlockVerifyProcessedFuncByIndex(tFblLbtBlockIndex blockIndex,
|
||
|
|
V_MEMRAM1 tExportFct V_MEMRAM2 V_MEMRAM3 * blockVerifyFunc)
|
||
|
|
{
|
||
|
|
tFblResult result = kFblFailed;
|
||
|
|
tBlockDescriptor blockDescriptor = {0};
|
||
|
|
|
||
|
|
/* Initialize verify function to resolve MISRA finding (blockDescriptor is only valid in case 'kFblOk' is returned) */
|
||
|
|
blockDescriptor.verifyProcessed = (tExportFct)0;
|
||
|
|
|
||
|
|
if (FblLbtGetBlockDescriptorByIndex(blockIndex, &blockDescriptor) == kFblOk)
|
||
|
|
{
|
||
|
|
*blockVerifyFunc = blockDescriptor.verifyProcessed;
|
||
|
|
result = kFblOk;
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
# endif /* FBL_LBT_ENABLE_VERIFY_PROCESSED */
|
||
|
|
|
||
|
|
# if defined( FBL_LBT_ENABLE_VERIFY_PIPELINED )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtGetBlockVerifyPipelinedFuncByIndex
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Look up and return the verification function
|
||
|
|
* \param[in] blockIndex Index value of the block to be retrieved
|
||
|
|
* \param[out] blockVerifyFunc Address of the block specific verification function
|
||
|
|
* \return Possible return values:
|
||
|
|
* - kFblOk if verification function could be retrieved successfully
|
||
|
|
* - kFblFailed otherwise
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblResult FblLbtGetBlockVerifyPipelinedFuncByIndex(tFblLbtBlockIndex blockIndex,
|
||
|
|
V_MEMRAM1 tExportFct V_MEMRAM2 V_MEMRAM3 * blockVerifyFunc)
|
||
|
|
{
|
||
|
|
tFblResult result = kFblFailed;
|
||
|
|
tBlockDescriptor blockDescriptor = {0};
|
||
|
|
|
||
|
|
/* Initialize verify function to resolve MISRA finding (blockDescriptor is only valid in case 'kFblOk' is returned) */
|
||
|
|
blockDescriptor.verifyPipelined = (tExportFct)0;
|
||
|
|
|
||
|
|
if (FblLbtGetBlockDescriptorByIndex(blockIndex, &blockDescriptor) == kFblOk)
|
||
|
|
{
|
||
|
|
*blockVerifyFunc = blockDescriptor.verifyPipelined;
|
||
|
|
result = kFblOk;
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
# endif /* FBL_LBT_ENABLE_VERIFY_PIPELINED */
|
||
|
|
|
||
|
|
# if defined( FBL_LBT_ENABLE_VERIFY_OUTPUT )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtGetBlockVerifyOutputFuncByIndex
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Look up and return the block header address with a certain block index value
|
||
|
|
* \param[in] blockIndex Index value of the block to be retrieved
|
||
|
|
* \param[out] blockVerifyFunc Address of the block specific verification function
|
||
|
|
* \return Possible return values:
|
||
|
|
* - kFblOk if verification function could be retrieved successfully
|
||
|
|
* - kFblFailed otherwise
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblResult FblLbtGetBlockVerifyOutputFuncByIndex(tFblLbtBlockIndex blockIndex,
|
||
|
|
V_MEMRAM1 tExportFct V_MEMRAM2 V_MEMRAM3 * blockVerifyFunc)
|
||
|
|
{
|
||
|
|
tFblResult result = kFblFailed;
|
||
|
|
tBlockDescriptor blockDescriptor = {0};
|
||
|
|
|
||
|
|
/* Initialize verify function to resolve MISRA finding (blockDescriptor is only valid in case 'kFblOk' is returned) */
|
||
|
|
blockDescriptor.verifyOutput = (tExportFct)0;
|
||
|
|
|
||
|
|
if (FblLbtGetBlockDescriptorByIndex(blockIndex, &blockDescriptor) == kFblOk)
|
||
|
|
{
|
||
|
|
*blockVerifyFunc = blockDescriptor.verifyOutput;
|
||
|
|
result = kFblOk;
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
# endif /* FBL_LBT_ENABLE_VERIFY_OUTPUT */
|
||
|
|
#endif /* FBL_LBT_ENABLE_BLOCK_INDEX */
|
||
|
|
|
||
|
|
#if defined( FBL_LBT_ENABLE_FILE_NAME )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtGetBlockDescriptorByFilenameLength
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Look up and return the block descriptor for a file name and length
|
||
|
|
* \param[in] fileName Name of the file
|
||
|
|
* \param[in] fileNameSize Size of the give file name
|
||
|
|
* \param[in] fileLength Length of the file to be downloaded
|
||
|
|
* \param[out] blockDescriptor Parameter structure with the information of the respective block
|
||
|
|
* \return Possible return values:
|
||
|
|
* - kFblOk if block descriptor could be retrieved successfully
|
||
|
|
* - kFblFailed otherwise
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblResult FblLbtGetBlockDescriptorByFilenameLength(const V_MEMRAM1 tFblLbtFileName V_MEMRAM2 V_MEMRAM3 * fileName,
|
||
|
|
tFblLbtFileNameSize fileNameSize, tFblLength fileLength, V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor)
|
||
|
|
{
|
||
|
|
tFblResult result = kFblFailed;
|
||
|
|
tBlockDescriptor localBlockDescriptor = {0};
|
||
|
|
tFblLbtBlockFilter blockFilter = {0};
|
||
|
|
|
||
|
|
/* Configure block filter (clear all filter settings) */
|
||
|
|
FblLbtBlockFilterInit(&blockFilter);
|
||
|
|
|
||
|
|
localBlockDescriptor = FblLbtBlockFirst(&blockFilter);
|
||
|
|
while ( FblLbtBlockDone() == FALSE )
|
||
|
|
{
|
||
|
|
/* Check if file name exists for checked block and if file name size matches.
|
||
|
|
Also allow a length with one byte less to support strings without zero termination */
|
||
|
|
if ((localBlockDescriptor.fileName != V_NULL) &&
|
||
|
|
(localBlockDescriptor.fileNameSize > 0u) &&
|
||
|
|
((localBlockDescriptor.fileNameSize == fileNameSize) ||
|
||
|
|
((localBlockDescriptor.fileNameSize - 1u) == fileNameSize )) &&
|
||
|
|
(localBlockDescriptor.blockLength >= fileLength))
|
||
|
|
{
|
||
|
|
vuintx i;
|
||
|
|
|
||
|
|
/* Compare file name */
|
||
|
|
for (i = 0u; i < fileNameSize; i++)
|
||
|
|
{
|
||
|
|
if (fileName[i] != localBlockDescriptor.fileName[i])
|
||
|
|
{
|
||
|
|
/* Missmatch detected -> File name is not equal */
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (i == fileNameSize)
|
||
|
|
{
|
||
|
|
*blockDescriptor = localBlockDescriptor;
|
||
|
|
result = kFblOk;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
localBlockDescriptor = FblLbtBlockNext();
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
#endif /* FBL_LBT_ENABLE_FILE_NAME */
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtCheckAddressRange
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Check whether an address lies within a specified address range
|
||
|
|
* \param[in] address Address to be checked
|
||
|
|
* \param[in] rangeStart Start of range
|
||
|
|
* \param[in] rangeLength Length of range
|
||
|
|
* \return Possible return values:
|
||
|
|
* - kFblOk if address lies within range
|
||
|
|
* - kFblFailed otherwise
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblResult FblLbtCheckAddressRange(tFblAddress address, tFblAddress rangeStart, tFblLength rangeLength)
|
||
|
|
{
|
||
|
|
tFblResult result = kFblFailed;
|
||
|
|
|
||
|
|
if ( (address >= rangeStart)
|
||
|
|
&& ((address - rangeStart) < rangeLength) )
|
||
|
|
{
|
||
|
|
result = kFblOk;
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtCheckRangeContained
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Check whether an address range lies within another specified address range
|
||
|
|
* \param[in] address Start address of range to be checked
|
||
|
|
* \param[in] length Length of range to be checked
|
||
|
|
* \param[in] rangeStart Start of range
|
||
|
|
* \param[in] rangeLength Length of range
|
||
|
|
* \return Possible return values:
|
||
|
|
* - kFblOk if range lies within range
|
||
|
|
* - kFblFailed otherwise
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblResult FblLbtCheckRangeContained(tFblAddress address, tFblLength length, tFblAddress rangeStart, tFblLength rangeLength)
|
||
|
|
{
|
||
|
|
tFblResult result = kFblFailed;
|
||
|
|
|
||
|
|
if ((FblLbtCheckAddressRange(address, rangeStart, rangeLength) == kFblOk)
|
||
|
|
&& (length <= rangeLength)
|
||
|
|
&& ((address - rangeStart) <= (rangeLength - length)) )
|
||
|
|
{
|
||
|
|
result = kFblOk;
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
#if defined( FBL_LBT_ENABLE_REPROGRAMMABLE_LBT )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtCheckConsistency
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Check consistency between the LBT which resides in the LBT block and the bootloader
|
||
|
|
* \return Possible return values:
|
||
|
|
* - kFblOk if the information in the new LBT is consistent with the bootloader
|
||
|
|
* - kFblFailed otherwise
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblResult FblLbtCheckConsistency(void)
|
||
|
|
{
|
||
|
|
tFblResult result = kFblOk;
|
||
|
|
tFblLbtBlockNr localBlockNr = 0u;
|
||
|
|
tBlockDescriptor baseBlock = {0};
|
||
|
|
tBlockDescriptor newBlock = {0};
|
||
|
|
|
||
|
|
/* Additional consistency checks should be performed by the generator which might be OEM/configuration specific, e.g.:
|
||
|
|
* - SBL and LBT block are unique and of type 'mandatory'
|
||
|
|
* - At least one logical block besides SBL/LBT is of type 'mandatory'
|
||
|
|
* - Block index of all blocks is unique
|
||
|
|
* - The configured logical blocks cover all blocks defined in the FBT
|
||
|
|
* - Block header address of all blocks lies inside the respective block area
|
||
|
|
* - Block header address has a reasonable distance from the presence pattern area
|
||
|
|
*/
|
||
|
|
|
||
|
|
/* Temporarily switch to new LBT for consistency checks */
|
||
|
|
FblLbtActivateLbtBlock();
|
||
|
|
|
||
|
|
/* Check if block count exceeds built-in maximum value */
|
||
|
|
if (fblLbtActive->noOfBlocks > (tFblLbtBlockCount)FBL_LBT_BLOCK_COUNT)
|
||
|
|
{
|
||
|
|
result = kFblFailed;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Check LBT against built-in FBT */
|
||
|
|
if ((result == kFblOk) && (fblLbtActive->magicFlag != FblLogicalBlockTable.magicFlag))
|
||
|
|
{
|
||
|
|
result = kFblFailed;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Compare fixed blocks in built-in LBT against new LBT */
|
||
|
|
if (result == kFblOk)
|
||
|
|
{
|
||
|
|
for (localBlockNr = 0u; localBlockNr < FblLogicalBlockTable.noOfBlocks; localBlockNr++)
|
||
|
|
{
|
||
|
|
baseBlock = FblLogicalBlockTable.logicalBlock[localBlockNr];
|
||
|
|
result = FblLbtGetBlockDescriptorByNr(localBlockNr, &newBlock);
|
||
|
|
if (result == kFblOk)
|
||
|
|
{
|
||
|
|
result = FblLbtBlockCompare(&baseBlock, &newBlock);
|
||
|
|
}
|
||
|
|
if (result != kFblOk)
|
||
|
|
{
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Check block type and verify functions against built-in values */
|
||
|
|
if (result == kFblOk)
|
||
|
|
{
|
||
|
|
result = FblLbtCheckReferences();
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Revert LBT pointer to built-in table */
|
||
|
|
FblLbtInitPowerOn();
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtActivateLbtBlock
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Activate usage of the reprogrammable LBT
|
||
|
|
* \pre FblLbtCheckConsistency() has been executed with positive result
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
void FblLbtActivateLbtBlock(void)
|
||
|
|
{
|
||
|
|
/* Switch to logical block table in LBT block */
|
||
|
|
# if defined( FBL_LBT_ENABLE_RAM_BUFFER )
|
||
|
|
FblLbtActivateLbtBlockByAddress(FblLogicalBlockTable.logicalBlock[FBL_MTAB_LBT_BLOCK_NUMBER].blockStartAddress);
|
||
|
|
# else
|
||
|
|
/* PRQA S 0306 1 */ /* MD_FblLib_Lbt_0306 */
|
||
|
|
fblLbtActive = (V_MEMROM1 tLogicalBlockTable V_MEMROM2 V_MEMROM3 *)FblLogicalBlockTable.logicalBlock[FBL_MTAB_LBT_BLOCK_NUMBER].blockStartAddress;
|
||
|
|
# endif /* FBL_LBT_ENABLE_RAM_BUFFER */
|
||
|
|
}
|
||
|
|
#endif /* FBL_LBT_ENABLE_REPROGRAMMABLE_LBT */
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* FblLbtActivateLbtBlockByAddress
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Activate usage of the reprogrammable LBT
|
||
|
|
* \details CAUTION: The function will set the internal LBT pointer without further consistency checks. It's in
|
||
|
|
* the responsibility of the caller to check the LBT consistency before accessing the contained
|
||
|
|
* information!
|
||
|
|
* \param[in] address Address of the logical block table, which should now be used
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
void FblLbtActivateLbtBlockByAddress(tFblAddress address)
|
||
|
|
{
|
||
|
|
/* Switch to logical block table in LBT block */
|
||
|
|
#if defined(FBL_LBT_ENABLE_RAM_BUFFER)
|
||
|
|
tFblLength readCount = FblReadProm(address, (vuint8*)&fblLbtRamBuffer, FBL_LBT_RAM_BUF_SIZE);
|
||
|
|
/* PRQA S 3205 1 */ /* MD_FblLib_Lbt_3205 */
|
||
|
|
assertFbl(readCount == FBL_LBT_RAM_BUF_SIZE, kFblSysAssertParameterOutOfRange);
|
||
|
|
#else
|
||
|
|
/* PRQA S 0306 1 */ /* MD_FblLib_Lbt_0306 */
|
||
|
|
fblLbtActive = (V_MEMROM1 tLogicalBlockTable V_MEMROM2 V_MEMROM3 *)address;
|
||
|
|
#endif /* FBL_LBT_ENABLE_RAM_BUFFER */
|
||
|
|
}
|
||
|
|
#define FBLLBT_STOP_SEC_CODE
|
||
|
|
#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* MISRA DEVIATIONS
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
|
||
|
|
/* module specific MISRA deviations:
|
||
|
|
|
||
|
|
MD_FblLib_Lbt_0306:
|
||
|
|
Reason: Address conversion between integer values and pointers is required to allow for hardware independent
|
||
|
|
configuration and address range checks.
|
||
|
|
Risk: The size of integer required to hold the result of a pointer cast is implementation-defined.
|
||
|
|
Prevention: The size of the respective integer data type which holds the address value is adapted on a hardware
|
||
|
|
specific basis. The correctness of the respective implementation is verified by runtime tests.
|
||
|
|
|
||
|
|
MD_FblLib_Lbt_3205:
|
||
|
|
Reason: Depending on the configuration some variables are not referenced by the code. For simplicity the
|
||
|
|
variables are kept.
|
||
|
|
Risk: No identifiable risk.
|
||
|
|
Prevention: No prevention required.
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* END OF FILE: FBL_LBT_ACCESS.C
|
||
|
|
**********************************************************************************************************************/
|