FLEX-FORD-OBC-BM/Source/bsw/Fbl/fbl_main.c

604 lines
26 KiB
C
Raw Permalink Normal View History

2026-03-19 11:49:16 +01:00
/***********************************************************************************************************************
* FILE DESCRIPTION
* ------------------------------------------------------------------------------------------------------------------*/
/** \file
* \brief Main module of FBL
*
* --------------------------------------------------------------------------------------------------------------------
* COPYRIGHT
* --------------------------------------------------------------------------------------------------------------------
* \par Copyright
* \verbatim
* Copyright (c) 2025 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
* --------------------------------------------------------------------------------------------------------------------
* 05.00.00 2019-10-10 vistmo FBL-388 Adapt main function interface for vBaseEnv
* 05.01.00 2019-11-14 visrcn FBL-830 Add support for VTT use case
* 05.01.01 2020-02-27 vistbe ESCAN00105432 [DemoAppl] No diagnostic requests can be processed
* 06.00.00 2020-04-08 visrie FBL-1016 Support of EcuM functions, support of new FblSb interface
* 06.01.00 2020-04-29 vistmo FBL-1584 Adding OTA startup support
* 06.01.01 2020-10-28 visrcn ESCAN00107190 Compiler error: Wrong definition for FblMain function
* 06.01.02 2020-11-26 visrcn ESCAN00107979 Tester connection is not shutdown after StayInBoot check
* 06.02.00 2022-04-08 lhopfhauer FBL-4852 Add support for new swap API
* 06.03.00 2022-05-06 lhopfhauer FBL-5148 Encapsulate call of FblInterruptDisable
* 06.04.00 2022-07-06 fmenke FBL-5235 Use Pre Timer/Wd init as standard
* 06.05.00 2022-11-30 visrie FBL-6065 Encapsulate FblMain declaration
* 06.05.01 2023-04-06 lhopfhauer ESCAN00113532 [DemoAppl only] FblCwClrCheckForStartMsg is not cleared if Stay
* in Boot is enabled - DemoAppl is not responding
* 06.06.00 2023-05-24 fmenke FBL-7036 P2 timeout in tester after the programming session request
* 06.07.00 2025-06-18 vsarcmijo FBL-9710 Extend presence pattern to connect validity information
* ESCAN00116602 [DemoAppl only] Compiler error: FblCwClrCheckForStartMsg is not
* defined
* 06.08.00 2025-10-21 pharring FBL-11469 Set a state when FblRepeat is reached
**********************************************************************************************************************/
#define FBL_MAIN_SOURCE
/***********************************************************************************************************************
* INCLUDES
**********************************************************************************************************************/
#include "fbl_inc.h"
#include "EcuM.h"
/***********************************************************************************************************************
* VERSION
**********************************************************************************************************************/
#if ( FBLMAIN_VERSION != 0x0608u ) || \
( FBLMAIN_RELEASE_VERSION != 0x00u )
# error "Error in fbl_main.c: Source and header file are inconsistent!"
#endif
#if ( FBLMAIN_VERSION != _FBL_MAIN_VERSION ) || \
( FBLMAIN_RELEASE_VERSION != _FBL_MAIN_RELEASE_VERSION)
# error "Error in fbl_main.c: Source and v_ver.h are inconsistent!"
#endif
#if defined( _MICROSOFT_C_VTT_ )
# define FBL_MAIN_ENABLE_VTT_USECASE
#endif /* _MICROSOFT_C_VTT_ */
/***********************************************************************************************************************
* DEFINES
**********************************************************************************************************************/
#if !defined( FBL_BM_HEADER_ADDRESS )
# define FBL_BM_HEADER_ADDRESS &FblBmHdrHeader
#endif /* FBL_BM_HEADER_ADDRESS */
/* FblStart feature */
#if defined( FBL_ENABLE_FBL_START )
# if !defined( FblStartReset )
# define FblStartReset() ApplFblReset()
# endif
#endif /* FBL_ENABLE_FBL_START */
# if defined( FBL_ENABLE_STAY_IN_BOOT )
# if !defined( kFblMainStartMessageDelay )
# define kFblMainStartMessageDelay 20u /**< Start message delay default value: 20ms */
# endif
# define kFblMainStartMessageReceived 0u /**< Indicates that a startup message has been received */
# define kFblMainStartMessageTimeout 1u /**< No startup message has been received before timeout */
# endif /* FBL_ENABLE_STAY_IN_BOOT */
/* Main state handling */
#define FblMainSetStartFromReset() SetFblMainState( kFblMainStateStartFromReset )
#define FblMainSetStartFromAppl() SetFblMainState( kFblMainStateStartFromAppl )
#define FblMainSetStartFromXcp() SetFblMainState( kFblMainStateStartFromXcp )
#define FblMainSetStartFromOta() SetFblMainState( kFblMainStateStartFromOta )
#define FblMainSetApplicationValid() SetFblMainState( kFblMainStateApplicationValid )
#define FblMainSetWaitStartMessage() { \
SetFblMainState( kFblMainStateWaitStartMessage ); \
startMessageDelay = kFblMainStartMessageDelay + 1u; \
}
#define FblMainSetStartMessageReceived() SetFblMainState( kFblMainStateStartMessageReceived )
#define FblMainClrStartFromReset() ClrFblMainState( kFblMainStateStartFromReset )
#define FblMainClrStartFromAppl() ClrFblMainState( kFblMainStateStartFromAppl )
#define FblMainClrStartFromXcp() ClrFblMainState( kFblMainStateStartFromXcp )
#define FblMainClrStartFromOta() ClrFblMainState( kFblMainStateStartFromOta )
#define FblMainClrApplicationValid() ClrFblMainState( kFblMainStateApplicationValid )
#define FblMainClrWaitStartMessage() ClrFblMainState( kFblMainStateWaitStartMessage )
#define FblMainClrStartMessageReceived() ClrFblMainState( kFblMainStateStartMessageReceived )
/***********************************************************************************************************************
* GLOBAL DATA
**********************************************************************************************************************/
# define FBLHEADER_START_SEC_CONST
# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */
/** FBL header data for access from application software */
V_MEMROM0 V_MEMROM1 tFblHeader V_MEMROM2 FblHeader = /* PRQA S 1514 */ /* MD_FblMain_1514_FblHeader */
{
FBL_MAIN_HEADER_MAGIC_FLAG
# if defined( FBL_MTAB_NO_OF_BLOCKS )
,(tFblHeaderLogicalBlockTablePtr)(&FblLogicalBlockTable)
,sizeof(FblLogicalBlockTable)
# else
,V_NULL
,0u
# endif
# if defined( FBL_ENABLE_COMMON_DATA )
,(tFblCommonDataPtr)(&fblCommonData)
# endif
,FBL_BLOCK_START_ADDRESS
,FBL_BLOCK_LENGTH
,FBL_BM_HEADER_ADDRESS
};
# define FBLHEADER_STOP_SEC_CONST
# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */
# define FBLMAIN_START_SEC_VAR
# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */
/***********************************************************************************************************************
* LOCAL DATA
**********************************************************************************************************************/
# if defined( FBL_ENABLE_STAY_IN_BOOT )
V_MEMRAM0 static V_MEMRAM1 vuint16 V_MEMRAM2 startMessageDelay;
# endif /* FBL_ENABLE_STAY_IN_BOOT */
V_MEMRAM0 V_MEMRAM1_NEAR tFblStateBitmap V_MEMRAM2_NEAR fblMainStates[FBL_STATE_INDEX(kFblMainNumberOfStates - 1u) + 1u];
#define FBLMAIN_STOP_SEC_VAR
#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */
/***********************************************************************************************************************
* LOCAL FUNCTION PROTOTYPES
**********************************************************************************************************************/
#define FBLMAIN_START_SEC_CODE
#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */
static void FblCheckProgrammingRequest(void);
# if defined( FBL_ENABLE_STAY_IN_BOOT )
static void FblPostProcessStartMsg( vuintx startMsgResult );
static void FblRepeatCheckForStartMsg(void);
# endif /* FBL_ENABLE_STAY_IN_BOOT */
static void FblInitPowerOn( void );
static void FblInit( vuint8 initposition );
static void FblDeinit( void );
static void FblRepeat( void );
/***********************************************************************************************************************
* LOCAL FUNCTIONS
**********************************************************************************************************************/
/***********************************************************************************************************************
* FblCheckProgrammingRequest
**********************************************************************************************************************/
/*! \brief Evaluates the programming request flag and decides the next steps (e.g. stay in bootloader, check for
* stay-in-boot message or some SecureBoot specific operations).
**********************************************************************************************************************/
static void FblCheckProgrammingRequest(void)
{
/* Decide the next step of the Bootloader */
switch (ApplFblExtProgRequest())
{
case kProgRequest:
{
FblMainSetStartFromAppl();
break;
}
# if defined( FBL_ENABLE_STAY_IN_BOOT )
case kCheckStayInBootRequest:
{
/* Check for stay in boot message during startup */
FblMainSetWaitStartMessage();
break;
}
# endif /* FBL_ENABLE_STAY_IN_BOOT */
# if defined( FBLBM_ENABLE_SECURE_BOOT )
# if defined ( FBLBM_ENABLE_SECBOOT_FBL_INIT_KEY )
case kInitKeysRequest: /* Intentional fall through */
# endif
# if defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC )
case kInitMacsRequest: /* Intentional fall through */
# endif
# endif /* FBLBM_ENABLE_SECURE_BOOT */
case kNoProgRequest: /* Intentional fall through */
default:
{
/* Normal startup */
FblMainSetStartFromReset();
break;
}
}
}
# if defined( FBL_ENABLE_STAY_IN_BOOT )
/***********************************************************************************************************************
* FblPostProcessStartMsg
**********************************************************************************************************************/
/*! \brief Post-process result of start message reception
* \details This function post-processes the result of the startup message check - either
* the Bootloader is prepared or the application is started.
* \param[in] startMsgResult Indicates if a start message has been received or not
**********************************************************************************************************************/
static void FblPostProcessStartMsg(vuintx startMsgResult)
{
switch (startMsgResult)
{
case kFblMainStartMessageReceived:
{
FblMainSetStartMessageReceived();
break;
}
case kFblMainStartMessageTimeout:
{
# if defined( FBL_NO_JSR_APPL )
# else /* FBL_NO_JSR_APPL */
/* Request shutdown from Com-Wrapper */
FblCwShutdownRequest(kFblCwResetEcuRegularCase);
while (!FblMainGetFblShutdownRequest())
{
FblLookForWatchdogVoid();
}
FblDeinit();
CallApplStart();
# endif /* FBL_NO_JSR_APPL */
break;
}
default:
{
assertFblInternal(0u, kFblSysAssertParameterOutOfRange); /* PRQA S 2741,4558 */ /* MD_FblMain_2741_4558 */
break;
}
}
}
# endif /* FBL_ENABLE_STAY_IN_BOOT */
/***********************************************************************************************************************
* FblInitPowerOn
**********************************************************************************************************************/
/*! \brief Pre-initialization of Bootloader variables
* \details Initializes all variables needed to control the Bootloader
**********************************************************************************************************************/
static void FblInitPowerOn(void) /* PRQA S 3006 */ /* MD_FblMain_3006 */
{
vuintx i;
#if defined( FBL_ENABLE_INTERRUPT_DISABLE_AT_POWER_ON )
/* Disable global interrupt handling */
FblInterruptDisable(); /* PRQA S 1006 */ /* MD_FblMain_1006 */
#endif /* FBL_ENABLE_INTERRUPT_DISABLE_AT_POWER_ON */
#if defined( FBL_MAIN_ENABLE_VTT_USECASE )
#else
/* Check if bootloader header address is correctly configured in generation tool */
/* PRQA S 0306 1 */ /* MD_FblMain_FblHeader */
assertFblGen(FblHeaderLocal == FblHeaderTable, kFblSysAssertParameterOutOfRange);
#endif /* FBL_ENABLE_DEMOAPPL || FBL_MAIN_ENABLE_VTT_USECASE */
/* Initialization of main variables */
for (i = 0u; i < (sizeof(fblMainStates) / sizeof(fblMainStates[0])); i++)
{
fblMainStates[i] = (tFblStateBitmap)0x00u;
}
# if defined( FBL_ENABLE_STAY_IN_BOOT )
startMessageDelay = 0u;
# endif /* FBL_ENABLE_STAY_IN_BOOT */
/* Power on initialization of core modules */
ClrWDInit();
FblDiagInitPowerOn();
MemDriver_InitPowerOn();
/* Initialize intermediate access layer for LBT */
FblLbtInitPowerOn();
#if defined( FBL_ENABLE_HARDWARE_SWAP )
/* Initialize hardware swap module */
FblSwapInitPowerOn();
#endif
# if defined( FBL_ENABLE_SECMOD_VECTOR )
(void)SecM_InitPowerOn(V_NULL);
# endif /* FBL_ENABLE_SECMOD_VECTOR */
}
/***********************************************************************************************************************
* FblInit
**********************************************************************************************************************/
/*! \brief Do initializations after reset or start out of application
**********************************************************************************************************************/
/* PRQA S 6050 1 */ /* MD_MSR_STCAL */
static void FblInit( vuint8 initposition )
{
/* User initialization before core initializations */
ApplFblStartup(kFblInitPreCallback | initposition); /* PRQA S 2986 */ /* MD_FblMain_2986 */
switch (initposition)
{
/* Initialization steps the application validity is checked */
case kFblInitBaseInitialization:
{
/* Initialize watchdog handling */
FblInitWatchdog();
/* Initialize Timer */
FblTimerInit();
break;
}
/* Initialization steps after the application validity is checked */
case kFblInitFblCommunication:
{
EcuM_StartupTwo();
/* Initialize diagnostic module */
FblDiagInit();
#if defined( FBLBM_ENABLE_SECURE_BOOT )
/* Initialize SecureBoot functionality */
FblSb_Init();
#endif /* FBLBM_ENABLE_SECURE_BOOT */
#if defined( FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN )
/* Initialize extended presence pattern once */
FblNvPatternSignedPresencePatternInit();
#endif /* FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN */
break;
}
/* Initialization steps executed after the Bootloader is invoked */
case kFblInitFblFinalize:
{
/* Diagnostic layer - init steps after NV-memory init */
FblDiagPostInit();
break;
}
default:
{
assertFblInternal(0u, kFblSysAssertParameterOutOfRange); /* PRQA S 2741,4558 */ /* MD_FblMain_2741_4558 */
break;
}
}
/* User initialization after core initialization */
ApplFblStartup(kFblInitPostCallback | initposition);
}
/***********************************************************************************************************************
* FblDeinit
**********************************************************************************************************************/
/*! \brief Do necessary deinitializations
**********************************************************************************************************************/
static void FblDeinit( void )
{
/* Deinitialize communication wrapper */
# if( FBL_CW_API_REFERENCE_VERSION_MAJOR == 0x02u )
FblCw_Deinit();
# else
FblCwDeinit();
# endif /* FBL_CW_API_REFERENCE_VERSION_MAJOR == 0x02u */
#if defined( FBL_WATCHDOG_ON )
/* Synchronize watchdog before reset */
ApplFblWDLong();
#endif /* FBL_WATCHDOG_ON */
FblTimerStopp(); /* PRQA S 0303 */ /* MD_FBL_0303_MemoryMappedRegAccess */
}
# if defined( FBL_ENABLE_STAY_IN_BOOT )
/***********************************************************************************************************************
* FblRepeatCheckForStartMsg
**********************************************************************************************************************/
/*! \brief This function waits during the acceptance window if the start message is received.
* \pre Hardware has to be initialized.
**********************************************************************************************************************/
static void FblRepeatCheckForStartMsg( void )
{
/* Set COM wrapper flag for start message window */
FblCwSetCheckForStartMsg();
while (FblMainGetWaitStartMessage())
{
/* Check if 1ms hardware timer expired */
if ((FblLookForWatchdog() & FBL_TM_TRIGGERED) == FBL_TM_TRIGGERED)
{
/* Handle timer each millisecond */
startMessageDelay--;
if (startMessageDelay == 0u)
{
/* Start message wait time expired */
FblMainClrWaitStartMessage();
FblPostProcessStartMsg(kFblMainStartMessageTimeout);
}
}
if (FblCwCheckStartMessage() == kFblOk)
{
/* Startup message has been received */
FblMainClrWaitStartMessage();
FblPostProcessStartMsg(kFblMainStartMessageReceived);
}
}
/* Start message window is closed now */
FblCwClrCheckForStartMsg();
}
# endif /* FBL_ENABLE_STAY_IN_BOOT */
/***********************************************************************************************************************
* FblRepeat
**********************************************************************************************************************/
/*! \brief This function contains the main loop of the FBL.
* \details In this loop, the Bus is polled and the watchdog is triggered.
* This function is used by the boot procedure for the start delay and for the real operation.
* \pre Hardware has to be initialized before.
* \return The return value is used by the boot procedure to determine whether to stay in FBL or start the appl.
**********************************************************************************************************************/
static void FblRepeat( void )
{
#if defined( FBL_DIAG_ENABLE_CORE_ASYNC_ROUTINE )
FblMainSetFblRepeatStarted();
#endif /* FBL_DIAG_ENABLE_CORE_ASYNC_ROUTINE */
/* This loop will be left only for reset */
while (!FblMainGetFblShutdownRequest())
{
/* Check if 1ms hardware timer expired */
if ((FblLookForWatchdog() & FBL_TM_TRIGGERED) == FBL_TM_TRIGGERED)
{
/* Run 1ms based tasks */
FblDiagTimerTask();
#if defined( FBL_ENABLE_APPL_TIMER_TASK )
/* Call cyclic function of fbl application module (if configured) */
ApplFblTask();
#endif /* FBL_ENABLE_APPL_TIMER_TASK */
}
/* Run non-timer relevant operations */
FblDiagStateTask();
FblCwIdleTask();
# if defined( FBL_MEM_ENABLE_PIPELINING )
if (FblMemTaskIsPending())
{
FblMemTask();
}
# endif /* FBL_MEM_ENABLE_PIPELINING */
#if defined( FBL_ENABLE_APPL_STATE_TASK )
/* Call background function of fbl application module (if configured) */
ApplFblStateTask();
#endif /* FBL_ENABLE_APPL_STATE_TASK */
}
#if defined( FBL_DIAG_ENABLE_CORE_ASYNC_ROUTINE )
FblMainClrFblRepeatStarted();
#endif /* FBL_DIAG_ENABLE_CORE_ASYNC_ROUTINE */
}
/***********************************************************************************************************************
* GLOBAL FUNCTIONS
**********************************************************************************************************************/
/***********************************************************************************************************************
* FblMain
**********************************************************************************************************************/
/*! \brief Wrapper function to call the actual FblMainInternal function
**********************************************************************************************************************/
#if !defined( FBLBM_INSTANCE_BOOTMANAGER )
void V_API_NEAR FblMain( void ) /* PRQA S 5209 */ /* MD_FblMain_5209 */
{
FblMainInternal();
}
#endif /* !FBLBM_INSTANCE_BOOTMANAGER */
/***********************************************************************************************************************
* FblMainInternal
**********************************************************************************************************************/
/*! \brief Main function of the Bootloader.
* \details The FBL initializes the hardware and waits for a download request.
**********************************************************************************************************************/
void V_API_NEAR FblMainInternal( void ) /* PRQA S 5209 */ /* MD_FblMain_5209 */
{
/* Initialize variables */
FblInitPowerOn();
/* Base initialization step - valid for both application and Bootloader */
FblInit(kFblInitBaseInitialization);
/* Evaluate programming request flag and decide next bootloader step */
FblCheckProgrammingRequest();
/* Bootloader initialization step 1 - hardware and basic communication */
FblInit(kFblInitFblCommunication);
# if defined( FBL_ENABLE_STAY_IN_BOOT )
/* Check for start message */
FblRepeatCheckForStartMsg();
# endif /* FBL_ENABLE_STAY_IN_BOOT */
/* Bootloader initialization step 2 - full diagnostics initialization */
FblInit(kFblInitFblFinalize);
/* Bootloader execution */
FblRepeat();
/* Deinitialize and reset bootloader */
FblDeinit();
ApplFblReset();
}
#define FBLMAIN_STOP_SEC_CODE
#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */
/***********************************************************************************************************************
* MISRA DEVIATIONS
**********************************************************************************************************************/
/* Justification for module-specific MISRA deviations:
MD_FBL_0303_MemoryMappedRegAccess:
Reason: Addressing memory mapped registers or other hardware specific feature requires casting a pointer type to
an integral type. This is a usual pattern for MCAL (Micro Controller Abstraction Layer) software.
Risk: Unintended read or write access into memory location.
Prevention: Code inspection focus on correct access to expected memory location.
MD_FblMain_1006:
Reason: Assembler code is used to deactivate interrupts and set context information.
Risk: The code is not portable for different compilers.
Prevention: The assembler code provided by each FblHw module has to be tested.
MD_FblMain_1514_FblHeader
Reason: MISRA: The object FblBmHeader is only referenced by function ..., in the translation unit where it is defined
This object is exported globally to other translation units
Risk: Name space pollution
Prevention: No Prevention necessary
MD_FblMain_2741_4558:
Reason: Assertion macros have to be disabled in production code and are used only for development.
Risk: Assertion code may be enabled in production code unintentionally. If a assertion condition is unexpectedly
false, the code is active. A problem may occur if the Macro is additionally changed from single statement
to multiple statement.
Prevention: Macro is not allowed to be changed without review. Development code is automatically disabled via
configuration of project state "Production".
MD_FblMain_2986:
Reason: This code is redundant but kept for clarity.
Risk: No risk.
Prevention: No prevention necessary.
MD_FblMain_3006:
Reason: Assembler code is used to deactivate interrupts and set context information.
Risk: The code is not portable for different compilers.
Prevention: The assembler code provided by each FblHw module has to be tested.
MD_FblMain_5209:
Reason: The Vector standard API for main function follows ANSI C typical definition of main function returning int.
Risk: No identifiable risk.
Prevention: No prevention required.
MD_FblMain_FblHeader:
Reason: A memory address is compared to a configured value. The configured value is interpreted as an integer.
Risk: The comparison may fail due to different data types.
Prevention: If this check fails, the configuration checks done by assertions have to verified manually.
*/
/***********************************************************************************************************************
* END OF FILE: FBL_MAIN.C
**********************************************************************************************************************/