diff --git a/Host/BootCommander.exe b/Host/BootCommander.exe new file mode 100644 index 00000000..aa986f21 Binary files /dev/null and b/Host/BootCommander.exe differ diff --git a/Host/SerialBoot.exe b/Host/SerialBoot.exe deleted file mode 100644 index 5d4e0a54..00000000 Binary files a/Host/SerialBoot.exe and /dev/null differ diff --git a/Host/Source/SerialBoot/CMakeLists.txt b/Host/Source/SerialBoot/CMakeLists.txt deleted file mode 100644 index 7aea5017..00000000 --- a/Host/Source/SerialBoot/CMakeLists.txt +++ /dev/null @@ -1,82 +0,0 @@ -#**************************************************************************************** -# \file CMakeLists.txt -# \brief CMake descriptor file for SerialBoot command line demonstration program. -# \ingroup SerialBoot -# \internal -#---------------------------------------------------------------------------------------- -# C O P Y R I G H T -#---------------------------------------------------------------------------------------- -# Copyright (c) 2017 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 -#**************************************************************************************** - -# Specify the version being used aswell as the language -cmake_minimum_required(VERSION 2.8) - -# Specify the project name -project(SerialBoot) - -# Set the port directory, which is platform specific -IF(WIN32) - set(PROJECT_PORT_DIR ${PROJECT_SOURCE_DIR}/port/windows) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DPLATFORM_WIN32 -D_CRT_SECURE_NO_WARNINGS") -ELSEIF(UNIX) - set(PROJECT_PORT_DIR ${PROJECT_SOURCE_DIR}/port/linux) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DPLATFORM_LINUX") -ENDIF(WIN32) - -# Build debug version by default -set(CMAKE_BUILD_TYPE "Debug") - -# Set include directories -include_directories("${PROJECT_SOURCE_DIR}" "${PROJECT_PORT_DIR}") - -# Set the output directory -set (PROJECT_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/../../..) - -# Set the output directory for the generic no-config case (e.g. with mingw) -set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_OUTPUT_DIRECTORY} ) -set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_OUTPUT_DIRECTORY} ) -set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_OUTPUT_DIRECTORY} ) -# Set the output directory for multi-config builds (e.g. msvc) -foreach( OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES} ) - string( TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG ) - set( CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${PROJECT_OUTPUT_DIRECTORY} ) - set( CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${PROJECT_OUTPUT_DIRECTORY} ) - set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${PROJECT_OUTPUT_DIRECTORY} ) -endforeach( OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES ) - -# Get header files -file(GLOB_RECURSE INCS "*.h") - -# Add sources -add_executable( - SerialBoot - firmware.c - main.c - srecparser.c - xcploader.c - xcptpuart.c - ${PROJECT_PORT_DIR}/serialport.c - ${PROJECT_PORT_DIR}/timeutil.c - ${INCS} -) - - -#*********************************** end of CMakeLists.txt ****************************** \ No newline at end of file diff --git a/Host/Source/SerialBoot/firmware.c b/Host/Source/SerialBoot/firmware.c deleted file mode 100644 index 1d4e095c..00000000 --- a/Host/Source/SerialBoot/firmware.c +++ /dev/null @@ -1,125 +0,0 @@ -/************************************************************************************//** -* \file firmware.c -* \brief Firmware module source file. -* \ingroup SerialBoot -* \internal -*---------------------------------------------------------------------------------------- -* C O P Y R I G H T -*---------------------------------------------------------------------------------------- -* Copyright (c) 2017 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 /* for NULL declaration */ -#include /* for assertions */ -#include "firmware.h" /* firmware module */ - - -/**************************************************************************************** -* Local data declarations -****************************************************************************************/ -/** \brief Pointer to the firmware parser that is linked. */ -static tFirmwareParser const * parserPtr = NULL; - - -/************************************************************************************//** -** \brief Initializes the firmware module. -** \param parser Pointer to the firmware parser to link. -** \return None. -** -****************************************************************************************/ -void FirmwareInit(tFirmwareParser const * const parser) -{ - /* verify parameters */ - assert(parser != NULL); - - /* link the firmware parser */ - parserPtr = parser; - /* initialize the firmware parser */ - parserPtr->Init(); -} /*** end of FirmwareInit ***/ - - -/************************************************************************************//** -** \brief Uninitializes the firmware module. -** \return None. -** -****************************************************************************************/ -void FirmwareDeinit(void) -{ - /* make sure the parser is linked */ - assert(parserPtr != NULL); - - /* uninitialize the parser */ - parserPtr->Deinit(); - /* unlink the parser */ - parserPtr = NULL; -} /*** end of FirmwareDeinit ***/ - - -/************************************************************************************//** -** \brief Loads the firmware data from the specified firmware file, using the linked -** parser. -** \return True is successful, false otherwise. -** -****************************************************************************************/ -bool FirmwareLoadFromFile(char *firmwareFile) -{ - /* make sure the parser is linked */ - assert(parserPtr != NULL); - /* make sure the filename is valid */ - assert(firmwareFile != NULL); - - return parserPtr->LoadFromFile(firmwareFile); -} /*** end of FirmwareLoadFromFile ***/ - - -/************************************************************************************//** -** \brief Returns the number of firmware segments that were loaded by the parser. -** \return Number of firmware segments. -** -****************************************************************************************/ -uint32_t FirmwareGetSegmentCount(void) -{ - /* make sure the parser is linked */ - assert(parserPtr != NULL); - - return parserPtr->GetSegmentCount(); -} /*** end of FirmwareGetSegmentCount ***/ - - -/************************************************************************************//** -** \brief Obtains a pointer to the firmware segment at the specified index. -** \return Pointer to firmware segment if successful, NULL otherwise. -** -****************************************************************************************/ -const tFirmwareSegment *FirmwareGetSegment(uint32_t segmentIdx) -{ - /* make sure the parser is linked */ - assert(parserPtr != NULL); - - return parserPtr->GetSegment(segmentIdx); -} /*** end of FirmwareGetSegment ***/ - - -/*********************************** end of firmware.c *********************************/ - diff --git a/Host/Source/SerialBoot/firmware.h b/Host/Source/SerialBoot/firmware.h deleted file mode 100644 index a6ff7652..00000000 --- a/Host/Source/SerialBoot/firmware.h +++ /dev/null @@ -1,84 +0,0 @@ -/************************************************************************************//** -* \file firmware.h -* \brief Firmware module header file. -* \ingroup SerialBoot -* \internal -*---------------------------------------------------------------------------------------- -* C O P Y R I G H T -*---------------------------------------------------------------------------------------- -* Copyright (c) 2017 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 FIRMWARE_H -#define FIRMWARE_H - -#ifdef __cplusplus -extern "C" { -#endif - -/**************************************************************************************** -* Include files -****************************************************************************************/ -#include /* for standard integer types */ -#include /* for boolean type */ - - -/**************************************************************************************** -* Type definitions -****************************************************************************************/ -/** \brief Groups information together of a firmware segments. */ -typedef struct t_firmware_segment -{ - uint32_t base; /**< Start memory address of the segment. */ - uint32_t length; /**< Number of data bytes in the segment. */ - uint8_t *data; /**< Pointer to array with the segment's data bytes. */ -} tFirmwareSegment; - -/** \brief Firmware file parser. */ -typedef struct t_firmware_parser -{ - /** \brief Initialization of the file parser. */ - void (*Init) (void); - /** \brief Uninitializes the file parser. */ - void (*Deinit) (void); - /** \brief Extract the firmware segments from the firmware file. */ - bool (*LoadFromFile) (char *firmwareFile); - /** \brief Obtains the number of segments. */ - uint32_t (*GetSegmentCount) (void); - /** \brief Obtains a segment. */ - const tFirmwareSegment * (*GetSegment) (uint32_t segmentIdx); -} tFirmwareParser; - - -/**************************************************************************************** -* Function prototypes -****************************************************************************************/ -void FirmwareInit(tFirmwareParser const * const parser); -void FirmwareDeinit(void); -bool FirmwareLoadFromFile(char *firmwareFile); -uint32_t FirmwareGetSegmentCount(void); -const tFirmwareSegment *FirmwareGetSegment(uint32_t segmentIdx); - -#ifdef __cplusplus -} -#endif - -#endif /* FIRMWARE_H */ -/********************************* end of firmware.h ***********************************/ - diff --git a/Host/Source/SerialBoot/main.c b/Host/Source/SerialBoot/main.c deleted file mode 100644 index fa1d9b89..00000000 --- a/Host/Source/SerialBoot/main.c +++ /dev/null @@ -1,365 +0,0 @@ -/************************************************************************************//** -* \file main.c -* \brief SerialBoot program source file. -* \ingroup SerialBoot -* \internal -*---------------------------------------------------------------------------------------- -* C O P Y R I G H T -*---------------------------------------------------------------------------------------- -* Copyright (c) 2017 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 /* standard I/O functions */ -#include /* for string library */ -#include "xcploader.h" /* XCP loader module */ -#include "xcptpuart.h" /* XCP transport layer for UART */ -#include "firmware.h" /* Firmware module */ -#include "srecparser.h" /* S-record parser */ -#include "timeutil.h" /* for time utilities module */ - - -/**************************************************************************************** -* Macro definitions -****************************************************************************************/ -/* Program return codes. */ -#define RESULT_OK (0) -#define RESULT_COMMANDLINE_ERROR (1) -#define RESULT_FIRMWARE_LOAD_ERROR (2) -#define RESULT_PROGRAM_START_ERROR (3) -#define RESULT_MEMORY_ERASE_ERROR (4) -#define RESULT_PROGRAM_STOP_ERROR (5) -#define RESULT_MEMORY_PROGRAM_ERROR (6) - - -/**************************************************************************************** -* Local data declarations -****************************************************************************************/ -/** \brief The firmware filename that is specified at the command line. */ -static char *firmwareFilename; - -/** \brief XCP loader settings. */ -static tXcpSettings xcpSettings = -{ - .timeoutT1 = 1000, - .timeoutT3 = 2000, - .timeoutT4 = 10000, - .timeoutT5 = 1000, - .timeoutT7 = 2000 -}; - -/** \brief XCP UART transport layer settings. */ -static tXcpTpUartSettings xcpTpUartSettings = -{ - .baudrate = SERIALPORT_BR57600, - .portname = "/dev/ttyS0" -}; - - -/**************************************************************************************** -* Function prototypes -****************************************************************************************/ -static void DisplayProgramInfo(void); -static void DisplayProgramUsage(void); -static bool ParseCommandLine(int argc, char *argv[]); - - -/************************************************************************************//** -** \brief This is the program entry point. -** \param argc Number of program arguments. -** \param argv Array with program arguments. -** \return Program return code. 0 for success, error code otherwise. -** -****************************************************************************************/ -int main(int argc, char *argv[]) -{ - int result = RESULT_OK; - uint32_t fwBaseAddress; - uint32_t fwTotalSize; - uint32_t segmentIdx; - const tFirmwareSegment *segment; - - /* -------------------- Display info ----------------------------------------------- */ - /* inform user about the program */ - DisplayProgramInfo(); - - /* -------------------- Process command line --------------------------------------- */ - /* start out by making sure program was started with the correct parameters */ - if (!ParseCommandLine(argc, argv)) - { - /* parameters invalid. inform user about how this program works */ - DisplayProgramUsage(); - return RESULT_COMMANDLINE_ERROR; - } - - /* -------------------- Initialization --------------------------------------------- */ - /* initialize the XCP loader module using the UART transport layer. */ - XcpLoaderInit(&xcpSettings, XcpTpUartGetTransport(), &xcpTpUartSettings); - /* initialize the firmware module and link the S-recorder parser */ - FirmwareInit(SRecParserGetParser()); - - /* -------------------- Parse the firmware file ------------------------------------ */ - /* attempt to load the firmware file */ - printf("Loading firmware file..."); fflush(stdout); - if (!FirmwareLoadFromFile(firmwareFilename)) - { - /* set error code and abort */ - printf("ERROR\n"); - result = RESULT_FIRMWARE_LOAD_ERROR; - goto finish; - } - printf("OK\n"); - /* determine firmware base address and total size */ - for (segmentIdx=0; segmentIdxbase; - fwTotalSize = segment->length; - } - else - { - /* update */ - if (segment->base < fwBaseAddress) - { - fwBaseAddress = segment->base; - } - fwTotalSize += segment->length; - } - } - /* display some firmware statistics */ - printf("-> Number of segments: %u\n", FirmwareGetSegmentCount()); - printf("-> Base memory address: 0x%08x\n", fwBaseAddress); - printf("-> Total data bytes: %u\n", fwTotalSize); - - /* -------------------- Connect to target ------------------------------------------ */ - printf("Connecting to bootloader..."); fflush(stdout); - if (!XcpLoaderConnect()) - { - /* no response. prompt the user to reset the system */ - printf("TIMEOUT\nReset your microcontroller..."); fflush(stdout); - /* now keep retrying until we get a response */ - while (!XcpLoaderConnect()) - { - /* delay a bit to not pump up the CPU load */ - TimeUtilDelayMs(20); - } - } - printf("OK\n"); - - /* -------------------- Start the programming session ------------------------------ */ - /* attempt to start the programming session */ - printf("Starting programming session..."); fflush(stdout); - if (!XcpLoaderStartProgrammingSession()) - { - /* set error code and abort */ - printf("ERROR\n"); - result = RESULT_PROGRAM_START_ERROR; - goto finish; - } - printf("OK\n"); - - /* -------------------- Erase memory ----------------------------------------------- */ - /* erase each segment one at a time */ - for (segmentIdx=0; segmentIdxlength, segment->base); fflush(stdout); - if (!XcpLoaderClearMemory(segment->base, segment->length)) - { - /* set error code and abort */ - printf("ERROR\n"); - result = RESULT_MEMORY_ERASE_ERROR; - goto finish; - } - printf("OK\n"); - } - - /* -------------------- Program data ----------------------------------------------- */ - /* program each segment one at a time */ - for (segmentIdx=0; segmentIdxlength, segment->base); fflush(stdout); - if (!XcpLoaderProgramData(segment->base, segment->length, segment->data)) - { - /* set error code and abort */ - printf("ERROR\n"); - result = RESULT_MEMORY_PROGRAM_ERROR; - goto finish; - } - printf("OK\n"); - } - - /* -------------------- Stop the programming session ------------------------------- */ - /* attempt to stop the programming session */ - printf("Finishing programming session..."); fflush(stdout); - if (!XcpLoaderStopProgrammingSession()) - { - /* set error code and abort */ - printf("ERROR\n"); - result = RESULT_PROGRAM_STOP_ERROR; - goto finish; - } - printf("OK\n"); - - /* -------------------- Cleanup ---------------------------------------------------- */ -finish: - /* uninitialize the firmware module */ - FirmwareDeinit(); - /* uninitialize the XCP loader module. note that this automatically disconnects the - * slave, if connected, by requesting it to perform a reset. - */ - XcpLoaderDeinit(); - /* give result back */ - return result; -} /*** end of main ***/ - - -/************************************************************************************//** -** \brief Outputs information to the user about this program. -** \return none. -** -****************************************************************************************/ -static void DisplayProgramInfo(void) -{ - printf("-------------------------------------------------------------------------\n"); - printf("SerialBoot version 2.00. Performs firmware updates via the serial port\n"); - printf("for a microcontroller based system that runs the OpenBLT bootloader.\n\n"); - printf("Copyright (c) by Feaser http://www.feaser.com\n"); - printf("-------------------------------------------------------------------------\n"); -} /*** end of DisplayProgramInfo ***/ - - -/************************************************************************************//** -** \brief Outputs information to the user about how to use this program. -** \return none. -** -****************************************************************************************/ -static void DisplayProgramUsage(void) -{ - printf("Usage: SerialBoot -d[device] -b[baudrate] [s-record file]\n\n"); -#ifdef PLATFORM_WIN32 - printf("Example: SerialBoot -dCOM4 -b57600 myfirmware.s19\n"); - printf(" -> Connects to COM4, configures a communication speed of 57600\n"); -#else - printf("Example: SerialBoot -d/dev/ttyS0 -b57600 myfirmware.s19\n"); - printf(" -> Connects to ttyS0, configures a communication speed of 57600\n"); -#endif - printf(" bits/second and programs the myfirmware.s19 file in non-\n"); - printf(" volatile memory of the microcontroller using OpenBLT.\n"); - printf(" Supported baudrates are: 9600, 19200, 38400, 57600 and\n"); - printf(" 115200 bits/second.\n"); - printf("-------------------------------------------------------------------------\n"); -} /*** end of DisplayProgramUsage ***/ - - -/************************************************************************************//** -** \brief Parses the command line arguments. A fixed amount of arguments is expected. -** The program should be called as: -** SerialBoot -d[device] -b[baudrate] [s-record file] -** \param argc Number of program parameters. -** \param argv array to program parameter strings. -** \return True if successful, false otherwise. -** -****************************************************************************************/ -static bool ParseCommandLine(int argc, char *argv[]) -{ - uint8_t paramIdx; - bool firmwareFileFound = false; - uint32_t baudrateValue; - - /* make sure that enough arguments were specified. this program needs at least 2. the - * first one is always the program name and the second one is the s-record file. - */ - if (argc < 2) - { - return false; - } - - /* loop through all the command line parameters, just skip the 1st one because this - * is the name of the program, which we are not interested in. - */ - for (paramIdx=1; paramIdx /* for NULL declaration */ -#include /* for assertions */ -#include /* UNIX standard functions */ -#include /* POSIX terminal control */ -#include /* file control definitions */ -#include /* system I/O control */ -#include "serialport.h" /* serial port module */ - - -/**************************************************************************************** -* Macro definitions -****************************************************************************************/ -/** \brief Invalid serial port device handle. */ -#define SERIALPORT_INVALID_HANDLE (-1) - - -/**************************************************************************************** -* Local data declarations -****************************************************************************************/ -static int32_t portHandle = SERIALPORT_INVALID_HANDLE; - - -/**************************************************************************************** -* Local constant declarations -****************************************************************************************/ -/** \brief Lookup table for converting this module's generic baudrate value to a value - * supported by the low level interface. - */ -static const speed_t baudrateLookup[] = -{ - B9600, /**< Index 0 = SERIALPORT_BR9600 */ - B19200, /**< Index 1 = SERIALPORT_BR19200 */ - B38400, /**< Index 2 = SERIALPORT_BR38400 */ - B57600, /**< Index 3 = SERIALPORT_BR57600 */ - B115200 /**< Index 4 = SERIALPORT_BR115200 */ -}; - - -/************************************************************************************//** -** \brief Opens the connection with the serial port configured as 8,N,1 and no flow -** control. -** \param portname The name of the serial port to open, i.e. /dev/ttyUSB0. -** \param baudrate The desired communication speed. -** \return True if successful, false otherwise. -** -****************************************************************************************/ -bool SerialPortOpen(char *portname, tSerialPortBaudrate baudrate) -{ - struct termios options; - int32_t iFlags; - - /* check parameters */ - assert(portname != NULL); - - /* open the port */ - portHandle = open(portname, O_RDWR | O_NOCTTY | O_NDELAY); - /* check the result */ - if (portHandle == SERIALPORT_INVALID_HANDLE) - { - return false; - } - /* configure the device to block during read operations */ - if (fcntl(portHandle, F_SETFL, 0) == -1) - { - SerialPortClose(); - return false; - } - /* get the current options for the port */ - if (tcgetattr(portHandle, &options) == -1) - { - SerialPortClose(); - return false; - } - /* configure the baudrate */ - if (cfsetispeed(&options, baudrateLookup[baudrate]) == -1) - { - SerialPortClose(); - return false; - } - if (cfsetospeed(&options, baudrateLookup[baudrate]) == -1) - { - SerialPortClose(); - return false; - } - - /* input modes - clear indicated ones giving: no break, no CR to NL, - * no parity check, no strip char, no start/stop output (sic) control - */ - options.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); - /* output modes - clear giving: no post processing such as NL to CR+NL */ - options.c_oflag &= ~(OPOST); - /* control modes - set 8 bit chars */ - options.c_cflag |= (CS8); - /* local modes - clear giving: echoing off, canonical off (no erase with - * backspace, ^U,...), no extended functions, no signal chars (^Z,^C) - */ - options.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG); - /* configure timeouts */ - options.c_cc[VMIN] = 0; - options.c_cc[VTIME] = 1; /* in units of 1/10th of a second */ - /* set the new options for the port */ - if (tcsetattr(portHandle, TCSAFLUSH, &options) == -1) - { - SerialPortClose(); - return false; - } - /* turn on DTR */ - iFlags = TIOCM_DTR; - ioctl(portHandle, TIOCMBIS, &iFlags); - /* success */ - return true; -} /*** end of SerialPortOpen ***/ - - -/************************************************************************************//** -** \brief Closes the connection with the serial port. -** \return None. -** -****************************************************************************************/ -void SerialPortClose(void) -{ - /* close the port handle if valid */ - if (portHandle != SERIALPORT_INVALID_HANDLE) - { - close(portHandle); - } - /* invalidate handle */ - portHandle = SERIALPORT_INVALID_HANDLE; -} /*** end of SerialPortClose ***/ - - -/************************************************************************************//** -** \brief Writes data to the serial port. -** \param data Pointer to byte array with data to write. -** \param length Number of bytes to write. -** \return True if successful, false otherwise. -** -****************************************************************************************/ -bool SerialPortWrite(uint8_t *data, uint32_t length) -{ - size_t bytesWritten; - - /* check parameters */ - assert(data != NULL); - assert(length > 0); - - /* submit the data for sending */ - bytesWritten = write(portHandle, data, length); - /* check and return the result */ - return (bytesWritten == length); -} /*** end of SerialPortWrite ***/ - - -/************************************************************************************//** -** \brief Reads data from the serial port in a blocking manner. -** \param data Pointer to byte array to store read data. -** \param length Number of bytes to read. -** \return True if successful, false otherwise. -** -****************************************************************************************/ -bool SerialPortRead(uint8_t *data, uint32_t length) -{ - size_t bytesRead; - - /* check parameters */ - assert(data != NULL); - assert(length > 0); - - /* attempt to read the requested data */ - bytesRead = read(portHandle, data, length); - /* check and return the result */ - return (bytesRead == length); -} /*** end of SerialPortRead ***/ - - -/*********************************** end of serialport.c *******************************/ - diff --git a/Host/Source/SerialBoot/port/linux/timeutil.c b/Host/Source/SerialBoot/port/linux/timeutil.c deleted file mode 100644 index 7b0d2baa..00000000 --- a/Host/Source/SerialBoot/port/linux/timeutil.c +++ /dev/null @@ -1,69 +0,0 @@ -/************************************************************************************//** -* \file port\linux\timeutil.c -* \brief Time utility source file. -* \ingroup SerialBoot -* \internal -*---------------------------------------------------------------------------------------- -* C O P Y R I G H T -*---------------------------------------------------------------------------------------- -* Copyright (c) 2017 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 /* for NULL declaration */ -#include /* UNIX standard functions */ -#include /* time definitions */ -#include "timeutil.h" /* for time utilities module */ - - -/************************************************************************************//** -** \brief Get the system time in milliseconds. -** \return Time in milliseconds. -** -****************************************************************************************/ -uint32_t TimeUtilGetSystemTimeMs(void) -{ - struct timeval tv; - - if (gettimeofday(&tv, NULL) != 0) - { - return 0; - } - - return (uint32_t)((tv.tv_sec * 1000ul) + (tv.tv_usec / 1000ul)); -} /*** end of XcpTransportClose ***/ - - -/************************************************************************************//** -** \brief Performs a delay of the specified amount of milliseconds. -** \param delay Delay time in milliseconds. -** \return none. -** -****************************************************************************************/ -void TimeUtilDelayMs(uint16_t delay) -{ - usleep(1000 * delay); -} /*** end of TimeUtilDelayMs **/ - - -/*********************************** end of timeutil.c *********************************/ - diff --git a/Host/Source/SerialBoot/port/windows/serialport.c b/Host/Source/SerialBoot/port/windows/serialport.c deleted file mode 100644 index bc2f1f9c..00000000 --- a/Host/Source/SerialBoot/port/windows/serialport.c +++ /dev/null @@ -1,260 +0,0 @@ -/************************************************************************************//** -* \file port\windows\serialport.c -* \brief Serial port source file. -* \ingroup SerialBoot -* \internal -*---------------------------------------------------------------------------------------- -* C O P Y R I G H T -*---------------------------------------------------------------------------------------- -* Copyright (c) 2017 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 /* for NULL declaration */ -#include /* for windows library */ -#include /* for assertions */ -#include "serialport.h" /* serial port module */ - - -/**************************************************************************************** -* Macro definitions -****************************************************************************************/ -#define UART_TX_BUFFER_SIZE (1024) /**< transmission buffer size */ -#define UART_RX_BUFFER_SIZE (1024) /**< reception buffer size */ - - -/**************************************************************************************** -* Local data declarations -****************************************************************************************/ -static HANDLE hUart = INVALID_HANDLE_VALUE; - - -/**************************************************************************************** -* Function prototypes -****************************************************************************************/ -static uint32_t SerialConvertBaudrate(tSerialPortBaudrate baudrate); - - -/************************************************************************************//** -** \brief Opens the connection with the serial port configured as 8,N,1 and no flow -** control. -** \param portname The name of the serial port to open, i.e. COM4. -** \param baudrate The desired communication speed. -** \return True if successful, false otherwise. -** -****************************************************************************************/ -bool SerialPortOpen(char *portname, tSerialPortBaudrate baudrate) -{ - COMMTIMEOUTS timeouts = { 0 }; - DCB dcbSerialParams = { 0 }; - char portStr[64] = "\\\\.\\\0"; - - /* check parameters */ - assert(portname != NULL); - - /* construct the COM port name as a string */ - strcat_s(portStr, 59, portname); - - /* obtain access to the COM port */ - hUart = CreateFile(portStr, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, 0); - - /* validate COM port handle */ - if (hUart == INVALID_HANDLE_VALUE) - { - return false; - } - - /* get current COM port configuration */ - dcbSerialParams.DCBlength = sizeof(dcbSerialParams); - if (!GetCommState(hUart, &dcbSerialParams)) - { - CloseHandle(hUart); - return false; - } - - /* configure the baudrate and 8,n,1 */ - dcbSerialParams.BaudRate = SerialConvertBaudrate(baudrate); - dcbSerialParams.ByteSize = 8; - dcbSerialParams.StopBits = ONESTOPBIT; - dcbSerialParams.Parity = NOPARITY; - dcbSerialParams.fOutX = FALSE; - dcbSerialParams.fInX = FALSE; - dcbSerialParams.fRtsControl = RTS_CONTROL_DISABLE; - dcbSerialParams.fDtrControl = DTR_CONTROL_ENABLE; - - if (!SetCommState(hUart, &dcbSerialParams)) - { - CloseHandle(hUart); - return false; - } - - /* set communication timeout parameters */ - timeouts.ReadIntervalTimeout = 0; - timeouts.ReadTotalTimeoutConstant = 0; - timeouts.ReadTotalTimeoutMultiplier = 100; - timeouts.WriteTotalTimeoutConstant = 0; - timeouts.WriteTotalTimeoutMultiplier = 100; - - if (!SetCommTimeouts(hUart, &timeouts)) - { - CloseHandle(hUart); - return false; - } - - /* set transmit and receive buffer sizes */ - if (!SetupComm(hUart, UART_RX_BUFFER_SIZE, UART_TX_BUFFER_SIZE)) - { - CloseHandle(hUart); - return false; - } - - /* empty the transmit and receive buffers */ - if (!FlushFileBuffers(hUart)) - { - CloseHandle(hUart); - return false; - } - /* successfully connected to the serial device */ - return true; -} /*** end of SerialPortOpen ***/ - - -/************************************************************************************//** -** \brief Closes the connection with the serial port. -** \return None. -** -****************************************************************************************/ -void SerialPortClose(void) -{ - /* close the COM port handle if valid */ - if (hUart != INVALID_HANDLE_VALUE) - { - CloseHandle(hUart); - } - - /* set handles to invalid */ - hUart = INVALID_HANDLE_VALUE; -} /*** end of SerialPortClose ***/ - - -/************************************************************************************//** -** \brief Writes data to the serial port. -** \param data Pointer to byte array with data to write. -** \param length Number of bytes to write. -** \return True if successful, false otherwise. -** -****************************************************************************************/ -bool SerialPortWrite(uint8_t *data, uint32_t length) -{ - uint32_t dwWritten = 0; - - /* check parameters */ - assert(data != NULL); - assert(length > 0); - - /* submit the data for transmission with the serial port */ - if (!WriteFile(hUart, data, length, &dwWritten, NULL)) - { - return false; - } - /* double check that all bytes were actually transmitted */ - if (dwWritten != length) - { - return false; - } - - /* success */ - return true; -} /*** end of SerialPortWrite ***/ - - -/************************************************************************************//** -** \brief Reads data from the serial port in a blocking manner. -** \param data Pointer to byte array to store read data. -** \param length Number of bytes to read. -** \return True if successful, false otherwise. -** -****************************************************************************************/ -bool SerialPortRead(uint8_t *data, uint32_t length) -{ - uint32_t dwRead = 0; - - /* check parameters */ - assert(data != NULL); - assert(length > 0); - - /* attempt to read data from the serial port */ - if (!ReadFile(hUart, data, length, &dwRead, NULL)) - { - return false; - } - /* double check that all bytes were actually read */ - if (dwRead != length) - { - return false; - } - - /* success */ - return true; -} /*** end of SerialPortRead ***/ - - -/************************************************************************************//** -** \brief Opens the connection with the serial port configured as 8,N,1 and no flow -** control. -** \param portname The name of the serial port to open, i.e. COM4. -** \param baudrate The desired communication speed. -** \return True if successful, false otherwise. -** -****************************************************************************************/ -static uint32_t SerialConvertBaudrate(tSerialPortBaudrate baudrate) -{ - uint32_t result; - - switch (baudrate) - { - case SERIALPORT_BR9600: - result = CBR_9600; - break; - case SERIALPORT_BR19200: - result = CBR_19200; - break; - case SERIALPORT_BR38400: - result = CBR_38400; - break; - case SERIALPORT_BR57600: - result = CBR_57600; - break; - case SERIALPORT_BR115200: - result = CBR_115200; - break; - default: - result = CBR_9600; - break; - } - return result; -} /*** end of SerialConvertBaudrate ***/ - - -/*********************************** end of serialport.c *******************************/ - diff --git a/Host/Source/SerialBoot/port/windows/timeutil.c b/Host/Source/SerialBoot/port/windows/timeutil.c deleted file mode 100644 index 714b761c..00000000 --- a/Host/Source/SerialBoot/port/windows/timeutil.c +++ /dev/null @@ -1,60 +0,0 @@ -/************************************************************************************//** -* \file port\windows\timeutil.c -* \brief Time utility source file. -* \ingroup SerialBoot -* \internal -*---------------------------------------------------------------------------------------- -* C O P Y R I G H T -*---------------------------------------------------------------------------------------- -* Copyright (c) 2017 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 /* for windows library */ -#include "timeutil.h" /* for time utilities module */ - - -/************************************************************************************//** -** \brief Get the system time in milliseconds. -** \return Time in milliseconds. -** -****************************************************************************************/ -uint32_t TimeUtilGetSystemTimeMs(void) -{ - return GetTickCount(); -} /*** end of XcpTransportClose ***/ - - -/************************************************************************************//** -** \brief Performs a delay of the specified amount of milliseconds. -** \param delay Delay time in milliseconds. -** \return none. -** -****************************************************************************************/ -void TimeUtilDelayMs(uint16_t delay) -{ - Sleep(delay); -} /*** end of TimeUtilDelayMs **/ - - -/*********************************** end of timeutil.c *********************************/ - diff --git a/Host/Source/SerialBoot/serialport.h b/Host/Source/SerialBoot/serialport.h deleted file mode 100644 index e82ab8dd..00000000 --- a/Host/Source/SerialBoot/serialport.h +++ /dev/null @@ -1,70 +0,0 @@ -/************************************************************************************//** -* \file serialport.h -* \brief Serial port header file. -* \ingroup SerialBoot -* \internal -*---------------------------------------------------------------------------------------- -* C O P Y R I G H T -*---------------------------------------------------------------------------------------- -* Copyright (c) 2017 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 SERIALPORT_H -#define SERIALPORT_H - -#ifdef __cplusplus -extern "C" { -#endif - -/**************************************************************************************** -* Include files -****************************************************************************************/ -#include /* for standard integer types */ -#include /* for boolean type */ - - -/**************************************************************************************** -* Typde definitions -****************************************************************************************/ -/** \brief Enumaration of the supported baudrates. */ -typedef enum -{ - SERIALPORT_BR9600 = 0, /**< 9600 bits/sec */ - SERIALPORT_BR19200 = 1, /**< 19200 bits/sec */ - SERIALPORT_BR38400 = 2, /**< 38400 bits/sec */ - SERIALPORT_BR57600 = 3, /**< 57600 bits/sec */ - SERIALPORT_BR115200 = 4 /**< 115200 bits/sec */ -} tSerialPortBaudrate; - - -/**************************************************************************************** -* Function prototypes -****************************************************************************************/ -bool SerialPortOpen(char *portname, tSerialPortBaudrate baudrate); -void SerialPortClose(void); -bool SerialPortWrite(uint8_t *data, uint32_t length); -bool SerialPortRead(uint8_t *data, uint32_t length); - -#ifdef __cplusplus -} -#endif - -#endif /* SERIALPORT_H */ -/********************************* end of serialport.h *********************************/ - diff --git a/Host/Source/SerialBoot/srecparser.c b/Host/Source/SerialBoot/srecparser.c deleted file mode 100644 index d0e089cb..00000000 --- a/Host/Source/SerialBoot/srecparser.c +++ /dev/null @@ -1,751 +0,0 @@ -/************************************************************************************//** -* \file srecparser.c -* \brief S-record parser source file. -* \ingroup SerialBoot -* \internal -*---------------------------------------------------------------------------------------- -* C O P Y R I G H T -*---------------------------------------------------------------------------------------- -* Copyright (c) 2017 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 /* for NULL declaration */ -#include /* for standard I/O library */ -#include /* for standard library */ -#include /* for string library */ -#include /* for character testing */ -#include /* for assertions */ -#include "srecparser.h" /* S-record parser */ - - -/**************************************************************************************** -* Macro definitions -****************************************************************************************/ -/** \brief Maximum number of characters that can be on a line in the firmware file. */ -#define SRECORD_MAX_CHARS_PER_LINE (512) - -/** \brief Maximum number of data bytes that can be on a line in the firmware file - * (S-record). - */ -#define SRECORD_MAX_DATA_BYTES_PER_LINE (SRECORD_MAX_CHARS_PER_LINE/2) - - -/**************************************************************************************** -* Type definitions -****************************************************************************************/ -/** \brief Layout of a firmware segment node in the linked list. */ -typedef struct t_segment_node -{ - /** \brief The firmware segment stored in this node. */ - tFirmwareSegment segment; - /** \brief Pointer to the next node, or NULL if it is the last one. */ - struct t_segment_node *next; -} tSegmentNode; - -/** \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 */ -} tSrecordLineType; - -/** \brief Structure type for grouping the parsing results of an S-record line. */ -typedef struct -{ - uint8_t data[SRECORD_MAX_DATA_BYTES_PER_LINE]; /**< array for S1,S2 or S3 data bytes */ - uint32_t address; /**< address on S1,S2 or S3 line */ - uint16_t length; /**< number of bytes written to array */ -} tSrecordLineParseResults; - - -/**************************************************************************************** -* Function prototypes -****************************************************************************************/ -static void SRecParserInit(void); -static void SRecParserDeinit(void); -static bool SRecParserLoadFromFile(char *firmwareFile); -static uint32_t SRecParserGetSegmentCount(void); -static const tFirmwareSegment *SRecParserGetSegment(uint32_t segmentIdx); -static void SRecParserSegmentListInit(void); -static void SRecParserSegmentListDeinit(void); -static tSegmentNode *SRecParserSegmentListCreateNode(void); -static uint32_t SRecParserSegmentListGetNodeCount(void); -static tSegmentNode *SRecParserSegmentListGetNode(uint32_t nodeIdx); -/* S-record utility functions */ -static bool SrecordParseNextDataLine(FILE* srecordHandle, tSrecordLineParseResults *parseResults); -static tSrecordLineType SrecordGetLineType(const char *line); -static bool SrecordVerifyChecksum(const char *line); -static uint8_t SrecordHexStringToByte(const char *hexstring); -static bool SrecordReadLine(FILE *srecordHandle, char *line); - - - -/**************************************************************************************** -* Local constant declarations -****************************************************************************************/ -/** \brief XCP transport structure filled with CAN specifics. */ -static const tFirmwareParser srecParser = -{ - SRecParserInit, - SRecParserDeinit, - SRecParserLoadFromFile, - SRecParserGetSegmentCount, - SRecParserGetSegment -}; - - -/**************************************************************************************** -* Local data declarations -****************************************************************************************/ -/** \brief Linked list with firmware segments. */ -static tSegmentNode *segmentList; - - -/***********************************************************************************//** -** \brief Obtains a pointer to the parser structure, so that it can be linked to the -** firmware loader module. -** \return Pointer to firmware parser structure. -** -****************************************************************************************/ -tFirmwareParser const * const SRecParserGetParser(void) -{ - return &srecParser; -} /*** end of SRecParserGetParser ***/ - - -/************************************************************************************//** -** \brief Initializes the parser. -** \return None. -** -****************************************************************************************/ -static void SRecParserInit(void) -{ - /* initialize the segment list */ - SRecParserSegmentListInit(); -} /*** end of SRecParserInit ***/ - - -/************************************************************************************//** -** \brief Uninitializes the parser. -** \return None. -** -****************************************************************************************/ -static void SRecParserDeinit(void) -{ - /* uninitialize the segment list */ - SRecParserSegmentListDeinit(); -} /*** end of SRecParserDeinit ***/ - - -/************************************************************************************//** -** \brief Parses the data in the specified firmware file into firmware segments that -** are stored internally in this module. -** \return True is successful, false otherwise. -** -****************************************************************************************/ -static bool SRecParserLoadFromFile(char *firmwareFile) -{ - FILE *fp; - char line[SRECORD_MAX_CHARS_PER_LINE]; - tSrecordLineParseResults lineResults; - tSegmentNode *node; - uint32_t nodeIdx; - bool matchFound; - uint32_t byteIdx; - uint32_t byteOffset; - - /* verify parameters */ - assert(firmwareFile != NULL); - - /* open the file for reading */ - fp = fopen(firmwareFile, "r"); - if (fp == NULL) - { - /* could not open the file */ - return false; - } - /* start at the beginning of the file */ - rewind(fp); - - /* -------------------------- file type validation --------------------------------- */ - /* validate S-record file. all lines should be formatted as S-records. read the first - * one to check this. - */ - if (!SrecordReadLine(fp, line)) - { - /* could not read a line. file must be empty */ - fclose(fp); - return false; - } - /* check if the line starts with the 'S' character, followed by a digit */ - if ( (toupper(line[0]) != 'S') || (isdigit(line[1]) == 0) ) - { - fclose(fp); - return false; - } - - /* -------------------------- extract segment info --------------------------------- */ - /* start at the beginning of the file */ - rewind(fp); - - /* loop through all S-records with program data to obtain segment info */ - while (SrecordParseNextDataLine(fp, &lineResults)) - { - /* reset flag that indicates that the line data was matched to an existing segment */ - matchFound = false; - /* loop through all segment nodes */ - for (nodeIdx=0; nodeIdx < SRecParserSegmentListGetNodeCount(); nodeIdx++) - { - /* get node access */ - node = SRecParserSegmentListGetNode(nodeIdx); - - /* does the line data fit at the start of this node's segment? */ - if ((lineResults.address + lineResults.length) == node->segment.base) - { - /* update the node's segment */ - node->segment.base -= lineResults.length; - node->segment.length += lineResults.length; - /* match found so continue with the next line */ - matchFound = true; - break; - } - /* does the line data fit at the end of this node's segment? */ - else if (lineResults.address == (node->segment.base + node->segment.length)) - { - /* update the node's segment */ - node->segment.length += lineResults.length; - /* match found so continue with the next line */ - matchFound = true; - break; - } - } - /* check if the line data was matched and added to an existing segment */ - if (!matchFound) - { - /* create a new segment */ - node = SRecParserSegmentListCreateNode(); - node->segment.base = lineResults.address; - node->segment.length = lineResults.length; - } - } - - /* -------------------------- allocate data memory --------------------------------- */ - /* loop through all segment nodes */ - for (nodeIdx=0; nodeIdx < SRecParserSegmentListGetNodeCount(); nodeIdx++) - { - /* get node access */ - node = SRecParserSegmentListGetNode(nodeIdx); - /* sanity check */ - assert(node->segment.length > 0); - /* allocate data */ - node->segment.data = malloc(node->segment.length); - /* check results */ - if (node->segment.data == NULL) - { - fclose(fp); - return false; - } - } - - /* -------------------------- extract segment data --------------------------------- */ - /* start at the beginning of the file */ - rewind(fp); - - /* loop through all S-records with program data to obtain segment info */ - while (SrecordParseNextDataLine(fp, &lineResults)) - { - /* loop through all segment nodes */ - for (nodeIdx=0; nodeIdx < SRecParserSegmentListGetNodeCount(); nodeIdx++) - { - /* get node access */ - node = SRecParserSegmentListGetNode(nodeIdx); - /* does the line data belong in this segment? */ - if ( (lineResults.address >= node->segment.base) && \ - ((lineResults.address+lineResults.length) <= (node->segment.base+node->segment.length)) ) - { - /* determine offset of the line data into the segment */ - byteOffset = lineResults.address - node->segment.base; - /* store bytes in this segment */ - for (byteIdx=0; byteIdxsegment.data[byteOffset + byteIdx] = lineResults.data[byteIdx]; - } - /* line data stored, so continue with the next S-record */ - break; - } - } - } - - /* close the file */ - fclose(fp); - /* s-record successfully loaded and parsed */ - return true; -} /*** end of SRecParserLoadFromFile ***/ - - -/************************************************************************************//** -** \brief Returns the number of firmware segments that were loaded by this parser. -** \return Number of firmware segments. -** -****************************************************************************************/ -static uint32_t SRecParserGetSegmentCount(void) -{ - return SRecParserSegmentListGetNodeCount(); -} /*** end of SRecParserGetSegmentCount ***/ - - -/************************************************************************************//** -** \brief Obtains a pointer to the firmware segment at the specified index. -** \return Pointer to firmware segment. -** -****************************************************************************************/ -static const tFirmwareSegment *SRecParserGetSegment(uint32_t segmentIdx) -{ - /* validate the parameter */ - assert(segmentIdx < SRecParserSegmentListGetNodeCount()); - - return &(SRecParserSegmentListGetNode(segmentIdx)->segment); -} /*** end of SRecParserGetSegment ***/ - - -/************************************************************************************//** -** \brief Initializes the linked list with firmware segments. -** \return None. -** -****************************************************************************************/ -static void SRecParserSegmentListInit(void) -{ - segmentList = NULL; -} /*** end of SRecParserSegmentListInit ***/ - - -/************************************************************************************//** -** \brief Uninitializes the linked list with firmware segments. -** \return None. -** -****************************************************************************************/ -static void SRecParserSegmentListDeinit(void) -{ - tSegmentNode *currentNode; - tSegmentNode *nodeToFree; - - /* free all nodes */ - if (segmentList != NULL) - { - currentNode = segmentList; - do - { - /* store pointer to the node that should be released for later usage */ - nodeToFree = currentNode; - /* move to the next node before freeing it */ - currentNode = currentNode->next; - /* sanity check */ - assert(nodeToFree != NULL); - /* free the node */ - if (nodeToFree->segment.data != NULL) - { - free(nodeToFree->segment.data); - } - free(nodeToFree); - } - while(currentNode != NULL); - } -} /*** end of SRecParserSegmentListDeinit ***/ - - -/************************************************************************************//** -** \brief Creates a new node in the linked list with firmware segments. -** \return Pointer to the new node. -** -****************************************************************************************/ -static tSegmentNode *SRecParserSegmentListCreateNode(void) -{ - tSegmentNode *newNode; - tSegmentNode *currentNode; - - /* allocate memory for the node */ - newNode = malloc(sizeof(tSegmentNode)); - assert(newNode != NULL); - - /* initialize the node */ - newNode->next = NULL; - newNode->segment.base = 0x00000000; - newNode->segment.length = 0; - newNode->segment.data = NULL; - - /* add the first node if the list is empty */ - if (segmentList == NULL) - { - segmentList = newNode; - } - /* add the node to the end of the list */ - else - { - /* find last entry in to list */ - currentNode = segmentList; - while(currentNode->next != NULL) - { - currentNode = currentNode->next; - } - /* add the now */ - currentNode->next = newNode; - } - - return newNode; -} /*** end of SRecParserSegmentListCreateNode ***/ - - -/************************************************************************************//** -** \brief Obtains the number of nodes in the linked list with firmware segments. -** \return Number of nodes. -** -****************************************************************************************/ -static uint32_t SRecParserSegmentListGetNodeCount(void) -{ - tSegmentNode *currentNode; - uint32_t nodeCount = 0; - - /* iterate over all nodes to determine to total count */ - if (segmentList != NULL) - { - currentNode = segmentList; - do - { - nodeCount++; - currentNode = currentNode->next; - } - while(currentNode != NULL); - } - - return nodeCount; -} /*** end of SRecParserSegmentListGetNodeCount ***/ - - -/************************************************************************************//** -** \brief Obtains the node at the specified index from the linked list with firmware -** segments. -** \return Pointer to the node. -** -****************************************************************************************/ -static tSegmentNode *SRecParserSegmentListGetNode(uint32_t nodeIdx) -{ - tSegmentNode *currentNode = NULL; - uint32_t currentIdx = 0; - - /* validate the parameter */ - assert(nodeIdx < SRecParserSegmentListGetNodeCount()); - - /* iterate until the specified index is found */ - currentNode = segmentList; - for (currentIdx=0; currentIdxnext; - } - - return currentNode; -} /*** end of SRecParserSegmentListGetNode ***/ - - -/************************************************************************************//** -** \brief Reads the next S-record with program data, parses it and returns the -** results. -** \param srecordHandle The S-record file handle. It is returned by SrecordOpen. -** \param parseResults Pointer to where the parse results should be stored. -** \return SB_TRUE is valid parse results were stored. SB_FALSE in case of end-of- -** file. -** -****************************************************************************************/ -static bool SrecordParseNextDataLine(FILE* srecordHandle, tSrecordLineParseResults *parseResults) -{ - char line[SRECORD_MAX_CHARS_PER_LINE]; - bool data_line_found = false; - tSrecordLineType lineType; - uint16_t bytes_on_line; - uint16_t i; - char *linePtr; - - /* first set the length paramter to 0 */ - parseResults->length = 0; - - while (!data_line_found) - { - /* read the next line from the file */ - if (!SrecordReadLine(srecordHandle, line)) - { - /* end-of-file encountered */ - return false; - } - /* we now have a line. check if it is a S-record data line */ - lineType = SrecordGetLineType(line); - if (lineType != LINE_TYPE_UNSUPPORTED) - { - /* check if the checksum on the line is correct */ - if (SrecordVerifyChecksum(line)) - { - /* found a valid line that can be parsed. loop will stop */ - data_line_found = true; - break; - } - } - } - - /* still here so we have a valid S-record data line. start parsing */ - linePtr = &line[0]; - /* 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 */ - linePtr += 2; - /* read out the number of byte values that follow on the line */ - bytes_on_line = SrecordHexStringToByte(linePtr); - /* read out the 16-bit address */ - linePtr += 2; - parseResults->address = SrecordHexStringToByte(linePtr) << 8; - linePtr += 2; - parseResults->address += SrecordHexStringToByte(linePtr); - /* adjust pointer to point to the first data byte after the address */ - linePtr += 2; - /* determine how many data bytes are on the line */ - parseResults->length = bytes_on_line - 3; /* -2 bytes address, -1 byte checksum */ - /* read and store data bytes if requested */ - for (i=0; ilength; i++) - { - parseResults->data[i] = SrecordHexStringToByte(linePtr); - linePtr += 2; - } - break; - - /* ---------------------------- S2 line type ------------------------------------- */ - case LINE_TYPE_S2: - /* adjust pointer to point to byte count value */ - linePtr += 2; - /* read out the number of byte values that follow on the line */ - bytes_on_line = SrecordHexStringToByte(linePtr); - /* read out the 32-bit address */ - linePtr += 2; - parseResults->address = SrecordHexStringToByte(linePtr) << 16; - linePtr += 2; - parseResults->address += SrecordHexStringToByte(linePtr) << 8; - linePtr += 2; - parseResults->address += SrecordHexStringToByte(linePtr); - /* adjust pointer to point to the first data byte after the address */ - linePtr += 2; - /* determine how many data bytes are on the line */ - parseResults->length = bytes_on_line - 4; /* -3 bytes address, -1 byte checksum */ - /* read and store data bytes if requested */ - for (i=0; ilength; i++) - { - parseResults->data[i] = SrecordHexStringToByte(linePtr); - linePtr += 2; - } - break; - - /* ---------------------------- S3 line type ------------------------------------- */ - case LINE_TYPE_S3: - /* adjust pointer to point to byte count value */ - linePtr += 2; - /* read out the number of byte values that follow on the line */ - bytes_on_line = SrecordHexStringToByte(linePtr); - /* read out the 32-bit address */ - linePtr += 2; - parseResults->address = SrecordHexStringToByte(linePtr) << 24; - linePtr += 2; - parseResults->address += SrecordHexStringToByte(linePtr) << 16; - linePtr += 2; - parseResults->address += SrecordHexStringToByte(linePtr) << 8; - linePtr += 2; - parseResults->address += SrecordHexStringToByte(linePtr); - /* adjust pointer to point to the first data byte after the address */ - linePtr += 2; - /* determine how many data bytes are on the line */ - parseResults->length = bytes_on_line - 5; /* -4 bytes address, -1 byte checksum */ - /* read and store data bytes if requested */ - for (i=0; ilength; i++) - { - parseResults->data[i] = SrecordHexStringToByte(linePtr); - linePtr += 2; - } - break; - - default: - /* will not happen */ - break; - } - - /* parsing all done */ - return true; -} /*** end of SrecordParseNextDataLine ***/ - - -/************************************************************************************//** -** \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. -** -****************************************************************************************/ -static tSrecordLineType SrecordGetLineType(const char *line) -{ - /* check if the line starts with the 'S' character, followed by a digit */ - if ( (toupper(line[0]) != 'S') || (isdigit(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 SrecordGetLineType ***/ - - -/************************************************************************************//** -** \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 SB_TRUE if the checksum is correct, SB_FALSE otherwise. -** -****************************************************************************************/ -static bool SrecordVerifyChecksum(const char *line) -{ - uint16_t bytes_on_line; - uint8_t 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 = SrecordHexStringToByte(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 += SrecordHexStringToByte(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 != SrecordHexStringToByte(line)) - { - /* checksum incorrect */ - return false; - } - /* still here so the checksum was correct */ - return true; -} /*** end of SrecordVerifyChecksum ***/ - - -/************************************************************************************//** -** \brief Helper function to convert a sequence of 2 characters that represent -** a hexadecimal value to the actual byte value. -** Example: SrecordHexStringToByte("2f") --> returns 47. -** \param hexstring String beginning with 2 characters that represent a hexa- -** decimal value. -** \return The resulting byte value. -** -****************************************************************************************/ -static uint8_t SrecordHexStringToByte(const char *hexstring) -{ - uint8_t result = 0; - char c; - uint8_t 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(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 SrecordHexStringToByte ***/ - - -/************************************************************************************//** -** \brief Reads the next line from the S-record file handle. -** \param srecordHandle The S-record file handle. It is returned by SrecordOpen. -** \param line Destination buffer for the line characters. Should be of size -** SRECORD_MAX_CHARS_PER_LINE. -** \return SB_TRUE if successful, SB_FALSE otherwise. -** -****************************************************************************************/ -static bool SrecordReadLine(FILE *srecordHandle, char *line) -{ - /* init the line as an empty line */ - line[0] = '\0'; - - /* loop as long as we find a non-empty line or end-of-file */ - while (line[0] == '\0') - { - if (fgets(line, SRECORD_MAX_CHARS_PER_LINE, srecordHandle) == NULL) - { - /* no more lines available */ - return false; - } - /* replace the line termination with a string termination */ - line[strcspn(line, "\n")] = '\0'; - } - /* still here so not EOF and not and empty line, so success */ - return true; -} /*** end of SrecordReadLine ***/ - - -/*********************************** end of srecparser.c *******************************/ - diff --git a/Host/Source/SerialBoot/srecparser.h b/Host/Source/SerialBoot/srecparser.h deleted file mode 100644 index b38e0a2f..00000000 --- a/Host/Source/SerialBoot/srecparser.h +++ /dev/null @@ -1,52 +0,0 @@ -/************************************************************************************//** -* \file srecparser.h -* \brief S-record parser header file. -* \ingroup SerialBoot -* \internal -*---------------------------------------------------------------------------------------- -* C O P Y R I G H T -*---------------------------------------------------------------------------------------- -* Copyright (c) 2017 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 SRECPARSER_H -#define SRECPARSER_H - -#ifdef __cplusplus -extern "C" { -#endif - -/**************************************************************************************** -* Include files -****************************************************************************************/ -#include "firmware.h" /* firmware module */ - - -/**************************************************************************************** -* Function prototypes -****************************************************************************************/ -tFirmwareParser const * const SRecParserGetParser(void); - -#ifdef __cplusplus -} -#endif - -#endif /* SRECPARSER_H */ -/********************************* end of srecparser.h *********************************/ - diff --git a/Host/Source/SerialBoot/timeutil.h b/Host/Source/SerialBoot/timeutil.h deleted file mode 100644 index 911b0d17..00000000 --- a/Host/Source/SerialBoot/timeutil.h +++ /dev/null @@ -1,52 +0,0 @@ -/************************************************************************************//** -* \file timeutil.h -* \brief Time utility header file. -* \ingroup SerialBoot -* \internal -*---------------------------------------------------------------------------------------- -* C O P Y R I G H T -*---------------------------------------------------------------------------------------- -* Copyright (c) 2017 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 TIMEUTIL_H -#define TIMEUTIL_H - -#ifdef __cplusplus -extern "C" { -#endif - -/**************************************************************************************** -* Include files -****************************************************************************************/ -#include /* for standard integer types */ - - -/**************************************************************************************** -* Function prototypes -****************************************************************************************/ -uint32_t TimeUtilGetSystemTimeMs(void); -void TimeUtilDelayMs(uint16_t delay); - -#ifdef __cplusplus -} -#endif - -#endif /* TIMEUTIL_H */ -/*********************************** end of timeutil.h *********************************/ diff --git a/Host/Source/SerialBoot/xcploader.c b/Host/Source/SerialBoot/xcploader.c deleted file mode 100644 index 40f63b86..00000000 --- a/Host/Source/SerialBoot/xcploader.c +++ /dev/null @@ -1,755 +0,0 @@ -/************************************************************************************//** -* \file xcploader.c -* \brief XCP Loader module source file. -* \ingroup SerialBoot -* \internal -*---------------------------------------------------------------------------------------- -* C O P Y R I G H T -*---------------------------------------------------------------------------------------- -* Copyright (c) 2017 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 /* for NULL declaration */ -#include /* for assertions */ -#include "xcploader.h" /* XCP loader module */ - - -/**************************************************************************************** -* Macro definitions -****************************************************************************************/ -/* XCP command codes as defined by the protocol currently supported by this module */ -#define XCPLOADER_CMD_CONNECT (0xFF) /**< XCP connect command code. */ -#define XCPLOADER_CMD_DISCONNECT (0xFE) /**< XCP disconnect command code. */ -#define XCPLOADER_CMD_SET_MTA (0xF6) /**< XCP set mta command code. */ -#define XCPLOADER_CMD_UPLOAD (0xF5) /**< XCP upload command code. */ -#define XCPLOADER_CMD_PROGRAM_START (0xD2) /**< XCP program start command code. */ -#define XCPLOADER_CMD_PROGRAM_CLEAR (0xD1) /**< XCP program clear command code. */ -#define XCPLOADER_CMD_PROGRAM (0xD0) /**< XCP program command code. */ -#define XCPLOADER_CMD_PROGRAM_RESET (0xCF) /**< XCP program reset command code. */ -#define XCPLOADER_CMD_PROGRAM_MAX (0xC9) /**< XCP program max command code. */ - -/* XCP response packet IDs as defined by the protocol. */ -#define XCPLOADER_CMD_PID_RES (0xFF) /**< positive response */ - -/** \brief Maximum timeout for the XCP connect command. */ -#define XCPLOADER_CONNECT_TIMEOUT_MS (20) - -/** \brief Number of retries to connect to the XCP slave. */ -#define XCPLOADER_CONNECT_RETRIES (5) - - -/**************************************************************************************** -* Function prototypes -****************************************************************************************/ -static bool XcpLoaderSendCmdConnect(void); -static bool XcpLoaderSendCmdSetMta(uint32_t address); -static bool XcpLoaderSendCmdUpload(uint8_t *data, uint8_t length); -static bool XcpLoaderSendCmdProgramStart(void); -static bool XcpLoaderSendCmdProgramReset(void); -static bool XcpLoaderSendCmdProgram(uint8_t length, uint8_t *data); -static bool XcpLoaderSendCmdProgramMax(uint8_t *data); -static bool XcpLoaderSendCmdProgramClear(uint32_t length); -static void XcpLoaderSetOrderedLong(uint32_t value, uint8_t *data); - - -/**************************************************************************************** -* Local data declarations -****************************************************************************************/ -/** \brief Pointer to the XCP transport layer that is linked. */ -static tXcpTransport const * transportPtr = NULL; - -/** \brief The settings that should be used by the XCP loader. */ -static tXcpSettings xcpSettings; - -/** \brief Flag to keep track of the connection status. */ -static bool xcpConnected; - -/** \brief Store the byte ordering of the XCP slave. */ -static bool xcpSlaveIsIntel; - -/** \brief The max number of bytes in the command transmit object (master->slave). */ -static uint8_t xcpMaxCto; - -/** \brief The max number of bytes in the command transmit object (master->slave) during - * a programming session. - */ -static uint8_t xcpMaxProgCto; - -/** \brief The max number of bytes in the data transmit object (slave->master). */ -static uint16_t xcpMaxDto; - - -/************************************************************************************//** -** \brief Initializes the loader module. -** \param settings Pointer to settings structure. -** \param transport Pointer to the transport layer to link. -** \param tpsettings Pointer to transport layer settings structure. -** \return None. -** -****************************************************************************************/ -void XcpLoaderInit(tXcpSettings *settings, tXcpTransport const * const transport, void *tpsettings) -{ - /* verify parameters */ - assert(transport != NULL); - assert(tpsettings != NULL); - assert(settings != NULL); - - /* shallow copy the XCP settings for later usage */ - xcpSettings = *settings; - /* link the XCP transport layer */ - transportPtr = transport; - /* initialize the transport layer */ - transportPtr->Init(tpsettings); - /* init locals */ - xcpConnected = false; - xcpSlaveIsIntel = false; - xcpMaxCto = 0; - xcpMaxProgCto = 0; - xcpMaxDto = 0; -} /*** end of XcpLoaderInit ***/ - - -/************************************************************************************//** -** \brief Uninitializes the loader module. -** \return None. -** -****************************************************************************************/ -void XcpLoaderDeinit(void) -{ - /* make sure the XCP transport layer is linked */ - assert(transportPtr != NULL); - - /* disconnect */ - XcpLoaderDisconnect(); - /* uninitialize the transport layer */ - transportPtr->Deinit(); - /* unlink the transport layer */ - transportPtr = NULL; -} /*** end of XcpLoaderDeinit ***/ - - -/************************************************************************************//** -** \brief Connect to the XCP slave. -** \return True is successful, false otherwise. -** -****************************************************************************************/ -bool XcpLoaderConnect(void) -{ - uint8_t retryCnt; - - /* make sure the XCP transport layer is linked */ - assert(transportPtr != NULL); - - /* make sure that we are disconnected before connecting */ - XcpLoaderDisconnect(); - - /* connect the transport layer */ - if (!transportPtr->Connect()) - { - return false; - } - - /* try to connect with a finite amount of retries */ - for (retryCnt=0; retryCntDisconnect(); - return false; -} /*** end of XcpLoaderConnect ***/ - - -/***********************************************************************************//** -** \brief Disconnect from the XCP slave. -** \return None. -** -****************************************************************************************/ -void XcpLoaderDisconnect(void) -{ - /* make sure the XCP transport layer is linked */ - assert(transportPtr != NULL); - - /* only disconnect if actually connected */ - if (xcpConnected) - { - /* send reset command instead of the disconnect. this causes the user program on the - * slave to automatically start again if present. - */ - XcpLoaderSendCmdProgramReset(); - /* disconnect the transport layer */ - transportPtr->Disconnect(); - /* reset connection status */ - xcpConnected = false; - } -} /*** end of XcpLoaderDisconnect ***/ - - -/************************************************************************************//** -** \brief Puts a connected slave in programming session. -** \return True is successful, false otherwise. -** -****************************************************************************************/ -bool XcpLoaderStartProgrammingSession(void) -{ - /* make sure the XCP transport layer is linked */ - assert(transportPtr != NULL); - - /* place the slave in programming mode */ - return XcpLoaderSendCmdProgramStart(); -} /*** end of XcpLoaderStartProgrammingSession ***/ - - -/************************************************************************************//** -** \brief Stops the programming session by sending a program command with size 0 and -** then resetting the slave. -** \return True is successful, false otherwise. -** -****************************************************************************************/ -bool XcpLoaderStopProgrammingSession(void) -{ - /* make sure the XCP transport layer is linked */ - assert(transportPtr != NULL); - - /* stop programming by sending the program command with size 0 */ - return XcpLoaderSendCmdProgram(0, NULL); -} /*** end of XcpLoaderStopProgrammingSession ***/ - - -/************************************************************************************//** -** \brief Erases non volatile memory on the slave. -** \param addr Base memory address for the erase operation. -** \param len Number of bytes to erase. -** \return True is successful, false otherwise. -** -****************************************************************************************/ -bool XcpLoaderClearMemory(uint32_t addr, uint32_t len) -{ - /* make sure the XCP transport layer is linked */ - assert(transportPtr != NULL); - /* verify parameters */ - assert(len > 0); - - /* first set the MTA pointer */ - if (!XcpLoaderSendCmdSetMta(addr)) - { - return false; - } - /* now perform the erase operation */ - return XcpLoaderSendCmdProgramClear(len); -} /*** end of XcpLoaderClearMemory ***/ - - -/***********************************************************************************//** -** \brief Reads data from the slave's memory. -** \param addr Base memory address for the read operation -** \param len Number of bytes to read. -** \param data Destination buffer for storing the read data bytes. -** \return True is successful, false otherwise. -** -****************************************************************************************/ -bool XcpLoaderReadData(uint32_t addr, uint32_t len, uint8_t *data) -{ - uint8_t currentReadCnt; - uint32_t bufferOffset = 0; - - /* make sure the XCP transport layer is linked */ - assert(transportPtr != NULL); - /* verify parameters */ - assert(data != NULL); - assert(len > 0); - - /* first set the MTA pointer */ - if (!XcpLoaderSendCmdSetMta(addr)) - { - return false; - } - /* perform segmented upload of the data */ - while (len > 0) - { - /* set the current read length to make optimal use of the available packet data. */ - currentReadCnt = len % (xcpMaxDto - 1); - if (currentReadCnt == 0) - { - currentReadCnt = (xcpMaxDto - 1); - } - /* upload some data */ - if (!XcpLoaderSendCmdUpload(&data[bufferOffset], currentReadCnt)) - { - return false; - } - /* update loop variables */ - len -= currentReadCnt; - bufferOffset += currentReadCnt; - } - /* still here so all data successfully read from the slave */ - return true; -} /*** end of XcpLoaderReadData ***/ - - -/************************************************************************************//** -** \brief Programs data to the slave's non volatile memory. Note that it must be -** erased first. -** \param addr Base memory address for the program operation -** \param len Number of bytes to program. -** \param data Source buffer with the to be programmed bytes. -** \return True is successful, false otherwise. -** -****************************************************************************************/ -bool XcpLoaderProgramData(uint32_t addr, uint32_t len, uint8_t *data) -{ - uint8_t currentWriteCnt; - uint32_t bufferOffset = 0; - - /* make sure the XCP transport layer is linked */ - assert(transportPtr != NULL); - /* verify parameters */ - assert(data != NULL); - assert(len > 0); - - /* first set the MTA pointer */ - if (!XcpLoaderSendCmdSetMta(addr)) - { - return false; - } - /* perform segmented programming of the data */ - while (len > 0) - { - /* set the current read length to make optimal use of the available packet data. */ - currentWriteCnt = len % (xcpMaxProgCto - 1); - if (currentWriteCnt == 0) - { - currentWriteCnt = (xcpMaxProgCto - 1); - } - /* prepare the packed data for the program command */ - if (currentWriteCnt < (xcpMaxProgCto - 1)) - { - /* program data */ - if (!XcpLoaderSendCmdProgram(currentWriteCnt, &data[bufferOffset])) - { - return false; - } - } - else - { - /* program max data */ - if (!XcpLoaderSendCmdProgramMax(&data[bufferOffset])) - { - return false; - } - } - /* update loop variables */ - len -= currentWriteCnt; - bufferOffset += currentWriteCnt; - } - /* still here so all data successfully programmed */ - return true; -} /*** end of XcpLoaderProgramData ***/ - - -/************************************************************************************//** -** \brief Sends the XCP Connect command. -** \return True if successful, false otherwise. -** -****************************************************************************************/ -static bool XcpLoaderSendCmdConnect(void) -{ - tXcpPacket cmdPacket; - tXcpPacket resPacket; - - /* prepare the command packet */ - cmdPacket.data[0] = XCPLOADER_CMD_CONNECT; - cmdPacket.data[1] = 0; /* normal mode */ - cmdPacket.len = 2; - - /* send the packet */ - if (!transportPtr->SendPacket(&cmdPacket, &resPacket, XCPLOADER_CONNECT_TIMEOUT_MS)) - { - /* could not send packet or receive response within the specified timeout */ - return false; - } - - /* still here so a response was received. check if the reponse was valid */ - if ( (resPacket.len == 0) || (resPacket.data[0] != XCPLOADER_CMD_PID_RES) ) - { - /* not a valid or positive response */ - return false; - } - - /* process response data */ - if ((resPacket.data[2] & 0x01) == 0) - { - /* store slave's byte ordering information */ - xcpSlaveIsIntel = true; - } - /* store max number of bytes the slave allows for master->slave packets. */ - xcpMaxCto = resPacket.data[3]; - xcpMaxProgCto = xcpMaxCto; - /* store max number of bytes the slave allows for slave->master packets. */ - if (xcpSlaveIsIntel) - { - xcpMaxDto = resPacket.data[4] + (resPacket.data[5] << 8); - } - else - { - xcpMaxDto = resPacket.data[5] + (resPacket.data[4] << 8); - } - - /* double check size configuration */ - assert(XCPLOADER_PACKET_SIZE_MAX >= xcpMaxCto); - assert(XCPLOADER_PACKET_SIZE_MAX >= xcpMaxDto); - - /* still here so all went well */ - return true; -} /*** end of XcpLoaderSendCmdConnect ***/ - - -/************************************************************************************//** -** \brief Sends the XCP Set MTA command. -** \param address New MTA address for the slave. -** \return True if successful, false otherwise. -** -****************************************************************************************/ -static bool XcpLoaderSendCmdSetMta(uint32_t address) -{ - tXcpPacket cmdPacket; - tXcpPacket resPacket; - - /* prepare the command packet */ - cmdPacket.data[0] = XCPLOADER_CMD_SET_MTA; - cmdPacket.data[1] = 0; /* reserved */ - cmdPacket.data[2] = 0; /* reserved */ - cmdPacket.data[3] = 0; /* address extension not supported */ - /* set the address taking into account byte ordering */ - XcpLoaderSetOrderedLong(address, &cmdPacket.data[4]); - cmdPacket.len = 8; - - /* send the packet */ - if (!transportPtr->SendPacket(&cmdPacket, &resPacket, xcpSettings.timeoutT1)) - { - /* could not send packet or receive response within the specified timeout */ - return false; - } - - /* still here so a response was received. check if the reponse was valid */ - if ( (resPacket.len == 0) || (resPacket.data[0] != XCPLOADER_CMD_PID_RES) ) - { - /* not a valid or positive response */ - return false; - } - - /* still here so all went well */ - return true; -} /*** end of XcpLoaderSendCmdSetMta ***/ - - -/************************************************************************************//** -** \brief Sends the XCP UPLOAD command. -** \param data Destination data buffer. -** \param length Number of bytes to upload. -** \return SB_TRUE is successfull, SB_FALSE otherwise. -** -****************************************************************************************/ -static bool XcpLoaderSendCmdUpload(uint8_t *data, uint8_t length) -{ - tXcpPacket cmdPacket; - tXcpPacket resPacket; - uint8_t data_index; - - /* cannot request more data then the max rx data - 1 */ - assert(length < XCPLOADER_PACKET_SIZE_MAX); - assert(data != NULL); - - /* prepare the command packet */ - cmdPacket.data[0] = XCPLOADER_CMD_UPLOAD; - cmdPacket.data[1] = length; - cmdPacket.len = 2; - - /* send the packet */ - if (!transportPtr->SendPacket(&cmdPacket, &resPacket, xcpSettings.timeoutT1)) - { - /* could not send packet or receive response within the specified timeout */ - return false; - } - - /* still here so a response was received. check if the reponse was valid */ - if ( (resPacket.len == 0) || (resPacket.data[0] != XCPLOADER_CMD_PID_RES) ) - { - /* not a valid or positive response */ - return false; - } - - /* now store the uploaded data */ - for (data_index=0; data_indexSendPacket(&cmdPacket, &resPacket, xcpSettings.timeoutT3)) - { - /* could not send packet or receive response within the specified timeout */ - return false; - } - - /* still here so a response was received. check if the reponse was valid */ - if ( (resPacket.len == 0) || (resPacket.data[0] != XCPLOADER_CMD_PID_RES) ) - { - /* not a valid or positive response */ - return false; - } - - /* store max number of bytes the slave allows for master->slave packets during the - * programming session - */ - xcpMaxProgCto = resPacket.data[3]; - - /* still here so all went well */ - return true; -} /*** end of XcpLoaderSendCmdProgramStart ***/ - - -/************************************************************************************//** -** \brief Sends the XCP PROGRAM RESET command. Note that this command is a bit -** different as in it does not require a response. -** \return True if successful, false otherwise. -** -****************************************************************************************/ -static bool XcpLoaderSendCmdProgramReset(void) -{ - tXcpPacket cmdPacket; - tXcpPacket resPacket; - - /* prepare the command packet */ - cmdPacket.data[0] = XCPLOADER_CMD_PROGRAM_RESET; - cmdPacket.len = 1; - - /* send the packet, assume the sending itself is ok and check if a response was - * received. - */ - if (!transportPtr->SendPacket(&cmdPacket, &resPacket, xcpSettings.timeoutT5)) - { - /* probably no response received within the specified timeout, but that is allowed - * for the reset command. - */ - return true; - } - - /* still here so a response was received. check if the reponse was valid */ - if ( (resPacket.len == 0) || (resPacket.data[0] != XCPLOADER_CMD_PID_RES) ) - { - /* not a valid or positive response */ - return false; - } - - /* still here so all went well */ - return true; -} /*** end of XcpLoaderSendCmdProgramReset ***/ - - -/************************************************************************************//** -** \brief Sends the XCP PROGRAM command. -** \param length Number of bytes in the data array to program. -** \param data Array with data bytes to program. -** \return True if successful, false otherwise. -** -****************************************************************************************/ -static bool XcpLoaderSendCmdProgram(uint8_t length, uint8_t *data) -{ - tXcpPacket cmdPacket; - tXcpPacket resPacket; - uint8_t cnt; - - /* verify that this number of bytes actually first in this command */ - assert(length <= (xcpMaxProgCto-2) && (xcpMaxProgCto <= XCPLOADER_PACKET_SIZE_MAX)); - if (length > 0) - { - assert(data != NULL); - } - - /* prepare the command packet */ - cmdPacket.data[0] = XCPLOADER_CMD_PROGRAM; - cmdPacket.data[1] = length; - for (cnt=0; cntSendPacket(&cmdPacket, &resPacket, xcpSettings.timeoutT5)) - { - /* could not send packet or receive response within the specified timeout */ - return false; - } - - /* still here so a response was received. check if the reponse was valid */ - if ( (resPacket.len == 0) || (resPacket.data[0] != XCPLOADER_CMD_PID_RES) ) - { - /* not a valid or positive response */ - return false; - } - - /* still here so all went well */ - return true; -} /*** end of XcpLoaderSendCmdProgram ***/ - - -/************************************************************************************//** -** \brief Sends the XCP PROGRAM MAX command. -** \param data Array with data bytes to program. -** \return True if successful, false otherwise. -** -****************************************************************************************/ -static bool XcpLoaderSendCmdProgramMax(uint8_t *data) -{ - tXcpPacket cmdPacket; - tXcpPacket resPacket; - uint8_t cnt; - - /* verify that this number of bytes actually first in this command */ - assert(xcpMaxProgCto <= XCPLOADER_PACKET_SIZE_MAX); - assert(data != NULL); - - /* prepare the command packet */ - cmdPacket.data[0] = XCPLOADER_CMD_PROGRAM_MAX; - for (cnt=0; cnt<(xcpMaxProgCto-1); cnt++) - { - cmdPacket.data[cnt+1] = data[cnt]; - } - cmdPacket.len = xcpMaxProgCto; - - /* send the packet */ - if (!transportPtr->SendPacket(&cmdPacket, &resPacket, xcpSettings.timeoutT5)) - { - /* could not send packet or receive response within the specified timeout */ - return false; - } - - /* still here so a response was received. check if the reponse was valid */ - if ( (resPacket.len == 0) || (resPacket.data[0] != XCPLOADER_CMD_PID_RES) ) - { - /* not a valid or positive response */ - return false; - } - - /* still here so all went well */ - return true; -} /*** end of XcpLoaderSendCmdProgramMax ***/ - - -/************************************************************************************//** -** \brief Sends the XCP PROGRAM CLEAR command. -** \param length Number of elements to clear starting at the MTA address. -** \return True if successful, false otherwise. -** -****************************************************************************************/ -static bool XcpLoaderSendCmdProgramClear(uint32_t length) -{ - tXcpPacket cmdPacket; - tXcpPacket resPacket; - - /* prepare the command packet */ - cmdPacket.data[0] = XCPLOADER_CMD_PROGRAM_CLEAR; - cmdPacket.data[1] = 0; /* use absolute mode */ - cmdPacket.data[2] = 0; /* reserved */ - cmdPacket.data[3] = 0; /* reserved */ - /* set the erase length taking into account byte ordering */ - XcpLoaderSetOrderedLong(length, &cmdPacket.data[4]); - cmdPacket.len = 8; - - /* send the packet */ - if (!transportPtr->SendPacket(&cmdPacket, &resPacket, xcpSettings.timeoutT4)) - { - /* could not send packet or receive response within the specified timeout */ - return false; - } - - /* still here so a response was received. check if the reponse was valid */ - if ( (resPacket.len == 0) || (resPacket.data[0] != XCPLOADER_CMD_PID_RES) ) - { - /* not a valid or positive response */ - return false; - } - - /* still here so all went well */ - return true; -} /*** end of XcpLoaderSendCmdProgramClear ***/ - - -/************************************************************************************//** -** \brief Stores a 32-bit value into a byte buffer taking into account Intel -** or Motorola byte ordering. -** \param value The 32-bit value to store in the buffer. -** \param data Array to the buffer for storage. -** \return None. -** -****************************************************************************************/ -static void XcpLoaderSetOrderedLong(uint32_t value, uint8_t *data) -{ - if (xcpSlaveIsIntel) - { - data[3] = (uint8_t)(value >> 24); - data[2] = (uint8_t)(value >> 16); - data[1] = (uint8_t)(value >> 8); - data[0] = (uint8_t)value; - } - else - { - data[0] = (uint8_t)(value >> 24); - data[1] = (uint8_t)(value >> 16); - data[2] = (uint8_t)(value >> 8); - data[3] = (uint8_t)value; - } -} /*** end of XcpLoaderSetOrderedLong ***/ - - -/*********************************** end of xcploader.c ********************************/ - diff --git a/Host/Source/SerialBoot/xcploader.h b/Host/Source/SerialBoot/xcploader.h deleted file mode 100644 index da586aee..00000000 --- a/Host/Source/SerialBoot/xcploader.h +++ /dev/null @@ -1,108 +0,0 @@ -/************************************************************************************//** -* \file xcploader.h -* \brief XCP Loader module header file. -* \ingroup SerialBoot -* \internal -*---------------------------------------------------------------------------------------- -* C O P Y R I G H T -*---------------------------------------------------------------------------------------- -* Copyright (c) 2017 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 XCPLOADER_H -#define XCPLOADER_H - -#ifdef __cplusplus -extern "C" { -#endif - -/**************************************************************************************** -* Include files -****************************************************************************************/ -#include /* for standard integer types */ -#include /* for boolean type */ - - -/**************************************************************************************** -* Macro definitions -****************************************************************************************/ -/** \brief Total number of bytes in a master<->slave data packet. It should be at least - * equal or larger than that configured on the slave. - */ -#define XCPLOADER_PACKET_SIZE_MAX (255) - - -/**************************************************************************************** -* Type definitions -****************************************************************************************/ -/** \brief XCP protocol specific settings. */ -typedef struct t_xcp_settings -{ - uint16_t timeoutT1; /**< Command response timeout in milliseconds. */ - uint16_t timeoutT3; /**< Start programming timeout in milliseconds. */ - uint16_t timeoutT4; /**< Erase memory timeout in milliseonds. */ - uint16_t timeoutT5; /**< Program memory and reset timeout in milliseonds. */ - uint16_t timeoutT7; /**< Busy wait timer timeout in milliseonds. */ -} tXcpSettings; - - -/** \brief XCP packet type. */ -typedef struct t_xcp_packet -{ - uint8_t data[XCPLOADER_PACKET_SIZE_MAX]; /**< Packet data. */ - uint8_t len; /**< Packet length. */ -} tXcpPacket; - - -/** \brief XCP transport layer. */ -typedef struct t_xcp_transport -{ - /** \brief Initialization of the XCP transpor layer. */ - void (*Init) (void *settings); - /** \brief Uninitializes the XCP transpor layer. */ - void (*Deinit) (void); - /** \brief Connects the XCP transpor layer. */ - bool (*Connect) (void); - /** \brief Disconnects the XCP transpor layer. */ - void (*Disconnect) (void); - /** \brief Sends an XCP packet and waits for the response to come back. */ - bool (*SendPacket) (tXcpPacket *txPacket, tXcpPacket *rxPacket, uint16_t timeout); -} tXcpTransport; - - -/**************************************************************************************** -* Function prototypes -****************************************************************************************/ -void XcpLoaderInit(tXcpSettings *settings, tXcpTransport const * const transport, void *tpsettings); -void XcpLoaderDeinit(void); -bool XcpLoaderConnect(void); -void XcpLoaderDisconnect(void); -bool XcpLoaderStartProgrammingSession(void); -bool XcpLoaderStopProgrammingSession(void); -bool XcpLoaderClearMemory(uint32_t addr, uint32_t len); -bool XcpLoaderReadData(uint32_t addr, uint32_t len, uint8_t *data); -bool XcpLoaderProgramData(uint32_t addr, uint32_t len, uint8_t *data); - -#ifdef __cplusplus -} -#endif - -#endif /* XCPLOADER_H */ -/********************************* end of xcploader.h **********************************/ - diff --git a/Host/Source/SerialBoot/xcptpuart.c b/Host/Source/SerialBoot/xcptpuart.c deleted file mode 100644 index d3347d55..00000000 --- a/Host/Source/SerialBoot/xcptpuart.c +++ /dev/null @@ -1,255 +0,0 @@ -/************************************************************************************//** -* \file xcptpuart.c -* \brief XCP transport layer module for UART source file. -* \ingroup SerialBoot -* \internal -*---------------------------------------------------------------------------------------- -* C O P Y R I G H T -*---------------------------------------------------------------------------------------- -* Copyright (c) 2017 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 /* for NULL declaration */ -#include /* for standard library */ -#include /* for string library */ -#include /* for assertions */ -#include "xcptpuart.h" /* XCP transport layer for UART */ -#include "timeutil.h" /* for time utilities module */ - - -/**************************************************************************************** -* Macro definitions -****************************************************************************************/ -/** \brief Maximum amount of data bytes that this module supports for XCP packets. */ -#define XCP_TP_UART_MAX_DATA_LEN (256) - - -/**************************************************************************************** -* Function prototypes -****************************************************************************************/ -static void XcpTpUartInit(void *settings); -static void XcpTpUartDeinit(void); -static bool XcpTpUartConnect(void); -static void XcpTpUartDisconnect(void); -static bool XcpTpUartSendPacket(tXcpPacket *txPacket, tXcpPacket *rxPacket, uint16_t timeout); - - -/**************************************************************************************** -* Local constant declarations -****************************************************************************************/ -/** \brief XCP transport structure filled with UART specifics. */ -static const tXcpTransport uartTransport = -{ - XcpTpUartInit, - XcpTpUartDeinit, - XcpTpUartConnect, - XcpTpUartDisconnect, - XcpTpUartSendPacket -}; - - -/**************************************************************************************** -* Local data declarations -****************************************************************************************/ -/** \brief The settings to use in this transport layer. */ -static tXcpTpUartSettings tpUartSettings; - - -/***********************************************************************************//** -** \brief Obtains a pointer to the XCP UART transport structure, so that it can -** be linked to the XCP loader module. -** \return Pointer to XCP UART transport structure. -** -****************************************************************************************/ -tXcpTransport const * const XcpTpUartGetTransport(void) -{ - return &uartTransport; -} /*** end of XcpTpUartGetTransport ***/ - - -/************************************************************************************//** -** \brief Initializes the transport layer. -** \param settings Pointer to settings structure. -** \return None. -** -****************************************************************************************/ -static void XcpTpUartInit(void *settings) -{ - /* verify parameters */ - assert(settings != NULL); - - /* shallow copy the transport layer settings for layer usage */ - tpUartSettings = *((tXcpTpUartSettings *)settings); - /* the portname is a pointer and it is not gauranteed that it stays valid so we need - * to deep copy this one. note the +1 for '\0' in malloc. - */ - tpUartSettings.portname = malloc(strlen(((tXcpTpUartSettings *)settings)->portname) + 1); - strcpy(tpUartSettings.portname, ((tXcpTpUartSettings *)settings)->portname); -} /*** end of XcpTpUartInit ***/ - - -/************************************************************************************//** -** \brief Uninitializes the transport layer. -** \return None. -** -****************************************************************************************/ -static void XcpTpUartDeinit(void) -{ - /* release memory that was allocated for storing the port name */ - if (tpUartSettings.portname != NULL) - { - free(tpUartSettings.portname); - } -} /*** end of XcpTpUartDeinit ***/ - - -/************************************************************************************//** -** \brief Connects to the transport layer. -** \return True is connected, false otherwise. -** -****************************************************************************************/ -static bool XcpTpUartConnect(void) -{ - /* connect to the serial port */ - return SerialPortOpen(tpUartSettings.portname, tpUartSettings.baudrate); -} /*** end of XcpTpUartConnect ***/ - - -/************************************************************************************//** -** \brief Disconnects from the transport layer. -** \return None. -** -****************************************************************************************/ -static void XcpTpUartDisconnect(void) -{ - /* disconnect from the serial port */ - SerialPortClose(); -} /*** end of XcpTpUartDisconnect ***/ - - -/************************************************************************************//** -** \brief Transmits an XCP packet on the transport layer and attempts to receive the -** response packet within the specified timeout. -** \return True is successful and a response packet was received, false otherwise. -** -****************************************************************************************/ -static bool XcpTpUartSendPacket(tXcpPacket *txPacket, tXcpPacket *rxPacket, uint16_t timeout) -{ - static uint8_t uartBuffer[XCP_TP_UART_MAX_DATA_LEN + 1]; /* static to lower stack load */ - uint8_t byteIdx; - uint32_t responseTimeoutTime; - bool packetReceptionComplete; - - /* verify parameters */ - assert(txPacket != NULL); - assert(txPacket->len <= XCP_TP_UART_MAX_DATA_LEN); - assert(rxPacket != NULL); - assert(timeout > 0); - - - /* prepare the XCP packet for transmission on UART. this is basically the same as the - * xcp packet data but just the length of the packet is added to the first byte. - */ - uartBuffer[0] = txPacket->len; - for (byteIdx=0; byteIdxlen; byteIdx++) - { - uartBuffer[byteIdx + 1] = txPacket->data[byteIdx]; - } - - /* transmit the packet */ - if (!SerialPortWrite(uartBuffer, txPacket->len + 1)) - { - return false; - } - - /* determine timeout time for the response packet */ - responseTimeoutTime = TimeUtilGetSystemTimeMs() + timeout; - - /* initialize packet reception length */ - uartBuffer[0] = 0; - /* poll with timeout detection to receive the first byte. this one contains the - * packet length and cannot be zero. - */ - while (TimeUtilGetSystemTimeMs() < responseTimeoutTime) - { - if (SerialPortRead(&uartBuffer[0], 1)) - { - /* length received. validate it before accepting it */ - if (uartBuffer[0] > 0) - { - /* start of packet received. stop this loop to continue with the - * reception of the packet. - */ - break; - } - } - } - /* check if a valid start of packet was received */ - if (uartBuffer[0] == 0) - { - /* no valid start of packet received, so a timeout occurred. */ - return false; - } - - /* continue with reception of the packet */ - packetReceptionComplete = false; - byteIdx = 1; - /* poll with timeout detection to receive the full packet */ - while (TimeUtilGetSystemTimeMs() < responseTimeoutTime) - { - /* check if the next byte was received */ - if (SerialPortRead(&uartBuffer[byteIdx], 1)) - { - /* check if the packet reception is now complete */ - if (byteIdx == uartBuffer[0]) - { - /* set flag and stop the loop */ - packetReceptionComplete = true; - break; - } - /* increment indexer to the next byte */ - byteIdx++; - } - } - - /* check if a timeout occurred */ - if (!packetReceptionComplete) - { - return false; - } - - /* still here so a full packet was received. copy its contents except the length info - * which is stored in the first byte - */ - for (byteIdx=0; byteIdxdata[byteIdx] = uartBuffer[byteIdx + 1]; - } - rxPacket->len = uartBuffer[0]; - - return true; -} /*** end of XcpTpUartSendPacket ***/ - - -/*********************************** end of xcptpuart.c ********************************/ - diff --git a/Host/Source/SerialBoot/xcptpuart.h b/Host/Source/SerialBoot/xcptpuart.h deleted file mode 100644 index b227dc93..00000000 --- a/Host/Source/SerialBoot/xcptpuart.h +++ /dev/null @@ -1,66 +0,0 @@ -/************************************************************************************//** -* \file xcptpuart.h -* \brief XCP transport layer module for UART header file. -* \ingroup SerialBoot -* \internal -*---------------------------------------------------------------------------------------- -* C O P Y R I G H T -*---------------------------------------------------------------------------------------- -* Copyright (c) 2017 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 XCPTPUART_H -#define XCPTPUART_H - -#ifdef __cplusplus -extern "C" { -#endif - -/**************************************************************************************** -* Include files -****************************************************************************************/ -#include "xcploader.h" /* XCP loader module */ -#include "serialport.h" /* serial port module */ - - -/*************************************************************************************** -* Type definitions -****************************************************************************************/ -/** \brief Layout of structure with settings specific to the XCP transport layer module - * for UART. - */ -typedef struct t_xcp_tp_uart_settings -{ - tSerialPortBaudrate baudrate; /**< UART communication speed. */ - char *portname; /**< interface port name, i.e. /dev/ttyUSB0. */ -} tXcpTpUartSettings; - - -/*************************************************************************************** -* Function prototypes -****************************************************************************************/ -tXcpTransport const * const XcpTpUartGetTransport(void); - -#ifdef __cplusplus -} -#endif - -#endif /* XCPTPUART_H */ -/********************************* end of xcptpuart.h **********************************/ -