/*********************************************************************************************************************** * FILE DESCRIPTION * ------------------------------------------------------------------------------------------------------------------*/ /** \file * \brief RAM driver functions * * -------------------------------------------------------------------------------------------------------------------- * COPYRIGHT * -------------------------------------------------------------------------------------------------------------------- * \par Copyright * \verbatim * Copyright (c) 2022 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 2013-10-23 visjhg - Initial release * 01.01.00 2015-11-27 visase ESCAN00086297 Allow to override the RAM buffer base address via configuration * 01.02.00 2016-06-17 visci ESCAN00090364 Added support for flashCode use case * 01.02.01 2018-03-22 visdkl ESCAN00098872 No changes * 01.02.02 2021-03-08 vishor ESCAN00108134 Added/adapted MemMap sections * 01.03.00 2022-03-17 visstn FBL-4366 Perform MISRA 2012 migration **********************************************************************************************************************/ #define FBL_RAMIO_SOURCE /*********************************************************************************************************************** * INCLUDES **********************************************************************************************************************/ #include "fbl_ramio_inc.h" /*********************************************************************************************************************** * VERSION **********************************************************************************************************************/ #if ( FBLWRAPPERFLASH_XRAMHIS_VERSION != 0x0103u ) || \ ( FBLWRAPPERFLASH_XRAMHIS_RELEASE_VERSION != 0x00u ) # error "Error in FBL_RAMIO.C: Source and header file are inconsistent!" #endif /*********************************************************************************************************************** * CONFIGURATION CHECKS **********************************************************************************************************************/ /* Check if buffer size is correctly defined */ #if defined( RAM_DRV_BUFFER_SIZE ) && ( RAM_DRV_BUFFER_SIZE > 0u ) #else # error "Error in FBL_RAMIO.C: Missing or wrong configuration of RAM_DRV_BUFFER_SIZE." #endif /* Check if segment size and buffer size match each other */ #if defined( RAM_DRV_SEGMENT_SIZE ) # if ( RAM_DRV_SEGMENT_SIZE > 1u ) # if ( 0u != (RAM_DRV_BUFFER_SIZE & (RAM_DRV_SEGMENT_SIZE - 1u)) ) # error "Error in FBL_RAMIO.C: Inconsistent configuration of RAM_DRV_SEGMENT_SIZE and RAM_DRV_BUFFER_SIZE." # endif # endif #endif /* Check if segment size has reasonable / supported value */ #if defined( RAM_DRV_SEGMENT_SIZE ) # if ( RAM_DRV_SEGMENT_SIZE == 1u ) || ( RAM_DRV_SEGMENT_SIZE == 2u ) || ( RAM_DRV_SEGMENT_SIZE == 4u ) # else # error "Error in FBL_RAMIO.C: Wrong configuration of RAM_DRV_SEGMENT_SIZE." # endif #endif #if defined( RAM_DRV_SEGMENT_SIZE ) && \ defined( RAM_DRV_BASE_ADDRESS_OVERRIDE ) /* Check alignment of base address */ # if ( 0u != (RAM_DRV_BASE_ADDRESS_OVERRIDE & (RAM_DRV_SEGMENT_SIZE - 1u)) ) # error "Error in FBL_RAMIO.C: Inconsistent configuration of RAM_DRV_SEGMENT_SIZE and RAM_DRV_BASE_ADDRESS_OVERRIDE." # endif #endif #if defined( RAM_DRV_POLLING_INTERVAL ) # if ( 0u == RAM_DRV_POLLING_INTERVAL ) || \ ( 0u != (RAM_DRV_POLLING_INTERVAL & (RAM_DRV_POLLING_INTERVAL - 1u)) ) # error "Error in FBL_RAMIO.C: Wrong configuration of RAM_DRV_POLLING_INTERVAL (shall be 2^n)." # endif #endif /*********************************************************************************************************************** * DEFINES **********************************************************************************************************************/ #if defined( RAM_DRV_EXT_BUFFER ) # define RAM_DRV_BUFFER RAM_DRV_EXT_BUFFER #else # define RAM_DRV_BUFFER g_RamData #endif #if defined( RAM_DRV_BASE_ADDRESS_OVERRIDE ) /** Allow to override the base address via fbl_ramio_cfg.h, e.g. if RAM_DRV_BUFFER shall be located at an arbitrary address */ # define RAM_DRV_BASE_ADDRESS RAM_DRV_BASE_ADDRESS_OVERRIDE #else /** Base address of accessible RAM area */ # define RAM_DRV_BASE_ADDRESS ((IO_PositionType)RAM_DRV_BUFFER) #endif /*********************************************************************************************************************** * GLOBAL DATA **********************************************************************************************************************/ #if defined( RAM_DRV_EXT_BUFFER ) #else # define FBLRAMIO_START_SEC_VAR # include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ /** Global data buffer that can be accessed via RamDriver interface */ V_MEMRAM0 static V_MEMRAM1 IO_U8 V_MEMRAM2 g_RamData[RAM_DRV_BUFFER_SIZE]; # define FBLRAMIO_STOP_SEC_VAR # include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ #endif /* RAM_DRV_EXT_BUFFER */ #define FBLRAMIO_START_SEC_CODE #include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ /*********************************************************************************************************************** * LOCAL FUNCTION PROTOTYPES **********************************************************************************************************************/ static IO_ErrorType V_API_NEAR RamDriver_GetOffset( IO_SizeType length, IO_PositionType address, V_MEMRAM1 IO_SizeType V_MEMRAM2 V_MEMRAM3 * pOffset ); /*********************************************************************************************************************** * LOCAL FUNCTIONS **********************************************************************************************************************/ /*********************************************************************************************************************** * RamDriver_GetOffset **********************************************************************************************************************/ /*! \brief Get the local buffer offset * \param[in] length The number of bytes to be modified * \param[in] address The start address * \param[out] offset The returned offset * \return IO_E_OK if succeeded, IO_E_NOT_OK otherwise **********************************************************************************************************************/ static IO_ErrorType V_API_NEAR RamDriver_GetOffset( IO_SizeType length, IO_PositionType address, V_MEMRAM1 IO_SizeType V_MEMRAM2 V_MEMRAM3 * pOffset ) { IO_ErrorType result; IO_SizeType offset; result = IO_E_NOT_OK; /* Avoid compiler warning (comparison against 0 always true) */ #if defined( RAM_DRV_BASE_ADDRESS_OVERRIDE ) # if ( 0u != RAM_DRV_BASE_ADDRESS ) if (address >= RAM_DRV_BASE_ADDRESS) /* PRQA S 0306 */ /* MD_FblRamio_0306 */ # endif #endif { offset = address - RAM_DRV_BASE_ADDRESS; /* PRQA S 0306 */ /* MD_FblRamio_0306 */ if ( (length <= RAM_DRV_BUFFER_SIZE) && (offset <= (RAM_DRV_BUFFER_SIZE - length)) ) { *pOffset = offset; result = IO_E_OK; } } return result; } /*********************************************************************************************************************** * GLOBAL FUNCTIONS **********************************************************************************************************************/ /*********************************************************************************************************************** * RamDriver_InitSync **********************************************************************************************************************/ /*! \brief Initialize the RAM algorithm * \param[in] address Unused parameter for HIS interface compliance * \return The return code shows the success of the initialization **********************************************************************************************************************/ /* PRQA S 3673 1 */ /* MD_MSR_Rule8.13 */ IO_ErrorType V_API_NEAR RamDriver_InitSync( void * address ) { IO_ErrorType result; #if defined( RAM_DRV_ENABLE_MEM_INIT ) IO_U32 i; #endif #if defined( V_ENABLE_USE_DUMMY_STATEMENT ) (void)address; #endif result = IO_E_OK; #if defined( RAM_DRV_BASE_ADDRESS_OVERRIDE ) /* Alignment check executed by preprocessor (see configuration checks section) */ #else /* PRQA S 2992, 2996, 0306 1 */ /* MD_FblRamio_2992_2996, MD_FblRamio_2992_2996, MD_FblRamio_0306 */ if (0u != (RAM_DRV_BASE_ADDRESS & (RAM_DRV_SEGMENT_SIZE - 1u))) { /* RAM buffer is not aligned with configured segment size */ result = IO_E_NOT_OK; } #endif /* RAM_DRV_BASE_ADDRESS_OVERRIDE */ #if defined( RAM_DRV_ENABLE_MEM_INIT ) if (IO_E_OK == result) /* PRQA S 2991, 2995 */ /* MD_FblRamio_2991_2995 */ { for (i = 0u; i < (RAM_DRV_BUFFER_SIZE / RAM_DRV_SEGMENT_SIZE); i++) { # if ( RAM_DRV_SEGMENT_SIZE == 1u ) ((IO_U8 *)RAM_DRV_BUFFER)[i] = 0u; # elif ( RAM_DRV_SEGMENT_SIZE == 2u ) ((IO_U16 *)RAM_DRV_BUFFER)[i] = 0u; /* PRQA S 0310, 3305 */ /* MD_FblRamio_0310_3305 */ # elif ( RAM_DRV_SEGMENT_SIZE == 4u ) ((IO_U32 *)RAM_DRV_BUFFER)[i] = 0u; /* PRQA S 0310, 3305 */ /* MD_FblRamio_0310_3305 */ # endif # if defined( RAM_DRV_POLLING_INTERVAL ) /* PRQA S 2985, 2991, 2995 1 */ /* MD_FblRamio_2985, MD_FblRamio_2991_2995, MD_FblRamio_2991_2995 */ if (0u == (i & (RAM_DRV_POLLING_INTERVAL - 1u))) { RAM_DRV_POLLING_FUNCTION(); } # endif /* RAM_DRV_POLLING_INTERVAL */ } } #endif /* RAM_DRV_ENABLE_MEM_INIT */ return result; } /*********************************************************************************************************************** * RamDriver_DeinitSync **********************************************************************************************************************/ /*! \brief Deinitialize the RAM algorithm * \param[in] address Unused parameter for HIS interface compliance * \return The return code shows the success of the deinitialization **********************************************************************************************************************/ IO_ErrorType V_API_NEAR RamDriver_DeinitSync( void * address ) { IO_ErrorType result; /* Clean-up memory */ result = RamDriver_InitSync(address); return result; } /*********************************************************************************************************************** * RamDriver_RWriteSync **********************************************************************************************************************/ /*! \brief Program RAM memory * \param[in] writeBuffer Write data buffer * \param[in] writeLength Number of bytes to be written * \param[in] writeAddress The write address * \return Status of RAM programming **********************************************************************************************************************/ /* PRQA S 3673 1 */ /* MD_MSR_Rule8.13 */ IO_ErrorType V_API_NEAR RamDriver_RWriteSync( IO_MemPtrType writeBuffer, IO_SizeType writeLength, IO_PositionType writeAddress ) { IO_ErrorType result; IO_SizeType offset; IO_SizeType i; result = RamDriver_GetOffset(writeLength, writeAddress, &offset); if (IO_E_OK == result) { for (i = 0u; i < writeLength; i++) { #if defined( RAM_DRV_POLLING_INTERVAL ) /* PRQA S 2985, 2991, 2995 1 */ /* MD_FblRamio_2985, MD_FblRamio_2991_2995, MD_FblRamio_2991_2995 */ if (0u == (i & (RAM_DRV_POLLING_INTERVAL - 1u))) { RAM_DRV_POLLING_FUNCTION(); } #endif /* RAM_DRV_POLLING_INTERVAL */ RAM_DRV_BUFFER[offset] = writeBuffer[i]; offset++; } } return result; } /*********************************************************************************************************************** * RamDriver_REraseSync **********************************************************************************************************************/ /*! \brief Erase RAM memory * \pre RAM driver has to be initialized * \param[in] eraseLength Number of bytes to be erased * \param[in] eraseAddress The erase address * \return Status of RAM erase **********************************************************************************************************************/ IO_ErrorType V_API_NEAR RamDriver_REraseSync( IO_SizeType eraseLength, IO_PositionType eraseAddress ) { #if defined( RAM_DRV_DELETED ) IO_ErrorType result; IO_SizeType offset; IO_SizeType i; result = RamDriver_GetOffset(eraseLength, eraseAddress, &offset); if (IO_E_OK == result) { for (i = 0u; i < eraseLength; i++) { # if defined( RAM_DRV_POLLING_INTERVAL ) /* PRQA S 2985, 2991, 2995 1 */ /* MD_FblRamio_2985, MD_FblRamio_2991_2995, MD_FblRamio_2991_2995 */ if (0u == (i & (RAM_DRV_POLLING_INTERVAL - 1u))) { RAM_DRV_POLLING_FUNCTION(); } # endif /* RAM_DRV_POLLING_INTERVAL */ RAM_DRV_BUFFER[offset] = RAM_DRV_DELETED; offset++; } } return result; #else /* ! RAM_DRV_DELETED */ # if defined( V_ENABLE_USE_DUMMY_STATEMENT ) (void)eraseLength; (void)eraseAddress; # endif /* V_ENABLE_USE_DUMMY_STATEMENT */ return IO_E_OK; #endif /* ! RAM_DRV_DELETED */ } /*********************************************************************************************************************** * RamDriver_RReadSync **********************************************************************************************************************/ /*! \brief Read RAM memory * \pre RAM driver has to be initialized * \param[out] readBuffer Read data buffer * \param[in] readLength Number of bytes to be read * \param[in] readAddress The read address * \return Status of RAM read **********************************************************************************************************************/ IO_ErrorType V_API_NEAR RamDriver_RReadSync( IO_MemPtrType readBuffer, IO_SizeType readLength, IO_PositionType readAddress ) { IO_ErrorType result; IO_SizeType offset; IO_SizeType i; result = RamDriver_GetOffset(readLength, readAddress, &offset); if (IO_E_OK == result) { for (i = 0u; i < readLength; i++) { #if defined( RAM_DRV_POLLING_INTERVAL ) /* PRQA S 2985, 2991, 2995 1 */ /* MD_FblRamio_2985, MD_FblRamio_2991_2995, MD_FblRamio_2991_2995 */ if (0u == (i & (RAM_DRV_POLLING_INTERVAL - 1u))) { RAM_DRV_POLLING_FUNCTION(); } #endif /* RAM_DRV_POLLING_INTERVAL */ readBuffer[i] = RAM_DRV_BUFFER[offset]; offset++; } } return result; } #define FBLRAMIO_STOP_SEC_CODE #include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ /* Module specific MISRA deviations: MD_FblRamio_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. MD_FblRamio_0310_3305: Reason: Pointer is casted as different memory access sizes are utilized due to performance reasons. Risk: Wrong pointer access is performed. Prevention: Code inspection and test of the different variants in the component test. MD_FblRamio_2985: Reason: Depending on configuration, RAM_DRV_POLLING_INTERVAL might be zero and thus i & (RAM_DRV_POLLING_INTERVAL - 1u) might be redundant. Risk: No identifiable risk. Prevention: No prevention required. MD_FblRamio_2991_2995: Reason: Depending on configuration, the controlling expression might always be true. This code structure maintains readbillity. Risk: No identifiable risk. Prevention: No prevention required. MD_FblRamio_2992_2996: Reason: Depending on configuration, the controlling expression might always be false. This code structure maintains readbillity. Risk: No identifiable risk. Prevention: No prevention required. */ /*********************************************************************************************************************** * END OF FILE: FBL_RAMIO.C **********************************************************************************************************************/