From 44f30fc5a0151fdd2f0f0bc22b89645213b45a08 Mon Sep 17 00:00:00 2001 From: Frank Voorburg Date: Wed, 26 Jul 2017 10:47:44 +0000 Subject: [PATCH] Refs #316. Implemented framework for the XCP on CAN transport layer. git-svn-id: https://svn.code.sf.net/p/openblt/code/trunk@313 5dc33758-31d5-4daf-9ae8-b24bf3d40d73 --- Host/Source/LibOpenBLT/openblt.pas | 2 +- Host/Source/LibOpenBLT/xcptpcan.c | 170 +++++++++++++++++++++++++++++ Host/Source/LibOpenBLT/xcptpcan.h | 67 ++++++++++++ Host/Source/LibOpenBLT/xcptpuart.c | 2 +- Host/libopenblt.dll | Bin 98304 -> 98816 bytes 5 files changed, 239 insertions(+), 2 deletions(-) create mode 100644 Host/Source/LibOpenBLT/xcptpcan.c create mode 100644 Host/Source/LibOpenBLT/xcptpcan.h diff --git a/Host/Source/LibOpenBLT/openblt.pas b/Host/Source/LibOpenBLT/openblt.pas index 5d517f40..d1a71194 100644 --- a/Host/Source/LibOpenBLT/openblt.pas +++ b/Host/Source/LibOpenBLT/openblt.pas @@ -93,7 +93,7 @@ type // Structure layout of the XCP version 1.0 CAN transport layer settings. tBltTransportSettingsXcpV10Can = record - deviceName: PAnsiChar; // Device name such as /dev/can0. + deviceName: PAnsiChar; // Device name such as can0, pcanusb, etc. deviceChannel: LongWord; // Channel on the device to use. baudrate: LongWord; // Communication speed in bits/sec. transmitId: LongWord; // Transmit CAN identifier. diff --git a/Host/Source/LibOpenBLT/xcptpcan.c b/Host/Source/LibOpenBLT/xcptpcan.c new file mode 100644 index 00000000..69e94ed2 --- /dev/null +++ b/Host/Source/LibOpenBLT/xcptpcan.c @@ -0,0 +1,170 @@ +/************************************************************************************//** +* \file xcptpcan.c +* \brief XCP CAN transport layer source file. +* \ingroup XcpTpCan +* \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 assertions */ +#include /* for standard integer types */ +#include /* for NULL declaration */ +#include /* for boolean type */ +#include /* for standard library */ +#include /* for string library */ +#include "session.h" /* Communication session module */ +#include "xcploader.h" /* XCP loader module */ +#include "xcptpcan.h" /* XCP CAN transport layer */ +#include "util.h" /* Utility module */ +#include "candriver.h" /* Generic CAN driver module */ +#if defined(PLATFORM_WIN32) +#include "pcanusb.h" /* Peak PCAN-USB interface */ +#endif + + +/**************************************************************************************** +* Function prototypes +****************************************************************************************/ +static void XcpTpCanInit(void const * settings); +static void XcpTpCanTerminate(void); +static bool XcpTpCanConnect(void); +static void XcpTpCanDisconnect(void); +static bool XcpTpCanSendPacket(tXcpTransportPacket const * txPacket, + tXcpTransportPacket * rxPacket, uint16_t timeout); + + +/**************************************************************************************** +* Local constant declarations +****************************************************************************************/ +/** \brief XCP transport layer structure filled with CAN specifics. */ +static const tXcpTransport canTransport = +{ + XcpTpCanInit, + XcpTpCanTerminate, + XcpTpCanConnect, + XcpTpCanDisconnect, + XcpTpCanSendPacket +}; + + +/***********************************************************************************//** +** \brief Obtains a pointer to the transport layer structure, so that it can be +** linked to the XCP protocol module. +** \return Pointer to transport layer structure. +** +****************************************************************************************/ +tXcpTransport const * XcpTpCanGetTransport(void) +{ + return &canTransport; +} /*** end of XcpTpCanGetTransport ***/ + + +/************************************************************************************//** +** \brief Initializes the transport layer. +** \param settings Pointer to settings structure. +** \return None. +** +****************************************************************************************/ +static void XcpTpCanInit(void const * settings) +{ + /* Check parameters. */ + assert(settings != NULL); + + /* Only continue with valid parameters. */ + if (settings != NULL) /*lint !e774 */ + { + /* ##Vg TODO Extract and set the pointer to the CAN interface to link. */ + } + /* ##Vg TODO Implement CAN module initialization. */ +} /*** end of XcpTpCanInit ***/ + + +/************************************************************************************//** +** \brief Terminates the transport layer. +** +****************************************************************************************/ +static void XcpTpCanTerminate(void) +{ + /* ##Vg TODO Implement. */ +} /*** end of XcpTpCanTerminate ***/ + + +/************************************************************************************//** +** \brief Connects to the transport layer. +** \return True is connected, false otherwise. +** +****************************************************************************************/ +static bool XcpTpCanConnect(void) +{ + bool result = false; + + /* ##Vg TODO Implement. */ + + /* Give the result back to the caller. */ + return result; +} /*** end of XcpTpCanConnect ***/ + + +/************************************************************************************//** +** \brief Disconnects from the transport layer. +** +****************************************************************************************/ +static void XcpTpCanDisconnect(void) +{ + /* ##Vg TODO Disconnect from the CAN bus. */ +} /*** end of XcpTpCanDisconnect ***/ + + +/************************************************************************************//** +** \brief Transmits an XCP packet on the transport layer and attempts to receive the +** response packet within the specified timeout. +** \param txPacket Pointer to the packet to transmit. +** \param rxPacket Pointer where the received packet info is stored. +** \param timeout Maximum time in milliseconds to wait for the reception of the +** response packet. +** \return True is successful and a response packet was received, false otherwise. +** +****************************************************************************************/ +static bool XcpTpCanSendPacket(tXcpTransportPacket const * txPacket, + tXcpTransportPacket * rxPacket, uint16_t timeout) +{ + bool result = false; + + /* Check parameters. */ + assert(txPacket != NULL); + assert(rxPacket != NULL); + + /* Only continue with valid parameters. */ + if ( (txPacket != NULL) && (rxPacket != NULL) ) /*lint !e774 */ + { + /* ##Vg TODO Implement. */ + } + /* Give the result back to the caller. */ + return result; +} /*** end of XcpTpCanSendPacket ***/ + + +/*********************************** end of xcptpcan.c *********************************/ diff --git a/Host/Source/LibOpenBLT/xcptpcan.h b/Host/Source/LibOpenBLT/xcptpcan.h new file mode 100644 index 00000000..e43c6ad0 --- /dev/null +++ b/Host/Source/LibOpenBLT/xcptpcan.h @@ -0,0 +1,67 @@ +/************************************************************************************//** +* \file xcptpcan.h +* \brief XCP CAN transport layer header file. +* \ingroup XcpTpCan +* \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 +****************************************************************************************/ +/************************************************************************************//** +* \defgroup XcpTpCan XCP CAN transport layer +* \brief This module implements the XCP transport layer for CAN. +* \ingroup XcpLoader +****************************************************************************************/ +#ifndef XCPTPCAN_H +#define XCPTPCAN_H + +#ifdef __cplusplus +extern "C" { +#endif + +/**************************************************************************************** +* Type definitions +****************************************************************************************/ +/** \brief Layout of structure with settings specific to the XCP transport layer module + * for CAN. + */ +typedef struct t_xcp_tp_can_settings +{ + char const * device; /**< Device name such as can0, pcanusb, etc. */ + uint32_t channel; /**< Channel on the device to use. */ + uint32_t baudrate; /**< Communication speed in bits/sec. */ + uint32_t transmitId; /**< Transmit CAN identifier. */ + uint32_t receiveId; /**< Receive CAN identifier. */ + bool useExtended; /**< Boolean to configure 29-bit CAN identifiers. */ +} tXcpTpCanSettings; + + +/*************************************************************************************** +* Function prototypes +****************************************************************************************/ +tXcpTransport const * XcpTpCanGetTransport(void); + +#ifdef __cplusplus +} +#endif + +#endif /* XCPTPCAN_H */ +/*********************************** end of xcptpcan.h *********************************/ diff --git a/Host/Source/LibOpenBLT/xcptpuart.c b/Host/Source/LibOpenBLT/xcptpuart.c index 2806a8cb..d66ccffb 100644 --- a/Host/Source/LibOpenBLT/xcptpuart.c +++ b/Host/Source/LibOpenBLT/xcptpuart.c @@ -83,7 +83,7 @@ static tXcpTpUartSettings tpUartSettings; tXcpTransport const * XcpTpUartGetTransport(void) { return &uartTransport; -} /*** end of XcpLoaderGetProtocol ***/ +} /*** end of XcpTpUartGetTransport ***/ /************************************************************************************//** diff --git a/Host/libopenblt.dll b/Host/libopenblt.dll index e1ad8195bdd7d5e001d2e919787b627175f7e7fe..b3cca9dda9fac75c85a136b2b9da086b6fdbfe8f 100644 GIT binary patch delta 17340 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 mL>U2T1}ihTY%Y&m&aLLQb33trKfyIqV*lUi