mirror of https://github.com/FOME-Tech/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
|
# could be handy for archiving the generated documentation or if some version
|
||||||
# control system is used.
|
# 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
|
# 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
|
# 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
|
# could be handy for archiving the generated documentation or if some version
|
||||||
# control system is used.
|
# 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
|
# 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
|
# 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
|
# could be handy for archiving the generated documentation or if some version
|
||||||
# control system is used.
|
# 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
|
# 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
|
# 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_INC ${PROJECT_SOURCE_DIR}/../LibOpenBLT)
|
||||||
set(LIBOPENBLT_LIB ${PROJECT_OUTPUT_DIRECTORY})
|
set(LIBOPENBLT_LIB ${PROJECT_OUTPUT_DIRECTORY})
|
||||||
|
|
||||||
|
|
||||||
#****************************************************************************************
|
#****************************************************************************************
|
||||||
# Compiler flags
|
# Compiler flags
|
||||||
#****************************************************************************************
|
#****************************************************************************************
|
||||||
|
@ -105,11 +106,11 @@ set(
|
||||||
${INCS}
|
${INCS}
|
||||||
)
|
)
|
||||||
|
|
||||||
# Set library name. When GNU GCC is used, the name to the static library file is used,
|
# Set library name of the OpenBLT Host Library
|
||||||
# otherwise the shared library is used by default. This works fine too, but the static
|
if(CMAKE_C_COMPILER_ID MATCHES MSVC)
|
||||||
# library makes it a bit easier to move the target executable around on the file system.
|
# When building LibOpenBLT with Microsoft Visual Studio, "lib" was added to the name
|
||||||
if(CMAKE_C_COMPILER_ID MATCHES GNU)
|
# of the DLL. This needs to be done as well when linking the library.
|
||||||
set (LIBOPENBLT_LIBNAME libopenblt.a)
|
set (LIBOPENBLT_LIBNAME libopenblt)
|
||||||
else()
|
else()
|
||||||
set (LIBOPENBLT_LIBNAME openblt)
|
set (LIBOPENBLT_LIBNAME openblt)
|
||||||
endif()
|
endif()
|
||||||
|
@ -124,8 +125,19 @@ add_executable(
|
||||||
${PROG_SRCS}
|
${PROG_SRCS}
|
||||||
)
|
)
|
||||||
|
|
||||||
# Add libraries
|
# Add libraries. Note that when compiling with GNU GCC the path of the executable is
|
||||||
target_link_libraries(BootCommander ${LIBOPENBLT_LIBNAME})
|
# 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"
|
# Only generate the PC-lint taget if the option is enabled. Use "make BootCommander_LINT"
|
||||||
# to lint the project sources
|
# to lint the project sources
|
||||||
|
|
|
@ -160,8 +160,13 @@ int main(int argc, char const * const argv[])
|
||||||
appTransportType);
|
appTransportType);
|
||||||
/* Extract the firmware filename from the command line. */
|
/* Extract the firmware filename from the command line. */
|
||||||
appFirmwareFile = ExtractFirmwareFileFromCommandLine(argc, argv);
|
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. */
|
/* Check the settings that were detected so far. */
|
||||||
if ( (appSessionSettings == NULL) || (appTransportSettings == NULL) ||
|
if ( (appSessionSettings == NULL) || (!appTransportSettingsOkay) ||
|
||||||
(appFirmwareFile == NULL) )
|
(appFirmwareFile == NULL) )
|
||||||
{
|
{
|
||||||
/* Display program info */
|
/* Display program info */
|
||||||
|
@ -430,7 +435,7 @@ int main(int argc, char const * const argv[])
|
||||||
static void DisplayProgramInfo(void)
|
static void DisplayProgramInfo(void)
|
||||||
{
|
{
|
||||||
printf("--------------------------------------------------------------------------\n");
|
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("based system that runs the OpenBLT bootloader.\n\n");
|
||||||
printf("Copyright (c) 2017 by Feaser http://www.feaser.com\n");
|
printf("Copyright (c) 2017 by Feaser http://www.feaser.com\n");
|
||||||
printf("-------------------------------------------------------------------------\n");
|
printf("-------------------------------------------------------------------------\n");
|
||||||
|
@ -454,6 +459,7 @@ static void DisplayProgramUsage(void)
|
||||||
printf(" -t=[name] Name of the communication transport layer:\n");
|
printf(" -t=[name] Name of the communication transport layer:\n");
|
||||||
printf(" xcp_rs232 (default) -> XCP on RS232.\n");
|
printf(" xcp_rs232 (default) -> XCP on RS232.\n");
|
||||||
printf(" xcp_can -> XCP on CAN.\n");
|
printf(" xcp_can -> XCP on CAN.\n");
|
||||||
|
printf(" xcp_usb -> XCP on USB.\n");
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf("XCP version 1.0 settings (xcp):\n");
|
printf("XCP version 1.0 settings (xcp):\n");
|
||||||
printf(" -t1=[timeout] Command response timeout in milliseconds as a 16-bit\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(" as 29-bit CAN identifiers, if this 8-bit value is > 0\n");
|
||||||
printf(" (Default = 0).\n");
|
printf(" (Default = 0).\n");
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
printf("XCP on USB settings (xcp_usb):\n");
|
||||||
|
printf(" No additional settings needed.\n");
|
||||||
|
printf("\n");
|
||||||
printf("Program settings:\n");
|
printf("Program settings:\n");
|
||||||
printf(" -sm Silent mode switch. When specified, only minimal\n");
|
printf(" -sm Silent mode switch. When specified, only minimal\n");
|
||||||
printf(" information is written to the output (Optional).\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:
|
case BLT_TRANSPORT_XCP_V10_CAN:
|
||||||
printf("XCP on CAN\n");
|
printf("XCP on CAN\n");
|
||||||
break;
|
break;
|
||||||
|
case BLT_TRANSPORT_XCP_V10_USB:
|
||||||
|
printf("XCP on USB\n");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
printf("Unknown\n");
|
printf("Unknown\n");
|
||||||
break;
|
break;
|
||||||
|
@ -671,6 +683,11 @@ static void DisplayTransportInfo(uint32_t transportType, void const * transportS
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case BLT_TRANSPORT_XCP_V10_USB:
|
||||||
|
{
|
||||||
|
printf(" -> No additional settings required.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
printf(" -> No settings specified\n");
|
printf(" -> No settings specified\n");
|
||||||
break;
|
break;
|
||||||
|
@ -956,7 +973,8 @@ static uint32_t ExtractTransportTypeFromCommandLine(int argc, char const * const
|
||||||
} transportMap[] =
|
} transportMap[] =
|
||||||
{
|
{
|
||||||
{ .name = "xcp_rs232", .value = BLT_TRANSPORT_XCP_V10_RS232 },
|
{ .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. */
|
/* Set the default transport type in case nothing was specified on the command line. */
|
||||||
|
@ -1158,6 +1176,12 @@ static void * ExtractTransportSettingsFromCommandLine(int argc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
/* -------------------------- XCP on USB --------------------------------------- */
|
||||||
|
case BLT_TRANSPORT_XCP_V10_USB:
|
||||||
|
/* No additional command line parameters are neede for the USB transport
|
||||||
|
* layer.
|
||||||
|
*/
|
||||||
|
break;
|
||||||
/* -------------------------- Unknown ------------------------------------------ */
|
/* -------------------------- Unknown ------------------------------------------ */
|
||||||
default:
|
default:
|
||||||
/* Noting to extract. */
|
/* Noting to extract. */
|
||||||
|
|
|
@ -41,16 +41,16 @@ set(CMAKE_BUILD_TYPE "Debug")
|
||||||
#****************************************************************************************
|
#****************************************************************************************
|
||||||
# Options
|
# 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
|
# 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
|
# library. By default it is turned on. It can be overridden on the command line when
|
||||||
# following parameter: -DBUILD_SHARED=OFF
|
# CMake is called using the following parameter: -DBUILD_SHARED=OFF
|
||||||
option(BUILD_SHARED "Configurable to enable/disable building of the shared library" ON)
|
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
|
# 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:
|
# be overridden on the command line when CMake is called using the following parameter:
|
||||||
# -DLINT_ENABLED=ON
|
# -DLINT_ENABLED=ON
|
||||||
|
@ -131,6 +131,9 @@ set(
|
||||||
#****************************************************************************************
|
#****************************************************************************************
|
||||||
# Only generate the static library taget if the option is enabled. Use
|
# Only generate the static library taget if the option is enabled. Use
|
||||||
# "make openblt_static" to individually build the static library.
|
# "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)
|
if(BUILD_STATIC)
|
||||||
add_library(openblt_static STATIC ${LIB_SRCS})
|
add_library(openblt_static STATIC ${LIB_SRCS})
|
||||||
SET_TARGET_PROPERTIES(openblt_static PROPERTIES OUTPUT_NAME openblt CLEAN_DIRECT_OUTPUT 1)
|
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.
|
# "make openblt_shared" to build individually shared library.
|
||||||
if(BUILD_SHARED)
|
if(BUILD_SHARED)
|
||||||
add_library(openblt_shared SHARED ${LIB_SRCS})
|
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)
|
if(CMAKE_C_COMPILER_ID MATCHES MSVC)
|
||||||
# Microsoft Visual Studio does not add "lib" to the name of the DLL, whereas GCC
|
# Microsoft Visual Studio does not add "lib" to the name of the DLL, whereas GCC
|
||||||
# (including MinGW) does. Correct this here.
|
# (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(93) // allow newlines within quoted string arguments to macros
|
||||||
-elib(46) // allow bit fields to have integral types other than
|
-elib(46) // allow bit fields to have integral types other than
|
||||||
// '_Bool' and 'int'.
|
// '_Bool' and 'int'.
|
||||||
|
-elibsym(793) // suppress warning about limit of 31 significant characters
|
||||||
-elibsym(628) // Suppress 628 for __builtin symbols.
|
-elibsym(628) // Suppress 628 for __builtin symbols.
|
||||||
|
|
||||||
-esym(528,__huge_val,__nan,__qnan,__qnanf,__snan,__snanf)
|
-esym(528,__huge_val,__nan,__qnan,__qnanf,__snan,__snanf)
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include "xcploader.h" /* XCP loader module */
|
#include "xcploader.h" /* XCP loader module */
|
||||||
#include "xcptpuart.h" /* XCP UART transport layer */
|
#include "xcptpuart.h" /* XCP UART transport layer */
|
||||||
#include "xcptpcan.h" /* XCP CAN 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
|
* for major-, minor-, and patch-version. Version 1.05.12 would for example be
|
||||||
* 10512.
|
* 10512.
|
||||||
*/
|
*/
|
||||||
#define BLT_VERSION_NUMBER (10100u)
|
#define BLT_VERSION_NUMBER (10200u)
|
||||||
|
|
||||||
/** \brief The version number of the library as a null-terminated string. */
|
/** \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(sessionType == BLT_SESSION_XCP_V10);
|
||||||
assert( (transportType == BLT_TRANSPORT_XCP_V10_RS232) || \
|
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. */
|
/* Initialize the correct session. */
|
||||||
if (sessionType == BLT_SESSION_XCP_V10) /*lint !e774 */
|
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)
|
else if (transportType == BLT_TRANSPORT_XCP_V10_CAN)
|
||||||
{
|
{
|
||||||
/* Cast transport settings to the correct type. */
|
/* Verify transportSettings parameters because the XCP CAN transport layer
|
||||||
tBltTransportSettingsXcpV10Can * bltTransportSettingsXcpV10CanPtr;
|
* requires them.
|
||||||
bltTransportSettingsXcpV10CanPtr =
|
*/
|
||||||
(tBltTransportSettingsXcpV10Can * )transportSettings;
|
assert(transportSettings != NULL);
|
||||||
/* Convert transport settings to the format supported by the XCP CAN transport
|
/* Only continue if the transportSettings parameter is valid. */
|
||||||
* layer. It was made static to make sure it doesn't get out of scope when
|
if (transportSettings != NULL) /*lint !e774 */
|
||||||
* used in xcpLoaderSettings.
|
{
|
||||||
*/
|
/* Cast transport settings to the correct type. */
|
||||||
static tXcpTpCanSettings xcpTpCanSettings;
|
tBltTransportSettingsXcpV10Can * bltTransportSettingsXcpV10CanPtr;
|
||||||
xcpTpCanSettings.device = bltTransportSettingsXcpV10CanPtr->deviceName;
|
bltTransportSettingsXcpV10CanPtr =
|
||||||
xcpTpCanSettings.channel = bltTransportSettingsXcpV10CanPtr->deviceChannel;
|
(tBltTransportSettingsXcpV10Can *)transportSettings;
|
||||||
xcpTpCanSettings.baudrate = bltTransportSettingsXcpV10CanPtr->baudrate;
|
/* Convert transport settings to the format supported by the XCP CAN transport
|
||||||
xcpTpCanSettings.transmitId = bltTransportSettingsXcpV10CanPtr->transmitId;
|
* layer. It was made static to make sure it doesn't get out of scope when
|
||||||
xcpTpCanSettings.receiveId = bltTransportSettingsXcpV10CanPtr->receiveId;
|
* used in xcpLoaderSettings.
|
||||||
xcpTpCanSettings.useExtended = (bltTransportSettingsXcpV10CanPtr->useExtended != 0);
|
*/
|
||||||
|
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. */
|
/* Store transport layer settings in the XCP loader settings. */
|
||||||
xcpLoaderSettings.transportSettings = &xcpTpCanSettings;
|
xcpLoaderSettings.transportSettings = NULL;
|
||||||
/* Link the transport layer to the XCP loader settings. */
|
/* Link the transport layer to the XCP loader settings. */
|
||||||
xcpLoaderSettings.transport = XcpTpCanGetTransport();
|
xcpLoaderSettings.transport = XcpTpUsbGetTransport();
|
||||||
}
|
}
|
||||||
/* Perform actual session initialization. */
|
/* Perform actual session initialization. */
|
||||||
SessionInit(XcpLoaderGetProtocol(), &xcpLoaderSettings);
|
SessionInit(XcpLoaderGetProtocol(), &xcpLoaderSettings);
|
||||||
|
|
|
@ -103,6 +103,11 @@ LIBOPENBLT_EXPORT char const * BltVersionGetString(void);
|
||||||
*/
|
*/
|
||||||
#define BLT_TRANSPORT_XCP_V10_CAN ((uint32_t)1u)
|
#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
|
* Type definitions
|
||||||
|
|
|
@ -73,6 +73,7 @@ const
|
||||||
// Transport layer for the XCP v1.0 protocol that uses Controller Area Network (CAN)
|
// Transport layer for the XCP v1.0 protocol that uses Controller Area Network (CAN)
|
||||||
// for data exchange.
|
// for data exchange.
|
||||||
BLT_TRANSPORT_XCP_V10_CAN: LongWord = 1;
|
BLT_TRANSPORT_XCP_V10_CAN: LongWord = 1;
|
||||||
|
BLT_TRANSPORT_XCP_V10_USB: LongWord = 2;
|
||||||
|
|
||||||
type
|
type
|
||||||
// Structure layout of the XCP version 1.0 session settings.
|
// 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. */
|
/** \brief Minor version number of the bootloader core. */
|
||||||
#define BOOT_VERSION_CORE_MINOR (4u)
|
#define BOOT_VERSION_CORE_MINOR (4u)
|
||||||
/** \brief Patch number of the bootloader core. */
|
/** \brief Patch number of the bootloader core. */
|
||||||
#define BOOT_VERSION_CORE_BUILD (1u)
|
#define BOOT_VERSION_CORE_BUILD (2u)
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
|
|
Loading…
Reference in New Issue