This commit is contained in:
Mysteo
2023-06-29 19:23:00 +03:00
commit bebfc1b5ab
415 changed files with 294688 additions and 0 deletions

56
Boot/loader/asserts.c Normal file
View File

@@ -0,0 +1,56 @@
/************************************************************************************//**
* \file Source/asserts.c
* \brief Bootloader assertion module source file.
* \ingroup Core
* \internal
*----------------------------------------------------------------------------------------
* C O P Y R I G H T
*----------------------------------------------------------------------------------------
* Copyright (c) 2011 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 */
#ifndef NDEBUG
/************************************************************************************//**
** \brief Called when a runtime assertion failed. It stores information about where
** the assertion occurred and halts the software program.
** \param file Name of the source file where the assertion occurred.
** \param line Linenumber in the source file where the assertion occurred.
** \return none
**
****************************************************************************************/
void AssertFailure(blt_char *file, blt_int32u line)
{
/* hang the software so that it requires a hard reset */
for (;;)
{
/* keep servicing the watchdog so that this one does not cause a reset */
CopService();
}
} /*** end of AssertFailure ***/
#endif /* !NDEBUG */
/*********************************** end of assert.c ***********************************/

62
Boot/loader/asserts.h Normal file
View File

@@ -0,0 +1,62 @@
/************************************************************************************//**
* \file Source/asserts.h
* \brief Bootloader assertion module header file.
* \ingroup Core
* \internal
*----------------------------------------------------------------------------------------
* C O P Y R I G H T
*----------------------------------------------------------------------------------------
* Copyright (c) 2011 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
****************************************************************************************/
#ifndef ASSERT_H
#define ASSERT_H
/****************************************************************************************
* Macro definitions
****************************************************************************************/
/* declare assertion macro's. ASSERT_CT is for compile time assertions and ASSERT_RT is
* for runtime assertions.
*/
#ifdef NDEBUG
#define ASSERT_CT(cond) ((void)0)
#define ASSERT_RT(cond) ((void)0)
#else
#define ASSERT_CONCAT_(a, b) a##b
#define ASSERT_CONCAT(a, b) ASSERT_CONCAT_(a, b)
/** \brief Macro for assertions that can be performed at compile time. */
#define ASSERT_CT(cond) enum { ASSERT_CONCAT(assert_error_on_line_, __LINE__) = 1/(!!(cond)) }
/** \brief Macro for assertions that can only be performed at run time. */
#define ASSERT_RT(cond) \
if (cond) \
{ ; } \
else \
AssertFailure(__FILE__, __LINE__)
#endif /* NDEBUG */
/****************************************************************************************
* Function prototypes
****************************************************************************************/
#ifndef NDEBUG
void AssertFailure(blt_char *file, blt_int32u line);
#endif
#endif /* ASSERT_H */
/*********************************** end of assert.h ***********************************/

221
Boot/loader/backdoor.c Normal file
View File

@@ -0,0 +1,221 @@
/************************************************************************************//**
* \file Source/backdoor.c
* \brief Bootloader backdoor entry source file.
* \ingroup Core
* \internal
*----------------------------------------------------------------------------------------
* C O P Y R I G H T
*----------------------------------------------------------------------------------------
* Copyright (c) 2011 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 */
/****************************************************************************************
* Macro definitions
****************************************************************************************/
#if (BOOT_BACKDOOR_HOOKS_ENABLE == 0)
#ifndef BOOT_BACKDOOR_ENTRY_TIMEOUT_MS
/** \brief Sets the time in milliseconds that the backdoor is open, but allow an
* override for this time. To change this value, simply add the macro
* BOOT_BACKDOOR_ENTRY_TIMEOUT_MS to blt_conf.h with your desired backdoor
* open time in milliseconds.
*/
#define BOOT_BACKDOOR_ENTRY_TIMEOUT_MS (500)
#endif
#endif /* BOOT_BACKDOOR_HOOKS_ENABLE == 0 */
/****************************************************************************************
* Hook functions
****************************************************************************************/
#if (BOOT_BACKDOOR_HOOKS_ENABLE > 0)
extern void BackDoorInitHook(void);
extern blt_bool BackDoorEntryHook(void);
#endif
/****************************************************************************************
* Local data declarations
****************************************************************************************/
#if (BOOT_BACKDOOR_HOOKS_ENABLE == 0)
/** \brief To determine if the backdoor is open or closed. */
static blt_bool backdoorOpen;
/** \brief To determine how long the backdoor has been open in milliseconds. */
static blt_int32u backdoorOpenTime;
/** \brief In certain scenarios it is desired to be able to extend the default backdoor
* entry time at runtime. This variable holds the extension time in milliseconds.
* Note that this value must be initialized to zero here and not in function
* BackDoorInit(), because BackDoorInit() is one of the last functions called
* in BootInit(). This order should not be changed otherwise there is a chance
* that the timed backdoor partially or completely times out during BootInit().
* Initializing the variable here, allows function BackDoorSetExtension() to be
* called before BackDoorInit() was called.
*/
static blt_int32u backdoorExtensionTime = 0;
#endif
/************************************************************************************//**
** \brief Initializes the backdoor entry option.
** \return none
**
****************************************************************************************/
void BackDoorInit(void)
{
#if (BOOT_BACKDOOR_HOOKS_ENABLE > 0)
/* initialize application's backdoor functionality */
BackDoorInitHook();
/* attempt to start the user program when no backdoor entry is requested */
if (BackDoorEntryHook() == BLT_FALSE)
{
/* this function does not return if a valid user program is present */
CpuStartUserProgram();
}
#if (BOOT_FILE_SYS_ENABLE > 0)
else
{
/* the backdoor is open so we should check if a update from locally attached storage
* is requested and, if so, start it.
*/
FileHandleFirmwareUpdateRequest();
}
#endif
#else
/* open the backdoor after a reset */
backdoorOpen = BLT_TRUE;
BackDoorRestartTimer();
#endif
/* perform the first check that open/closes the backdoor */
BackDoorCheck();
} /*** end of BackDoorInit ***/
/************************************************************************************//**
** \brief The default backdoor entry feature keeps the bootloader active for a
** predetermined time after reset, allowing the host application to
** establish a connection and start a programming sequence. This function
** controls the opening/closing of the backdoor.
** \return none
**
****************************************************************************************/
void BackDoorCheck(void)
{
#if (BOOT_BACKDOOR_HOOKS_ENABLE == 0)
#if (BOOT_COM_ENABLE > 0)
/* check if a connection with the host was already established. in this case the
* backdoor stays open anyway, so no need to check if it needs to be closed.
*/
if (ComIsConnected() == BLT_TRUE)
{
return;
}
#endif
#if (BOOT_FILE_SYS_ENABLE > 0)
/* check if the file module is busy, indicating that a firmware update through the
* locally attached storage is in progress. in this case the backdoor stays open
* anyway, so no need to check if it needs to be closed.
*/
if (FileIsIdle() == BLT_FALSE)
{
return;
}
#endif
/* when the backdoor is still open, check if it's time to close it */
if (backdoorOpen == BLT_TRUE)
{
/* check if the backdoor entry time window elapsed */
if (TimerGet() >= (BOOT_BACKDOOR_ENTRY_TIMEOUT_MS + backdoorExtensionTime + backdoorOpenTime))
{
/* close the backdoor */
backdoorOpen = BLT_FALSE;
#if (BOOT_FILE_SYS_ENABLE > 0)
/* during the timed backdoor no remote update request was detected. now do one
* last check to see if a firmware update from locally attached storage is
* pending.
*/
if (FileHandleFirmwareUpdateRequest() == BLT_FALSE)
#endif
{
/* no firmware update requests detected, so attempt to start the user program.
* this function does not return if a valid user program is present.
*/
CpuStartUserProgram();
}
}
}
#endif
} /*** end of BackDoorCheck ***/
#if (BOOT_BACKDOOR_HOOKS_ENABLE == 0)
/************************************************************************************//**
** \brief Sets the amount of milliseconds that the default backdoor timeout time
** (BOOT_BACKDOOR_ENTRY_TIMEOUT_MS) is extended.
** \param extension_ms Extension time in milliseconds.
** \return none
**
****************************************************************************************/
void BackDoorSetExtension(blt_int32u extension_ms)
{
/* update the extension time */
backdoorExtensionTime = extension_ms;
} /*** end of BackDoorSetExtension ***/
/************************************************************************************//**
** \brief Gets the amount of milliseconds that the default backdoor timeout time
** (BOOT_BACKDOOR_ENTRY_TIMEOUT_MS) is extended.
** \return Extension time in milliseconds.
**
****************************************************************************************/
blt_int32u BackDoorGetExtension(void)
{
/* read out and reutrn the currently configured extension time */
return backdoorExtensionTime;
} /*** end of BackDoorGetExtension ***/
/************************************************************************************//**
** \brief Restarts the timed backdoor timer. It uses the current system time as the
** start time. The backdoor stays open for BOOT_BACKDOOR_ENTRY_TIMEOUT_MS
** after this start time, possibly extended in case BackDoorSetExtension() was
** called.
** \return none
**
****************************************************************************************/
void BackDoorRestartTimer(void)
{
/* only restart the time if the backdoor is actually still open */
if (backdoorOpen == BLT_TRUE)
{
backdoorOpenTime = TimerGet();
}
} /*** end of BackDoorRestartTimer ***/
#endif /* BOOT_BACKDOOR_HOOKS_ENABLE == 0 */
/*********************************** end of backdoor.c *********************************/

43
Boot/loader/backdoor.h Normal file
View File

@@ -0,0 +1,43 @@
/************************************************************************************//**
* \file Source/backdoor.h
* \brief Bootloader backdoor entry header file.
* \ingroup Core
* \internal
*----------------------------------------------------------------------------------------
* C O P Y R I G H T
*----------------------------------------------------------------------------------------
* Copyright (c) 2011 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
****************************************************************************************/
#ifndef BACKDOOR_H
#define BACKDOOR_H
/****************************************************************************************
* Function prototypes
****************************************************************************************/
void BackDoorInit(void);
void BackDoorCheck(void);
#if (BOOT_BACKDOOR_HOOKS_ENABLE == 0)
void BackDoorSetExtension(blt_int32u extension_ms);
blt_int32u BackDoorGetExtension(void);
void BackDoorRestartTimer(void);
#endif
#endif /* BACKDOOR_H */
/*********************************** end of backdoor.h *********************************/

95
Boot/loader/boot.c Normal file
View File

@@ -0,0 +1,95 @@
/************************************************************************************//**
* \file Source/boot.c
* \brief Bootloader core module source file.
* \ingroup Core
* \internal
*----------------------------------------------------------------------------------------
* C O P Y R I G H T
*----------------------------------------------------------------------------------------
* Copyright (c) 2011 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 */
/************************************************************************************//**
** \brief Initializes the bootloader core.
** \return none
**
****************************************************************************************/
void BootInit(void)
{
/* initialize the CPU */
CpuInit();
/* initialize the watchdog */
CopInit();
/* initialize the millisecond timer */
TimerInit();
/* initialize the non-volatile memory driver */
NvmInit();
#if (BOOT_FILE_SYS_ENABLE > 0)
/* initialize the file system module */
FileInit();
#endif
#if (BOOT_COM_ENABLE > 0)
/* initialize the communication module */
ComInit();
#endif
#if (ADDON_GATEWAY_MOD_ENABLE > 0)
/* initialize the gateway module */
GatewayInit();
#endif
/* initialize the backdoor entry */
BackDoorInit();
} /*** end of BootInit ***/
/************************************************************************************//**
** \brief Task function of the bootloader core that drives the program.
** \return none
**
****************************************************************************************/
void BootTask(void)
{
/* service the watchdog */
CopService();
/* update the millisecond timer */
TimerUpdate();
#if (BOOT_FILE_SYS_ENABLE > 0)
/* call worker task for updating firmware from locally attached file storage */
FileTask();
#endif /* BOOT_FILE_SYS_ENABLE > 0 */
#if (BOOT_COM_ENABLE > 0)
/* process possibly pending communication data */
ComTask();
#endif
#if (ADDON_GATEWAY_MOD_ENABLE > 0)
/* run the gateway */
GatewayTask();
#endif
/* control the backdoor */
BackDoorCheck();
} /*** end of BootTask ***/
/*********************************** end of boot.c *************************************/

79
Boot/loader/boot.h Normal file
View File

@@ -0,0 +1,79 @@
/************************************************************************************//**
* \file Source/boot.h
* \brief Bootloader core module header file.
* \ingroup Core
* \internal
*----------------------------------------------------------------------------------------
* C O P Y R I G H T
*----------------------------------------------------------------------------------------
* Copyright (c) 2011 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
****************************************************************************************/
#ifndef BOOT_H
#define BOOT_H
/****************************************************************************************
* Defines
****************************************************************************************/
/** \brief Main version number of the bootloader core. */
#define BOOT_VERSION_CORE_MAIN (1u)
/** \brief Minor version number of the bootloader core. */
#define BOOT_VERSION_CORE_MINOR (15u)
/** \brief Patch number of the bootloader core. */
#define BOOT_VERSION_CORE_PATCH (0u)
/****************************************************************************************
* Include files
****************************************************************************************/
/* Note that it is possible to override the standard blt_conf.h configuration header
* file with a project specific one that is defined in the IDE/makefile. For example,
* the following define could be configured: PROJ_BLT_CONF_H="my_boot_config.h". This can
* be handy if you use the bootloader in several projects with a different configuration,
* and enables you to have just one bootloader source base.
*/
#include "types.h" /* variable types */
#include "asserts.h" /* assertion checks */
#ifdef PROJ_BLT_CONF_H
#include PROJ_BLT_CONF_H /* custom configuration */
#else
#include "blt_conf.h" /* bootloader configuration */
#endif /* PROJ_BLT_CONF_H */
#include "plausibility.h" /* plausibility checks */
#include "cpu.h" /* cpu driver module */
#include "cop.h" /* watchdog driver module */
#include "nvm.h" /* memory driver module */
#include "timer.h" /* timer driver module */
#include "backdoor.h" /* backdoor entry module */
#include "file.h" /* file system module */
#include "com.h" /* communication interface */
#if (ADDON_GATEWAY_MOD_ENABLE > 0)
#include "gateway.h" /* gateway add-on module */
#endif
/****************************************************************************************
* Function prototypes
****************************************************************************************/
void BootInit(void);
void BootTask(void);
#endif /* BOOT_H */
/*********************************** end of boot.h *************************************/

42
Boot/loader/can.h Normal file
View File

@@ -0,0 +1,42 @@
/************************************************************************************//**
* \file Source/can.h
* \brief Bootloader CAN communication interface header file.
* \ingroup Core
* \internal
*----------------------------------------------------------------------------------------
* C O P Y R I G H T
*----------------------------------------------------------------------------------------
* Copyright (c) 2016 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
****************************************************************************************/
#ifndef CAN_H
#define CAN_H
#if (BOOT_COM_CAN_ENABLE > 0)
/****************************************************************************************
* Function prototypes
****************************************************************************************/
void CanInit(void);
void CanTransmitPacket(blt_int8u *data, blt_int8u len);
blt_bool CanReceivePacket(blt_int8u *data, blt_int8u *len);
#endif /* BOOT_COM_CAN_ENABLE > 0 */
#endif /* CAN_H */
/*********************************** end of can.h **************************************/

356
Boot/loader/com.c Normal file
View File

@@ -0,0 +1,356 @@
/************************************************************************************//**
* \file Source/com.c
* \brief Bootloader communication interface source file.
* \ingroup Core
* \internal
*----------------------------------------------------------------------------------------
* C O P Y R I G H T
*----------------------------------------------------------------------------------------
* Copyright (c) 2011 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_COM_CAN_ENABLE > 0)
#include "can.h" /* can driver module */
#endif
#if (BOOT_COM_RS232_ENABLE > 0)
#include "rs232.h" /* rs232 driver module */
#endif
#if (BOOT_COM_USB_ENABLE > 0)
#include "usb.h" /* usb driver module */
#endif
#if (BOOT_COM_NET_ENABLE > 0)
#include "net.h" /* tcp/ip driver module */
#endif
#if (BOOT_COM_ENABLE > 0)
/****************************************************************************************
* Local data declarations
****************************************************************************************/
/** \brief Holds the communication interface of the currently active interface. */
static tComInterfaceId comActiveInterface = COM_IF_OTHER;
/************************************************************************************//**
** \brief Initializes the communication module including the hardware needed for
** the communication.
** \return none
**
****************************************************************************************/
void ComInit(void)
{
/* initialize the XCP communication protocol */
XcpInit();
#if (BOOT_COM_CAN_ENABLE > 0)
/* initialize the CAN controller */
CanInit();
/* set it as active */
comActiveInterface = COM_IF_CAN;
#endif
#if (BOOT_COM_RS232_ENABLE > 0)
/* initialize the RS232 interface */
Rs232Init();
/* set it as active */
comActiveInterface = COM_IF_RS232;
#endif
#if (BOOT_COM_USB_ENABLE > 0)
/* initialize the USB interface */
UsbInit();
/* set it as active */
comActiveInterface = COM_IF_USB;
#endif
#if (BOOT_COM_NET_ENABLE > 0)
#if (BOOT_COM_NET_DEFERRED_INIT_ENABLE == 0)
/* initialize the TCP/IP interface */
NetInit();
/* set it as active */
comActiveInterface = COM_IF_NET;
#endif
#endif
} /*** end of ComInit ***/
/************************************************************************************//**
** \brief Updates the communication module by checking if new data was received
** and submitting the request to process newly received data.
** \return none
**
****************************************************************************************/
void ComTask(void)
{
blt_int8u xcpPacketLen;
/* make xcpCtoReqPacket static for runtime efficiency */
static blt_int8u xcpCtoReqPacket[BOOT_COM_RX_MAX_DATA];
#if (BOOT_COM_CAN_ENABLE > 0)
if (CanReceivePacket(&xcpCtoReqPacket[0], &xcpPacketLen) == BLT_TRUE)
{
/* make this the active interface */
comActiveInterface = COM_IF_CAN;
/* process packet */
XcpPacketReceived(&xcpCtoReqPacket[0], xcpPacketLen);
}
#endif
#if (BOOT_COM_RS232_ENABLE > 0)
if (Rs232ReceivePacket(&xcpCtoReqPacket[0], &xcpPacketLen) == BLT_TRUE)
{
/* make this the active interface */
comActiveInterface = COM_IF_RS232;
/* process packet */
XcpPacketReceived(&xcpCtoReqPacket[0], xcpPacketLen);
}
#endif
#if (BOOT_COM_USB_ENABLE > 0)
if (UsbReceivePacket(&xcpCtoReqPacket[0], &xcpPacketLen) == BLT_TRUE)
{
/* make this the active interface */
comActiveInterface = COM_IF_USB;
/* process packet */
XcpPacketReceived(&xcpCtoReqPacket[0], xcpPacketLen);
}
#endif
#if (BOOT_COM_NET_ENABLE > 0)
if (NetReceivePacket(&xcpCtoReqPacket[0], &xcpPacketLen) == BLT_TRUE)
{
/* make this the active interface */
comActiveInterface = COM_IF_NET;
/* process packet */
XcpPacketReceived(&xcpCtoReqPacket[0], xcpPacketLen);
}
#endif
} /*** end of ComTask ***/
/************************************************************************************//**
** \brief Releases the communication module.
** \return none
**
****************************************************************************************/
void ComFree(void)
{
#if (BOOT_COM_USB_ENABLE > 0)
/* disconnect the usb device from the usb host */
UsbFree();
#endif
} /*** end of ComFree ***/
/************************************************************************************//**
** \brief Transmits the packet using the xcp transport layer.
** \param data Pointer to the byte buffer with packet data.
** \param len Number of data bytes that need to be transmitted.
** \return none
**
****************************************************************************************/
void ComTransmitPacket(blt_int8u *data, blt_int16u len)
{
#if (BOOT_COM_CAN_ENABLE > 0)
/* transmit the packet. note that len is limited to 8 in the plausibility check,
* so cast is okay.
*/
if (comActiveInterface == COM_IF_CAN)
{
CanTransmitPacket(data, (blt_int8u)len);
}
#endif
#if (BOOT_COM_RS232_ENABLE > 0)
/* transmit the packet. note that len is limited to 255 in the plausibility check,
* so cast is okay.
*/
if (comActiveInterface == COM_IF_RS232)
{
Rs232TransmitPacket(data, (blt_int8u)len);
}
#endif
#if (BOOT_COM_USB_ENABLE > 0)
/* transmit the packet */
if (comActiveInterface == COM_IF_USB)
{
UsbTransmitPacket(data, len);
}
#endif
#if (BOOT_COM_NET_ENABLE > 0)
if (comActiveInterface == COM_IF_NET)
{
/* transmit the packet */
NetTransmitPacket(data, len);
}
#endif
/* send signal that the packet was transmitted */
XcpPacketTransmitted();
} /*** end of ComTransmitPacket ***/
/************************************************************************************//**
** \brief Obtains the maximum number of bytes that can be received on the specified
** communication interface.
** \return Maximum number of bytes that can be received.
**
****************************************************************************************/
blt_int16u ComGetActiveInterfaceMaxRxLen(void)
{
blt_int16u result;
/* filter on communication interface identifier */
switch (comActiveInterface)
{
case COM_IF_RS232:
result = BOOT_COM_RS232_RX_MAX_DATA;
break;
case COM_IF_CAN:
result = BOOT_COM_CAN_RX_MAX_DATA;
break;
case COM_IF_USB:
result = BOOT_COM_USB_RX_MAX_DATA;
break;
case COM_IF_NET:
result = BOOT_COM_NET_RX_MAX_DATA;
break;
default:
result = BOOT_COM_RX_MAX_DATA;
break;
}
return result;
} /*** end of ComGetActiveInterfaceMaxRxLen ***/
/************************************************************************************//**
** \brief Obtains the maximum number of bytes that can be transmitted on the
** specified communication interface.
** \return Maximum number of bytes that can be received.
**
****************************************************************************************/
blt_int16u ComGetActiveInterfaceMaxTxLen(void)
{
blt_int16u result;
/* filter on communication interface identifier */
switch (comActiveInterface)
{
case COM_IF_RS232:
result = BOOT_COM_RS232_TX_MAX_DATA;
break;
case COM_IF_CAN:
result = BOOT_COM_CAN_TX_MAX_DATA;
break;
case COM_IF_USB:
result = BOOT_COM_USB_TX_MAX_DATA;
break;
case COM_IF_NET:
result = BOOT_COM_NET_TX_MAX_DATA;
break;
default:
result = BOOT_COM_TX_MAX_DATA;
break;
}
return result;
} /*** end of ComGetActiveInterfaceMaxTxLen ***/
/************************************************************************************//**
** \brief This function obtains the XCP connection state.
** \return BLT_TRUE when an XCP connection is established, BLT_FALSE otherwise.
**
****************************************************************************************/
blt_bool ComIsConnected(void)
{
blt_bool result = BLT_FALSE;
/* Is there an active XCP connection? This indicates that the communication interface
* is in the connection state.
*/
if (XcpIsConnected())
{
result = BLT_TRUE;
}
#if (ADDON_GATEWAY_MOD_ENABLE > 0)
/* Is the gateway active? This indicates an XCP connection with a slave. */
if (GatewayIsActive())
{
result = BLT_TRUE;
}
#endif
/* give the result back to the caller. */
return result;
} /*** end of ComIsConnected ***/
#if (BOOT_COM_DEFERRED_INIT_ENABLE == 1)
/************************************************************************************//**
** \brief The deferred init feature makes it possible to bypass the initialization of
** a communication interface until this function is called. This feature can
** be enabled for a specific communication interface via macro
** BOOT_COM_XXX_DEFERRED_INIT_ENABLE in blt_conf.h. At this point only the NET
** communication interface supports this feature, as its initialization can
** take quite a long time. If there is a valid user program present, then this
** would cause an unwanted delay after each reset before the user program can
** be started.
** \attention Note that when this feature is enabled for a communication interface, the
** communication interface is only enabled when: (a) no valid user program is
** present or (b) when CpuUserProgramStartHook() returns BLT_FALSE. This means
** that after a normal reactivation of the bootloader from the user program,
** the communication interface is not initialized and firmware updates are
** not possible! In this case it is recommended to somehow pass on the
** communication initialization request from the user program to the
** bootloader. When this request detected by the bootloader application, this
** function should be called. EEPROM or shared RAM can be used to pass on such
** a request.
** \return none
**
****************************************************************************************/
void ComDeferredInit(void)
{
#if (BOOT_COM_NET_ENABLE > 0)
#if (BOOT_COM_NET_DEFERRED_INIT_ENABLE == 1)
/* perform deferred initialization the TCP/IP interface */
NetDeferredInit();
/* set it as active */
comActiveInterface = COM_IF_NET;
#endif
#endif
#if (BOOT_BACKDOOR_HOOKS_ENABLE == 0)
/* the default internal timed backdoor mechanism should start its timer after the
* communication interfaces are initialized. since a deferred initialization was now
* performed, the backdoor timer should be restarted.
*/
BackDoorRestartTimer();
#endif
} /*** end of ComDeferredInit ***/
#endif /* BOOT_COM_DEFERRED_INIT_ENABLE == 1 */
#endif /* BOOT_COM_ENABLE > 0 */
/*********************************** end of com.c **************************************/

145
Boot/loader/com.h Normal file
View File

@@ -0,0 +1,145 @@
/************************************************************************************//**
* \file Source/com.h
* \brief Bootloader communication interface header file.
* \ingroup Core
* \internal
*----------------------------------------------------------------------------------------
* C O P Y R I G H T
*----------------------------------------------------------------------------------------
* Copyright (c) 2011 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
****************************************************************************************/
#ifndef COM_H
#define COM_H
#if (BOOT_COM_ENABLE > 0)
/****************************************************************************************
* Include files
****************************************************************************************/
#include "xcp.h" /* xcp communication layer */
/****************************************************************************************
* Macro definitions
****************************************************************************************/
/** \brief Defines the maximum number of bytes for transport layer reception
* depending on the activates interface(s).
*/
#define BOOT_COM_RX_MAX_DATA (1)
/* update in case CAN interface uses more */
#if (BOOT_COM_CAN_RX_MAX_DATA > BOOT_COM_RX_MAX_DATA)
#undef BOOT_COM_RX_MAX_DATA
#define BOOT_COM_RX_MAX_DATA (BOOT_COM_CAN_RX_MAX_DATA)
#endif
/* update in case RS232 interface uses more */
#if (BOOT_COM_RS232_RX_MAX_DATA > BOOT_COM_RX_MAX_DATA)
#undef BOOT_COM_RX_MAX_DATA
#define BOOT_COM_RX_MAX_DATA (BOOT_COM_RS232_RX_MAX_DATA)
#endif
/* update in case USB interface uses more */
#if (BOOT_COM_USB_RX_MAX_DATA > BOOT_COM_RX_MAX_DATA)
#undef BOOT_COM_RX_MAX_DATA
#define BOOT_COM_RX_MAX_DATA (BOOT_COM_USB_RX_MAX_DATA)
#endif
/* update in case NET interface uses more */
#if (BOOT_COM_NET_RX_MAX_DATA > BOOT_COM_RX_MAX_DATA)
#undef BOOT_COM_RX_MAX_DATA
#define BOOT_COM_RX_MAX_DATA (BOOT_COM_NET_RX_MAX_DATA)
#endif
/** \brief Defines the maximum number of bytes for transport layer transmission
* depending on the activates interface(s).
*/
#define BOOT_COM_TX_MAX_DATA (1)
/* update in case CAN interface uses more */
#if (BOOT_COM_CAN_TX_MAX_DATA > BOOT_COM_TX_MAX_DATA)
#undef BOOT_COM_TX_MAX_DATA
#define BOOT_COM_TX_MAX_DATA (BOOT_COM_CAN_TX_MAX_DATA)
#endif
/* update in case RS232 interface uses more */
#if (BOOT_COM_RS232_TX_MAX_DATA > BOOT_COM_TX_MAX_DATA)
#undef BOOT_COM_TX_MAX_DATA
#define BOOT_COM_TX_MAX_DATA (BOOT_COM_RS232_TX_MAX_DATA)
#endif
/* update in case USB interface uses more */
#if (BOOT_COM_USB_TX_MAX_DATA > BOOT_COM_TX_MAX_DATA)
#undef BOOT_COM_TX_MAX_DATA
#define BOOT_COM_TX_MAX_DATA (BOOT_COM_USB_TX_MAX_DATA)
#endif
/* update in case NET interface uses more */
#if (BOOT_COM_NET_TX_MAX_DATA > BOOT_COM_TX_MAX_DATA)
#undef BOOT_COM_TX_MAX_DATA
#define BOOT_COM_TX_MAX_DATA (BOOT_COM_NET_TX_MAX_DATA)
#endif
/****************************************************************************************
* Plausibility
****************************************************************************************/
#if (BOOT_COM_TX_MAX_DATA < 1)
#undef BOOT_COM_TX_MAX_DATA
#define BOOT_COM_TX_MAX_DATA (8)
#endif
#if (BOOT_COM_TX_MAX_DATA > 256)
#error "COM.H, BOOT_COM_TX_MAX_DATA cannot be larger than 256."
#endif
#if (BOOT_COM_RX_MAX_DATA < 1)
#undef BOOT_COM_RX_MAX_DATA
#define BOOT_COM_RX_MAX_DATA (8)
#endif
#if (BOOT_COM_RX_MAX_DATA > 65536)
#error "COM.H, BOOT_COM_RX_MAX_DATA cannot be larger than 65536."
#endif
/****************************************************************************************
* Type definitions
****************************************************************************************/
/** \brief Enumeration for the different communication interfaces. */
typedef enum
{
COM_IF_RS232, /**< RS232 interface */
COM_IF_CAN, /**< CAN interface */
COM_IF_USB, /**< USB interface */
COM_IF_NET, /**< NET interface */
COM_IF_OTHER /**< Other interface */
} tComInterfaceId;
/****************************************************************************************
* Function prototypes
****************************************************************************************/
void ComInit(void);
#if (BOOT_COM_DEFERRED_INIT_ENABLE == 1)
void ComDeferredInit(void);
#endif
void ComTask(void);
void ComFree(void);
blt_int16u ComGetActiveInterfaceMaxRxLen(void);
blt_int16u ComGetActiveInterfaceMaxTxLen(void);
void ComTransmitPacket(blt_int8u *data, blt_int16u len);
blt_bool ComIsConnected(void);
#endif /* BOOT_COM_ENABLE > 0 */
#endif /* COM_H */
/*********************************** end of com.h **************************************/

70
Boot/loader/cop.c Normal file
View File

@@ -0,0 +1,70 @@
/************************************************************************************//**
* \file Source/cop.c
* \brief Bootloader watchdog module source file.
* \ingroup Core
* \internal
*----------------------------------------------------------------------------------------
* C O P Y R I G H T
*----------------------------------------------------------------------------------------
* Copyright (c) 2011 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 */
/****************************************************************************************
* Hook functions
****************************************************************************************/
#if (BOOT_COP_HOOKS_ENABLE > 0)
extern void CopInitHook(void);
extern void CopServiceHook(void);
#endif
/************************************************************************************//**
** \brief Watchdog initialization function.
** \return none
**
****************************************************************************************/
void CopInit(void)
{
#if (BOOT_COP_HOOKS_ENABLE > 0)
CopInitHook();
#endif
} /*** end of CopInit ***/
/************************************************************************************//**
** \brief Watchdog service function to prevent the watchdog from timing out.
** \return none
**
****************************************************************************************/
void CopService(void)
{
#if (BOOT_COP_HOOKS_ENABLE > 0)
CopServiceHook();
#endif
} /*** end of CopService ***/
/*********************************** end of cop.c **************************************/

39
Boot/loader/cop.h Normal file
View File

@@ -0,0 +1,39 @@
/************************************************************************************//**
* \file Source/cop.h
* \brief Bootloader watchdog module header file.
* \ingroup Core
* \internal
*----------------------------------------------------------------------------------------
* C O P Y R I G H T
*----------------------------------------------------------------------------------------
* Copyright (c) 2011 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
****************************************************************************************/
#ifndef COP_H
#define COP_H
/****************************************************************************************
* Function prototypes
****************************************************************************************/
void CopInit(void);
void CopService(void);
#endif /* COP_H */
/*********************************** end of cop.h **************************************/

23
Boot/loader/core.dox Normal file
View File

@@ -0,0 +1,23 @@
/**
\defgroup Core Bootloader Core
\brief Target independent code.
\details The bootloader core contains the main functionality of the bootloader,
independent of the microcontroller/compiler and independent of your
specific application. There in generally no need for you to make changes
here, unless you are adding new functionality such as the support for a
new communication interface or a different communication protocol.
By default the XCP version 1.0 is used as the communication transport layer
for remote firmware updates, for example via UART or CAN. Its official name
is ASAM MCD-1 XCP V1.0.0 and it is a universal measurement and calibration
protocol that defines a bus-independent, master-slave communication protocol
to connect ECU's with calibration systems. More information can be found at
http://www.asam.net/.
For local firmware updates, for example from a locally attached SD-card,
the FATFS file system is used as a target independent interface to access
files. More information can be found at
http://elm-chan.org/fsw/ff/00index_e.html
*/

44
Boot/loader/cpu.h Normal file
View File

@@ -0,0 +1,44 @@
/************************************************************************************//**
* \file Source/cpu.h
* \brief Bootloader cpu module header file.
* \ingroup Core
* \internal
*----------------------------------------------------------------------------------------
* C O P Y R I G H T
*----------------------------------------------------------------------------------------
* Copyright (c) 2016 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
****************************************************************************************/
#ifndef CPU_H
#define CPU_H
/****************************************************************************************
* Function prototypes
****************************************************************************************/
void CpuInit(void);
void CpuStartUserProgram(void);
void CpuMemCopy(blt_addr dest, blt_addr src, blt_int16u len);
void CpuMemSet(blt_addr dest, blt_int8u value, blt_int16u len);
void CpuIrqDisable(void);
void CpuIrqEnable(void);
#endif /* CPU_H */
/*********************************** end of cpu.h **************************************/

853
Boot/loader/file.c Normal file
View File

@@ -0,0 +1,853 @@
/************************************************************************************//**
* \file Source/file.c
* \brief Bootloader file system interface source file.
* \ingroup Core
* \internal
*----------------------------------------------------------------------------------------
* C O P Y R I G H T
*----------------------------------------------------------------------------------------
* Copyright (c) 2013 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 */
#include <string.h> /* for strcpy etc. */
#include <ctype.h> /* for toupper() etc. */
#if (BOOT_FILE_SYS_ENABLE > 0)
/****************************************************************************************
* Type definitions
****************************************************************************************/
/** \brief Enumeration for the different internal module states. */
typedef enum
{
FIRMWARE_UPDATE_STATE_IDLE, /**< idle state */
FIRMWARE_UPDATE_STATE_STARTING, /**< starting state */
FIRMWARE_UPDATE_STATE_ERASING, /**< erasing state */
FIRMWARE_UPDATE_STATE_PROGRAMMING /**< programming state */
} tFirmwareUpdateState;
/** \brief Structure type with information for the memory erase opeartion. */
typedef struct
{
blt_addr start_address; /**< erase start address */
blt_int32u total_size; /**< total number of bytes to erase */
} tFileEraseInfo;
/** \brief Structure type for grouping FATFS related objects used by this module. */
typedef struct
{
FATFS fs; /**< file system object for mouting */
FIL file; /**< file object for firmware file */
} tFatFsObjects;
/****************************************************************************************
* Function prototypes
****************************************************************************************/
#if (BOOT_FILE_LOGGING_ENABLE > 0)
static blt_char FileLibByteNibbleToChar(blt_int8u nibble);
static blt_char *FileLibByteToHexString(blt_int8u byte_val, blt_char *destination);
static blt_char *FileLibLongToIntString(blt_int32u long_val, blt_char *destination);
#endif
static blt_int8u FileLibHexStringToByte(const blt_char *hexstring);
/****************************************************************************************
* Hook functions
****************************************************************************************/
extern blt_bool FileIsFirmwareUpdateRequestedHook(void);
extern const blt_char *FileGetFirmwareFilenameHook(void);
extern void FileFirmwareUpdateStartedHook(void);
extern void FileFirmwareUpdateCompletedHook(void);
extern void FileFirmwareUpdateErrorHook(blt_int8u error_code);
extern void FileFirmwareUpdateLogHook(blt_char *info_string);
/****************************************************************************************
* Local data declarations
****************************************************************************************/
/** \brief Local variable that holds the internal module state. */
static tFirmwareUpdateState firmwareUpdateState;
/** \brief Local variable for the used FATFS objects in this module. */
static tFatFsObjects fatFsObjects;
/** \brief Local variable for storing S-record line parsing results. */
static tSrecLineParseObject lineParseObject;
/** \brief Local variable for storing information regarding the memory erase operation.*/
static tFileEraseInfo eraseInfo;
#if (BOOT_FILE_LOGGING_ENABLE > 0)
/** \brief Local character buffer for storing the string with log information. */
static blt_char loggingStr[64];
#endif
/***********************************************************************************//**
** \brief Initializes the file system interface module. The initial firmware
** update state is set to idle and the file system is mounted as
** logical disk 0.
** \return none
**
****************************************************************************************/
void FileInit(void)
{
FRESULT fresult;
/* set the initial state */
firmwareUpdateState = FIRMWARE_UPDATE_STATE_IDLE;
/* mount the file system, using logical disk 0 */
fresult = f_mount(&fatFsObjects.fs, "0:", 0);
/* mounting does not access the disk and should succeed unless misconfigured */
ASSERT_RT(fresult == FR_OK);
} /*** end of FileInit ***/
/***********************************************************************************//**
** \brief This function checks if a firmware update through the locally attached
** storage is in progress or not (idle).
** \return BLT_TRUE when in idle state, BLT_FALSE otherwise.
**
****************************************************************************************/
blt_bool FileIsIdle(void)
{
if (firmwareUpdateState == FIRMWARE_UPDATE_STATE_IDLE)
{
return BLT_TRUE;
}
return BLT_FALSE;
} /*** end of FileIsIdle ***/
/***********************************************************************************//**
** \brief This function checks if a firmware update through the locally attached
** storage is requested to be started and if so processes this request
** by transitioning from the IDLE to the STARTING state.
** \return BLT_TRUE when a firmware update is requested, BLT_FALSE otherwise.
**
****************************************************************************************/
blt_bool FileHandleFirmwareUpdateRequest(void)
{
#if (BOOT_COM_ENABLE > 0)
/* make sure that there is no connection with a remote host to prevent two firmware
* updates happening at the same time
*/
if (ComIsConnected() == BLT_TRUE)
{
return BLT_FALSE;
}
#endif
/* a new firmware update request can only be handled if not already busy with one */
if (firmwareUpdateState != FIRMWARE_UPDATE_STATE_IDLE)
{
return BLT_FALSE;
}
/* check if a firmware update is requested */
if (FileIsFirmwareUpdateRequestedHook() == BLT_TRUE)
{
/* transition from IDLE to STARTING state, which kicks off the update sequence */
firmwareUpdateState = FIRMWARE_UPDATE_STATE_STARTING;
return BLT_TRUE;
}
/* still here so no update request pending */
return BLT_FALSE;
} /*** end of FileHandleFirmwareUpdateRequest ***/
/***********************************************************************************//**
** \brief File system task function for managing the firmware updates from
** locally attached storage.
** \return none.
**
****************************************************************************************/
void FileTask(void)
{
blt_int16s parse_result = 0;
blt_char *read_line_ptr;
/* ------------------------------- idle -------------------------------------------- */
if (firmwareUpdateState == FIRMWARE_UPDATE_STATE_IDLE)
{
/* currently, nothings need to be done while idling */
}
/* ------------------------------- starting ---------------------------------------- */
else if (firmwareUpdateState == FIRMWARE_UPDATE_STATE_STARTING)
{
/* reinit the NVM driver because a new firmware update is about the start */
NvmInit();
#if (BOOT_FILE_STARTED_HOOK_ENABLE > 0)
/* inform application about update started event via hook function */
FileFirmwareUpdateStartedHook();
#endif
#if (BOOT_FILE_LOGGING_ENABLE > 0)
FileFirmwareUpdateLogHook("Firmware update request detected\n\r");
FileFirmwareUpdateLogHook("Opening firmware file for reading...");
#endif
/* attempt to obtain a file object for the firmware file */
if (f_open(&fatFsObjects.file, FileGetFirmwareFilenameHook(), FA_OPEN_EXISTING | FA_READ) != FR_OK)
{
/* cannot continue with firmware update so go back to idle state */
firmwareUpdateState = FIRMWARE_UPDATE_STATE_IDLE;
/* can't open file */
#if (BOOT_FILE_LOGGING_ENABLE > 0)
FileFirmwareUpdateLogHook("ERROR\n\r");
#endif
#if (BOOT_FILE_ERROR_HOOK_ENABLE > 0)
FileFirmwareUpdateErrorHook(FILE_ERROR_CANNOT_OPEN_FIRMWARE_FILE);
#endif
/* nothing left to do now */
return;
}
#if (BOOT_FILE_LOGGING_ENABLE > 0)
FileFirmwareUpdateLogHook("OK\n\r");
FileFirmwareUpdateLogHook("Starting the programming sequence\n\r");
FileFirmwareUpdateLogHook("Parsing firmware file to detect erase blocks...");
#endif
/* prepare data objects for the erasing state */
eraseInfo.start_address = 0;
eraseInfo.total_size = 0;
/* transition from idle to erasing state */
firmwareUpdateState = FIRMWARE_UPDATE_STATE_ERASING;
}
/* ------------------------------- erasing ----------------------------------------- */
else if (firmwareUpdateState == FIRMWARE_UPDATE_STATE_ERASING)
{
/* read a line from the file */
read_line_ptr = f_gets(lineParseObject.line, sizeof(lineParseObject.line), &fatFsObjects.file);
/* check if an error occurred */
if (f_error(&fatFsObjects.file) > 0)
{
/* cannot continue with firmware update so go back to idle state */
firmwareUpdateState = FIRMWARE_UPDATE_STATE_IDLE;
#if (BOOT_FILE_LOGGING_ENABLE > 0)
FileFirmwareUpdateLogHook("ERROR\n\r");
#endif
#if (BOOT_FILE_ERROR_HOOK_ENABLE > 0)
FileFirmwareUpdateErrorHook(FILE_ERROR_CANNOT_READ_FROM_FILE);
#endif
/* close the file */
f_close(&fatFsObjects.file);
return;
}
/* parse the S-Record line without copying the data values if the line is not empty */
if (read_line_ptr != BLT_NULL)
{
parse_result = FileSrecParseLine(lineParseObject.line, &lineParseObject.address, BLT_NULL);
/* check parsing result */
if (parse_result == ERROR_SREC_INVALID_CHECKSUM)
{
/* cannot continue with firmware update so go back to idle state */
firmwareUpdateState = FIRMWARE_UPDATE_STATE_IDLE;
#if (BOOT_FILE_LOGGING_ENABLE > 0)
FileFirmwareUpdateLogHook("ERROR\n\r");
#endif
#if (BOOT_FILE_ERROR_HOOK_ENABLE > 0)
FileFirmwareUpdateErrorHook(FILE_ERROR_INVALID_CHECKSUM_IN_FILE);
#endif
/* close the file */
f_close(&fatFsObjects.file);
return;
}
}
/* only process parsing results if the line contained address/data info */
if (parse_result > 0)
{
/* is this the first address/data info we encountered? */
if (eraseInfo.total_size == 0)
{
/* store the start_address and byte count */
eraseInfo.start_address = lineParseObject.address;
eraseInfo.total_size = parse_result;
}
else
{
/* does this data fit at the end of the previously detected program block? */
if (lineParseObject.address == (eraseInfo.start_address + eraseInfo.total_size))
{
/* update the byte count */
eraseInfo.total_size += parse_result;
}
else
{
/* data does not belong to the previously detected block so there must be a
* gap in the data. first erase the currently detected block and then start
* tracking a new block.
*/
#if (BOOT_FILE_LOGGING_ENABLE > 0)
FileFirmwareUpdateLogHook("OK\n\r");
FileFirmwareUpdateLogHook("Erasing ");
/* convert size to string */
FileLibLongToIntString(eraseInfo.total_size, loggingStr);
FileFirmwareUpdateLogHook(loggingStr);
FileFirmwareUpdateLogHook(" bytes from memory at 0x");
/* convert address to hex-string */
FileLibByteToHexString((blt_int8u)(eraseInfo.start_address >> 24), &loggingStr[0]);
FileLibByteToHexString((blt_int8u)(eraseInfo.start_address >> 16), &loggingStr[2]);
FileLibByteToHexString((blt_int8u)(eraseInfo.start_address >> 8), &loggingStr[4]);
FileLibByteToHexString((blt_int8u)eraseInfo.start_address, &loggingStr[6]);
FileFirmwareUpdateLogHook(loggingStr);
FileFirmwareUpdateLogHook("...");
#endif
/* still here so we are ready to perform the memory erase operation */
if (NvmErase(eraseInfo.start_address, eraseInfo.total_size) == BLT_FALSE)
{
/* cannot continue with firmware update so go back to idle state */
firmwareUpdateState = FIRMWARE_UPDATE_STATE_IDLE;
#if (BOOT_FILE_LOGGING_ENABLE > 0)
FileFirmwareUpdateLogHook("ERROR\n\r");
#endif
#if (BOOT_FILE_ERROR_HOOK_ENABLE > 0)
FileFirmwareUpdateErrorHook(FILE_ERROR_CANNOT_ERASE_MEMORY);
#endif
/* close the file */
f_close(&fatFsObjects.file);
return;
}
#if (BOOT_FILE_LOGGING_ENABLE > 0)
FileFirmwareUpdateLogHook("OK\n\r");
FileFirmwareUpdateLogHook("Parsing firmware file to detect erase blocks...");
#endif
/* store the start_address and element count */
eraseInfo.start_address = lineParseObject.address;
eraseInfo.total_size = parse_result;
}
}
}
/* check if the end of the file was reached */
if (f_eof(&fatFsObjects.file) > 0)
{
/* rewind the file in preparation for the programming state */
if (f_lseek(&fatFsObjects.file, 0) != FR_OK)
{
/* cannot continue with firmware update so go back to idle state */
firmwareUpdateState = FIRMWARE_UPDATE_STATE_IDLE;
#if (BOOT_FILE_LOGGING_ENABLE > 0)
FileFirmwareUpdateLogHook("ERROR\n\r");
#endif
#if (BOOT_FILE_ERROR_HOOK_ENABLE > 0)
FileFirmwareUpdateErrorHook(FILE_ERROR_REWINDING_FILE_READ_POINTER);
#endif
/* close the file */
f_close(&fatFsObjects.file);
return;
}
/* still here so we are ready to perform the last memory erase operation, if there
* is still something left to erase.
*/
if (eraseInfo.total_size > 0)
{
#if (BOOT_FILE_LOGGING_ENABLE > 0)
FileFirmwareUpdateLogHook("OK\n\r");
FileFirmwareUpdateLogHook("Erasing ");
/* convert size to string */
FileLibLongToIntString(eraseInfo.total_size, loggingStr);
FileFirmwareUpdateLogHook(loggingStr);
FileFirmwareUpdateLogHook(" bytes from memory at 0x");
/* convert address to hex-string */
FileLibByteToHexString((blt_int8u)(eraseInfo.start_address >> 24), &loggingStr[0]);
FileLibByteToHexString((blt_int8u)(eraseInfo.start_address >> 16), &loggingStr[2]);
FileLibByteToHexString((blt_int8u)(eraseInfo.start_address >> 8), &loggingStr[4]);
FileLibByteToHexString((blt_int8u)eraseInfo.start_address, &loggingStr[6]);
FileFirmwareUpdateLogHook(loggingStr);
FileFirmwareUpdateLogHook("...");
#endif
if (NvmErase(eraseInfo.start_address, eraseInfo.total_size) == BLT_FALSE)
{
/* cannot continue with firmware update so go back to idle state */
firmwareUpdateState = FIRMWARE_UPDATE_STATE_IDLE;
#if (BOOT_FILE_LOGGING_ENABLE > 0)
FileFirmwareUpdateLogHook("ERROR\n\r");
#endif
#if (BOOT_FILE_ERROR_HOOK_ENABLE > 0)
FileFirmwareUpdateErrorHook(FILE_ERROR_CANNOT_ERASE_MEMORY);
#endif
/* close the file */
f_close(&fatFsObjects.file);
return;
}
}
#if (BOOT_FILE_LOGGING_ENABLE > 0)
FileFirmwareUpdateLogHook("OK\n\r");
#endif
/* all okay, then go to programming state */
firmwareUpdateState = FIRMWARE_UPDATE_STATE_PROGRAMMING;
}
}
/* ------------------------------- programming ------------------------------------- */
else if (firmwareUpdateState == FIRMWARE_UPDATE_STATE_PROGRAMMING)
{
/* read a line from the file */
read_line_ptr = f_gets(lineParseObject.line, sizeof(lineParseObject.line), &fatFsObjects.file);
/* check if an error occurred */
if (f_error(&fatFsObjects.file) > 0)
{
/* cannot continue with firmware update so go back to idle state */
firmwareUpdateState = FIRMWARE_UPDATE_STATE_IDLE;
#if (BOOT_FILE_LOGGING_ENABLE > 0)
FileFirmwareUpdateLogHook("Reading line from file...ERROR\n\r");
#endif
#if (BOOT_FILE_ERROR_HOOK_ENABLE > 0)
FileFirmwareUpdateErrorHook(FILE_ERROR_CANNOT_READ_FROM_FILE);
#endif
/* close the file */
f_close(&fatFsObjects.file);
return;
}
/* parse the S-Record line if the line is not empty */
if (read_line_ptr != BLT_NULL)
{
parse_result = FileSrecParseLine(lineParseObject.line, &lineParseObject.address, lineParseObject.data);
/* check parsing result */
if (parse_result == ERROR_SREC_INVALID_CHECKSUM)
{
/* cannot continue with firmware update so go back to idle state */
firmwareUpdateState = FIRMWARE_UPDATE_STATE_IDLE;
#if (BOOT_FILE_LOGGING_ENABLE > 0)
FileFirmwareUpdateLogHook("Invalid checksum found...ERROR\n\r");
#endif
#if (BOOT_FILE_ERROR_HOOK_ENABLE > 0)
FileFirmwareUpdateErrorHook(FILE_ERROR_INVALID_CHECKSUM_IN_FILE);
#endif
/* close the file */
f_close(&fatFsObjects.file);
return;
}
}
/* only process parsing results if the line contained address/data info */
if (parse_result > 0)
{
#if (BOOT_FILE_LOGGING_ENABLE > 0)
FileFirmwareUpdateLogHook("Programming ");
/* convert size to string */
FileLibLongToIntString(parse_result, loggingStr);
FileFirmwareUpdateLogHook(loggingStr);
FileFirmwareUpdateLogHook(" bytes to memory at 0x");
/* convert address to hex-string */
FileLibByteToHexString((blt_int8u)(lineParseObject.address >> 24), &loggingStr[0]);
FileLibByteToHexString((blt_int8u)(lineParseObject.address >> 16), &loggingStr[2]);
FileLibByteToHexString((blt_int8u)(lineParseObject.address >> 8), &loggingStr[4]);
FileLibByteToHexString((blt_int8u)lineParseObject.address, &loggingStr[6]);
FileFirmwareUpdateLogHook(loggingStr);
FileFirmwareUpdateLogHook("...");
#endif
/* program the data */
if (NvmWrite(lineParseObject.address, parse_result, lineParseObject.data) == BLT_FALSE)
{
/* cannot continue with firmware update so go back to idle state */
firmwareUpdateState = FIRMWARE_UPDATE_STATE_IDLE;
#if (BOOT_FILE_LOGGING_ENABLE > 0)
FileFirmwareUpdateLogHook("ERROR\n\r");
#endif
#if (BOOT_FILE_ERROR_HOOK_ENABLE > 0)
FileFirmwareUpdateErrorHook(FILE_ERROR_CANNOT_PROGRAM_MEMORY);
#endif
/* close the file */
f_close(&fatFsObjects.file);
return;
}
#if (BOOT_FILE_LOGGING_ENABLE > 0)
FileFirmwareUpdateLogHook("OK\n\r");
#endif
}
/* check if the end of the file was reached */
if (f_eof(&fatFsObjects.file) > 0)
{
#if (BOOT_FILE_LOGGING_ENABLE > 0)
FileFirmwareUpdateLogHook("Writing program checksum...");
#endif
/* finish the programming by writing the checksum */
if (NvmDone() == BLT_FALSE)
{
/* cannot continue with firmware update so go back to idle state */
firmwareUpdateState = FIRMWARE_UPDATE_STATE_IDLE;
#if (BOOT_FILE_LOGGING_ENABLE > 0)
FileFirmwareUpdateLogHook("ERROR\n\r");
#endif
#if (BOOT_FILE_ERROR_HOOK_ENABLE > 0)
FileFirmwareUpdateErrorHook(FILE_ERROR_CANNOT_WRITE_CHECKSUM);
#endif
/* close the file */
f_close(&fatFsObjects.file);
return;
}
#if (BOOT_FILE_LOGGING_ENABLE > 0)
FileFirmwareUpdateLogHook("OK\n\r");
FileFirmwareUpdateLogHook("Closing firmware file\n\r");
#endif
/* close the file */
f_close(&fatFsObjects.file);
#if (BOOT_FILE_LOGGING_ENABLE > 0)
FileFirmwareUpdateLogHook("Firmware update successfully completed\n\r");
#endif
/* all done so transistion back to idle mode */
firmwareUpdateState = FIRMWARE_UPDATE_STATE_IDLE;
#if (BOOT_FILE_COMPLETED_HOOK_ENABLE > 0)
/* inform application about update completed event via hook function */
FileFirmwareUpdateCompletedHook();
#endif
/* attempt to start the user program now that programming is done */
CpuStartUserProgram();
}
}
} /*** end of FileTask ***/
/************************************************************************************//**
** \brief Inspects a line from a Motorola S-Record file to determine its type.
** \param line A line from the S-Record.
** \return the S-Record line type.
**
****************************************************************************************/
tSrecLineType FileSrecGetLineType(const blt_char *line)
{
/* check if the line starts with the 'S' character, followed by a digit */
if ((toupper((blt_int16s)(line[0])) != 'S') || (isdigit((blt_int16s)(line[1])) == 0))
{
/* not a valid S-Record line type */
return LINE_TYPE_UNSUPPORTED;
}
/* determine the line type */
if (line[1] == '1')
{
return LINE_TYPE_S1;
}
if (line[1] == '2')
{
return LINE_TYPE_S2;
}
if (line[1] == '3')
{
return LINE_TYPE_S3;
}
/* still here so not a supported line type found */
return LINE_TYPE_UNSUPPORTED;
} /*** end of FileSrecGetLineType ***/
/************************************************************************************//**
** \brief Inspects an S1, S2 or S3 line from a Motorola S-Record file to
** determine if the checksum at the end is corrrect.
** \param line An S1, S2 or S3 line from the S-Record.
** \return BLT_TRUE if the checksum is correct, BLT_FALSE otherwise.
**
****************************************************************************************/
blt_bool FileSrecVerifyChecksum(const blt_char *line)
{
blt_int16u bytes_on_line;
blt_int8u checksum = 0;
/* adjust pointer to point to byte count value */
line += 2;
/* read out the number of byte values that follow on the line */
bytes_on_line = FileLibHexStringToByte(line);
/* byte count is part of checksum */
checksum += bytes_on_line;
/* adjust pointer to the first byte of the address */
line += 2;
/* add byte values of address and data, but not the final checksum */
do
{
/* add the next byte value to the checksum */
checksum += FileLibHexStringToByte(line);
/* update counter */
bytes_on_line--;
/* point to next hex string in the line */
line += 2;
}
while (bytes_on_line > 1);
/* the checksum is calculated by summing up the values of the byte count, address and
* databytes and then taking the 1-complement of the sum's least signigicant byte */
checksum = ~checksum;
/* finally verify the calculated checksum with the one at the end of the line */
if (checksum != FileLibHexStringToByte(line))
{
/* checksum incorrect */
return BLT_FALSE;
}
/* still here so the checksum was correct */
return BLT_TRUE;
} /*** end of FileSrecVerifyChecksum ***/
/************************************************************************************//**
** \brief Parses a line from a Motorola S-Record file and looks for S1, S2 or S3
** lines with data. Note that if a null pointer is passed as the data
** parameter, then no data is extracted from the line.
** \param line A line from the S-Record.
** \param address Address found in the S-Record data line.
** \param data Byte array where the data bytes from the S-Record data line
** are stored.
** \return The number of data bytes found on the S-record data line, 0 in case
** the line is not an S1, S2 or S3 line or ERROR_SREC_INVALID_CHECKSUM
** in case the checksum validation failed.
**
****************************************************************************************/
blt_int16s FileSrecParseLine(const blt_char *line, blt_addr *address, blt_int8u *data)
{
tSrecLineType lineType;
blt_int16s data_byte_count = 0;
blt_int16u bytes_on_line;
blt_int16u i;
/* check pointers and not that data can be a null pointer */
ASSERT_RT((address != BLT_NULL) && (line != BLT_NULL));
/* figure out what type of line we are dealing with */
lineType = FileSrecGetLineType(line);
/* make sure it is one that we can parse */
if (lineType == LINE_TYPE_UNSUPPORTED)
{
/* not a parsing error, but simply no data on this line */
return 0;
}
/* verify the checksum */
if (FileSrecVerifyChecksum(line) == BLT_FALSE)
{
/* error on data line encountered */
return ERROR_SREC_INVALID_CHECKSUM;
}
/* all good so far, now read out the address and databytes for the line */
switch (lineType)
{
/* ---------------------------- S1 line type ------------------------------------- */
case LINE_TYPE_S1:
/* adjust pointer to point to byte count value */
line += 2;
/* read out the number of byte values that follow on the line */
bytes_on_line = FileLibHexStringToByte(line);
/* read out the 16-bit address */
line += 2;
*address = FileLibHexStringToByte(line) << 8;
line += 2;
*address += FileLibHexStringToByte(line);
/* adjust pointer to point to the first data byte after the address */
line += 2;
/* determine how many data bytes are on the line */
data_byte_count = bytes_on_line - 3; /* -2 bytes address, -1 byte checksum */
/* read and store data bytes if requested */
if (data != BLT_NULL)
{
for (i=0; i<data_byte_count; i++)
{
data[i] = FileLibHexStringToByte(line);
line += 2;
}
}
break;
/* ---------------------------- S2 line type ------------------------------------- */
case LINE_TYPE_S2:
/* adjust pointer to point to byte count value */
line += 2;
/* read out the number of byte values that follow on the line */
bytes_on_line = FileLibHexStringToByte(line);
/* read out the 32-bit address */
line += 2;
*address = FileLibHexStringToByte(line) << 16;
line += 2;
*address += FileLibHexStringToByte(line) << 8;
line += 2;
*address += FileLibHexStringToByte(line);
/* adjust pointer to point to the first data byte after the address */
line += 2;
/* determine how many data bytes are on the line */
data_byte_count = bytes_on_line - 4; /* -3 bytes address, -1 byte checksum */
/* read and store data bytes if requested */
if (data != BLT_NULL)
{
for (i=0; i<data_byte_count; i++)
{
data[i] = FileLibHexStringToByte(line);
line += 2;
}
}
break;
/* ---------------------------- S3 line type ------------------------------------- */
case LINE_TYPE_S3:
/* adjust pointer to point to byte count value */
line += 2;
/* read out the number of byte values that follow on the line */
bytes_on_line = FileLibHexStringToByte(line);
/* read out the 32-bit address */
line += 2;
*address = FileLibHexStringToByte(line) << 24;
line += 2;
*address += FileLibHexStringToByte(line) << 16;
line += 2;
*address += FileLibHexStringToByte(line) << 8;
line += 2;
*address += FileLibHexStringToByte(line);
/* adjust pointer to point to the first data byte after the address */
line += 2;
/* determine how many data bytes are on the line */
data_byte_count = bytes_on_line - 5; /* -4 bytes address, -1 byte checksum */
/* read and store data bytes if requested */
if (data != BLT_NULL)
{
for (i=0; i<data_byte_count; i++)
{
data[i] = FileLibHexStringToByte(line);
line += 2;
}
}
break;
default:
break;
}
return data_byte_count;
} /*** end of FileSrecParseLine ***/
#if (BOOT_FILE_LOGGING_ENABLE > 0)
/************************************************************************************//**
** \brief Helper function to convert a 4-bit value to a character that represents its
** value in hexadecimal format.
** Example: FileLibByteNibbleToChar(11) --> returns 'B'.
** \param nibble 4-bit value to convert.
** \return The resulting byte value.
**
****************************************************************************************/
static blt_char FileLibByteNibbleToChar(blt_int8u nibble)
{
blt_char c;
/* convert to ASCII value */
c = (nibble & 0x0f) + '0';
if (nibble > 9)
{
c += 7;
}
else
{
c = toupper((blt_int16s)c);
}
/* return the character */
return c;
} /*** end of FileLibByteNibbleToChar ***/
/************************************************************************************//**
** \brief Helper function to convert a byte value to a string representing the
** value in hexadecimal format.
** Example: FileLibByteToHexString(28, strBuffer) --> returns "1C".
** \param byte_val 8-bit value to convert.
** \param destination Pointer to character buffer for storing the results.
** \return The resulting string.
**
****************************************************************************************/
static blt_char *FileLibByteToHexString(blt_int8u byte_val, blt_char *destination)
{
/* first the most significant n-bit nibble */
destination[0] = FileLibByteNibbleToChar(byte_val >> 4);
/* next the least significant n-bit nibble */
destination[1] = FileLibByteNibbleToChar(byte_val & 0x0f);
/* add string termination */
destination[2] = '\0';
/* return pointer to resulting string */
return destination;
} /*** end of FileLibByteToHexString ***/
/************************************************************************************//**
** \brief Helper function to convert a 32-bit unsigned number to a string that
** represents its decimal value.
** Example: FileLibLongToIntString(1234, strBuffer) --> returns "1234".
** \param long_val 32-bit value to convert.
** \param destination Pointer to character buffer for storing the results.
** \return The resulting string.
**
****************************************************************************************/
static blt_char *FileLibLongToIntString(blt_int32u long_val, blt_char *destination)
{
blt_int32u long_val_cpy = long_val;
/* first determine how many digits there will be */
do
{
destination++;
long_val_cpy /= 10;
}
while (long_val_cpy > 0);
/* add space for the string termination and add it */
*destination = '\0';
/* now add the digits from right to left */
long_val_cpy = long_val;
do
{
/* set write pointer to where the next character should go */
destination--;
/* write digit in ASCII format */
*destination = long_val_cpy % 10 + '0';
/* move on to the next digit */
long_val_cpy /= 10;
}
while (long_val_cpy > 0);
return destination;
} /*** end of FileLibLongToIntString ***/
#endif /* (BOOT_FILE_LOGGING_ENABLE > 0) */
/************************************************************************************//**
** \brief Helper function to convert a sequence of 2 characters that represent
** a hexadecimal value to the actual byte value.
** Example: FileLibHexStringToByte("2f") --> returns 47.
** \param hexstring String beginning with 2 characters that represent a hexa-
** decimal value.
** \return The resulting byte value.
**
****************************************************************************************/
static blt_int8u FileLibHexStringToByte(const blt_char *hexstring)
{
blt_int8u result = 0;
blt_char c;
blt_int8u counter;
/* a hexadecimal character is 2 characters long (i.e 0x4F minus the 0x part) */
for (counter=0; counter < 2; counter++)
{
/* read out the character */
c = toupper((blt_int16s)(hexstring[counter]));
/* check that the character is 0..9 or A..F */
if ((c < '0') || (c > 'F') || ((c > '9') && (c < 'A')))
{
/* character not valid */
return 0;
}
/* convert character to 4-bit value (check ASCII table for more info) */
c -= '0';
if (c > 9)
{
c -= 7;
}
/* add it to the result */
result = (result << 4) + c;
}
/* return the results */
return result;
} /*** end of FileLibHexStringToByte ***/
#endif /* BOOT_FILE_SYS_ENABLE > 0 */
/*********************************** end of file.c *************************************/

103
Boot/loader/file.h Normal file
View File

@@ -0,0 +1,103 @@
/************************************************************************************//**
* \file Source/file.h
* \brief Bootloader file system interface header file.
* \ingroup Core
* \internal
*----------------------------------------------------------------------------------------
* C O P Y R I G H T
*----------------------------------------------------------------------------------------
* Copyright (c) 2013 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
****************************************************************************************/
#ifndef FILE_H
#define FILE_H
#if (BOOT_FILE_SYS_ENABLE > 0)
/****************************************************************************************
* Include files
****************************************************************************************/
#include "ff.h" /* FATFS file system library */
/****************************************************************************************
* Defines
****************************************************************************************/
/** \brief Error code for not being able to open the firmware file. */
#define FILE_ERROR_CANNOT_OPEN_FIRMWARE_FILE (1)
/** \brief Error code for not being able to read from the firmware file. */
#define FILE_ERROR_CANNOT_READ_FROM_FILE (2)
/** \brief Error code because in incorrect checksum was found in the firmware file. */
#define FILE_ERROR_INVALID_CHECKSUM_IN_FILE (3)
/** \brief Error code because the file pointers read pointer could not be rewinded. */
#define FILE_ERROR_REWINDING_FILE_READ_POINTER (4)
/** \brief Error code because an error occurred during the memory erase operation. */
#define FILE_ERROR_CANNOT_ERASE_MEMORY (5)
/** \brief Error code because an error occurred during the memory write operation. */
#define FILE_ERROR_CANNOT_PROGRAM_MEMORY (6)
/** \brief Error code because the program's checksum could not be written to memory. */
#define FILE_ERROR_CANNOT_WRITE_CHECKSUM (7)
/** \brief Maximum number of characters that can be on a line in the firmware file. */
#define MAX_CHARS_PER_LINE (256)
/** \brief Maximum number of data bytes that can be on a line in the firmware file
* (S-record).
*/
#define MAX_DATA_BYTES_PER_LINE (MAX_CHARS_PER_LINE/2)
/** \brief Return code in case an invalid checksum was detected on an S-record line. */
#define ERROR_SREC_INVALID_CHECKSUM (-1)
/****************************************************************************************
* Type definitions
****************************************************************************************/
/** \brief Enumeration for the different S-record line types. */
typedef enum
{
LINE_TYPE_S1, /**< 16-bit address line */
LINE_TYPE_S2, /**< 24-bit address line */
LINE_TYPE_S3, /**< 32-bit address line */
LINE_TYPE_UNSUPPORTED /**< unsupported line */
} tSrecLineType;
/** \brief Structure type for grouping the parsing results of an S-record line. */
typedef struct
{
blt_char line[MAX_CHARS_PER_LINE]; /**< string buffer for the line chars */
blt_int8u data[MAX_DATA_BYTES_PER_LINE]; /**< array for S1, S2 or S3 data bytes*/
blt_addr address; /**< address on S1, S2 or S3 line */
} tSrecLineParseObject;
/****************************************************************************************
* Function prototypes
****************************************************************************************/
void FileInit(void);
void FileTask(void);
blt_bool FileIsIdle(void);
blt_bool FileHandleFirmwareUpdateRequest(void);
/* functions for reading data from a Motorola S-record file. */
tSrecLineType FileSrecGetLineType(const blt_char *line);
blt_bool FileSrecVerifyChecksum(const blt_char *line);
blt_int16s FileSrecParseLine(const blt_char *line, blt_addr *address, blt_int8u *data);
#endif /* BOOT_FILE_SYS_ENABLE > 0 */
#endif /* FILE_H */
/*********************************** end of file.h *************************************/

446
Boot/loader/net.c Normal file
View File

@@ -0,0 +1,446 @@
/************************************************************************************//**
* \file Source/net.c
* \brief Bootloader TCP/IP network communication interface source file.
* \ingroup Core
* \internal
*----------------------------------------------------------------------------------------
* C O P Y R I G H T
*----------------------------------------------------------------------------------------
* Copyright (c) 2014 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_COM_NET_ENABLE > 0)
#include "netdev.h"
#include "uip.h"
#include "uip_arp.h"
#endif
#if (BOOT_COM_NET_ENABLE > 0)
/****************************************************************************************
* Configuration macros
****************************************************************************************/
/* Extend the default time that the backdoor is open if firmware updates via TCP/IP
* are supported. in this case an activation of the bootloader results in an
* initialization of the ethernet MAC. when connected to the network via a router this
* can take several seconds. Feel free to shorten/lengthen this time for finetuning,
* Note that adding this configuration macro to blt_conf.h overrides the value here.
*/
#ifndef BOOT_COM_NET_BACKDOOR_EXTENSION_MS
#define BOOT_COM_NET_BACKDOOR_EXTENSION_MS (10000)
#endif
/****************************************************************************************
* Macro definitions
****************************************************************************************/
/** \brief Delta time for the uIP periodic timer. */
#define NET_UIP_PERIODIC_TIMER_MS (500)
/** \brief Delta time for the uIP ARP timer. */
#define NET_UIP_ARP_TIMER_MS (10000)
/** \brief Macro for accessing the Ethernet header information in the buffer */
#define NET_UIP_HEADER_BUF ((struct uip_eth_hdr *)&uip_buf[0])
/****************************************************************************************
* Function prototypes
****************************************************************************************/
static void NetServerTask(void);
/****************************************************************************************
* Local data declarations
****************************************************************************************/
/** \brief Holds the time out value of the uIP periodic timer. */
static blt_int32u periodicTimerTimeOut;
/** \brief Holds the time out value of the uIP ARP timer. */
static blt_int32u ARPTimerTimeOut;
#if (BOOT_COM_NET_DHCP_ENABLE > 0)
/** \brief Holds the MAC address which is used by the DHCP client. */
static struct uip_eth_addr macAddress;
#endif
/** \brief Boolean flag to determine if the module was initialized or not. */
static blt_bool netInitializedFlag = BLT_FALSE;
#if (BOOT_COM_NET_DEFERRED_INIT_ENABLE == 1)
/** \brief Boolean flag initialized such that the normal initialization via NetInit()
* should be deferred. A called to NetDeferredInit() is need to do the actual
* initialization of this module.
*/
static blt_bool netInitializationDeferred = BLT_TRUE;
#else
/** \brief Boolean flag initialized such that the normal initialization via NetInit()
* proceeds as usual.
*/
static blt_bool netInitializationDeferred = BLT_FALSE;
#endif
/************************************************************************************//**
** \brief Initializes the TCP/IP network communication interface.
** \return none.
**
****************************************************************************************/
void NetInit(void)
{
uip_ipaddr_t ipaddr;
/* only perform the initialization if there is no request to defer it */
if (netInitializationDeferred == BLT_FALSE)
{
/* initialize the network device */
netdev_init();
/* initialize the timer variables */
periodicTimerTimeOut = TimerGet() + NET_UIP_PERIODIC_TIMER_MS;
ARPTimerTimeOut = TimerGet() + NET_UIP_ARP_TIMER_MS;
/* initialize the uIP TCP/IP stack. */
uip_init();
#if (BOOT_COM_NET_DHCP_ENABLE == 0)
/* set the IP address */
uip_ipaddr(ipaddr, BOOT_COM_NET_IPADDR0, BOOT_COM_NET_IPADDR1, BOOT_COM_NET_IPADDR2,
BOOT_COM_NET_IPADDR3);
uip_sethostaddr(ipaddr);
/* set the network mask */
uip_ipaddr(ipaddr, BOOT_COM_NET_NETMASK0, BOOT_COM_NET_NETMASK1, BOOT_COM_NET_NETMASK2,
BOOT_COM_NET_NETMASK3);
uip_setnetmask(ipaddr);
/* set the gateway address */
uip_ipaddr(ipaddr, BOOT_COM_NET_GATEWAY0, BOOT_COM_NET_GATEWAY1, BOOT_COM_NET_GATEWAY2,
BOOT_COM_NET_GATEWAY3);
uip_setdraddr(ipaddr);
#else
/* set the IP address */
uip_ipaddr(ipaddr, 0, 0, 0, 0);
uip_sethostaddr(ipaddr);
/* set the network mask */
uip_ipaddr(ipaddr, 0, 0, 0, 0);
uip_setnetmask(ipaddr);
/* set the gateway address */
uip_ipaddr(ipaddr, 0, 0, 0, 0);
uip_setdraddr(ipaddr);
#endif
/* start listening on the configured port for XCP transfers on TCP/IP */
uip_listen(HTONS(BOOT_COM_NET_PORT));
/* initialize the MAC and set the MAC address */
netdev_init_mac();
#if (BOOT_COM_NET_DHCP_ENABLE > 0)
/* initialize the DHCP client application and send the initial request. */
netdev_get_mac(&macAddress.addr[0]);
dhcpc_init(&macAddress.addr[0], 6);
dhcpc_request();
#endif
/* extend the time that the backdoor is open in case the default timed backdoor
* mechanism is used.
*/
#if (BOOT_BACKDOOR_HOOKS_ENABLE == 0)
if (BackDoorGetExtension() < BOOT_COM_NET_BACKDOOR_EXTENSION_MS)
{
BackDoorSetExtension(BOOT_COM_NET_BACKDOOR_EXTENSION_MS);
}
#endif /* BOOT_BACKDOOR_HOOKS_ENABLE == 0 */
/* set flag to indicate that we are now initialized. */
netInitializedFlag = BLT_TRUE;
}
} /*** end of NetInit ***/
#if (BOOT_COM_NET_DEFERRED_INIT_ENABLE == 1)
/************************************************************************************//**
** \brief Performs a deferred initialization of the TCP/IP network communication
** interface.
** \return none.
**
****************************************************************************************/
void NetDeferredInit(void)
{
/* reset the request to defer the initializaton */
netInitializationDeferred = BLT_FALSE;
/* perform the initialization if not yet initialized */
if (netInitializedFlag == BLT_FALSE)
{
NetInit();
}
} /*** end of NetDeferredInit ***/
#endif
/************************************************************************************//**
** \brief Transmits a packet formatted for the communication interface.
** \param data Pointer to byte array with data that it to be transmitted.
** \param len Number of bytes that are to be transmitted.
** \return none.
**
****************************************************************************************/
void NetTransmitPacket(blt_int8u *data, blt_int8u len)
{
uip_tcp_appstate_t *s;
blt_int16u cnt;
/* no need to send the packet if this module is not initialized */
if (netInitializedFlag == BLT_TRUE)
{
/* get pointer to application state */
s = &(uip_conn->appstate);
/* add the dto counter first */
*(blt_int32u *)&(s->dto_data[0]) = s->dto_counter;
/* copy the actual XCP response */
for (cnt=0; cnt<len; cnt++)
{
s->dto_data[cnt+4] = data[cnt];
}
/* set the length of the TCP/IP packet */
s->dto_len = len + 4;
/* set the flag to request the transmission of this packet. */
s->dto_tx_req = BLT_TRUE;
/* update dto counter for the next transmission */
s->dto_counter++;
}
} /*** end of NetTransmitPacket ***/
/************************************************************************************//**
** \brief Receives a communication interface packet if one is present.
** \param data Pointer to byte array where the data is to be stored.
** \param len Pointer where the length of the packet is to be stored.
** \return BLT_TRUE if a packet was received, BLT_FALSE otherwise.
**
****************************************************************************************/
blt_bool NetReceivePacket(blt_int8u *data, blt_int8u *len)
{
/* no need to check for newly received packets if this module is not initialized */
if (netInitializedFlag == BLT_TRUE)
{
/* run the TCP/IP server task function, which will handle the reception and
* transmission of XCP packets
*/
NetServerTask();
}
/* packet reception and transmission is completely handled by the NetServerTask so
* always return BLT_FALSE here.
*/
return BLT_FALSE;
} /*** end of NetReceivePacket ***/
/************************************************************************************//**
** \brief The uIP network application that implements XCP on TCP/IP. Note that this
** application make use of the fact that XCP is request/response based. So
** no new request will come in when a response is pending for transmission,
** if so, the transmission of the pending response is aborted.
** \return none.
**
****************************************************************************************/
void NetApp(void)
{
uip_tcp_appstate_t *s;
blt_int8u *newDataPtr;
/* get pointer to application state */
s = &(uip_conn->appstate);
if (uip_connected())
{
/* init the dto counter and reset the pending dto data length and transmit related
* flags.
*/
s->dto_counter = 1;
s->dto_len = 0;
s->dto_tx_req = BLT_FALSE;
s->dto_tx_pending = BLT_FALSE;
return;
}
if (uip_acked())
{
/* dto sent so reset the pending flag. */
s->dto_tx_pending = BLT_FALSE;
}
if (uip_rexmit())
{
/* is a dto transmission pending that should now be retransmitted? */
/* retransmit the currently pending dto response */
if (s->dto_tx_pending == BLT_TRUE)
{
/* resend the last pending dto response */
uip_send(s->dto_data, s->dto_len);
}
}
if (uip_poll())
{
/* check if there is a packet waiting to be transmitted. this is done via polling
* because then it is possible to asynchronously send data. otherwise data is
* only really send after a newly received packet was received.
*/
if (s->dto_tx_req == BLT_TRUE)
{
/* reset the transmit request flag. */
s->dto_tx_req = BLT_FALSE;
if (s->dto_len > 0)
{
/* set the transmit pending flag. */
s->dto_tx_pending = BLT_TRUE;
/* submit the data for transmission. */
uip_send(s->dto_data, s->dto_len);
}
}
}
if (uip_newdata())
{
/* only process the data if its length is not longer than expected. otherwise just
* ignore it. XCP is request/response. this means that a new requests should
* only be processed when the response the the previous request was sent. new
* requests before the last response was sent can therefore also be ignored.
*/
if ( ((uip_datalen() - 4) <= BOOT_COM_NET_RX_MAX_DATA) &&
(s->dto_tx_pending == BLT_FALSE) )
{
/* the first 4 bytes contain a counter value in which we are not really interested */
newDataPtr = uip_appdata;
XcpPacketReceived(&newDataPtr[4], (blt_int8u)(uip_datalen() - 4));
}
}
} /*** end of NetApp ***/
/************************************************************************************//**
** \brief Runs the TCP/IP server task.
** \return none.
**
****************************************************************************************/
static void NetServerTask(void)
{
blt_int32u connection;
blt_int32u packetLen;
/* check for an RX packet and read it. */
packetLen = netdev_read();
if (packetLen > 0)
{
/* set uip_len for uIP stack usage */
uip_len = (blt_int16u)packetLen;
/* process incoming IP packets here. */
if (NET_UIP_HEADER_BUF->type == htons(UIP_ETHTYPE_IP))
{
uip_arp_ipin();
uip_input();
/* if the above function invocation resulted in data that
* should be sent out on the network, the global variable
* uip_len is set to a value > 0.
*/
if (uip_len > 0)
{
uip_arp_out();
netdev_send();
uip_len = 0;
}
}
/* process incoming ARP packets here. */
else if (NET_UIP_HEADER_BUF->type == htons(UIP_ETHTYPE_ARP))
{
uip_arp_arpin();
/* if the above function invocation resulted in data that
* should be sent out on the network, the global variable
* uip_len is set to a value > 0.
*/
if (uip_len > 0)
{
netdev_send();
uip_len = 0;
}
}
}
/* process TCP/IP Periodic Timer here. */
if (TimerGet() >= periodicTimerTimeOut)
{
periodicTimerTimeOut += NET_UIP_PERIODIC_TIMER_MS;
for (connection = 0; connection < UIP_CONNS; connection++)
{
uip_periodic(connection);
/* If the above function invocation resulted in data that
* should be sent out on the network, the global variable
* uip_len is set to a value > 0.
*/
if (uip_len > 0)
{
uip_arp_out();
netdev_send();
uip_len = 0;
}
}
#if UIP_UDP
for (connection = 0; connection < UIP_UDP_CONNS; connection++)
{
uip_udp_periodic(connection);
/* If the above function invocation resulted in data that
* should be sent out on the network, the global variable
* uip_len is set to a value > 0.
*/
if(uip_len > 0)
{
uip_arp_out();
netdev_send();
uip_len = 0;
}
}
#endif
}
/* process ARP Timer here. */
if (TimerGet() >= ARPTimerTimeOut)
{
ARPTimerTimeOut += NET_UIP_ARP_TIMER_MS;
uip_arp_timer();
}
/* perform polling operations here. */
for (connection = 0; connection < UIP_CONNS; connection++)
{
uip_poll_conn(&uip_conns[connection]);
/* If the above function invocation resulted in data that
* should be sent out on the network, the global variable
* uip_len is set to a value > 0.
*/
if (uip_len > 0)
{
uip_arp_out();
netdev_send();
uip_len = 0;
}
}
} /*** end of NetServerTask ***/
#endif /* BOOT_COM_NET_ENABLE > 0 */
/*********************************** end of net.c **************************************/

80
Boot/loader/net.h Normal file
View File

@@ -0,0 +1,80 @@
/************************************************************************************//**
* \file Source/net.h
* \brief Bootloader TCP/IP network communication interface header file.
* \ingroup Core
* \internal
*----------------------------------------------------------------------------------------
* C O P Y R I G H T
*----------------------------------------------------------------------------------------
* Copyright (c) 2014 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
****************************************************************************************/
#ifndef NET_H
#define NET_H
#if (BOOT_COM_NET_ENABLE > 0)
/****************************************************************************************
* Macro definitions
****************************************************************************************/
#ifndef UIP_APPCALL
#define UIP_APPCALL NetApp
#endif /* UIP_APPCALL */
/****************************************************************************************
* Type definitions
****************************************************************************************/
/** \brief Define the uip_tcp_appstate_t datatype. This is the state of our tcp/ip
* application, and the memory required for this state is allocated together
* with each TCP connection. One application state for each TCP connection.
*/
typedef struct net_state
{
blt_int32u dto_counter;
blt_int8u dto_data[BOOT_COM_NET_TX_MAX_DATA + 4]; /* +4 for counter overhead */
blt_int16u dto_len;
blt_bool dto_tx_req;
blt_bool dto_tx_pending;
} uip_tcp_appstate_t;
/****************************************************************************************
* Function prototypes
****************************************************************************************/
void NetInit(void);
#if (BOOT_COM_NET_DEFERRED_INIT_ENABLE == 1)
void NetDeferredInit(void);
#endif
void NetApp(void);
void NetTransmitPacket(blt_int8u *data, blt_int8u len);
blt_bool NetReceivePacket(blt_int8u *data, blt_int8u *len);
#else /* BOOT_COM_NET_ENABLE > 0 */
typedef struct net_state
{
blt_int8u unused;
} uip_tcp_appstate_t;
#define UIP_APPCALL();
#endif /* BOOT_COM_NET_ENABLE > 0 */
#endif /* NET_H */
/*********************************** end of net.h **************************************/

56
Boot/loader/nvm.h Normal file
View File

@@ -0,0 +1,56 @@
/************************************************************************************//**
* \file Source/nvm.h
* \brief Bootloader non-volatile memory driver header file.
* \ingroup Core
* \internal
*----------------------------------------------------------------------------------------
* C O P Y R I G H T
*----------------------------------------------------------------------------------------
* Copyright (c) 2016 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
****************************************************************************************/
#ifndef NVM_H
#define NVM_H
/****************************************************************************************
* Function prototypes
****************************************************************************************/
void NvmInit(void);
void NvmReinit(void);
blt_bool NvmWrite(blt_addr addr, blt_int32u len, blt_int8u *data);
blt_bool NvmErase(blt_addr addr, blt_int32u len);
blt_bool NvmVerifyChecksum(void);
blt_addr NvmGetUserProgBaseAddress(void);
blt_bool NvmDone(void);
/****************************************************************************************
* Macro definitions
****************************************************************************************/
/* return codes for hook function NvmWrite/Erase */
/** \brief Return code for success. */
#define BLT_NVM_ERROR (0x00)
/** \brief Return code for error. */
#define BLT_NVM_OKAY (0x01)
/** \brief Return code for not in range. */
#define BLT_NVM_NOT_IN_RANGE (0x02)
#endif /* NVM_H */
/*********************************** end of nvm.h **************************************/

519
Boot/loader/plausibility.h Normal file
View File

@@ -0,0 +1,519 @@
/************************************************************************************//**
* \file Source/plausibility.h
* \brief Bootloader plausibility check header file, for checking the configuration
* at compile time.
* \ingroup Core
* \internal
*----------------------------------------------------------------------------------------
* C O P Y R I G H T
*----------------------------------------------------------------------------------------
* Copyright (c) 2011 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
****************************************************************************************/
#ifndef PLAUSIBILITY_H
#define PLAUSIBILITY_H
/****************************************************************************************
* C P U D R I V E R C O N F I G U R A T I O N C H E C K
****************************************************************************************/
#ifndef BOOT_CPU_XTAL_SPEED_KHZ
#error "BOOT_CPU_XTAL_SPEED_KHZ is missing in blt_conf.h"
#endif
#if (BOOT_CPU_XTAL_SPEED_KHZ <= 0)
#error "BOOT_CPU_XTAL_SPEED_KHZ must be > 0"
#endif
#ifndef BOOT_CPU_SYSTEM_SPEED_KHZ
#error "BOOT_CPU_SYSTEM_SPEED_KHZ is missing in blt_conf.h"
#endif
#if (BOOT_CPU_SYSTEM_SPEED_KHZ <= 0)
#error "BOOT_CPU_SYSTEM_SPEED_KHZ must be > 0"
#endif
#ifndef BOOT_CPU_BYTE_ORDER_MOTOROLA
#error "BOOT_CPU_BYTE_ORDER_MOTOROLA is missing in blt_conf.h"
#endif
#if (BOOT_CPU_BYTE_ORDER_MOTOROLA < 0) || (BOOT_CPU_BYTE_ORDER_MOTOROLA > 1)
#error "BOOT_CPU_BYTE_ORDER_MOTOROLA must be 0 or 1"
#endif
#ifndef BOOT_CPU_USER_PROGRAM_START_HOOK
#define BOOT_CPU_USER_PROGRAM_START_HOOK (0)
#endif
#if (BOOT_CPU_USER_PROGRAM_START_HOOK < 0) || (BOOT_CPU_USER_PROGRAM_START_HOOK > 1)
#error "BOOT_CPU_USER_PROGRAM_START_HOOK must be 0 or 1"
#endif
/****************************************************************************************
* C O M M U N I C A T I O N I N T E R F A C E C O N F I G U R A T I O N C H E C K
****************************************************************************************/
#ifndef BOOT_COM_CAN_TX_MAX_DATA
#define BOOT_COM_CAN_TX_MAX_DATA (0)
#endif
#ifndef BOOT_COM_CAN_RX_MAX_DATA
#define BOOT_COM_CAN_RX_MAX_DATA (0)
#endif
#ifndef BOOT_COM_RS232_TX_MAX_DATA
#define BOOT_COM_RS232_TX_MAX_DATA (0)
#endif
#ifndef BOOT_COM_RS232_RX_MAX_DATA
#define BOOT_COM_RS232_RX_MAX_DATA (0)
#endif
#ifndef BOOT_COM_USB_TX_MAX_DATA
#define BOOT_COM_USB_TX_MAX_DATA (0)
#endif
#ifndef BOOT_COM_USB_RX_MAX_DATA
#define BOOT_COM_USB_RX_MAX_DATA (0)
#endif
#ifndef BOOT_COM_NET_TX_MAX_DATA
#define BOOT_COM_NET_TX_MAX_DATA (0)
#endif
#ifndef BOOT_COM_NET_RX_MAX_DATA
#define BOOT_COM_NET_RX_MAX_DATA (0)
#endif
#ifndef BOOT_COM_CAN_ENABLE
#define BOOT_COM_CAN_ENABLE (0)
#endif
#if (BOOT_COM_CAN_ENABLE > 0)
/* Note that the value check was disabled for the following configuration macros, which
* makes it possible to link them to a function, allowing a more dynamic configuration:
* - BOOT_COM_CAN_BAUDRATE
* - BOOT_COM_CAN_TX_MSG_ID
* - BOOT_COM_CAN_RX_MSG_ID
*/
#ifndef BOOT_COM_CAN_BAUDRATE
#error "BOOT_COM_CAN_BAUDRATE is missing in blt_conf.h"
#endif
#ifndef BOOT_COM_CAN_TX_MSG_ID
#error "BOOT_COM_CAN_TX_MSG_ID is missing in blt_conf.h"
#endif
#ifndef BOOT_COM_CAN_TX_MAX_DATA
#error "BOOT_COM_CAN_TX_MAX_DATA is missing in blt_conf.h"
#endif
#if (BOOT_COM_CAN_TX_MAX_DATA <= 0)
#error "BOOT_COM_CAN_TX_MAX_DATA must be > 0"
#endif
#if (BOOT_COM_CAN_TX_MAX_DATA > 8)
#error "BOOT_COM_CAN_TX_MAX_DATA must be <= 8"
#endif
#ifndef BOOT_COM_CAN_RX_MSG_ID
#error "BOOT_COM_CAN_RX_MSG_ID is missing in blt_conf.h"
#endif
#ifndef BOOT_COM_CAN_RX_MAX_DATA
#error "BOOT_COM_CAN_RX_MAX_DATA is missing in blt_conf.h"
#endif
#if (BOOT_COM_CAN_RX_MAX_DATA <= 0)
#error "BOOT_COM_CAN_RX_MAX_DATA must be > 0"
#endif
#if (BOOT_COM_CAN_RX_MAX_DATA > 8)
#error "BOOT_COM_CAN_RX_MAX_DATA must be <= 8"
#endif
#ifndef BOOT_COM_CAN_CHANNEL_INDEX
#error "BOOT_COM_CAN_CHANNEL_INDEX is missing in blt_conf.h"
#endif
#if (BOOT_COM_CAN_CHANNEL_INDEX < 0)
#error "BOOT_COM_CAN_CHANNEL_INDEX must be >= 0"
#endif
#endif /* BOOT_COM_CAN_ENABLE > 0 */
#ifndef BOOT_COM_RS232_ENABLE
#define BOOT_COM_RS232_ENABLE (0)
#endif
#if (BOOT_COM_RS232_ENABLE > 0)
/* Note that the value check was disabled for the following configuration macros, which
* makes it possible to link them to a function, allowing a more dynamic configuration:
* - BOOT_COM_RS232_BAUDRATE
*/
#ifndef BOOT_COM_RS232_BAUDRATE
#error "BOOT_COM_RS232_BAUDRATE is missing in blt_conf.h"
#endif
#ifndef BOOT_COM_RS232_TX_MAX_DATA
#error "BOOT_COM_RS232_TX_MAX_DATA is missing in blt_conf.h"
#endif
#if (BOOT_COM_RS232_TX_MAX_DATA <= 0)
#error "BOOT_COM_RS232_TX_MAX_DATA must be > 0"
#endif
#if (BOOT_COM_RS232_TX_MAX_DATA > 255)
#error "BOOT_COM_RS232_TX_MAX_DATA must be <= 255"
#endif
#ifndef BOOT_COM_RS232_RX_MAX_DATA
#error "BOOT_COM_RS232_RX_MAX_DATA is missing in blt_conf.h"
#endif
#if (BOOT_COM_RS232_RX_MAX_DATA <= 0)
#error "BOOT_COM_RS232_RX_MAX_DATA must be > 0"
#endif
#if (BOOT_COM_RS232_RX_MAX_DATA > 255)
#error "BOOT_COM_RS232_RX_MAX_DATA must be <= 255"
#endif
#ifndef BOOT_COM_RS232_CHANNEL_INDEX
#error "BOOT_COM_RS232_CHANNEL_INDEX is missing in blt_conf.h"
#endif
#if (BOOT_COM_RS232_CHANNEL_INDEX < 0)
#error "BOOT_COM_RS232_CHANNEL_INDEX must be >= 0"
#endif
#endif /* BOOT_COM_RS232_ENABLE > 0 */
#ifndef BOOT_COM_USB_ENABLE
#define BOOT_COM_USB_ENABLE (0)
#endif
#if (BOOT_COM_USB_ENABLE > 0)
#ifndef BOOT_COM_USB_TX_MAX_DATA
#error "BOOT_COM_USB_TX_MAX_DATA is missing in blt_conf.h"
#endif
#if (BOOT_COM_USB_TX_MAX_DATA <= 0)
#error "BOOT_COM_USB_TX_MAX_DATA must be > 0"
#endif
#ifndef BOOT_COM_USB_RX_MAX_DATA
#error "BOOT_COM_USB_RX_MAX_DATA is missing in blt_conf.h"
#endif
#if (BOOT_COM_USB_RX_MAX_DATA <= 0)
#error "BOOT_COM_USB_RX_MAX_DATA must be > 0"
#endif
#ifdef BOOT_COM_USB_BACKDOOR_EXTENSION_MS
#if (BOOT_COM_USB_BACKDOOR_EXTENSION_MS < 0)
#error "BOOT_COM_USB_BACKDOOR_EXTENSION_MS must be >= 0"
#endif
#endif
#endif /* BOOT_COM_USB_ENABLE > 0 */
#ifndef BOOT_COM_NET_ENABLE
#define BOOT_COM_NET_ENABLE (0)
#endif
#if (BOOT_COM_NET_ENABLE > 0)
/* Note that the value check was disabled for the following configuration macros, which
* makes it possible to link them to a function, allowing a more dynamic configuration:
* - BOOT_COM_NET_IPADDR0
* - BOOT_COM_NET_IPADDR1
* - BOOT_COM_NET_IPADDR2
* - BOOT_COM_NET_IPADDR3
* - BOOT_COM_NET_NETMASK0
* - BOOT_COM_NET_NETMASK1
* - BOOT_COM_NET_NETMASK2
* - BOOT_COM_NET_NETMASK3
* - BOOT_COM_NET_GATEWAY0
* - BOOT_COM_NET_GATEWAY1
* - BOOT_COM_NET_GATEWAY2
* - BOOT_COM_NET_GATEWAY3
* - BOOT_COM_NET_PORT
*/
#ifndef BOOT_COM_NET_TX_MAX_DATA
#error "BOOT_COM_NET_TX_MAX_DATA is missing in blt_conf.h"
#endif
#if (BOOT_COM_NET_TX_MAX_DATA <= 0)
#error "BOOT_COM_NET_TX_MAX_DATA must be > 0"
#endif
#ifndef BOOT_COM_NET_RX_MAX_DATA
#error "BOOT_COM_NET_RX_MAX_DATA is missing in blt_conf.h"
#endif
#if (BOOT_COM_NET_RX_MAX_DATA <= 0)
#error "BOOT_COM_NET_RX_MAX_DATA must be > 0"
#endif
#ifndef BOOT_COM_NET_DHCP_ENABLE
#define BOOT_COM_NET_DHCP_ENABLE (0)
#endif
#if (BOOT_COM_NET_DHCP_ENABLE < 0) || (BOOT_COM_NET_DHCP_ENABLE > 1)
#error "BOOT_COM_NET_DHCP_ENABLE must be 0 or 1"
#endif
#if (BOOT_COM_NET_DHCP_ENABLE == 0)
#ifndef BOOT_COM_NET_IPADDR0
#error "BOOT_COM_NET_IPADDR0 is missing in blt_conf.h"
#endif
#ifndef BOOT_COM_NET_IPADDR1
#error "BOOT_COM_NET_IPADDR1 is missing in blt_conf.h"
#endif
#ifndef BOOT_COM_NET_IPADDR2
#error "BOOT_COM_NET_IPADDR2 is missing in blt_conf.h"
#endif
#ifndef BOOT_COM_NET_IPADDR3
#error "BOOT_COM_NET_IPADDR3 is missing in blt_conf.h"
#endif
#ifndef BOOT_COM_NET_NETMASK0
#error "BOOT_COM_NET_NETMASK0 is missing in blt_conf.h"
#endif
#ifndef BOOT_COM_NET_NETMASK1
#error "BOOT_COM_NET_NETMASK1 is missing in blt_conf.h"
#endif
#ifndef BOOT_COM_NET_NETMASK2
#error "BOOT_COM_NET_NETMASK2 is missing in blt_conf.h"
#endif
#ifndef BOOT_COM_NET_NETMASK3
#error "BOOT_COM_NET_NETMASK3 is missing in blt_conf.h"
#endif
#ifndef BOOT_COM_NET_GATEWAY0
#error "BOOT_COM_NET_GATEWAY0 is missing in blt_conf.h"
#endif
#ifndef BOOT_COM_NET_GATEWAY1
#error "BOOT_COM_NET_GATEWAY1 is missing in blt_conf.h"
#endif
#ifndef BOOT_COM_NET_GATEWAY2
#error "BOOT_COM_NET_GATEWAY2 is missing in blt_conf.h"
#endif
#ifndef BOOT_COM_NET_GATEWAY3
#error "BOOT_COM_NET_GATEWAY3 is missing in blt_conf.h"
#endif
#ifndef BOOT_COM_NET_PORT
#error "BOOT_COM_NET_PORT is missing in blt_conf.h"
#endif
#endif /* BOOT_COM_NET_DHCP_ENABLE == 0 */
#ifdef BOOT_COM_NET_BACKDOOR_EXTENSION_MS
#if (BOOT_COM_NET_BACKDOOR_EXTENSION_MS < 0)
#error "BOOT_COM_NET_BACKDOOR_EXTENSION_MS must be >= 0"
#endif
#endif
#ifndef BOOT_COM_NET_DEFERRED_INIT_ENABLE
#define BOOT_COM_NET_DEFERRED_INIT_ENABLE (0)
#endif
#if (BOOT_COM_NET_DEFERRED_INIT_ENABLE < 0) || (BOOT_COM_NET_DEFERRED_INIT_ENABLE > 1)
#error "BOOT_COM_NET_DEFERRED_INIT_ENABLE must be 0 or 1"
#endif
#endif /* BOOT_COM_NET_ENABLE > 0 */
#if (BOOT_COM_NET_DEFERRED_INIT_ENABLE == 1)
#define BOOT_COM_DEFERRED_INIT_ENABLE (1)
#else
#define BOOT_COM_DEFERRED_INIT_ENABLE (0)
#endif
#if (BOOT_COM_CAN_ENABLE == 1) || (BOOT_COM_RS232_ENABLE == 1) || (BOOT_COM_NET_ENABLE == 1) || (BOOT_COM_USB_ENABLE == 1)
#define BOOT_COM_ENABLE (1)
#else
#define BOOT_COM_ENABLE (0)
#endif
/****************************************************************************************
* F I L E S Y S T E M I N T E R F A C E C O N F I G U R A T I O N C H E C K
****************************************************************************************/
#ifndef BOOT_FILE_SYS_ENABLE
#define BOOT_FILE_SYS_ENABLE (0)
#endif
#if (BOOT_FILE_SYS_ENABLE < 0) || (BOOT_FILE_SYS_ENABLE > 1)
#error "BOOT_FILE_SYS_ENABLE must be 0 or 1"
#endif
#if (BOOT_FILE_SYS_ENABLE > 0)
#ifndef BOOT_FILE_LOGGING_ENABLE
#define BOOT_FILE_LOGGING_ENABLE (0)
#endif
#if (BOOT_FILE_LOGGING_ENABLE < 0) || (BOOT_FILE_LOGGING_ENABLE > 1)
#error "BOOT_FILE_LOGGING_ENABLE must be 0 or 1"
#endif
#ifndef BOOT_FILE_ERROR_HOOK_ENABLE
#define BOOT_FILE_ERROR_HOOK_ENABLE (0)
#endif
#if (BOOT_FILE_ERROR_HOOK_ENABLE < 0) || (BOOT_FILE_ERROR_HOOK_ENABLE > 1)
#error "BOOT_FILE_ERROR_HOOK_ENABLE must be 0 or 1"
#endif
#ifndef BOOT_FILE_STARTED_HOOK_ENABLE
#define BOOT_FILE_STARTED_HOOK_ENABLE (0)
#endif
#if (BOOT_FILE_STARTED_HOOK_ENABLE < 0) || (BOOT_FILE_STARTED_HOOK_ENABLE > 1)
#error "BOOT_FILE_STARTED_HOOK_ENABLE must be 0 or 1"
#endif
#ifndef BOOT_FILE_COMPLETED_HOOK_ENABLE
#define BOOT_FILE_COMPLETED_HOOK_ENABLE (0)
#endif
#if (BOOT_FILE_COMPLETED_HOOK_ENABLE < 0) || (BOOT_FILE_COMPLETED_HOOK_ENABLE > 1)
#error "BOOT_FILE_COMPLETED_HOOK_ENABLE must be 0 or 1"
#endif
#endif /* BOOT_FILE_SYS_ENABLE > 0 */
/****************************************************************************************
* B A C K D O O R E N T R Y C H E C K
****************************************************************************************/
#ifndef BOOT_BACKDOOR_HOOKS_ENABLE
#define BOOT_BACKDOOR_HOOKS_ENABLE (0)
#endif
#if (BOOT_BACKDOOR_HOOKS_ENABLE < 0) || (BOOT_BACKDOOR_HOOKS_ENABLE > 1)
#error "BOOT_BACKDOOR_HOOKS_ENABLE must be 0 or 1"
#endif
/****************************************************************************************
* F L A S H D R I V E R C O N F I G U R A T I O N C H E C K
****************************************************************************************/
#ifndef BOOT_FLASH_CRYPTO_HOOKS_ENABLE
#define BOOT_FLASH_CRYPTO_HOOKS_ENABLE (0)
#endif
#if (BOOT_FLASH_CRYPTO_HOOKS_ENABLE < 0) || (BOOT_FLASH_CRYPTO_HOOKS_ENABLE > 1)
#error "BOOT_FLASH_CRYPTO_HOOKS_ENABLE must be 0 or 1"
#endif
/****************************************************************************************
* N V M D R I V E R C O N F I G U R A T I O N C H E C K
****************************************************************************************/
#ifndef BOOT_NVM_HOOKS_ENABLE
#define BOOT_NVM_HOOKS_ENABLE (0)
#endif
#if (BOOT_NVM_HOOKS_ENABLE < 0) || (BOOT_NVM_HOOKS_ENABLE > 1)
#error "BOOT_NVM_HOOKS_ENABLE must be 0 or 1"
#endif
#ifndef BOOT_NVM_SIZE_KB
#error "BOOT_NVM_SIZE_KB is missing in blt_conf.h"
#endif
#if (BOOT_NVM_SIZE_KB <= 0)
#error "BOOT_NVM_SIZE_KB must be > 0"
#endif
#ifndef BOOT_NVM_CHECKSUM_HOOKS_ENABLE
#define BOOT_NVM_CHECKSUM_HOOKS_ENABLE (0)
#endif
#if (BOOT_NVM_CHECKSUM_HOOKS_ENABLE < 0) || (BOOT_NVM_CHECKSUM_HOOKS_ENABLE > 1)
#error "BOOT_NVM_CHECKSUM_HOOKS_ENABLE must be 0 or 1"
#endif
/****************************************************************************************
* W A T C H D O G D R I V E R C O N F I G U R A T I O N C H E C K
****************************************************************************************/
#ifndef BOOT_COP_HOOKS_ENABLE
#define BOOT_COP_HOOKS_ENABLE (0)
#endif
#if (BOOT_COP_HOOKS_ENABLE < 0) || (BOOT_COP_HOOKS_ENABLE > 1)
#error "BOOT_COP_HOOKS_ENABLE must be 0 or 1"
#endif
/****************************************************************************************
* X C P M O D U L E C O N F I G U R A T I O N C H E C K
****************************************************************************************/
#ifndef BOOT_XCP_SEED_KEY_ENABLE
#define BOOT_XCP_SEED_KEY_ENABLE (0)
#endif
#if (BOOT_XCP_SEED_KEY_ENABLE < 0) || (BOOT_XCP_SEED_KEY_ENABLE > 1)
#error "BOOT_XCP_SEED_KEY_ENABLE must be 0 or 1"
#endif
#ifndef BOOT_XCP_UPLOAD_ENABLE
#define BOOT_XCP_UPLOAD_ENABLE (1)
#endif
#if (BOOT_XCP_UPLOAD_ENABLE < 0) || (BOOT_XCP_UPLOAD_ENABLE > 1)
#error "BOOT_XCP_UPLOAD_ENABLE must be 0 or 1"
#endif
#ifndef BOOT_XCP_PACKET_RECEIVED_HOOK
#define BOOT_XCP_PACKET_RECEIVED_HOOK (0)
#endif
#if (BOOT_XCP_PACKET_RECEIVED_HOOK < 0) || (BOOT_XCP_PACKET_RECEIVED_HOOK > 1)
#error "BOOT_XCP_PACKET_RECEIVED_HOOK must be 0 or 1"
#endif
#ifndef BOOT_XCP_SEED_MAX_LEN
#define BOOT_XCP_SEED_MAX_LEN (64)
#endif
#if (BOOT_XCP_SEED_MAX_LEN <= 0)
#error "BOOT_XCP_SEED_MAX_LEN must be > 0"
#endif
#ifndef BOOT_XCP_KEY_MAX_LEN
#define BOOT_XCP_KEY_MAX_LEN (64)
#endif
#if (BOOT_XCP_KEY_MAX_LEN <= 0)
#error "BOOT_XCP_KEY_MAX_LEN must be > 0"
#endif
#endif /* PLAUSIBILITY_H */
/*********************************** end of plausibility.h *****************************/

10
Boot/loader/ports.dox Normal file
View File

@@ -0,0 +1,10 @@
/**
\defgroup Ports Bootloader Ports
\brief Target dependent code.
\details The bootloader targets contain the microcontroller and compiler dependent
parts of the bootloader. They are grouped per microcontroller family. This is
the part that needs to be newly developed when porting the bootloader to a
new microcontroller family.
*/

50
Boot/loader/readme.dox Normal file
View File

@@ -0,0 +1,50 @@
/**
\mainpage OpenBLT Firmware Documentation
\details
\section into Introduction
This documentation covers the OpenBLT (Open source BootLoader Tool) firmware. With
OpenBLT you can make software updates through an on-chip communication interface
(RS232, CAN, TCP/IP, USB etc.), without the need of specialized debugger hardware.
\section arch Software Architecture
The software program's architecture is divided into 4 major categories, namely the
application code (App), target independent code (Core), target dependent code
(Target), and compiler specific code (Comp).
\image html openblt_architecture.png
\image latex openblt_architecture.png
To configure and fine-tune the bootloader for integration in your product, all you have
to do is take the demo bootloader project for the microcontroller and compiler you are
using, and (optionally) modify just the application code (App) to fit your needs. This
typically involves changing the configuration header file (blt_conf.h) and the
implementation of the hook functions (hooks.c).
For more in-depth information behind the design of the OpenBLT bootloader, you can visit:
https://www.feaser.com/openblt/doku.php?id=manual:design.
\section copy Copyright and Licensing
\verbatim
----------------------------------------------------------------------------------------
C O P Y R I G H T
----------------------------------------------------------------------------------------
Copyright (c) by Feaser 2011-2023 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.
----------------------------------------------------------------------------------------
\endverbatim
*/

42
Boot/loader/rs232.h Normal file
View File

@@ -0,0 +1,42 @@
/************************************************************************************//**
* \file Source/rs232.h
* \brief Bootloader RS232 communication interface header file.
* \ingroup Core
* \internal
*----------------------------------------------------------------------------------------
* C O P Y R I G H T
*----------------------------------------------------------------------------------------
* Copyright (c) 2016 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
****************************************************************************************/
#ifndef RS232_H
#define RS232_H
#if (BOOT_COM_RS232_ENABLE > 0)
/****************************************************************************************
* Function prototypes
****************************************************************************************/
void Rs232Init(void);
void Rs232TransmitPacket(blt_int8u *data, blt_int8u len);
blt_bool Rs232ReceivePacket(blt_int8u *data, blt_int8u *len);
#endif /* BOOT_COM_RS232_ENABLE > 0 */
#endif /* RS232_H */
/*********************************** end of rs232.h ************************************/

41
Boot/loader/timer.h Normal file
View File

@@ -0,0 +1,41 @@
/************************************************************************************//**
* \file Source/timer.h
* \brief Bootloader timer driver header file.
* \ingroup Core
* \internal
*----------------------------------------------------------------------------------------
* C O P Y R I G H T
*----------------------------------------------------------------------------------------
* Copyright (c) 2016 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
****************************************************************************************/
#ifndef TIMER_H
#define TIMER_H
/****************************************************************************************
* Function prototypes
****************************************************************************************/
void TimerInit(void);
void TimerUpdate(void);
blt_int32u TimerGet(void);
void TimerReset(void);
#endif /* TIMER_H */
/*********************************** end of timer.h ************************************/

52
Boot/loader/usb.h Normal file
View File

@@ -0,0 +1,52 @@
/************************************************************************************//**
* \file Source/usb.h
* \brief Bootloader USB communication interface header file.
* \ingroup Core
* \internal
*----------------------------------------------------------------------------------------
* C O P Y R I G H T
*----------------------------------------------------------------------------------------
* Copyright (c) 2016 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
****************************************************************************************/
#ifndef USB_H
#define USB_H
#if (BOOT_COM_USB_ENABLE > 0)
/****************************************************************************************
* Function prototypes
****************************************************************************************/
void UsbInit(void);
void UsbFree(void);
void UsbTransmitPacket(blt_int8u *data, blt_int8u len);
blt_bool UsbReceivePacket(blt_int8u *data, blt_int8u *len);
/****************************************************************************************
* Hook functions
****************************************************************************************/
extern void UsbEnterLowPowerModeHook(void);
extern void UsbLeaveLowPowerModeHook(void);
extern void UsbConnectHook(blt_bool connect);
#endif /* BOOT_COM_USB_ENABLE > 0 */
#endif /* USB_H */
/*********************************** end of usb.h **************************************/

1500
Boot/loader/xcp.c Normal file

File diff suppressed because it is too large Load Diff

357
Boot/loader/xcp.h Normal file
View File

@@ -0,0 +1,357 @@
/************************************************************************************//**
* \file Source/xcp.h
* \brief XCP 1.0 protocol core header file.
* \ingroup Core
* \internal
*----------------------------------------------------------------------------------------
* C O P Y R I G H T
*----------------------------------------------------------------------------------------
* Copyright (c) 2011 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
****************************************************************************************/
#ifndef XCP_H
#define XCP_H
#if (BOOT_COM_ENABLE > 0)
/****************************************************************************************
* Configuration
****************************************************************************************/
/** \brief Maximum length of the transport layer's command transmit object packet. */
#if defined(BOOT_XCP_CUSTOM_RX_MAX_DATA)
#define XCP_CTO_PACKET_LEN (BOOT_XCP_CUSTOM_RX_MAX_DATA)
#else
#define XCP_CTO_PACKET_LEN (ComGetActiveInterfaceMaxRxLen())
#endif
/** \brief Maximum length of the transport layer's data transmit object packet. */
#if defined(BOOT_XCP_CUSTOM_TX_MAX_DATA)
#define XCP_DTO_PACKET_LEN (BOOT_XCP_CUSTOM_TX_MAX_DATA)
#else
#define XCP_DTO_PACKET_LEN (ComGetActiveInterfaceMaxTxLen())
#endif
/** \brief Name in string format that is used to identify the ECU to the XCP master
* using the GET_ID command.
*/
#define XCP_STATION_ID_STRING "OpenBLT"
#if (BOOT_CPU_BYTE_ORDER_MOTOROLA > 0)
/** \brief XCP byte ordering according to the Motorola (big-endian). */
#define XCP_MOTOROLA_FORMAT (0x01)
#else
/** \brief XCP byte ordering according to the Intel (little-endian). */
#define XCP_MOTOROLA_FORMAT (0x00)
#endif
/** \brief Enable (=1) or disable (=0) support for the calibration resource. This is
* required when data is written to RAM during the XCP session.
*/
#define XCP_RES_CALIBRATION_EN (0)
/** \brief Enable (=1) or disable (=0) support for the paging resource. This is
* required when switching between application specific calibration pages
* should be supported. In this case the application specific external
* functions AppCalSetPage and AppCalGetPage must be provided.
*/
#define XCP_RES_PAGING_EN (0)
/** \brief Enable (=1) or disable (=0) support for the programming resource. This is
* required when non-volatile memory will be erased or programmed during an
* XCP session. In this case the following external hardware specific
* functions must be provided: NvmWrite, NvmErase and CpuStartUserProgram.
*/
#define XCP_RES_PROGRAMMING_EN (1)
/** \brief Enable (=1) or disable (=0) support for the data acquisition resource. This
* note that this feature is currently not supported by the XCP driver.
*/
#define XCP_RES_DATA_ACQUISITION_EN (0)
/** \brief Enable (=1) or disable (=0) support for the data stimulation resource. This
* note that this feature is currently not supported by the XCP driver.
*/
#define XCP_RES_DATA_STIMULATION_EN (0)
/** \brief Enable (=1) or disable (=0) support for the seed/key protection feature.
* If enabled, the XCP master has to perform a GET_SEED/UNLOCK sequence to
* obtain access to a resource. The protection algorithm is implemented in
* XcpGetSeed and XcpVerifyKey.
*/
#if (BOOT_XCP_SEED_KEY_ENABLE > 0)
#define XCP_SEED_KEY_PROTECTION_EN (1)
#else
#define XCP_SEED_KEY_PROTECTION_EN (0)
#endif
/** \brief Enable (=1) or disable (=0) uploading. By default, XCP always allows memory
* read operations using the commands UPLOAD and SHORT_UPLOAD. This is not
* always desired for security reasons. If disabled, memory reads via XCP always
* return zero values.
*/
#if (BOOT_XCP_UPLOAD_ENABLE > 0)
#define XCP_UPLOAD_EN (1)
#else
#define XCP_UPLOAD_EN (0)
#endif
/** \brief Enable (=1) or disable the hook function that gets called each time an XCP
* packet was received from the host.
* \details A master-slave bootloader can be realized by using this hook-function. The
* mode parameter in the XCP Connect command can be interpreted as a node ID.
* When trying to connect to a slave, a gateway could be activated that passes
* the packet on to the slave. When the response packet is received from the
* slave, ComTransmitPacket() can be called to pass the response on to the
* host. At the end of a firmware update procedure, the XCP Program Reset
* command is called, which can be used to deactivate the gateway. If this
* hook-function returns BLT_TRUE, the packet is no longer processed by the XCP
* module. If it returns BLT_FALSE, then the packet is processed as usual by
* the XCP module.
*/
#if (BOOT_XCP_PACKET_RECEIVED_HOOK > 0)
#define XCP_PACKET_RECEIVED_HOOK_EN (1)
#else
#define XCP_PACKET_RECEIVED_HOOK_EN (0)
#endif
/****************************************************************************************
* Defines
****************************************************************************************/
/** \brief XCP protocol layer version number (16-bit). */
#define XCP_VERSION_PROTOCOL_LAYER (0x0100)
/** \brief XCP transport layer version number (16-bit). */
#define XCP_VERSION_TRANSPORT_LAYER (0x0100)
/* XCP packet identifiers */
/** \brief Command response packet identifier. */
#define XCP_PID_RES (0xff)
/** \brief Error packet identifier. */
#define XCP_PID_ERR (0xfe)
/* XCP error codes */
/** \brief Cmd processor synchronization error code. */
#define XCP_ERR_CMD_SYNCH (0x00)
/** \brief Command was not executed error code. */
#define XCP_ERR_CMD_BUSY (0x10)
/** \brief Unknown or unsupported command error code. */
#define XCP_ERR_CMD_UNKNOWN (0x20)
/** \brief Parameter out of range error code. */
#define XCP_ERR_OUT_OF_RANGE (0x22)
/** \brief Protected error code. Seed/key required. */
#define XCP_ERR_ACCESS_LOCKED (0x25)
/** \brief Cal page not valid error code. */
#define XCP_ERR_PAGE_NOT_VALID (0x26)
/** \brief Sequence error code. */
#define XCP_ERR_SEQUENCE (0x29)
/** \brief Generic error code. */
#define XCP_ERR_GENERIC (0x31)
/* XCP command codes */
/** \brief CONNECT command code. */
#define XCP_CMD_CONNECT (0xff)
/** \brief DISCONNECT command code. */
#define XCP_CMD_DISCONNECT (0xfe)
/** \brief GET_STATUS command code. */
#define XCP_CMD_GET_STATUS (0xfd)
/** \brief SYNCH command code. */
#define XCP_CMD_SYNCH (0xfc)
/** \brief GET_ID command code. */
#define XCP_CMD_GET_ID (0xfa)
/** \brief GET_SEED command code. */
#define XCP_CMD_GET_SEED (0xf8)
/** \brief UNLOCK command code. */
#define XCP_CMD_UNLOCK (0xf7)
/** \brief SET_MTA command code. */
#define XCP_CMD_SET_MTA (0xf6)
/** \brief UPLOAD command code. */
#define XCP_CMD_UPLOAD (0xf5)
/** \brief SHORT_UPLOAD command code. */
#define XCP_CMD_SHORT_UPLOAD (0xf4)
/** \brief BUILD_CHECKSUM command code. */
#define XCP_CMD_BUILD_CHECKSUM (0xf3)
/** \brief DOWNLOAD command code. */
#define XCP_CMD_DOWNLOAD (0xf0)
/** \brief DOWNLOAD_MAX command code. */
#define XCP_CMD_DOWLOAD_MAX (0xee)
/** \brief SET_CALPAGE command code. */
#define XCP_CMD_SET_CAL_PAGE (0xeb)
/** \brief GET_CALPAGE command code. */
#define XCP_CMD_GET_CAL_PAGE (0xea)
/** \brief PROGRAM_START command code. */
#define XCP_CMD_PROGRAM_START (0xd2)
/** \brief PROGRAM_CLEAR command code. */
#define XCP_CMD_PROGRAM_CLEAR (0xd1)
/** \brief PROGRAM command code. */
#define XCP_CMD_PROGRAM (0xd0)
/** \brief PROGRAM_RESET command code. */
#define XCP_CMD_PROGRAM_RESET (0xcf)
/** \brief PROGRAM_PREPARE command code. */
#define XCP_CMD_PROGRAM_PREPARE (0xcc)
/** \brief PROGRAM_MAX command code. */
#define XCP_CMD_PROGRAM_MAX (0xc9)
/* xcp supported resources */
/** \brief ProGraMming resource. */
#define XCP_RES_PGM (0x10)
/** \brief data STIMulation resource. */
#define XCP_RES_STIM (0x08)
/** \brief Data AcQuisition resource. */
#define XCP_RES_DAQ (0x04)
/** \brief CALibration and PAGing resource. */
#define XCP_RES_CALPAG (0x01)
/* xcp checksum types */
/** \brief Add byte into byte checksum. */
#define XCP_CS_ADD11 (0x01)
/** \brief Add byte into word checksum. */
#define XCP_CS_ADD12 (0x02)
/** \brief Add byte into dword checksum. */
#define XCP_CS_ADD14 (0x03)
/** \brief Add word into word checksum. */
#define XCP_CS_ADD22 (0x04)
/** \brief Add word into dword checksum. */
#define XCP_CS_ADD24 (0x05)
/** \brief Add dword into dword checksum. */
#define XCP_CS_ADD44 (0x06)
/** \brief Use 16-bit CRC algorithm. */
#define XCP_CS_CRC16 (0x07)
/** \brief Use 16-bit CRC CITT algorithm. */
#define XCP_CS_CRC16CITT (0x08)
/** \brief Use 32-bit CRC algorithm. */
#define XCP_CS_CRC32 (0x09)
/** \brief Use user defined algorithm. */
#define XCP_CS_USER (0xff)
/** \brief Maximum number of bytes of a seed for the seed/key security feature. */
#define XCP_SEED_MAX_LEN (BOOT_XCP_SEED_MAX_LEN)
/** \brief Maximum number of bytes of a key for the seed/key security feature. */
#define XCP_KEY_MAX_LEN (BOOT_XCP_KEY_MAX_LEN)
/****************************************************************************************
* Function prototypes
****************************************************************************************/
void XcpInit(void);
blt_bool XcpIsConnected(void);
void XcpPacketTransmitted(void);
void XcpPacketReceived(blt_int8u *data, blt_int8u len);
/****************************************************************************************
* Configuration check
****************************************************************************************/
#if (XCP_RES_DATA_ACQUISITION_EN == 1)
#error "XCP.H, Current XCP driver does not support Data AcQuisition resource."
#endif
#if (XCP_RES_DATA_STIMULATION_EN == 1)
#error "XCP.H, Current XCP driver does not support Data StIMulation resource."
#endif
#ifndef XCP_CTO_PACKET_LEN
#error "XCP.H, Configuration macro XCP_CTO_PACKET_LEN is missing."
#endif
#ifndef XCP_DTO_PACKET_LEN
#error "XCP.H, Configuration macro XCP_DTO_PACKET_LEN is missing."
#endif
#ifndef XCP_STATION_ID_STRING
#error "XCP.H, Configuration macro XCP_STATION_ID_STRING is missing."
#endif
#ifndef XCP_RES_CALIBRATION_EN
#error "XCP.H, Configuration macro XCP_RES_CALIBRATION_EN is missing."
#endif
#if (XCP_RES_CALIBRATION_EN < 0) || (XCP_RES_CALIBRATION_EN > 1)
#error "XCP.H, XCP_RES_CALIBRATION_EN must be 0 or 1."
#endif
#ifndef XCP_RES_PAGING_EN
#error "XCP.H, Configuration macro XCP_RES_PAGING_EN is missing."
#endif
#if (XCP_RES_PAGING_EN < 0) || (XCP_RES_PAGING_EN > 1)
#error "XCP.H, XCP_RES_PAGING_EN must be 0 or 1."
#endif
#ifndef XCP_RES_PROGRAMMING_EN
#error "XCP.H, Configuration macro XCP_RES_PAGING_EN is missing."
#endif
#if (XCP_RES_PROGRAMMING_EN < 0) || (XCP_RES_PROGRAMMING_EN > 1)
#error "XCP.H, XCP_RES_PROGRAMMING_EN must be 0 or 1."
#endif
#ifndef XCP_RES_DATA_ACQUISITION_EN
#error "XCP.H, Configuration macro XCP_RES_DATA_ACQUISITION_EN is missing."
#endif
#if (XCP_RES_DATA_ACQUISITION_EN < 0) || (XCP_RES_DATA_ACQUISITION_EN > 1)
#error "XCP.H, XCP_RES_DATA_ACQUISITION_EN must be 0 or 1."
#endif
#ifndef XCP_RES_DATA_STIMULATION_EN
#error "XCP.H, Configuration macro XCP_RES_DATA_STIMULATION_EN is missing."
#endif
#if (XCP_RES_DATA_STIMULATION_EN < 0) || (XCP_RES_DATA_STIMULATION_EN > 1)
#error "XCP.H, XCP_RES_DATA_STIMULATION_EN must be 0 or 1."
#endif
#ifndef XCP_SEED_KEY_PROTECTION_EN
#error "XCP.H, Configuration macro XCP_SEED_KEY_PROTECTION_EN is missing."
#endif
#if (XCP_SEED_KEY_PROTECTION_EN < 0) || (XCP_SEED_KEY_PROTECTION_EN > 1)
#error "XCP.H, XCP_SEED_KEY_PROTECTION_EN must be 0 or 1."
#endif
#ifndef XCP_UPLOAD_EN
#error "XCP.H, Configuration macro XCP_UPLOAD_EN is missing."
#endif
#if (XCP_UPLOAD_EN < 0) || (XCP_UPLOAD_EN > 1)
#error "XCP.H, XCP_UPLOAD_EN must be 0 or 1."
#endif
#ifndef XCP_PACKET_RECEIVED_HOOK_EN
#error "XCP.H, Configuration macro XCP_PACKET_RECEIVED_HOOK_EN is missing."
#endif
#if (XCP_PACKET_RECEIVED_HOOK_EN < 0) || (XCP_PACKET_RECEIVED_HOOK_EN > 1)
#error "XCP.H, XCP_PACKET_RECEIVED_HOOK_EN must be 0 or 1."
#endif
#endif /* BOOT_COM_ENABLE > 0 */
#endif /* XCP_H */
/******************************** end of xcp.h *~~~~~***********************************/