mirror of https://github.com/rusefi/openblt.git
Refs #317. Added USB support to LibOpenBLT and BootCommander. Use LibOpenBLT shared library in BootCommander instead of the static library. Prepared OpenBLT version number for new patch release.
git-svn-id: https://svn.code.sf.net/p/openblt/code/trunk@376 5dc33758-31d5-4daf-9ae8-b24bf3d40d73
This commit is contained in:
parent
d37ad9f3ae
commit
3d853fb851
|
@ -38,7 +38,7 @@ PROJECT_NAME = "BootCommander - Reference Manual"
|
|||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = 1.1.0
|
||||
PROJECT_NUMBER = 1.2.0
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer a
|
||||
|
|
|
@ -38,7 +38,7 @@ PROJECT_NAME = "OpenBLT Host Library - Reference Manual"
|
|||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = 1.1.0
|
||||
PROJECT_NUMBER = 1.2.0
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer a
|
||||
|
|
|
@ -38,7 +38,7 @@ PROJECT_NAME = "OpenBLT Bootloader - Reference Manual"
|
|||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = 1.4.1
|
||||
PROJECT_NUMBER = 1.4.2
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer a
|
||||
|
|
Binary file not shown.
|
@ -69,6 +69,7 @@ endforeach( OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES )
|
|||
set(LIBOPENBLT_INC ${PROJECT_SOURCE_DIR}/../LibOpenBLT)
|
||||
set(LIBOPENBLT_LIB ${PROJECT_OUTPUT_DIRECTORY})
|
||||
|
||||
|
||||
#****************************************************************************************
|
||||
# Compiler flags
|
||||
#****************************************************************************************
|
||||
|
@ -105,11 +106,11 @@ set(
|
|||
${INCS}
|
||||
)
|
||||
|
||||
# Set library name. When GNU GCC is used, the name to the static library file is used,
|
||||
# otherwise the shared library is used by default. This works fine too, but the static
|
||||
# library makes it a bit easier to move the target executable around on the file system.
|
||||
if(CMAKE_C_COMPILER_ID MATCHES GNU)
|
||||
set (LIBOPENBLT_LIBNAME libopenblt.a)
|
||||
# Set library name of the OpenBLT Host Library
|
||||
if(CMAKE_C_COMPILER_ID MATCHES MSVC)
|
||||
# When building LibOpenBLT with Microsoft Visual Studio, "lib" was added to the name
|
||||
# of the DLL. This needs to be done as well when linking the library.
|
||||
set (LIBOPENBLT_LIBNAME libopenblt)
|
||||
else()
|
||||
set (LIBOPENBLT_LIBNAME openblt)
|
||||
endif()
|
||||
|
@ -124,8 +125,19 @@ add_executable(
|
|||
${PROG_SRCS}
|
||||
)
|
||||
|
||||
# Add libraries
|
||||
target_link_libraries(BootCommander ${LIBOPENBLT_LIBNAME})
|
||||
# Add libraries. Note that when compiling with GNU GCC the path of the executable is
|
||||
# added to the run-time search path for libraries. This way LibOpenBLT's shared
|
||||
# object file (.so) does not have to be installed in the Linux's library path as long
|
||||
# as it is located in the same directory as BootCommander's executable.
|
||||
if(CMAKE_C_COMPILER_ID MATCHES GNU)
|
||||
# According to the CMake docs, item names starting with '-', but not '-l' or
|
||||
# '-framework', are treated as linker flags. This means "-Wl" type linker flags can be
|
||||
# specified here.
|
||||
target_link_libraries(BootCommander ${LIBOPENBLT_LIBNAME} "-Wl,-rpath,.")
|
||||
elseif(CMAKE_C_COMPILER_ID MATCHES MSVC)
|
||||
target_link_libraries(BootCommander ${LIBOPENBLT_LIBNAME})
|
||||
endif()
|
||||
|
||||
|
||||
# Only generate the PC-lint taget if the option is enabled. Use "make BootCommander_LINT"
|
||||
# to lint the project sources
|
||||
|
|
|
@ -160,8 +160,13 @@ int main(int argc, char const * const argv[])
|
|||
appTransportType);
|
||||
/* Extract the firmware filename from the command line. */
|
||||
appFirmwareFile = ExtractFirmwareFileFromCommandLine(argc, argv);
|
||||
/* Note that the transport settings are allowed to be NULL in case of
|
||||
* BLT_TRANSPORT_XCP_V10_USB.
|
||||
*/
|
||||
bool appTransportSettingsOkay = (appTransportType == BLT_TRANSPORT_XCP_V10_USB) ?
|
||||
true : (appTransportSettings != NULL);
|
||||
/* Check the settings that were detected so far. */
|
||||
if ( (appSessionSettings == NULL) || (appTransportSettings == NULL) ||
|
||||
if ( (appSessionSettings == NULL) || (!appTransportSettingsOkay) ||
|
||||
(appFirmwareFile == NULL) )
|
||||
{
|
||||
/* Display program info */
|
||||
|
@ -430,7 +435,7 @@ int main(int argc, char const * const argv[])
|
|||
static void DisplayProgramInfo(void)
|
||||
{
|
||||
printf("--------------------------------------------------------------------------\n");
|
||||
printf("BootCommander version 1.01. Performs firmware updates on a microcontroller\n");
|
||||
printf("BootCommander version 1.02. Performs firmware updates on a microcontroller\n");
|
||||
printf("based system that runs the OpenBLT bootloader.\n\n");
|
||||
printf("Copyright (c) 2017 by Feaser http://www.feaser.com\n");
|
||||
printf("-------------------------------------------------------------------------\n");
|
||||
|
@ -454,6 +459,7 @@ static void DisplayProgramUsage(void)
|
|||
printf(" -t=[name] Name of the communication transport layer:\n");
|
||||
printf(" xcp_rs232 (default) -> XCP on RS232.\n");
|
||||
printf(" xcp_can -> XCP on CAN.\n");
|
||||
printf(" xcp_usb -> XCP on USB.\n");
|
||||
printf("\n");
|
||||
printf("XCP version 1.0 settings (xcp):\n");
|
||||
printf(" -t1=[timeout] Command response timeout in milliseconds as a 16-bit\n");
|
||||
|
@ -502,6 +508,9 @@ static void DisplayProgramUsage(void)
|
|||
printf(" as 29-bit CAN identifiers, if this 8-bit value is > 0\n");
|
||||
printf(" (Default = 0).\n");
|
||||
printf("\n");
|
||||
printf("XCP on USB settings (xcp_usb):\n");
|
||||
printf(" No additional settings needed.\n");
|
||||
printf("\n");
|
||||
printf("Program settings:\n");
|
||||
printf(" -sm Silent mode switch. When specified, only minimal\n");
|
||||
printf(" information is written to the output (Optional).\n");
|
||||
|
@ -594,6 +603,9 @@ static void DisplayTransportInfo(uint32_t transportType, void const * transportS
|
|||
case BLT_TRANSPORT_XCP_V10_CAN:
|
||||
printf("XCP on CAN\n");
|
||||
break;
|
||||
case BLT_TRANSPORT_XCP_V10_USB:
|
||||
printf("XCP on USB\n");
|
||||
break;
|
||||
default:
|
||||
printf("Unknown\n");
|
||||
break;
|
||||
|
@ -671,6 +683,11 @@ static void DisplayTransportInfo(uint32_t transportType, void const * transportS
|
|||
}
|
||||
break;
|
||||
}
|
||||
case BLT_TRANSPORT_XCP_V10_USB:
|
||||
{
|
||||
printf(" -> No additional settings required.\n");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
printf(" -> No settings specified\n");
|
||||
break;
|
||||
|
@ -956,7 +973,8 @@ static uint32_t ExtractTransportTypeFromCommandLine(int argc, char const * const
|
|||
} transportMap[] =
|
||||
{
|
||||
{ .name = "xcp_rs232", .value = BLT_TRANSPORT_XCP_V10_RS232 },
|
||||
{ .name = "xcp_can", .value = BLT_TRANSPORT_XCP_V10_CAN }
|
||||
{ .name = "xcp_can", .value = BLT_TRANSPORT_XCP_V10_CAN },
|
||||
{ .name = "xcp_usb", .value = BLT_TRANSPORT_XCP_V10_USB }
|
||||
};
|
||||
|
||||
/* Set the default transport type in case nothing was specified on the command line. */
|
||||
|
@ -1158,6 +1176,12 @@ static void * ExtractTransportSettingsFromCommandLine(int argc,
|
|||
}
|
||||
}
|
||||
break;
|
||||
/* -------------------------- XCP on USB --------------------------------------- */
|
||||
case BLT_TRANSPORT_XCP_V10_USB:
|
||||
/* No additional command line parameters are neede for the USB transport
|
||||
* layer.
|
||||
*/
|
||||
break;
|
||||
/* -------------------------- Unknown ------------------------------------------ */
|
||||
default:
|
||||
/* Noting to extract. */
|
||||
|
|
|
@ -41,16 +41,16 @@ set(CMAKE_BUILD_TYPE "Debug")
|
|||
#****************************************************************************************
|
||||
# Options
|
||||
#****************************************************************************************
|
||||
# Add option with default value to enable the generation and building of the static
|
||||
# library. It can be overridden on the command line when CMake is called using the
|
||||
# following parameter: -DBUILD_STATIC=OFF
|
||||
option(BUILD_STATIC "Configurable to enable/disable building of the static library" ON)
|
||||
|
||||
# Add option with default value to enable the generation and building of the shared
|
||||
# library. It can be overridden on the command line when CMake is called using the
|
||||
# following parameter: -DBUILD_SHARED=OFF
|
||||
# library. By default it is turned on. It can be overridden on the command line when
|
||||
# CMake is called using the following parameter: -DBUILD_SHARED=OFF
|
||||
option(BUILD_SHARED "Configurable to enable/disable building of the shared library" ON)
|
||||
|
||||
# Add option with default value to enable the generation and building of the static
|
||||
# library. By default it is turned off. It can be overridden on the command line when
|
||||
# CMake is called using the following parameter: -DBUILD_STATIC=ON
|
||||
option(BUILD_STATIC "Configurable to enable/disable building of the static library" OFF)
|
||||
|
||||
# Add option with default value to disable the generation of the PC-lint target. It can
|
||||
# be overridden on the command line when CMake is called using the following parameter:
|
||||
# -DLINT_ENABLED=ON
|
||||
|
@ -131,6 +131,9 @@ set(
|
|||
#****************************************************************************************
|
||||
# Only generate the static library taget if the option is enabled. Use
|
||||
# "make openblt_static" to individually build the static library.
|
||||
# Note that when you link your own application to the static library of LibOpenBLT under
|
||||
# Unix, you need to also link the LibUsb library by adding usb-1.0 to the linker library
|
||||
# dependencies.
|
||||
if(BUILD_STATIC)
|
||||
add_library(openblt_static STATIC ${LIB_SRCS})
|
||||
SET_TARGET_PROPERTIES(openblt_static PROPERTIES OUTPUT_NAME openblt CLEAN_DIRECT_OUTPUT 1)
|
||||
|
@ -140,6 +143,13 @@ endif(BUILD_STATIC)
|
|||
# "make openblt_shared" to build individually shared library.
|
||||
if(BUILD_SHARED)
|
||||
add_library(openblt_shared SHARED ${LIB_SRCS})
|
||||
if(UNIX)
|
||||
# Under Unix the LibUsb library (http://libusb.info/) is needed for the USB support.
|
||||
# Make sure the libusb-1.0-0 and libusb-1.0-0-dev packages are installed to be able to
|
||||
# build LibOpenBLT. Example under Debian/Ubuntu:
|
||||
# sudo apt-get install libusb-1.0-0 libusb-1.0-0-dev
|
||||
target_link_libraries(openblt_shared usb-1.0)
|
||||
endif(UNIX)
|
||||
if(CMAKE_C_COMPILER_ID MATCHES MSVC)
|
||||
# Microsoft Visual Studio does not add "lib" to the name of the DLL, whereas GCC
|
||||
# (including MinGW) does. Correct this here.
|
||||
|
|
|
@ -179,6 +179,7 @@ size-options.lnt // This .lnt file should be generated (preferrably
|
|||
-elib(93) // allow newlines within quoted string arguments to macros
|
||||
-elib(46) // allow bit fields to have integral types other than
|
||||
// '_Bool' and 'int'.
|
||||
-elibsym(793) // suppress warning about limit of 31 significant characters
|
||||
-elibsym(628) // Suppress 628 for __builtin symbols.
|
||||
|
||||
-esym(528,__huge_val,__nan,__qnan,__qnanf,__snan,__snanf)
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "xcploader.h" /* XCP loader module */
|
||||
#include "xcptpuart.h" /* XCP UART transport layer */
|
||||
#include "xcptpcan.h" /* XCP CAN transport layer */
|
||||
#include "xcptpusb.h" /* XCP USB transport layer */
|
||||
|
||||
|
||||
/****************************************************************************************
|
||||
|
@ -49,10 +50,10 @@
|
|||
* for major-, minor-, and patch-version. Version 1.05.12 would for example be
|
||||
* 10512.
|
||||
*/
|
||||
#define BLT_VERSION_NUMBER (10100u)
|
||||
#define BLT_VERSION_NUMBER (10200u)
|
||||
|
||||
/** \brief The version number of the library as a null-terminated string. */
|
||||
#define BLT_VERSION_STRING "1.01.00"
|
||||
#define BLT_VERSION_STRING "1.02.00"
|
||||
|
||||
|
||||
/****************************************************************************************
|
||||
|
@ -117,7 +118,8 @@ LIBOPENBLT_EXPORT void BltSessionInit(uint32_t sessionType,
|
|||
*/
|
||||
assert(sessionType == BLT_SESSION_XCP_V10);
|
||||
assert( (transportType == BLT_TRANSPORT_XCP_V10_RS232) || \
|
||||
(transportType == BLT_TRANSPORT_XCP_V10_CAN) );
|
||||
(transportType == BLT_TRANSPORT_XCP_V10_CAN) || \
|
||||
(transportType == BLT_TRANSPORT_XCP_V10_USB) );
|
||||
|
||||
/* Initialize the correct session. */
|
||||
if (sessionType == BLT_SESSION_XCP_V10) /*lint !e774 */
|
||||
|
@ -169,25 +171,40 @@ LIBOPENBLT_EXPORT void BltSessionInit(uint32_t sessionType,
|
|||
}
|
||||
else if (transportType == BLT_TRANSPORT_XCP_V10_CAN)
|
||||
{
|
||||
/* Cast transport settings to the correct type. */
|
||||
tBltTransportSettingsXcpV10Can * bltTransportSettingsXcpV10CanPtr;
|
||||
bltTransportSettingsXcpV10CanPtr =
|
||||
(tBltTransportSettingsXcpV10Can * )transportSettings;
|
||||
/* Convert transport settings to the format supported by the XCP CAN transport
|
||||
* layer. It was made static to make sure it doesn't get out of scope when
|
||||
* used in xcpLoaderSettings.
|
||||
*/
|
||||
static tXcpTpCanSettings xcpTpCanSettings;
|
||||
xcpTpCanSettings.device = bltTransportSettingsXcpV10CanPtr->deviceName;
|
||||
xcpTpCanSettings.channel = bltTransportSettingsXcpV10CanPtr->deviceChannel;
|
||||
xcpTpCanSettings.baudrate = bltTransportSettingsXcpV10CanPtr->baudrate;
|
||||
xcpTpCanSettings.transmitId = bltTransportSettingsXcpV10CanPtr->transmitId;
|
||||
xcpTpCanSettings.receiveId = bltTransportSettingsXcpV10CanPtr->receiveId;
|
||||
xcpTpCanSettings.useExtended = (bltTransportSettingsXcpV10CanPtr->useExtended != 0);
|
||||
/* Verify transportSettings parameters because the XCP CAN transport layer
|
||||
* requires them.
|
||||
*/
|
||||
assert(transportSettings != NULL);
|
||||
/* Only continue if the transportSettings parameter is valid. */
|
||||
if (transportSettings != NULL) /*lint !e774 */
|
||||
{
|
||||
/* Cast transport settings to the correct type. */
|
||||
tBltTransportSettingsXcpV10Can * bltTransportSettingsXcpV10CanPtr;
|
||||
bltTransportSettingsXcpV10CanPtr =
|
||||
(tBltTransportSettingsXcpV10Can *)transportSettings;
|
||||
/* Convert transport settings to the format supported by the XCP CAN transport
|
||||
* layer. It was made static to make sure it doesn't get out of scope when
|
||||
* used in xcpLoaderSettings.
|
||||
*/
|
||||
static tXcpTpCanSettings xcpTpCanSettings;
|
||||
xcpTpCanSettings.device = bltTransportSettingsXcpV10CanPtr->deviceName;
|
||||
xcpTpCanSettings.channel = bltTransportSettingsXcpV10CanPtr->deviceChannel;
|
||||
xcpTpCanSettings.baudrate = bltTransportSettingsXcpV10CanPtr->baudrate;
|
||||
xcpTpCanSettings.transmitId = bltTransportSettingsXcpV10CanPtr->transmitId;
|
||||
xcpTpCanSettings.receiveId = bltTransportSettingsXcpV10CanPtr->receiveId;
|
||||
xcpTpCanSettings.useExtended = (bltTransportSettingsXcpV10CanPtr->useExtended != 0);
|
||||
/* Store transport layer settings in the XCP loader settings. */
|
||||
xcpLoaderSettings.transportSettings = &xcpTpCanSettings;
|
||||
/* Link the transport layer to the XCP loader settings. */
|
||||
xcpLoaderSettings.transport = XcpTpCanGetTransport();
|
||||
}
|
||||
}
|
||||
else if (transportType == BLT_TRANSPORT_XCP_V10_USB)
|
||||
{
|
||||
/* Store transport layer settings in the XCP loader settings. */
|
||||
xcpLoaderSettings.transportSettings = &xcpTpCanSettings;
|
||||
xcpLoaderSettings.transportSettings = NULL;
|
||||
/* Link the transport layer to the XCP loader settings. */
|
||||
xcpLoaderSettings.transport = XcpTpCanGetTransport();
|
||||
xcpLoaderSettings.transport = XcpTpUsbGetTransport();
|
||||
}
|
||||
/* Perform actual session initialization. */
|
||||
SessionInit(XcpLoaderGetProtocol(), &xcpLoaderSettings);
|
||||
|
|
|
@ -103,6 +103,11 @@ LIBOPENBLT_EXPORT char const * BltVersionGetString(void);
|
|||
*/
|
||||
#define BLT_TRANSPORT_XCP_V10_CAN ((uint32_t)1u)
|
||||
|
||||
/** \brief Transport layer for the XCP v1.0 protocol that uses USB Bulk for data
|
||||
* exchange.
|
||||
*/
|
||||
#define BLT_TRANSPORT_XCP_V10_USB ((uint32_t)2u)
|
||||
|
||||
|
||||
/****************************************************************************************
|
||||
* Type definitions
|
||||
|
|
|
@ -73,6 +73,7 @@ const
|
|||
// Transport layer for the XCP v1.0 protocol that uses Controller Area Network (CAN)
|
||||
// for data exchange.
|
||||
BLT_TRANSPORT_XCP_V10_CAN: LongWord = 1;
|
||||
BLT_TRANSPORT_XCP_V10_USB: LongWord = 2;
|
||||
|
||||
type
|
||||
// Structure layout of the XCP version 1.0 session settings.
|
||||
|
|
|
@ -0,0 +1,366 @@
|
|||
/************************************************************************************//**
|
||||
* \file port/linux/usbbulk.c
|
||||
* \brief USB bulk driver source file.
|
||||
* \ingroup XcpTpUsb
|
||||
* \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 <assert.h> /* for assertions */
|
||||
#include <stdint.h> /* for standard integer types */
|
||||
#include <stddef.h> /* for NULL declaration */
|
||||
#include <stdbool.h> /* for boolean type */
|
||||
#include "usbbulk.h" /* USB bulk driver */
|
||||
#include <libusb-1.0/libusb.h> /* LibUsb 1.0 driver */
|
||||
|
||||
|
||||
/****************************************************************************************
|
||||
* Macro definitions
|
||||
****************************************************************************************/
|
||||
/** \brief Size of the internal endpoint read buffer. This should be the same as the size
|
||||
* of the buffer size of the endpoint on the USB device itself.
|
||||
*/
|
||||
#define USBBULK_READ_DATA_BUFFER_SIZE (64u)
|
||||
|
||||
|
||||
/****************************************************************************************
|
||||
* Local constant declarations
|
||||
****************************************************************************************/
|
||||
/** \brief Vendor ID of the OpenBLT bootloader as assigned by the OpenMoko project. */
|
||||
static const uint16_t openBltVendorId = 0x1D50;
|
||||
|
||||
/** \brief Product ID of the OpenBLT bootloader as assigned by the OpenMoko project. */
|
||||
static const uint16_t openBltProductId = 0x60AC;
|
||||
|
||||
|
||||
/****************************************************************************************
|
||||
* Local data declarations
|
||||
****************************************************************************************/
|
||||
/** \brief LibUsb context. */
|
||||
static libusb_context * libUsbCtx;
|
||||
|
||||
/** \brief LibUsb device handle. */
|
||||
static libusb_device_handle * libUsbDevHandle;
|
||||
|
||||
/** \brief Internal endpoint read buffer. With LibUsb endpoint read operations should
|
||||
* always be attempted with the size of the endpoint buffer on the USB device
|
||||
* itself.
|
||||
*/
|
||||
static uint8_t readDataBuffer[USBBULK_READ_DATA_BUFFER_SIZE];
|
||||
|
||||
/** \brief Variable that holds the number of bytes that were read from the endpoint, but
|
||||
* were not yet retrieved from this module via UsbBulkRead().
|
||||
*/
|
||||
static uint8_t readDataPending;
|
||||
|
||||
/** \brief Index into the endpoint read buffer (readDataBuffer[]) that point to the next
|
||||
* byte value that should be read.
|
||||
*/
|
||||
static uint8_t readDataCurrentReadIdx;
|
||||
|
||||
|
||||
/************************************************************************************//**
|
||||
** \brief Initializes the USB bulk driver.
|
||||
**
|
||||
****************************************************************************************/
|
||||
void UsbBulkInit(void)
|
||||
{
|
||||
/* Initialize locals. */
|
||||
libUsbCtx = NULL;
|
||||
libUsbDevHandle = NULL;
|
||||
readDataPending = 0;
|
||||
readDataCurrentReadIdx = 0;
|
||||
|
||||
/* Initialize LibUsb. */
|
||||
if (libusb_init(&libUsbCtx) != (int)LIBUSB_SUCCESS)
|
||||
{
|
||||
/* Error occurred while initializing LibUsb. Invalidate the context. */
|
||||
libUsbCtx = NULL;
|
||||
}
|
||||
/* Only continue initialization with a valid context. */
|
||||
if (libUsbCtx != NULL)
|
||||
{
|
||||
/* Set the log message verbosity as advised by the documentation. */
|
||||
libusb_set_debug(libUsbCtx, (int)LIBUSB_LOG_LEVEL_WARNING);
|
||||
}
|
||||
} /*** end of UsbBulkInit ***/
|
||||
|
||||
|
||||
/************************************************************************************//**
|
||||
** \brief Terminates the USB bulk driver.
|
||||
**
|
||||
****************************************************************************************/
|
||||
void UsbBulkTerminate(void)
|
||||
{
|
||||
/* Terminate LibUsb. */
|
||||
if (libUsbCtx != NULL)
|
||||
{
|
||||
libusb_exit(libUsbCtx);
|
||||
/* Invalidate the context. */
|
||||
libUsbCtx = NULL;
|
||||
}
|
||||
} /*** end of UsbBulkTerminate ***/
|
||||
|
||||
|
||||
/************************************************************************************//**
|
||||
** \brief Opens the connection with the USB device.
|
||||
** \return True if successful, false otherwise.
|
||||
**
|
||||
****************************************************************************************/
|
||||
bool UsbBulkOpen(void)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
/* Reset read buffer management variables. */
|
||||
readDataPending = 0;
|
||||
readDataCurrentReadIdx = 0;
|
||||
|
||||
/* Only continue with a valid context. */
|
||||
if (libUsbCtx != NULL)
|
||||
{
|
||||
/* Set the result to okay and only update it in case of an error from here on. */
|
||||
result = true;
|
||||
/* Attempt to open the USB device. */
|
||||
libUsbDevHandle = libusb_open_device_with_vid_pid(libUsbCtx, openBltVendorId,
|
||||
openBltProductId);
|
||||
/* Check if the USB device could be opened. */
|
||||
if (libUsbDevHandle == NULL)
|
||||
{
|
||||
/* Update result. */
|
||||
result = false;
|
||||
}
|
||||
/* Before the USB device can be claimed, it cannot be attached to a kernel driver. */
|
||||
if (result)
|
||||
{
|
||||
if (libusb_kernel_driver_active(libUsbDevHandle, 0) == 1)
|
||||
{
|
||||
/* Kernel driver active, so detach it. */
|
||||
(void)libusb_detach_kernel_driver(libUsbDevHandle, 0);
|
||||
}
|
||||
}
|
||||
/* Attempt to claim the interface. */
|
||||
if (result)
|
||||
{
|
||||
if (libusb_claim_interface(libUsbDevHandle, 0) != (int)LIBUSB_SUCCESS)
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Give the result back to the caller. */
|
||||
return result;
|
||||
} /*** end of UsbBulkOpen ***/
|
||||
|
||||
|
||||
/************************************************************************************//**
|
||||
** \brief Closes the connection with the USB device.
|
||||
**
|
||||
****************************************************************************************/
|
||||
void UsbBulkClose(void)
|
||||
{
|
||||
/* Release the interface and close the connection with the USB device. */
|
||||
if (libUsbDevHandle != NULL)
|
||||
{
|
||||
(void)libusb_release_interface(libUsbDevHandle, 0);
|
||||
libusb_close(libUsbDevHandle);
|
||||
/* Invalidate the handler. */
|
||||
libUsbDevHandle = NULL;
|
||||
}
|
||||
} /*** end of UsbBulkClose ***/
|
||||
|
||||
|
||||
/************************************************************************************//**
|
||||
** \brief Writes data to the USB device.
|
||||
** \param data Pointer to byte array with data to write.
|
||||
** \param length Number of bytes in the data array.
|
||||
** \return True if successful, false otherwise.
|
||||
**
|
||||
****************************************************************************************/
|
||||
bool UsbBulkWrite(uint8_t const * data, uint16_t length)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
/* Check parameters. */
|
||||
assert(data != NULL);
|
||||
assert(length > 0);
|
||||
|
||||
/* Only continue with valid parameters. */
|
||||
if ((data != NULL) && (length > 0)) /*lint !e774 */
|
||||
{
|
||||
/* Only continue with a valid context and device handle. */
|
||||
if ( (libUsbDevHandle != NULL) && (libUsbCtx != NULL) )
|
||||
{
|
||||
/* Attempt to write the data to the endpoint. */
|
||||
int bytesWritten = 0;
|
||||
int transferResult = libusb_bulk_transfer(libUsbDevHandle, 0x01, (uint8_t *)data,
|
||||
(int)length, &bytesWritten, 0);
|
||||
/* Check the transfer result. */
|
||||
if (transferResult == (int)LIBUSB_SUCCESS)
|
||||
{
|
||||
/* Check if all data was written. */
|
||||
if (bytesWritten == length)
|
||||
{
|
||||
/* Data successfully written the endpoint. */
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Give the result back to the caller. */
|
||||
return result;
|
||||
} /*** end of UsbBulkWrite ***/
|
||||
|
||||
|
||||
/************************************************************************************//**
|
||||
** \brief Reads data from the USB device.
|
||||
** \param data Pointer to byte array where received data should be stored.
|
||||
** \param length Number of bytes to read from the USB device.
|
||||
** \param timeout Timeout in milliseconds for the read operation.
|
||||
** \return True if successful, false otherwise.
|
||||
**
|
||||
****************************************************************************************/
|
||||
bool UsbBulkRead(uint8_t * data, uint16_t length, uint32_t timeout)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
/* Check parameters. */
|
||||
assert(data != NULL);
|
||||
assert(length > 0);
|
||||
assert(length <= USBBULK_READ_DATA_BUFFER_SIZE);
|
||||
|
||||
/* Only continue with valid parameters. */
|
||||
if ((data != NULL) && (length > 0) &&
|
||||
(length <= USBBULK_READ_DATA_BUFFER_SIZE) ) /*lint !e774 */
|
||||
{
|
||||
/* Only continue with a valid context and device handle. */
|
||||
if ( (libUsbDevHandle != NULL) && (libUsbCtx != NULL) )
|
||||
{
|
||||
uint16_t totalBytesRead = 0;
|
||||
uint8_t * currentWriteDataPtr = data;
|
||||
|
||||
/* First empty out whatever is still pending in the read buffer. */
|
||||
uint16_t bytesPendingInBuffer = length;
|
||||
if (readDataPending < length)
|
||||
{
|
||||
bytesPendingInBuffer = readDataPending;
|
||||
}
|
||||
uint16_t bytesToReadFromDevice = length - bytesPendingInBuffer;
|
||||
/* Copy data. */
|
||||
for (uint16_t idx = 0; idx < bytesPendingInBuffer; idx++)
|
||||
{
|
||||
/* Sanity check for the current read indexer/ */
|
||||
assert(readDataCurrentReadIdx < USBBULK_READ_DATA_BUFFER_SIZE);
|
||||
/* Only copy data if current read indexer is not out of bounds. */
|
||||
if (readDataCurrentReadIdx < USBBULK_READ_DATA_BUFFER_SIZE)
|
||||
{
|
||||
*currentWriteDataPtr = readDataBuffer[readDataCurrentReadIdx];
|
||||
}
|
||||
/* Update total bytes read counter. */
|
||||
totalBytesRead++;
|
||||
/* Increment the write data pointer. */
|
||||
currentWriteDataPtr++;
|
||||
/* Increment current read indexer. */
|
||||
readDataCurrentReadIdx++;
|
||||
/* Sanity check for data pending counter. */
|
||||
assert(readDataPending > 0);
|
||||
/* Decrement data pending counter. */
|
||||
if (readDataPending > 0)
|
||||
{
|
||||
readDataPending--;
|
||||
}
|
||||
}
|
||||
|
||||
/* If more data is still to be read, then perform a read operation of the full
|
||||
* endpoint size.
|
||||
*/
|
||||
if (bytesToReadFromDevice > 0)
|
||||
{
|
||||
/* Sanity check. */
|
||||
assert(readDataPending == 0);
|
||||
|
||||
/* Attempt to read data from the endpoint. Should be done in steps of the
|
||||
* endpoint buffer size on the target. This is 64 for OpenBLT so exactly the size
|
||||
* of our read buffer.
|
||||
*/
|
||||
int bytesRead = 0;
|
||||
int transferResult = libusb_bulk_transfer(libUsbDevHandle, 0x81, readDataBuffer,
|
||||
USBBULK_READ_DATA_BUFFER_SIZE,
|
||||
&bytesRead, timeout);
|
||||
if (transferResult == (int)LIBUSB_SUCCESS)
|
||||
{
|
||||
/* Update read buffer management. */
|
||||
readDataPending = (uint8_t)bytesRead;
|
||||
readDataCurrentReadIdx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy remaining data from the newly read data buffer contents as long as they
|
||||
* are present.
|
||||
*/
|
||||
uint16_t bytesToCopy = bytesToReadFromDevice;
|
||||
if (readDataPending < bytesToCopy)
|
||||
{
|
||||
bytesToCopy = readDataPending;
|
||||
}
|
||||
/* Copy data. */
|
||||
for (uint16_t idx = 0; idx < bytesToCopy; idx++)
|
||||
{
|
||||
/* Sanity check for the current read indexer/ */
|
||||
assert(readDataCurrentReadIdx < USBBULK_READ_DATA_BUFFER_SIZE);
|
||||
/* Only copy data if current read indexer is not out of bounds. */
|
||||
if (readDataCurrentReadIdx < USBBULK_READ_DATA_BUFFER_SIZE)
|
||||
{
|
||||
*currentWriteDataPtr = readDataBuffer[readDataCurrentReadIdx];
|
||||
}
|
||||
/* Update total bytes read counter. */
|
||||
totalBytesRead++;
|
||||
/* Increment the write data pointer. */
|
||||
currentWriteDataPtr++;
|
||||
/* Increment current read indexer. */
|
||||
readDataCurrentReadIdx++;
|
||||
/* Sanity check for data pending counter. */
|
||||
assert(readDataPending > 0);
|
||||
/* Decrement data pending counter. */
|
||||
if (readDataPending > 0)
|
||||
{
|
||||
readDataPending--;
|
||||
}
|
||||
}
|
||||
|
||||
/* As a final step, check that all requested data bytes were read. */
|
||||
if (totalBytesRead == length)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Give the result back to the caller. */
|
||||
return result;
|
||||
} /*** end of UsbBulkRead ***/
|
||||
|
||||
|
||||
/*********************************** end of usbbulk.c **********************************/
|
||||
|
|
@ -0,0 +1,374 @@
|
|||
/************************************************************************************//**
|
||||
* \file port/windows/usbbulk.c
|
||||
* \brief USB bulk driver source file.
|
||||
* \ingroup XcpTpUsb
|
||||
* \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 <assert.h> /* for assertions */
|
||||
#include <stdint.h> /* for standard integer types */
|
||||
#include <stddef.h> /* for NULL declaration */
|
||||
#include <stdbool.h> /* for boolean type */
|
||||
#include <windows.h> /* for Windows API */
|
||||
#include "usbbulk.h" /* USB bulk driver */
|
||||
|
||||
|
||||
/****************************************************************************************
|
||||
* Macro definitions
|
||||
****************************************************************************************/
|
||||
/* USB bulk driver return values. */
|
||||
#define UBL_ERROR (0u)
|
||||
#define UBL_OKAY (1u)
|
||||
|
||||
|
||||
/****************************************************************************************
|
||||
* Type definitions
|
||||
****************************************************************************************/
|
||||
/* USB bulk driver interface functions. */
|
||||
typedef uint8_t (__stdcall * tUsbBulkLibFuncOpen)(LPGUID guid);
|
||||
typedef void (__stdcall * tUsbBulkLibFuncClose)(void);
|
||||
typedef uint8_t (__stdcall * tUsbBulkLibFuncTransmit)(uint8_t * data, uint16_t len);
|
||||
typedef uint8_t (__stdcall * tUsbBulkLibFuncReceive)(uint8_t * data, uint16_t len, uint32_t timeout);
|
||||
|
||||
|
||||
/***************************************************************************************
|
||||
* Function prototypes
|
||||
****************************************************************************************/
|
||||
/* USB bulk driver handling. */
|
||||
static void UsbBulkLibLoadDll(void);
|
||||
static void UsbBulkLibUnloadDll(void);
|
||||
static uint8_t UsbBulkLibFuncOpen(LPGUID guid);
|
||||
static void UsbBulkLibFuncClose(void);
|
||||
static uint8_t UsbBulkLibFuncTransmit(uint8_t * data, uint16_t len);
|
||||
static uint8_t UsbBulkLibFuncReceive(uint8_t * data, uint16_t len, uint32_t timeout);
|
||||
|
||||
|
||||
/****************************************************************************************
|
||||
* Local data declarations
|
||||
****************************************************************************************/
|
||||
/** \brief Handle to the USB bulk driver dynamic link library. */
|
||||
static HINSTANCE usbBulkLibDllHandle;
|
||||
|
||||
/** \brief Function pointer to the USB bulk driver library Open function. */
|
||||
static tUsbBulkLibFuncOpen usbBulkLibFuncOpenPtr;
|
||||
|
||||
/** \brief Function pointer to the USB bulk driver library Close function. */
|
||||
static tUsbBulkLibFuncClose usbBulkLibFuncClosePtr;
|
||||
|
||||
/** \brief Function pointer to the USB bulk driver library Transmit function. */
|
||||
static tUsbBulkLibFuncTransmit usbBulkLibFuncTransmitPtr;
|
||||
|
||||
/** \brief Function pointer to the USB bulk driver library Receive function. */
|
||||
static tUsbBulkLibFuncReceive usbBulkLibFuncReceivePtr;
|
||||
|
||||
|
||||
/************************************************************************************//**
|
||||
** \brief Initializes the USB bulk driver.
|
||||
**
|
||||
****************************************************************************************/
|
||||
void UsbBulkInit(void)
|
||||
{
|
||||
/* Initialize locals. */
|
||||
usbBulkLibDllHandle = NULL;
|
||||
/* Reset library function pointers. */
|
||||
usbBulkLibFuncOpenPtr = NULL;
|
||||
usbBulkLibFuncClosePtr = NULL;
|
||||
usbBulkLibFuncTransmitPtr = NULL;
|
||||
usbBulkLibFuncReceivePtr = NULL;
|
||||
/* Perform initialization of USB bulk driver API. */
|
||||
UsbBulkLibLoadDll();
|
||||
} /*** end of UsbBulkInit ***/
|
||||
|
||||
|
||||
/************************************************************************************//**
|
||||
** \brief Terminates the USB bulk driver.
|
||||
**
|
||||
****************************************************************************************/
|
||||
void UsbBulkTerminate(void)
|
||||
{
|
||||
/* Perform termination of USB bulk driver API. */
|
||||
UsbBulkLibUnloadDll();
|
||||
} /*** end of UsbBulkTerminate ***/
|
||||
|
||||
|
||||
/************************************************************************************//**
|
||||
** \brief Opens the connection with the USB device.
|
||||
** \return True if successful, false otherwise.
|
||||
**
|
||||
****************************************************************************************/
|
||||
bool UsbBulkOpen(void)
|
||||
{
|
||||
/* This must be the same GUID as the one declared in the *.inf driver file. */
|
||||
static GUID deviceGuidOpenBLT =
|
||||
{
|
||||
0x807999C3, 0xE4E0, 0x40EA, 0x81, 0x88, 0x48, 0xE8, 0x52, 0xB5, 0x4F, 0x2B
|
||||
};
|
||||
bool result = false;
|
||||
|
||||
/* Open the connection with the USB device. */
|
||||
if (UsbBulkLibFuncOpen(&deviceGuidOpenBLT) == UBL_OKAY)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
/* Give the result back to the caller. */
|
||||
return result;
|
||||
} /*** end of UsbBulkOpen ***/
|
||||
|
||||
|
||||
/************************************************************************************//**
|
||||
** \brief Closes the connection with the USB device.
|
||||
**
|
||||
****************************************************************************************/
|
||||
void UsbBulkClose(void)
|
||||
{
|
||||
/* Close the connection with the USB device. */
|
||||
UsbBulkLibFuncClose();
|
||||
} /*** end of UsbBulkClose ***/
|
||||
|
||||
|
||||
/************************************************************************************//**
|
||||
** \brief Writes data to the USB device.
|
||||
** \param data Pointer to byte array with data to write.
|
||||
** \param length Number of bytes in the data array.
|
||||
** \return True if successful, false otherwise.
|
||||
**
|
||||
****************************************************************************************/
|
||||
bool UsbBulkWrite(uint8_t const * data, uint16_t length)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
/* Check parameters. */
|
||||
assert(data != NULL);
|
||||
assert(length > 0);
|
||||
|
||||
/* Only continue with valid parameters. */
|
||||
if ((data != NULL) && (length > 0)) /*lint !e774 */
|
||||
{
|
||||
/* Write data to the USB device. */
|
||||
if (UsbBulkLibFuncTransmit((uint8_t *)data, length) == UBL_OKAY)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
/* Give the result back to the caller. */
|
||||
return result;
|
||||
} /*** end of UsbBulkWrite ***/
|
||||
|
||||
|
||||
/************************************************************************************//**
|
||||
** \brief Reads data from the USB device.
|
||||
** \param data Pointer to byte array where received data should be stored.
|
||||
** \param length Number of bytes to read from the USB device.
|
||||
** \param timeout Timeout in milliseconds for the read operation.
|
||||
** \return True if successful, false otherwise.
|
||||
**
|
||||
****************************************************************************************/
|
||||
bool UsbBulkRead(uint8_t * data, uint16_t length, uint32_t timeout)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
(void)timeout;
|
||||
|
||||
/* Check parameters. */
|
||||
assert(data != NULL);
|
||||
assert(length > 0);
|
||||
|
||||
/* Only continue with valid parameters. */
|
||||
if ((data != NULL) && (length > 0)) /*lint !e774 */
|
||||
{
|
||||
/* Read data from the USB device. */
|
||||
if (UsbBulkLibFuncReceive(data, length, timeout) == UBL_OKAY)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
/* Give the result back to the caller. */
|
||||
return result;
|
||||
} /*** end of UsbBulkRead ***/
|
||||
|
||||
|
||||
/************************************************************************************//**
|
||||
** \brief Loads the USB bulk driver DLL and initializes the API function pointers.
|
||||
**
|
||||
****************************************************************************************/
|
||||
static void UsbBulkLibLoadDll(void)
|
||||
{
|
||||
/* Start out by resetting the API function pointers. */
|
||||
usbBulkLibFuncOpenPtr = NULL;
|
||||
usbBulkLibFuncClosePtr = NULL;
|
||||
usbBulkLibFuncTransmitPtr = NULL;
|
||||
usbBulkLibFuncReceivePtr = NULL;
|
||||
|
||||
/* Attempt to load the library and obtain a handle to it. */
|
||||
usbBulkLibDllHandle = LoadLibrary("UsbBulkLib");
|
||||
|
||||
/* Assert libary handle. */
|
||||
assert(usbBulkLibDllHandle != NULL);
|
||||
|
||||
/* Only continue if the library was successfully loaded */
|
||||
if (usbBulkLibDllHandle != NULL) /*lint !e774 */
|
||||
{
|
||||
/* Set UblOpen function pointer. */
|
||||
usbBulkLibFuncOpenPtr = (tUsbBulkLibFuncOpen)GetProcAddress(usbBulkLibDllHandle, "UblOpen");
|
||||
/* Set UblClose function pointer. */
|
||||
usbBulkLibFuncClosePtr = (tUsbBulkLibFuncClose)GetProcAddress(usbBulkLibDllHandle, "UblClose");
|
||||
/* Set UblTransmit function pointer. */
|
||||
usbBulkLibFuncTransmitPtr = (tUsbBulkLibFuncTransmit)GetProcAddress(usbBulkLibDllHandle, "UblTransmit");
|
||||
/* Set UblReceive function pointer. */
|
||||
usbBulkLibFuncReceivePtr = (tUsbBulkLibFuncReceive)GetProcAddress(usbBulkLibDllHandle, "UblReceive");
|
||||
}
|
||||
} /*** end of UsbBulkLibLoadDll ***/
|
||||
|
||||
|
||||
/************************************************************************************//**
|
||||
** \brief Unloads the USB bulk driver DLL and resets the API function pointers.
|
||||
**
|
||||
****************************************************************************************/
|
||||
static void UsbBulkLibUnloadDll(void)
|
||||
{
|
||||
/* Reset the API function pointers. */
|
||||
usbBulkLibFuncOpenPtr = NULL;
|
||||
usbBulkLibFuncClosePtr = NULL;
|
||||
usbBulkLibFuncTransmitPtr = NULL;
|
||||
usbBulkLibFuncReceivePtr = NULL;
|
||||
|
||||
/* Unload the library and invalidate its handle. */
|
||||
if (usbBulkLibDllHandle != NULL)
|
||||
{
|
||||
(void)FreeLibrary(usbBulkLibDllHandle);
|
||||
usbBulkLibDllHandle = NULL;
|
||||
}
|
||||
} /*** end of UsbBulkLibUnloadDll ***/
|
||||
|
||||
|
||||
/************************************************************************************//**
|
||||
** \brief Opens and configures the connection with the USB bulk device.
|
||||
** \param guid Pointer to GUID of the USB bulk device as found in the driver's
|
||||
** INF-file.
|
||||
** \return UBL_OKAY if successful, UBL_ERROR otherwise.
|
||||
**
|
||||
****************************************************************************************/
|
||||
static uint8_t UsbBulkLibFuncOpen(LPGUID guid)
|
||||
{
|
||||
uint8_t result = UBL_ERROR;
|
||||
|
||||
/* Check function pointer and library handle. */
|
||||
assert(usbBulkLibFuncOpenPtr != NULL);
|
||||
assert(usbBulkLibDllHandle != NULL);
|
||||
|
||||
/* Only continue with valid function pointer and library handle. */
|
||||
if ((usbBulkLibFuncOpenPtr != NULL) && (usbBulkLibDllHandle != NULL)) /*lint !e774 */
|
||||
{
|
||||
/* Call library function. */
|
||||
result = usbBulkLibFuncOpenPtr(guid);
|
||||
}
|
||||
/* Give the result back to the caller. */
|
||||
return result;
|
||||
} /*** end of UsbBulkLibFuncOpen ***/
|
||||
|
||||
|
||||
/************************************************************************************//**
|
||||
** \brief Closes the connection with the USB bulk device and frees all the related
|
||||
** handles.
|
||||
**
|
||||
****************************************************************************************/
|
||||
static void UsbBulkLibFuncClose(void)
|
||||
{
|
||||
/* Check function pointer and library handle. */
|
||||
assert(usbBulkLibFuncClosePtr != NULL);
|
||||
assert(usbBulkLibDllHandle != NULL);
|
||||
|
||||
/* Only continue with valid function pointer and library handle. */
|
||||
if ((usbBulkLibFuncClosePtr != NULL) && (usbBulkLibDllHandle != NULL)) /*lint !e774 */
|
||||
{
|
||||
/* Call library function. */
|
||||
usbBulkLibFuncClosePtr();
|
||||
}
|
||||
} /*** end of UsbBulkLibFuncClose ***/
|
||||
|
||||
|
||||
/************************************************************************************//**
|
||||
** \brief Starts transmission of the data on the bulk OUT pipe. Because USB bulk
|
||||
** transmissions are quick, this function does not use the overlapped
|
||||
** functionality, which means the caller is blocked until the tranmission
|
||||
** completed.
|
||||
** \param data Pointer to byte array with transmit data.
|
||||
** \param len Number of bytes to transmit.
|
||||
** \return UBL_OKAY if successful, UBL_ERROR otherwise.
|
||||
**
|
||||
****************************************************************************************/
|
||||
static uint8_t UsbBulkLibFuncTransmit(uint8_t * data, uint16_t len)
|
||||
{
|
||||
uint8_t result = UBL_ERROR;
|
||||
|
||||
/* Check function pointer and library handle. */
|
||||
assert(usbBulkLibFuncTransmitPtr != NULL);
|
||||
assert(usbBulkLibDllHandle != NULL);
|
||||
|
||||
/* Only continue with valid function pointer and library handle. */
|
||||
if ((usbBulkLibFuncTransmitPtr != NULL) && (usbBulkLibDllHandle != NULL)) /*lint !e774 */
|
||||
{
|
||||
/* Call library function. */
|
||||
result = usbBulkLibFuncTransmitPtr(data, len);
|
||||
}
|
||||
/* Give the result back to the caller. */
|
||||
return result;
|
||||
} /*** end of UsbBulkLibFuncTransmit ***/
|
||||
|
||||
|
||||
/************************************************************************************//**
|
||||
** \brief Starts the asynchronous reception of the data from the bulk IN pipe. This
|
||||
** function makes use of the overlapped functionality, which means the calling
|
||||
** thread is placed into sleep mode until the reception is complete.
|
||||
** \param data Pointer to byte array where the data will be stored.
|
||||
** \param len Number of bytes to receive.
|
||||
** \param timeout Maximum time in milliseconds for the read to complete.
|
||||
** \return UBL_OKAY if successful, UBL_TIMEOUT if failure due to timeout or
|
||||
** UBL_ERROR otherwise.
|
||||
**
|
||||
****************************************************************************************/
|
||||
static uint8_t UsbBulkLibFuncReceive(uint8_t * data, uint16_t len, uint32_t timeout)
|
||||
{
|
||||
uint8_t result = UBL_ERROR;
|
||||
|
||||
/* Check function pointer and library handle. */
|
||||
assert(usbBulkLibFuncReceivePtr != NULL);
|
||||
assert(usbBulkLibDllHandle != NULL);
|
||||
|
||||
/* Only continue with valid function pointer and library handle. */
|
||||
if ((usbBulkLibFuncReceivePtr != NULL) && (usbBulkLibDllHandle != NULL)) /*lint !e774 */
|
||||
{
|
||||
/* Call library function. */
|
||||
result = usbBulkLibFuncReceivePtr(data, len, timeout);
|
||||
}
|
||||
/* Give the result back to the caller. */
|
||||
return result;
|
||||
} /*** end of UsbBulkLibFuncReceive ***/
|
||||
|
||||
|
||||
/*********************************** end of usbbulk.c **********************************/
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/************************************************************************************//**
|
||||
* \file usbbulk.h
|
||||
* \brief USB bulk driver header file.
|
||||
* \ingroup XcpTpUsb
|
||||
* \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 USBBULK_H
|
||||
#define USBBULK_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/****************************************************************************************
|
||||
* Function prototypes
|
||||
****************************************************************************************/
|
||||
void UsbBulkInit(void);
|
||||
void UsbBulkTerminate(void);
|
||||
bool UsbBulkOpen(void);
|
||||
void UsbBulkClose(void);
|
||||
bool UsbBulkWrite(uint8_t const * data, uint16_t length);
|
||||
bool UsbBulkRead(uint8_t * data, uint16_t length, uint32_t timeout);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* USBBULK_H */
|
||||
/********************************* end of usbbulk.h ************************************/
|
||||
|
|
@ -0,0 +1,229 @@
|
|||
/************************************************************************************//**
|
||||
* \file xcptpusb.c
|
||||
* \brief XCP USB transport layer source file.
|
||||
* \ingroup XcpTpUsb
|
||||
* \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 <assert.h> /* for assertions */
|
||||
#include <stdint.h> /* for standard integer types */
|
||||
#include <stddef.h> /* for NULL declaration */
|
||||
#include <stdbool.h> /* for boolean type */
|
||||
#include <stdlib.h> /* for standard library */
|
||||
#include <string.h> /* for string library */
|
||||
#include "session.h" /* Communication session module */
|
||||
#include "xcploader.h" /* XCP loader module */
|
||||
#include "xcptpusb.h" /* XCP USB transport layer */
|
||||
#include "util.h" /* Utility module */
|
||||
#include "usbbulk.h" /* USB bulk driver */
|
||||
|
||||
|
||||
/****************************************************************************************
|
||||
* Function prototypes
|
||||
****************************************************************************************/
|
||||
static void XcpTpUsbInit(void const * settings);
|
||||
static void XcpTpUsbTerminate(void);
|
||||
static bool XcpTpUsbConnect(void);
|
||||
static void XcpTpUsbDisconnect(void);
|
||||
static bool XcpTpUsbSendPacket(tXcpTransportPacket const * txPacket,
|
||||
tXcpTransportPacket * rxPacket, uint16_t timeout);
|
||||
|
||||
|
||||
/****************************************************************************************
|
||||
* Local constant declarations
|
||||
****************************************************************************************/
|
||||
/** \brief XCP transport layer structure filled with USB specifics. */
|
||||
static const tXcpTransport usbTransport =
|
||||
{
|
||||
XcpTpUsbInit,
|
||||
XcpTpUsbTerminate,
|
||||
XcpTpUsbConnect,
|
||||
XcpTpUsbDisconnect,
|
||||
XcpTpUsbSendPacket
|
||||
};
|
||||
|
||||
|
||||
/***********************************************************************************//**
|
||||
** \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 * XcpTpUsbGetTransport(void)
|
||||
{
|
||||
return &usbTransport;
|
||||
} /*** end of XcpTpUsbGetTransport ***/
|
||||
|
||||
|
||||
/************************************************************************************//**
|
||||
** \brief Initializes the transport layer.
|
||||
** \param settings Pointer to settings structure.
|
||||
** \return None.
|
||||
**
|
||||
****************************************************************************************/
|
||||
static void XcpTpUsbInit(void const * settings)
|
||||
{
|
||||
/* No settings needed for this transport layer. */
|
||||
(void)settings;
|
||||
|
||||
/* Initialize the USB bulk driver. */
|
||||
UsbBulkInit();
|
||||
} /*** end of XcpTpUsbInit ***/
|
||||
|
||||
|
||||
/************************************************************************************//**
|
||||
** \brief Terminates the transport layer.
|
||||
**
|
||||
****************************************************************************************/
|
||||
static void XcpTpUsbTerminate(void)
|
||||
{
|
||||
/* Terminate the USB bulk driver. */
|
||||
UsbBulkTerminate();
|
||||
} /*** end of XcpTpUsbTerminate ***/
|
||||
|
||||
|
||||
/************************************************************************************//**
|
||||
** \brief Connects to the transport layer.
|
||||
** \return True is connected, false otherwise.
|
||||
**
|
||||
****************************************************************************************/
|
||||
static bool XcpTpUsbConnect(void)
|
||||
{
|
||||
bool result;
|
||||
|
||||
/* Connect to USB device via USB bulk driver. */
|
||||
result = UsbBulkOpen();
|
||||
/* Give the result back to the caller. */
|
||||
return result;
|
||||
} /*** end of XcpTpUsbConnect ***/
|
||||
|
||||
|
||||
/************************************************************************************//**
|
||||
** \brief Disconnects from the transport layer.
|
||||
**
|
||||
****************************************************************************************/
|
||||
static void XcpTpUsbDisconnect(void)
|
||||
{
|
||||
/* Disconnect from USB device via USB bulk driver. */
|
||||
UsbBulkClose();
|
||||
} /*** end of XcpTpUsbDisconnect ***/
|
||||
|
||||
|
||||
/************************************************************************************//**
|
||||
** \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 XcpTpUsbSendPacket(tXcpTransportPacket const * txPacket,
|
||||
tXcpTransportPacket * rxPacket, uint16_t timeout)
|
||||
{
|
||||
bool result = false;
|
||||
uint16_t byteIdx;
|
||||
/* usbBuffer is static to lower the stack load. +1 because the first byte for an XCP
|
||||
* packet on the USB transport layer contains the packet lenght.
|
||||
*/
|
||||
static uint8_t usbBuffer[XCPLOADER_PACKET_SIZE_MAX + 1];
|
||||
uint32_t responseTimeoutTime = 0;
|
||||
|
||||
/* Check parameters. */
|
||||
assert(txPacket != NULL);
|
||||
assert(rxPacket != NULL);
|
||||
|
||||
/* Only continue with valid parameters. */
|
||||
if ( (txPacket != NULL) && (rxPacket != NULL) ) /*lint !e774 */
|
||||
{
|
||||
/* Set result value to okay and only change it from now on if an error occurred. */
|
||||
result = true;
|
||||
/* 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.
|
||||
*/
|
||||
usbBuffer[0] = txPacket->len;
|
||||
for (byteIdx=0; byteIdx<txPacket->len; byteIdx++)
|
||||
{
|
||||
usbBuffer[byteIdx + 1] = txPacket->data[byteIdx];
|
||||
}
|
||||
/* Transmit the packet via the USB bulk driver. */
|
||||
if (!UsbBulkWrite(usbBuffer, txPacket->len + 1))
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
|
||||
/* Only continue if the transmission was successful. */
|
||||
if (result)
|
||||
{
|
||||
/* Determine timeout time for the response packet. */
|
||||
responseTimeoutTime = UtilTimeGetSystemTimeMs() + timeout;
|
||||
/* Initialize packet reception length. */
|
||||
rxPacket->len = 0;
|
||||
/* Receive the first byte. This one contains the packet length and cannot be
|
||||
* zero.
|
||||
*/
|
||||
if (!UsbBulkRead(&rxPacket->len, 1, timeout))
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
/* Check if a valid start of packet was received, in which case the first
|
||||
* byte won't have a zero value.
|
||||
*/
|
||||
if (rxPacket->len == 0)
|
||||
{
|
||||
/* No valid start of packet received, so a timeout occurred. */
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Only continue with reception if a valid packet length was received. */
|
||||
if (result)
|
||||
{
|
||||
/* Check if there is still time available before the initial timeout. */
|
||||
uint32_t currentTime = UtilTimeGetSystemTimeMs();
|
||||
if (currentTime >= responseTimeoutTime)
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Receive the actual packet data. */
|
||||
if (!UsbBulkRead(&rxPacket->data[0], rxPacket->len, responseTimeoutTime - currentTime))
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Give the result back to the caller. */
|
||||
return result;
|
||||
} /*** end of XcpTpUsbSendPacket ***/
|
||||
|
||||
|
||||
/*********************************** end of xcptpusb.c *********************************/
|
|
@ -0,0 +1,50 @@
|
|||
/************************************************************************************//**
|
||||
* \file xcptpusb.h
|
||||
* \brief XCP USB transport layer header file.
|
||||
* \ingroup XcpTpUsb
|
||||
* \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 XcpTpUsb XCP USB transport layer
|
||||
* \brief This module implements the XCP transport layer for USB.
|
||||
* \ingroup XcpLoader
|
||||
****************************************************************************************/
|
||||
#ifndef XCPTPUSB_H
|
||||
#define XCPTPUSB_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************************
|
||||
* Function prototypes
|
||||
****************************************************************************************/
|
||||
tXcpTransport const * XcpTpUsbGetTransport(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* XCPTPUSB_H */
|
||||
/*********************************** end of xcptpusb.h *********************************/
|
Binary file not shown.
|
@ -36,7 +36,7 @@
|
|||
/** \brief Minor version number of the bootloader core. */
|
||||
#define BOOT_VERSION_CORE_MINOR (4u)
|
||||
/** \brief Patch number of the bootloader core. */
|
||||
#define BOOT_VERSION_CORE_BUILD (1u)
|
||||
#define BOOT_VERSION_CORE_BUILD (2u)
|
||||
|
||||
|
||||
/****************************************************************************************
|
||||
|
|
Loading…
Reference in New Issue