arm_joint_sensor_bootloader/Drivers/OpenBLT/infotable.c
2026-04-03 19:04:32 +08:00

252 lines
10 KiB
C

/************************************************************************************//**
* \file Source/infotable.v
* \brief Info table check feature source file.
* \ingroup Core
* \internal
*----------------------------------------------------------------------------------------
* C O P Y R I G H T
*----------------------------------------------------------------------------------------
* Copyright (c) 2025 by Feaser http://www.feaser.com All rights reserved
*
*----------------------------------------------------------------------------------------
* L I C E N S E
*----------------------------------------------------------------------------------------
* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You have received a copy of the GNU General Public License along with OpenBLT. It
* should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy.
*
* \endinternal
****************************************************************************************/
/****************************************************************************************
* Include files
****************************************************************************************/
#include "boot.h" /* bootloader generic header */
#if (BOOT_INFO_TABLE_ENABLE > 0)
/****************************************************************************************
* Hook functions
****************************************************************************************/
extern blt_bool InfoTableCheckHook(blt_addr newInfoTable, blt_addr currentInfoTable);
/****************************************************************************************
* Local data declarations
****************************************************************************************/
/** \brief RAM buffer for storing the info table that is extracted from the firmware
* file at the start of the firmware update.
* \details For remote firmware updates, the extracted info table is downloaded to this
* RAM buffer. For firmware updates from locally attached storage, the
* extracted info table is directly copied to this RAM buffer.
*/
static blt_int8u infoTableBuffer[BOOT_INFO_TABLE_LEN];
/** \brief Current write pointer for storing data into the RAM info buffer. */
static blt_int8u * infoTableWritePtr;
/***********************************************************************************//**
** \brief Initializes the info table module.
** \return none
**
****************************************************************************************/
void InfoTableInit(void)
{
/* Initialize module locals. */
infoTableWritePtr = &infoTableBuffer[0];
/* Clear the info table in the internal RAM buffer. */
InfoTableClear(INFO_TABLE_ID_INTERNAL_RAM);
} /*** end of InfoTableInit ***/
/***********************************************************************************//**
** \brief Invokes the hook function to compare the info table contents of the to-be-
** programmed firmware (in the internal RAM info table) with the info table
** contents of the currently programmed firmware (in the NVM info table).
** It allows the bootloader application to implement comparison logic to
** determine if the firmware update is allowed to proceed. Could for example
** be used to make sure a firmware update only goes through if the selected
** firmware file contains firmware for the correct product type.
** \return BLT_TRUE if the info table check passed and the firmware update is allowed
** to proceed. BLT_FALSE if the firmware update is not allowed to proceed.
**
****************************************************************************************/
blt_bool InfoTableCheck(void)
{
blt_bool result;
blt_addr infoTableNewAddr;
blt_addr infoTableCurrentAddr;
/* Collect info table pointers. */
infoTableNewAddr = InfoTableGetPtr(INFO_TABLE_ID_INTERNAL_RAM);
infoTableCurrentAddr = InfoTableGetPtr(INFO_TABLE_ID_FIRMWARE_NVM);
/* An info table check can only be performed if a valid one is present. Check the
* currently programmed firmware's checksum for this reason.
*/
if (NvmVerifyChecksum() == BLT_FALSE)
{
/* No valid firmware present. This usually means that no firmware is yet programmed
* or the previous firmware update did not run all the way to completion. In either
* case, the current firmware update is allowed to proceed, without further info
* table checking.
*/
result = BLT_TRUE;
}
/* Checksum verification of current firmware okay, which means that an info table
* should be present.
*/
else
{
/* Request bootloader application to perform the info table check. */
result = InfoTableCheckHook(infoTableNewAddr, infoTableCurrentAddr);
}
/* Give the result back to the caller. */
return result;
} /*** end of InfoTableCheck ***/
/***********************************************************************************//**
** \brief Obtains the memory pointer of the selected info table.
** \param infoTableId Specifies the info table to get the pointer to.
** \return Address of the selected info table.
**
****************************************************************************************/
blt_addr InfoTableGetPtr(tInfoTableId infoTableId)
{
blt_addr result;
/* Info table of this module's RAM buffer? This is where the info table of the to-be-
* programmed firmware will be written to.
*/
if (infoTableId == INFO_TABLE_ID_INTERNAL_RAM)
{
result = (blt_addr)(&infoTableBuffer[0]);
}
/* Info table of the currently programmed firmware. Note that it is possible that
* no firmware is programmed at all.
*/
else
{
result = (blt_addr)BOOT_INFO_TABLE_ADDR;
}
/* Give the result back to the caller. */
return result;
} /*** end of InfoTableGetPtr ***/
/***********************************************************************************//**
** \brief Utility function to clear the contents of the internal RAM buffer and to
** re-initialize its write pointer to the start.
** \param infoTableId Specifies the info table to get the pointer to. Must be
** INFO_TABLE_ID_INTERNAL_RAM, because the INFO_TABLE_ID_FIRMWARE_NVM cannot
** be changed.
** \return none.
**
****************************************************************************************/
void InfoTableClear(tInfoTableId infoTableId)
{
blt_int16u idx;
/* Verify parameter. */
ASSERT_RT(infoTableId == INFO_TABLE_ID_INTERNAL_RAM);
/* Only continue with a valid parameter. */
if (infoTableId == INFO_TABLE_ID_INTERNAL_RAM)
{
/* Clear the contents of the info table RAM buffer. */
for (idx = 0U; idx < BOOT_INFO_TABLE_LEN; idx++)
{
infoTableBuffer[idx] = 0U;
}
/* Reset the write pointer. */
infoTableWritePtr = &infoTableBuffer[0];
}
} /*** end of InfoTableClear ***/
/***********************************************************************************//**
** \brief Utility function to determine the current number of bytes stored in the
** specified buffer. For INFO_TABLE_ID_FIRMWARE_NVM this is always the
** same. For INFO_TABLE_ID_INTERNAL_RAM is returns the number of bytes that
** were currenty written to it.
** \param infoTableId Specifies the info table to get the pointer to. Must be
** INFO_TABLE_ID_INTERNAL_RAM, because the INFO_TABLE_ID_FIRMWARE_NVM cannot
** be changed.
** \return The number of bytes currently present in the info table.
**
****************************************************************************************/
blt_int16u InfoTableCurrentSize(tInfoTableId infoTableId)
{
blt_int16u result = BOOT_INFO_TABLE_LEN + 1; /* Invalid length (too full). */
if (infoTableId == INFO_TABLE_ID_INTERNAL_RAM)
{
/* Calculate stored number of bytes by making use of the write pointer. First do a
* sanity check.
*/
if (infoTableWritePtr >= &infoTableBuffer[0])
{
result = (blt_int16u)((blt_addr)infoTableWritePtr-(blt_addr)(&infoTableBuffer[0]));
}
}
else
{
/* Info table in NVM has fixed size as it cannot be changed. */
result = BOOT_INFO_TABLE_LEN;
}
/* Give the result back to the caller. */
return result;
} /*** end of InfoTableCurrentSize ***/
/***********************************************************************************//**
** \brief Utility function to add data to the internal RAM info table, while also
** auto incrementing the write pointer.
** \param infoTableId Specifies the info table to get the pointer to. Must be
** INFO_TABLE_ID_INTERNAL_RAM, because the INFO_TABLE_ID_FIRMWARE_NVM cannot
** be changed.
** \param data Pointer to the byte array with data to add.
** \param len Number of bytes to add.
** \return BLT_TRUE if the data could be added to the info table, BLT_FALSE otherwise.
**
****************************************************************************************/
blt_bool InfoTableAddData(tInfoTableId infoTableId, blt_int8u const * data,
blt_int16u len)
{
blt_bool result = BLT_FALSE;
/* Can only add data to the internal RAM info table and with a valid data pointer. */
if ( (infoTableId == INFO_TABLE_ID_INTERNAL_RAM) && (data != BLT_NULL) && (len > 0) )
{
/* Only continue if this data still fits in the info table. */
if ((InfoTableCurrentSize(INFO_TABLE_ID_INTERNAL_RAM) + len) <= BOOT_INFO_TABLE_LEN)
{
/* Store the data in the internal RAM info table. */
CpuMemCopy((blt_addr)infoTableWritePtr, (blt_addr)((blt_int32u)&data[0]), len);
/* Update the write pointer accordingly. */
infoTableWritePtr += len;
/* Update the result. */
result = BLT_TRUE;
}
}
/* Give the result back to the caller. */
return result;
} /*** end of InfoTableAddData ***/
#endif /* BOOT_INFO_TABLE_ENABLE > 0 */
/*********************************** end of infotable.c ********************************/