/**********************************************************************************************************************
 *  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
 *  -------------------------------------------------------------------------------------------------------------------
 *  FILE DESCRIPTION
 *  -----------------------------------------------------------------------------------------------------------------*/
/** \file  File:  BrsMain.c
 *      Project:  Vector Basic Runtime System
 *       Module:  BrsMain
 *
 *  \brief Description:  Main file of BRS contains
 *                       - Main function (called from StartUpCode and calls stack entry EcuM_Init())
 *                       - Call of BrsHw HW initialization routines
 *                       - 1ms handler, with support of cycle functions with several cycle times
 *                       - Default_Init_Task, Main and Background Task which can be used by the operating system
 *
 *  \attention Please note:
 *    The demo and example programs only show special aspects of the software. With regard to the fact
 *    that these programs are meant for demonstration purposes only, Vector Informatik liability shall be
 *    expressly excluded in cases of ordinary negligence, to the extent admissible by law or statute.
 *********************************************************************************************************************/

/**********************************************************************************************************************
 *  REVISION HISTORY
 *  -------------------------------------------------------------------------------------------------------------------
 *  Refer to BrsMain.h.
 *********************************************************************************************************************/

/**********************************************************************************************************************
 *  EXAMPLE CODE ONLY
 *  -------------------------------------------------------------------------------------------------------------------
 *  This Example Code is only intended for illustrating an example of a possible BSW integration and BSW configuration.
 *  The Example Code has not passed any quality control measures and may be incomplete. The Example Code is neither
 *  intended nor qualified for use in series production. The Example Code as well as any of its modifications and/or
 *  implementations must be tested with diligent care and must comply with all quality requirements which are necessary
 *  according to the state of the art before their use.
 *********************************************************************************************************************/

#define _BRSMAIN_C_

/**********************************************************************************************************************
 *  INCLUDES
 *********************************************************************************************************************/
#include "BrsMain.h"

#if !defined (VVIRTUALTARGET)
  #include "vBrs_Lcfg.h"
#else
  #include "CANoeApi.h"
  #include <stdio.h>
  #include "Os.h"
#endif

#if defined (BRS_ENABLE_TESTSUITE_SUPPORT)
  #include "BrsTestsuite.h"
#endif

#include "BrsMain_Appl.h"

/**********************************************************************************************************************
 *  VERSION CHECK
 *********************************************************************************************************************/
#if (BRSMAIN_MAJOR_VERSION != 2u) || (BRSMAIN_MINOR_VERSION != 27u)
  #error "Header and source file are inconsistent!"
#endif
#if (BRSMAIN_PATCH_VERSION != 0u)
  #error "Different versions of patch in Header and Source used!"
#endif

/* BRS_GENERATED_HW_CONFIG_VERSION is generated into vBrsCfg.h by Cfg5/Cfg6 vBrs generator */
#if (BRS_GENERATED_HW_CONFIG_VERSION < 406U)
  #error "Version of vBrs Generator too old! Please update it."
#endif

/**********************************************************************************************************************
 *  CONFIGURATION CHECK
 *********************************************************************************************************************/
#if !defined (VVIRTUALTARGET)
/* BRSHW_SOURCECODE_TEMPLATE_VERSION_COMBINED was introduced in Brs_Template 1.04.00 - no check needed */
# if !defined (BRSHW_SOURCECODE_TEMPLATE_VERSION_COMBINED)
#  if (BRSHW_SOURCECODE_TEMPLATE_VERSION < 0x0103u)
  #error "This BrsMain version requires a BrsHw package with a minimum template version of 1.03.00!"
#  endif
# endif
#endif

#if defined (BRS_ENABLE_OS_INTERRUPT_ONLY) && defined (BRS_ENABLE_OS_MULTICORESUPPORT)
  #error "OS MultiCore support is not supported together with OS INTERRUPT_ONLY UseCase!"
#endif

#if defined (BRS_ENABLE_OS_MULTICORESUPPORT)
  #error "This file was filtered for SingleCore UseCase, but MultiCore UseCase is configured!"
#endif

#if defined (BRS_ENABLE_HSM_UPDATER_SUPPORT)
# if !defined (BRSHW_SOURCECODE_TEMPLATE_VERSION_COMBINED)
/* BRSHW_SOURCECODE_TEMPLATE_VERSION_COMBINED was introduced in Brs_Template_HSM 1.05.00 - no check needed */
#  if (BRSHW_SOURCECODE_TEMPLATE_VERSION < 0x0104u)
  #error "HSM Updater functionality requires a BrsHw package with a minimum template version of 1.04.00!"
#  endif
# endif
#endif

#if defined (BRS_ENABLE_HYPERVISOR_SUPPORT) || defined (BRS_HYPERVISOR_GUEST_EXECUTION_INSTANCE)
# if !defined (BRSHW_SOURCECODE_TEMPLATE_VERSION_COMBINED)
/* BRSHW_SOURCECODE_TEMPLATE_VERSION_COMBINED was introduced in Brs_Template 1.04.00 - no check needed */
#  if (BRSHW_SOURCECODE_TEMPLATE_VERSION < 0x0103u) || ((BRSHW_SOURCECODE_TEMPLATE_VERSION == 0x0103u) && \
                                                       (BRSHW_SOURCECODE_TEMPLATE_BUGFIX_VERSION < 0x12u))
  #error "Hypervisor functionality requires a BrsHw package with a minimum template version of 1.03.12!"
#  endif
# endif
#endif

/**********************************************************************************************************************
 *  DEFINITION + MACROS
 *********************************************************************************************************************/

/**********************************************************************************************************************
 *  GLOBAL VARIABLES
 *********************************************************************************************************************/
#if defined (BRS_ENABLE_1MS_HANDLER)
# if !defined (BRSMAIN_CYCLIC_MAX_CALLBACKS)
  #define BRSMAIN_CYCLIC_MAX_CALLBACKS 2u
# endif

  #define START_SEC_VAR_NOINIT_UNSPECIFIED
  #include "MemMap.h"
  typedef struct
  {
    void (*FunctionPointer[BRSMAIN_CYCLIC_MAX_CALLBACKS]) (void);
    uint8 FunctionCounter;
  } brsMain_Cyclic_Callbacks;
  #define STOP_SEC_VAR
  #include "MemMap.h"
#endif /* BRS_ENABLE_1MS_HANDLER */

#if !defined (VVIRTUALTARGET)
#define BRS_START_SEC_SHARED_VAR
#include "Brs_MemMap.h"
extern volatile brsMain_ResetReasonType brsMain_ResetReason;
#define BRS_STOP_SEC_SHARED_VAR
#include "Brs_MemMap.h"
#endif

/**********************************************************************************************************************
 *  GLOBAL CONST VARIABLES
 *********************************************************************************************************************/

/**********************************************************************************************************************
 *  LOCAL VARIABLES
 *********************************************************************************************************************/
#if defined (BRS_ENABLE_1MS_HANDLER)
  #define START_SEC_VAR_NOINIT_16BIT
  #include "MemMap.h"
  /*
  * \var brsMain_CallCounter1ms
  *      Counter for calls of the function BrsMainCyclic1ms
  */
  static volatile uint16 brsMain_CallCounter1ms;

  /*
  * \var brsMain_CallCounter1sec
  *      Counter for 1000 calls of the function BrsMainCyclic1ms
  */
  static volatile uint16 brsMain_CallCounter1sec;
  #define STOP_SEC_VAR
  #include "MemMap.h"

  #define START_SEC_VAR_NOINIT_UNSPECIFIED
  #include "MemMap.h"
  static brsMain_Cyclic_Callbacks brsMain_Cyclic_Callbacks_Background;
  static brsMain_Cyclic_Callbacks brsMain_Cyclic_Callbacks_1ms;
  static brsMain_Cyclic_Callbacks brsMain_Cyclic_Callbacks_10ms;
  static brsMain_Cyclic_Callbacks brsMain_Cyclic_Callbacks_100ms;
  static brsMain_Cyclic_Callbacks brsMain_Cyclic_Callbacks_250ms;
  static brsMain_Cyclic_Callbacks brsMain_Cyclic_Callbacks_500ms;
  static brsMain_Cyclic_Callbacks brsMain_Cyclic_Callbacks_1000ms;
  #define STOP_SEC_VAR
  #include "MemMap.h"
#endif /* BRS_ENABLE_1MS_HANDLER */

#if defined (BRS_ENABLE_OS_INTERRUPT_ONLY)
  #define START_SEC_VAR_NOINIT_32BIT
  #include "MemMap.h"
  static volatile uint32 brsMain_SuspendAllCounter;
  #define STOP_SEC_VAR
  #include "MemMap.h"
#endif

/**********************************************************************************************************************
 *  LOCAL CONST VARIABLES
 *********************************************************************************************************************/
# if defined (VVIRTUALTARGET)
  #define BRSMAIN_ERRORBUFFERSIZE  120
#endif

/**********************************************************************************************************************
 *  PROTOTYPES OF GLOBAL FUNCTIONS
 *********************************************************************************************************************/
#if defined (BRS_FBL_NO_ECUMINIT)
extern void FblMain(void);
#endif

/**********************************************************************************************************************
 *  PROTOTYPES OF LOCAL FUNCTIONS
 *********************************************************************************************************************/

/**********************************************************************************************************************
 *  FUNCTION DEFINITIONS
 *********************************************************************************************************************/
#if !defined (VVIRTUALTARGET)
# if defined (BRS_ENABLE_SUPPORT_LEDS)
void BrsMainWrapperTogglePinLED(void)
{
  BrsMainTogglePin(BRSMAIN_TOGGLEPIN_LED);
}
# endif

# if defined (BRS_ENABLE_SUPPORT_TOGGLE_WD_PIN)
void BrsMainWrapperTogglePinWD(void)
{
  BrsMainTogglePin(BRSMAIN_TOGGLEPIN_WD);
}
# endif

# if defined (BRS_ENABLE_SUPPORT_TOGGLE_CUSTOM_PIN)
void BrsMainWrapperTogglePinCustom(void)
{
  BrsMainTogglePin(BRSMAIN_TOGGLEPIN_CUSTOM);
}
# endif
#endif /* !VVIRTUALTARGET */

/*****************************************************************************/
/* @brief      Main initialization routine.
 *             Contains configuration specific initialization of BrsHw parts
 *             and BrsMain specific mechanisms.
 * @pre        -
 * @param[in]  -
 * @param[out] -
 * @return     -
 * @context    Function is called from main
 *****************************************************************************/
void BrsMainInit(void)
{
#if defined (BRSMAIN_BRSMAININIT_CALLOUT)
  BrsTestsuite_BrsMain_BrsMainInit();
#endif

  BrsMain_Appl_Init();

#if (!defined (BRS_FBL_NO_ECUMINIT)) && (!defined (VVIRTUALTARGET))
# if !defined (BRS_ENABLE_PREFER_PLL_WATCHDOG_INIT)
  /* If preferred feature is acivated, initialization will take place in BrsMain_MemoryInit_StageOne_Hook(). */
#  if defined (BRSHW_PREINIT_AVAILABLE)
  BrsHwPreInitPowerOn();
#  endif

#  if defined (BRS_ENABLE_WATCHDOG)
  BrsHwWatchdogInitPowerOn();
#  endif

#  if defined (BRS_ENABLE_PLLCLOCKS)
  BrsHwPllInitPowerOn();
#  endif
# endif /* !BRS_ENABLE_PREFER_PLL_WATCHDOG_INIT */

# if defined (BRS_ENABLE_PORT)
  BrsHwPortInitPowerOn();
# endif

# if defined (BRS_ENABLE_FBL_SUPPORT) || defined (BRS_ENABLE_HSM_UPDATER_SUPPORT)
#  if defined (BRSHW_DISABLE_ECC_AVAILABLE)
  BrsHwDisableEccErrorReporting();
#  endif
# endif
#endif /* !BRS_FBL_NO_ECUMINIT&&!VVIRTUALTARGET */

#if defined (BRS_ENABLE_1MS_HANDLER)
  brsMain_CallCounter1ms = 0u;
  brsMain_CallCounter1sec = 0u;

  brsMain_Cyclic_Callbacks_Background.FunctionCounter = 0u;
  brsMain_Cyclic_Callbacks_1ms.FunctionCounter        = 0u;
  brsMain_Cyclic_Callbacks_10ms.FunctionCounter       = 0u;
  brsMain_Cyclic_Callbacks_100ms.FunctionCounter      = 0u;
  brsMain_Cyclic_Callbacks_250ms.FunctionCounter      = 0u;
  brsMain_Cyclic_Callbacks_500ms.FunctionCounter      = 0u;
  brsMain_Cyclic_Callbacks_1000ms.FunctionCounter     = 0u;
#endif /* BRS_ENABLE_1MS_HANDLER */

#if !defined (VVIRTUALTARGET)
# if defined (BRS_ENABLE_SUPPORT_LEDS)
  BrsMainRegisterCyclic(&BrsMainWrapperTogglePinLED, BRSMAIN_CYCLETIME_500MS);
# endif

# if defined (BRS_ENABLE_SUPPORT_TOGGLE_WD_PIN)
  BrsMainRegisterCyclic(&BrsMainWrapperTogglePinWD, BRSMAIN_CYCLETIME_250MS);
# endif

# if defined (BRS_ENABLE_SUPPORT_TOGGLE_CUSTOM_PIN)
  BrsMainRegisterCyclic(&BrsMainWrapperTogglePinCustom, BRSMAIN_CYCLETIME_1000MS);
# endif
#endif /* !VVIRTUALTARGET */

#if defined (BRS_ENABLE_OS_INTERRUPT_ONLY)
  brsMain_SuspendAllCounter = 0u;
#endif
}

#if defined (BRS_ENABLE_1MS_HANDLER)
/*****************************************************************************/
/* @brief      Routine to register cyclic callbacks.
 * @pre        Initialization of BrsMain was done threw call of BrsMainInit().
 * @param[in]  FunctionPointer has to be a pointer to a function of type
 *             void function(void).
 * @param[in]  Cycletime described the cycletime, the callback should be triggered.
 * @param[out] -
 * @return     -
 * @context    Function is called from modules that need cyclic callbacks.
 *****************************************************************************/
void BrsMainRegisterCyclic(void (*FunctionPointer)(void), brsMain_Cyclic_Cycletime Cycletime)
{
#if defined (BRSMAIN_BRSMAINREGISTERCYCLIC_CALLOUT)
  BrsTestsuite_BrsMain_BrsMainRegisterCyclic(FunctionPointer, Cycletime);
#endif

  switch (Cycletime)
  {
    case BRSMAIN_CYCLETIME_BACKGROUND:
      if (brsMain_Cyclic_Callbacks_Background.FunctionCounter >= BRSMAIN_CYCLIC_MAX_CALLBACKS)
      {
        BrsMainExceptionHandler(kBrsIllegalParameter, BRSERROR_MODULE_BRSMAIN, (uint16)(__LINE__));
      }
      brsMain_Cyclic_Callbacks_Background.FunctionPointer[
        brsMain_Cyclic_Callbacks_Background.FunctionCounter] = FunctionPointer;
      brsMain_Cyclic_Callbacks_Background.FunctionCounter++;
      break;

    case BRSMAIN_CYCLETIME_1MS:
      if (brsMain_Cyclic_Callbacks_1ms.FunctionCounter >= BRSMAIN_CYCLIC_MAX_CALLBACKS)
      {
        BrsMainExceptionHandler(kBrsIllegalParameter, BRSERROR_MODULE_BRSMAIN, (uint16)(__LINE__));
      }
      brsMain_Cyclic_Callbacks_1ms.FunctionPointer[
        brsMain_Cyclic_Callbacks_1ms.FunctionCounter] = FunctionPointer;
      brsMain_Cyclic_Callbacks_1ms.FunctionCounter++;
      break;

    case BRSMAIN_CYCLETIME_10MS:
      if (brsMain_Cyclic_Callbacks_10ms.FunctionCounter >= BRSMAIN_CYCLIC_MAX_CALLBACKS)
      {
        BrsMainExceptionHandler(kBrsIllegalParameter, BRSERROR_MODULE_BRSMAIN, (uint16)(__LINE__));
      }
      brsMain_Cyclic_Callbacks_10ms.FunctionPointer[
        brsMain_Cyclic_Callbacks_10ms.FunctionCounter] = FunctionPointer;
      brsMain_Cyclic_Callbacks_10ms.FunctionCounter++;
      break;

    case BRSMAIN_CYCLETIME_100MS:
      if (brsMain_Cyclic_Callbacks_100ms.FunctionCounter >= BRSMAIN_CYCLIC_MAX_CALLBACKS)
      {
        BrsMainExceptionHandler(kBrsIllegalParameter, BRSERROR_MODULE_BRSMAIN, (uint16)(__LINE__));
      }
      brsMain_Cyclic_Callbacks_100ms.FunctionPointer[
        brsMain_Cyclic_Callbacks_100ms.FunctionCounter] = FunctionPointer;
      brsMain_Cyclic_Callbacks_100ms.FunctionCounter++;
      break;

    case BRSMAIN_CYCLETIME_250MS:
      if (brsMain_Cyclic_Callbacks_250ms.FunctionCounter >= BRSMAIN_CYCLIC_MAX_CALLBACKS)
      {
        BrsMainExceptionHandler(kBrsIllegalParameter, BRSERROR_MODULE_BRSMAIN, (uint16)(__LINE__));
      }
      brsMain_Cyclic_Callbacks_250ms.FunctionPointer[
        brsMain_Cyclic_Callbacks_250ms.FunctionCounter] = FunctionPointer;
      brsMain_Cyclic_Callbacks_250ms.FunctionCounter++;
      break;

    case BRSMAIN_CYCLETIME_500MS:
      if (brsMain_Cyclic_Callbacks_500ms.FunctionCounter >= BRSMAIN_CYCLIC_MAX_CALLBACKS)
      {
        BrsMainExceptionHandler(kBrsIllegalParameter, BRSERROR_MODULE_BRSMAIN, (uint16)(__LINE__));
      }
      brsMain_Cyclic_Callbacks_500ms.FunctionPointer[
        brsMain_Cyclic_Callbacks_500ms.FunctionCounter] = FunctionPointer;
      brsMain_Cyclic_Callbacks_500ms.FunctionCounter++;
      break;

    case BRSMAIN_CYCLETIME_1000MS:
      if (brsMain_Cyclic_Callbacks_1000ms.FunctionCounter >= BRSMAIN_CYCLIC_MAX_CALLBACKS)
      {
        BrsMainExceptionHandler(kBrsIllegalParameter, BRSERROR_MODULE_BRSMAIN, (uint16)(__LINE__));
      }
      brsMain_Cyclic_Callbacks_1000ms.FunctionPointer[
        brsMain_Cyclic_Callbacks_1000ms.FunctionCounter] = FunctionPointer;
      brsMain_Cyclic_Callbacks_1000ms.FunctionCounter++;
      break;

    default:
      BrsMainExceptionHandler(kBrsIllegalParameter, BRSERROR_MODULE_BRSMAIN, (uint16)(__LINE__));
      break;
  }
}
#endif /* BRS_ENABLE_1MS_HANDLER */

#if (!defined (BRS_DISABLE_OS_USAGE)) && (!defined (BRS_ENABLE_OS_INTERRUPT_ONLY))
/*****************************************************************************/
/* @brief      InitTask to call EcuM_StartupTwo() on the MasterCore.
 * @pre        -
 * @param[in]  -
 * @param[out] -
 * @return     -
 * @context    The task is started once by the OS.
 *****************************************************************************/
TASK(Default_Init_Task)
{
#if defined (BRSMAIN_DEFAULT_INIT_TASK_CALLOUT)
  BrsTestsuite_BrsMain_Default_Init_Task();
#endif

#if defined (BRS_ENABLE_TESTSUITE_SUPPORT)
  BrsTestsuiteInit();
#endif

#if defined (BRS_ENABLE_HSM_SUPPORT)
  vHsm_StartupTwo();
#else
  EcuM_StartupTwo();
#endif

#if defined (BRS_ENABLE_1MS_HANDLER)
  (void)SetRelAlarm(BrsMainCyclicAlarm_1ms, OS_MS2TICKS_SystemTimer(1), OS_MS2TICKS_SystemTimer(1));
#endif

  (void)TerminateTask();
}

/*****************************************************************************/
/* @brief      InitTask to call Os_InitialEnableInterruptSources() on the MasterCore.
 * @pre        -
 * @param[in]  -
 * @param[out] -
 * @return     -
 * @context    The task is started once by the OS. It is separated from
 *             Default_Init_Task() to allow the SafeContext partitioning UseCase.
 *****************************************************************************/
TASK(Default_Init_Task_Trusted)
{
#if defined (BRSMAIN_DEFAULT_INIT_TASK_TRUSTED_CALLOUT)
  BrsTestsuite_BrsMain_Default_Init_Task_Trusted();
#endif

  Os_InitialEnableInterruptSources(FALSE);

  (void)TerminateTask();
}

#endif /* !BRS_DISABLE_OS_USAGE&&!BRS_ENABLE_OS_INTERRUPT_ONLY */

#if defined (BRS_ENABLE_1MS_HANDLER)
/*****************************************************************************/
/* @brief      One millisecond handler for BrsMain
 *               - Executes retransmission of BRS TCC messages
 *               - Toggling of LED (alive signal)
 *               - BRS Test code (1s cyclic negative TCC response message)
 * @pre        Initialization of BrsMain was done threw call of BrsMainInit().
 * @param[in]  -
 * @param[out] -
 * @return     -
 * @context    Function is called each millisecond either from the main loop
 *             or from the BRS main task (TASK(mainTask))
 *****************************************************************************/
void BrsMainCyclic1ms(void)
{
  uint8 cycliccounter;

#if defined (BRSMAIN_BRSMAINCYCLIC1MS_CALLOUT)
  BrsTestsuite_BrsMain_BrsMainCyclic1ms();
#endif

  brsMain_CallCounter1ms++;

  for (cycliccounter = 0u; cycliccounter < brsMain_Cyclic_Callbacks_1ms.FunctionCounter; cycliccounter++)
  {
    brsMain_Cyclic_Callbacks_1ms.FunctionPointer[cycliccounter]();
  }

  if ((brsMain_CallCounter1ms % 10u) == 0u)
  {
    for (cycliccounter = 0u; cycliccounter<brsMain_Cyclic_Callbacks_10ms.FunctionCounter; cycliccounter++)
    {
      brsMain_Cyclic_Callbacks_10ms.FunctionPointer[cycliccounter]();
    }
  }

  if ((brsMain_CallCounter1ms % 100u) == 0u)
  {
    for (cycliccounter = 0u; cycliccounter<brsMain_Cyclic_Callbacks_100ms.FunctionCounter; cycliccounter++)
    {
      brsMain_Cyclic_Callbacks_100ms.FunctionPointer[cycliccounter]();
    }
  }

  if ((brsMain_CallCounter1ms % 250u) == 0u)
  {
    for (cycliccounter = 0u; cycliccounter<brsMain_Cyclic_Callbacks_250ms.FunctionCounter; cycliccounter++)
    {
      brsMain_Cyclic_Callbacks_250ms.FunctionPointer[cycliccounter]();
    }
  }

  if ((brsMain_CallCounter1ms % 500u) == 0u)
  {
    for (cycliccounter = 0u; cycliccounter<brsMain_Cyclic_Callbacks_500ms.FunctionCounter; cycliccounter++)
    {
      brsMain_Cyclic_Callbacks_500ms.FunctionPointer[cycliccounter]();
    }
  }

  if ((brsMain_CallCounter1ms % 1000u) == 0u)
  {
    for (cycliccounter = 0u; cycliccounter<brsMain_Cyclic_Callbacks_1000ms.FunctionCounter; cycliccounter++)
    {
      brsMain_Cyclic_Callbacks_1000ms.FunctionPointer[cycliccounter]();
    }
    brsMain_CallCounter1ms = 0u;
    brsMain_CallCounter1sec++;
  }
}

# if (!defined (BRS_DISABLE_OS_USAGE)) && (!defined (BRS_ENABLE_OS_INTERRUPT_ONLY))
/*****************************************************************************/
/* @brief      BrsMainTask executes the 1 millisecond handler
 *             The function initiates calls to BrsMainCyclic1ms
 * @pre        -
 * @param[in]  -
 * @param[out] -
 * @return     -
 * @context    The task is triggered by the OS alarm BrsMainCyclicAlarm_1ms,
 *             which is set as 1ms cyclic within the task Default_Init_Task()
 *****************************************************************************/
TASK(BrsMainTask)
{
#if defined (BRSMAIN_BRSMAINTASK_CALLOUT)
  BrsTestsuite_BrsMain_BrsMainTask();
#endif

  BrsMainCyclic1ms();

  (void)TerminateTask();
}

TASK(BrsMainBackgroundTask)
{
  uint8 cycliccounter;

#if defined (BRSMAIN_BRSMAINBACKGROUNDTASK_CALLOUT)
  BrsTestsuite_BrsMain_BrsMainBackgroundTask();
#endif

  for(;;)
  {
# if defined (VVIRTUALTARGET)
    CANoeAPI_ConsumeTicks(100);
# endif

    for (cycliccounter = 0u; cycliccounter < brsMain_Cyclic_Callbacks_Background.FunctionCounter; cycliccounter++)
    {
      brsMain_Cyclic_Callbacks_Background.FunctionPointer[cycliccounter]();
    }

    (void)Schedule();
  }
}
# endif /* !BRS_DISABLE_OS_USAGE && !BRS_ENABLE_OS_INTERRUPT_ONLY */
#endif /* BRS_ENABLE_1MS_HANDLER */

#if defined (BRS_ENABLE_SUPPORT_LEDS)          || \
    defined (BRS_ENABLE_SUPPORT_TOGGLE_WD_PIN) || \
    defined (BRS_ENABLE_SUPPORT_TOGGLE_CUSTOM_PIN)
# if !defined (BRS_ENABLE_PORT)
  #define BRSHW_PORT_LOGIC_HIGH STD_HIGH
  #define BRSHW_PORT_LOGIC_LOW STD_LOW
# endif
# if defined (BRS_ENABLE_FBL_SUPPORT)
  #define BRS_START_SEC_RAM_CODE
  #include "Brs_MemMap.h"
# endif
/*****************************************************************************/
/* @brief      This API is used to toggle a PortPin.
 *             Per default, the following parameters are available:
 *               BRSMAIN_TOGGLEPIN_LED
 *               BRSMAIN_TOGGLEPIN_WD
 *               BRSMAIN_TOGGLEPIN_CUSTOM
 *             Depending pins must be configured and initialized within BrsHw.
 * @pre        -
 * @param[in]  Pin to be toggled
 * @param[out] -
 * @return     -
 * @context    Function is called from all modules to set or clear a PortPin
 *****************************************************************************/
void BrsMainTogglePin(brsMain_TogglePin Pin)
{
  #define START_SEC_VAR_INIT_UNSPECIFIED
  #include "MemMap.h"
#if defined (BRS_ENABLE_SUPPORT_LEDS)
  static uint8 BrsMain_ToggleSwitch_LED = BRSHW_PORT_LOGIC_HIGH;
#endif
#if defined (BRS_ENABLE_SUPPORT_TOGGLE_WD_PIN)
  static uint8 BrsMain_ToggleSwitch_WD = BRSHW_PORT_LOGIC_HIGH;
#endif
#if defined (BRS_ENABLE_SUPPORT_TOGGLE_CUSTOM_PIN)
  static uint8 BrsMain_ToggleSwitch_CUSTOM = BRSHW_PORT_LOGIC_HIGH;
#endif
  #define STOP_SEC_VAR
  #include "MemMap.h"

  switch (Pin)
  {
#if defined (BRS_ENABLE_SUPPORT_LEDS)
    case BRSMAIN_TOGGLEPIN_LED:
# if defined (BRS_ENABLE_PORT)
      BrsHwPort_SetLevel(BRSHW_PORT_LED, BrsMain_ToggleSwitch_LED & 0x01u);
# else
      Dio_WriteChannel(BrsHw_DioChannel_ToggleLED, BrsMain_ToggleSwitch_LED & 0x01u);
# endif
      BrsMain_ToggleSwitch_LED++;
      break;
#endif /* BRS_ENABLE_SUPPORT_LEDS */
#if defined (BRS_ENABLE_SUPPORT_TOGGLE_WD_PIN)
    case BRSMAIN_TOGGLEPIN_WD:
# if defined (BRS_ENABLE_PORT)
      BrsHwPort_SetLevel(BRSHW_PORT_TOGGLE_WD, BrsMain_ToggleSwitch_WD & 0x01u);
# else
      Dio_WriteChannel(BrsHw_DioChannel_ToggleWdPin, BrsMain_ToggleSwitch_WD & 0x01u);
# endif
      BrsMain_ToggleSwitch_WD++;
      break;
#endif /* BRS_ENABLE_SUPPORT_TOGGLE_WD_PIN */
#if defined (BRS_ENABLE_SUPPORT_TOGGLE_CUSTOM_PIN)
    case BRSMAIN_TOGGLEPIN_CUSTOM:
# if defined (BRS_ENABLE_PORT)
      BrsHwPort_SetLevel(BRSHW_PORT_TOGGLE_CUSTOM, BrsMain_ToggleSwitch_CUSTOM & 0x01u);
# else
      Dio_WriteChannel(BrsHw_DioChannel_ToggleCustomPin, BrsMain_ToggleSwitch_CUSTOM & 0x01u);
# endif
      BrsMain_ToggleSwitch_CUSTOM++;
      break;
#endif /* BRS_ENABLE_SUPPORT_TOGGLE_CUSTOM_PIN */
    default:
      BrsMainExceptionHandler(kBrsIllegalParameter, BRSERROR_MODULE_BRSHW, (uint16)(__LINE__));
      break;
  }
}
# if defined (BRS_ENABLE_FBL_SUPPORT)
  #define BRS_STOP_SEC_RAM_CODE
  #include "Brs_MemMap.h"
# endif
#endif /* BRS_ENABLE_SUPPORT_LEDS || BRS_ENABLE_SUPPORT_TOGGLE_WD_PIN || BRS_ENABLE_SUPPORT_TOGGLE_CUSTOM_PIN */

#if defined (BRS_ENABLE_FBL_SUPPORT) || defined (BRS_ENABLE_HSM_UPDATER_SUPPORT)
  #define BRS_START_SEC_RAM_CODE
  #include "Brs_MemMap.h"
#endif
/*****************************************************************************/
/* @brief      This is the central exeption handler of BRS.
 *             All BRS modules and all CANbedded specific fatal error handler will
 *             call this API in case an assertion has failed.
 * @pre        -
 * @param[in]  ErrorCode shall hold the caller specific error code (uint8)
 * @param[in]  ModuleCode shall describe the caller; please use the CI constant as parameter (uint8)
 * @param[in]  LineNumber shall be the line where the assertion has failed, or,
 *             if not available on caller location, the line where this API is
 *             called from
 * @param[out] -
 * @return     -
 * @context    This function implements an endless loop with locked interrupts.
 *             The recommendation is to set a breakpoint on top of this function
 *             to see if any assertion has failed during the code execution.
 *             Due to an assertion has failed and the endless loop runs with
 *             locked global interrupts there will be no life after the call ...
 *****************************************************************************/
void BrsMainExceptionHandler(uint8 ErrorCode, uint8 ModuleCode, uint16 LineNumber)
{
#if defined (BRSMAIN_BRSMAINEXCEPTIONHANDLER_CALLOUT)
  BrsTestsuite_BrsMain_BrsMainExceptionHandler();
#endif

#if defined (BRS_ENABLE_SAFECTXSUPPORT) || !defined (VVIRTUALTARGET)
  BRS_DUMMY_STATEMENT(ErrorCode);
  BRS_DUMMY_STATEMENT(ModuleCode);
  BRS_DUMMY_STATEMENT(LineNumber);
#endif

#if defined (BRS_ENABLE_SAFECTXSUPPORT)
  while(1)
  {}

#else
# if defined (VVIRTUALTARGET)
  char error[BRSMAIN_ERRORBUFFERSIZE];

  snprintf(error,
           BRSMAIN_ERRORBUFFERSIZE,
           "BrsMainExceptionHandler Code: [0x%x] ModuleCode: [0x%x] LineNumber: [0x%x]",
           ErrorCode,
           ModuleCode,
           LineNumber);
  CANoeAPI_WriteString(error);
  ShutdownOS(0);

# else
  volatile uint8 BrsMain_Continue;
  BrsMain_Continue = 0;

/* API is only available, if an OS is part of the environment; never needed in polling environments. */
#if !defined (BRS_DISABLE_OS_USAGE)
  DisableAllInterrupts();
#endif

  while (BrsMain_Continue == 0u)
  {
    /*
    * Set BrsMain_Continue to 1 to continue here.
    *  If the debugger is not able to show the stack properly, this mechanism can be used to find the
    *  source of the exception.
    */
  }
# endif /* VVIRTUALTARGET */
#endif /* BRS_ENABLE_SAFECTXSUPPORT */
}
#if defined (BRS_ENABLE_FBL_SUPPORT) || defined (BRS_ENABLE_HSM_UPDATER_SUPPORT)
  #define BRS_STOP_SEC_RAM_CODE
  #include "Brs_MemMap.h"
#endif

#if !defined (VVIRTUALTARGET)
/*****************************************************************************/
/* @brief      Get reset reason
 * @pre        BrsHwGetResetReasonStartup() is called first and the rest reason
 *             is saved in global variable brsMain_ResetReason.
 * @param[in]  -
 * @param[out] -
 * @return     Reset reason
 * @context    This is a wrapper function for previous BrsHwGetResetReason().
 *             This is to prevent multiple selection of reset reason
 *             registers, as this is not supported on all platforms.
 *             The HW registers for the reset reason are evaluated via a call
 *             of BrsHwGetResetReasonStartup() in Brs_PreMainStartup().
 *             The result is stored by BrsMainStartup in the global variable
 *             brsMain_ResetReason.
 *****************************************************************************/
brsMain_ResetReasonType BrsMainGetResetReason(void)
{
  return brsMain_ResetReason;
}
#endif /* VVIRTUALTARGET */

#if defined (BRS_ENABLE_OS_INTERRUPT_ONLY)
  /* OS is configured for UseCase Interrupt Only (/MICROSAR/Os/OsOS/OsUseCase) */
/*****************************************************************************/
/* @brief      With OS UseCase "Interrupt Only" (/MICROSAR/Os/OsOS/OsUseCase),
 *             the default API SuspendAllInterrupts() is not functional.
 *             Instead, this wrapper function is handling nested calls and the
 *             alternative suspend API call.
 * @pre        -
 * @param[in]  -
 * @param[out] -
 * @return     -
 * @context    Called by vBrs generated SchM stub in OS UseCase Interrupt Only.
 *****************************************************************************/
void BrsMainSuspendAllInterrupts(void)
{
  if (brsMain_SuspendAllCounter == 0u)
  {
    DisableAllInterrupts();
  }

  brsMain_SuspendAllCounter++;
}

/*****************************************************************************/
/* @brief      With OS UseCase "Interrupt Only" (/MICROSAR/Os/OsOS/OsUseCase),
 *             the default API ResumeAllInterrupts() is not functional.
 *             Instead, this wrapper function is handling nested calls and the
 *             alternative resume API call.
 * @pre        -
 * @param[in]  -
 * @param[out] -
 * @return     -
 * @context    Called by vBrs generated SchM stub in OS UseCase Interrupt Only.
 *****************************************************************************/
void BrsMainResumeAllInterrupts(void)
{
  if (brsMain_SuspendAllCounter != 0u)
  {
    brsMain_SuspendAllCounter--;

    if (brsMain_SuspendAllCounter == 0u)
    {
      EnableAllInterrupts();
    }
  }
}
#endif /* BRS_ENABLE_OS_INTERRUPT_ONLY */

/*****************************************************************************/
/*@brief      Main function
 * @pre        -
 * @param[in]  -
 * @param[out] -
 * @return     always 0 as the function is not expected to return
 * @context    Called by the startup code
 *****************************************************************************/
int main(void)
{
#if !defined (VVIRTUALTARGET)
  uint32 coreID = BrsHw_GetCore();
# if ((!defined (BRS_ENABLE_HYPERVISOR_SUPPORT)) && ((!defined (BRS_ENABLE_FBL_SUPPORT)) || \
                                                     (defined (BRS_FBL_EXCEPTIONTABLE_IN_RAM))))
  uint32 i;
  uint8 validCoreConfig = 0u;
# endif
# if defined (BRS_ENABLE_OS_MULTICORESUPPORT) && (!defined (BRS_ENABLE_HYPERVISOR_SUPPORT))
  uint8 triggerNonAsrHook = 0u;
#  if defined (BRS_ENABLE_START_NONASR_CORES)
  StatusType OsStatus = E_OK;
#  endif
# endif
#endif /* !VVIRTUALTARGET */

#if defined (BRSMAIN_MAIN_CALLOUT)
  BrsTestsuite_BrsMain_main();
#endif

#if !defined (VVIRTUALTARGET)
  BrsHwDisableInterruptAtPowerOn();

# if ((!defined (BRS_ENABLE_HYPERVISOR_SUPPORT)) && ((!defined (BRS_ENABLE_FBL_SUPPORT)) || \
                                                     (defined (BRS_FBL_EXCEPTIONTABLE_IN_RAM))))
  /*
  * For FBL UseCase, only needed, if functionality to activate the additional ExceptionTable
  * in RAM is enabled (vBRSGeneral/vBRSFblSupportExceptionTableInRam)
  */

  for (i=0; i<BrsMain_CoreConfig_Size; i++)
  {
    /* Search for valid Exception- and Interrupt Table in BrsMain_CoreConfig[] (vBRS generated into vBrs_Lcfg.c) */
    if (BRS_EXCEPTIONTABLE_INIT_NEEDED(i, coreID))
    {
      BrsHw_ExceptionTable_Init(BrsMain_CoreConfig[i].ExcVecLabel, BrsMain_CoreConfig[i].IntVecLabel);
    }
    validCoreConfig |= ((BrsMain_CoreConfig[i].PhysicalCoreId == coreID) ? 1u : 0u);


#  if defined (BRS_ENABLE_OS_MULTICORESUPPORT)
    /* Additional handling of non-ASR cores in multicore environments */
    if (BrsMain_CoreConfig[i].CoreIsAsr == NON_ASR)
    {
#   if defined (BRS_ENABLE_START_NONASR_CORES)
      /* BRS_ENABLE_START_NONASR_CORES needs to be set manually, if the InitCore should start the non-Autosar cores */
      if ((coreID == BRSHW_INIT_CORE_ID) && (BrsMain_CoreConfig[i].PhysicalCoreId != coreID))
      { /* Init Core must start the non-Autosar-Cores */
        StartNonAutosarCore(BrsMain_CoreConfig[i].PhysicalCoreId, &OsStatus);
      }
      else
#   endif
      { /* If current Core is non-Autosar Core, we shall go to nonAutosarHook instead of EcuM_Init */
        triggerNonAsrHook = (BrsMain_CoreConfig[i].PhysicalCoreId == coreID);
      }
    }
#  endif /* BRS_ENABLE_OS_MULTICORESUPPORT */
  }

  /* Check, if no valid core config was found */
  if (validCoreConfig == 0u)
  {
    BrsMainExceptionHandler(kBrsInvalidCoreConfig, BRSERROR_MODULE_BRSMAIN, (uint16)(__LINE__));
  }
#  if defined (BRS_ENABLE_OS_MULTICORESUPPORT) && defined (BRS_ENABLE_START_NONASR_CORES)
  if (OsStatus != E_OK)
    BrsMainExceptionHandler(kBrsFailedNonAsrCoreStart, BRSERROR_MODULE_BRSMAIN, (uint16)(__LINE__));
#  endif
# endif /* !BRS_ENABLE_HYPERVISOR_SUPPORT && (!BRS_ENABLE_FBL_SUPPORT || BRS_FBL_EXCEPTIONTABLE_IN_RAM */

# if (BRS_CPU_CORE_AMOUNT>1)
  if (coreID == BRSHW_INIT_CORE_ID)
# endif
#endif /* !VVIRTUALTARGET */
  {
    BrsMainInit();
  }

#if defined (BRSMAIN_POSTBRSMAININIT_CALLOUT)
  BrsTestsuite_BrsMain_PostBrsMainInit();
#endif

#if defined (BRS_FBL_NO_ECUMINIT)
  FblMain(); /* never returns */

#else
# if (!defined (BRS_ENABLE_FBL_SUPPORT)) && (!defined (BRS_ENABLE_HSM_UPDATER_SUPPORT)) || (defined (VVIRTUALTARGET))
#  if defined (BRS_ENABLE_HYPERVISOR_SUPPORT)
  BrsMain_Appl_HypervisorStartCoreApi(coreID);

  vHyp_InitMemory();
  vHyp_Init();

#  elif defined (BRS_ENABLE_OS_INTERRUPT_ONLY)
  /* OS is configured for UseCase Interrupt Only (/MICROSAR/Os/OsOS/OsUseCase) */
  Os_InitInterruptOnly();

#  else
  Os_InitMemory();
  Os_Init();
#  endif
# endif /* (!BRS_ENABLE_FBL_SUPPORT && !BRS_ENABLE_HSM_UPDATER_SUPPORT) || VVIRTUALTARGET */

# if defined (BRS_ENABLE_OS_MULTICORESUPPORT) && (!defined (VVIRTUALTARGET)) && \
                                                 (!defined (BRS_ENABLE_HYPERVISOR_SUPPORT))
  if (triggerNonAsrHook)
  { /*
    * New callout API for non-Autosar-Cores that are not FBL/HSM-Updater related (core configured as non-ASR core
    * in OS)
    */
    BrsMain_NonAsrCore_Hook();
  }
# endif

# if defined (BRS_ENABLE_HSM_SUPPORT) || defined (BRS_ENABLE_HSM_UPDATER_SUPPORT)
  vHsm_Init(); /* never returns */

# elif defined (BRS_ENABLE_HYPERVISOR_SUPPORT)
  BrsMain_Appl_HypervisorApi(coreID);

  vHyp_Start(); /* never returns */

# else
  EcuM_Init(); /* never returns */
# endif
#endif /* else BRS_FBL_NO_ECUMINIT */

  BrsMainExceptionHandler(kBrsIllegalReturnFromMain, BRSERROR_MODULE_BRSMAIN, (uint16)(__LINE__));

  return 0;
}
