From 5668abfeb7f2a28cc1f659c140ca293ec486a24f Mon Sep 17 00:00:00 2001 From: Uwe Vogt Date: Wed, 4 Oct 2023 18:01:58 +0200 Subject: [PATCH 1/8] Set version numbers for development Relates to [CANAPI-51] --- Sources/PeakCAN.cpp | 4 ++-- Sources/Wrapper/can_api.c | 4 ++-- Utilities/can_moni/Driver.h | 2 +- Utilities/can_test/Driver.h | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Sources/PeakCAN.cpp b/Sources/PeakCAN.cpp index dcee968..218b216 100644 --- a/Sources/PeakCAN.cpp +++ b/Sources/PeakCAN.cpp @@ -49,11 +49,11 @@ #ifdef _MSC_VER #define VERSION_MAJOR 0 #define VERSION_MINOR 4 -#define VERSION_PATCH 6 +#define VERSION_PATCH 99 #else #define VERSION_MAJOR 0 #define VERSION_MINOR 2 -#define VERSION_PATCH 6 +#define VERSION_PATCH 99 #endif #define VERSION_BUILD BUILD_NO #define VERSION_STRING TOSTRING(VERSION_MAJOR) "." TOSTRING(VERSION_MINOR) "." TOSTRING(VERSION_PATCH) " (" TOSTRING(BUILD_NO) ")" diff --git a/Sources/Wrapper/can_api.c b/Sources/Wrapper/can_api.c index deff7e4..369da0f 100644 --- a/Sources/Wrapper/can_api.c +++ b/Sources/Wrapper/can_api.c @@ -53,11 +53,11 @@ #ifdef _MSC_VER #define VERSION_MAJOR 0 #define VERSION_MINOR 4 -#define VERSION_PATCH 6 +#define VERSION_PATCH 99 #else #define VERSION_MAJOR 0 #define VERSION_MINOR 2 -#define VERSION_PATCH 6 +#define VERSION_PATCH 99 #endif #define VERSION_BUILD BUILD_NO #define VERSION_STRING TOSTRING(VERSION_MAJOR) "." TOSTRING(VERSION_MINOR) "." TOSTRING(VERSION_PATCH) " (" TOSTRING(BUILD_NO) ")" diff --git a/Utilities/can_moni/Driver.h b/Utilities/can_moni/Driver.h index a1dda61..75a70a1 100644 --- a/Utilities/can_moni/Driver.h +++ b/Utilities/can_moni/Driver.h @@ -22,7 +22,7 @@ #include "build_no.h" #define VERSION_MAJOR 0 #define VERSION_MINOR 4 -#define VERSION_PATCH 6 +#define VERSION_PATCH 99 #define VERSION_BUILD BUILD_NO #define VERSION_STRING TOSTRING(VERSION_MAJOR) "." TOSTRING(VERSION_MINOR) "." TOSTRING(VERSION_PATCH) " (" TOSTRING(BUILD_NO) ")" #if defined(_WIN64) diff --git a/Utilities/can_test/Driver.h b/Utilities/can_test/Driver.h index f3b2f61..bd11205 100644 --- a/Utilities/can_test/Driver.h +++ b/Utilities/can_test/Driver.h @@ -22,7 +22,7 @@ #include "build_no.h" #define VERSION_MAJOR 0 #define VERSION_MINOR 4 -#define VERSION_PATCH 6 +#define VERSION_PATCH 99 #define VERSION_BUILD BUILD_NO #define VERSION_STRING TOSTRING(VERSION_MAJOR) "." TOSTRING(VERSION_MINOR) "." TOSTRING(VERSION_PATCH) " (" TOSTRING(BUILD_NO) ")" #if defined(_WIN64) From 4928bfe1c29d16e6731f570b197a7b985db592e7 Mon Sep 17 00:00:00 2001 From: Uwe Vogt Date: Wed, 4 Oct 2023 19:10:25 +0200 Subject: [PATCH 2/8] Update CAN API V3 testing sources to rev. 1205 Relates to [CANAPI-55] --- Tests/README.md | 4 ++-- Tests/Testcases/TC03_StartController.cc | 7 ++++++- Tests/Testcases/TC11_GetBitrate.cc | 7 ++++++- Tests/Version.h | 6 +++--- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/Tests/README.md b/Tests/README.md index 06d8c50..d1a43b8 100644 --- a/Tests/README.md +++ b/Tests/README.md @@ -1,9 +1,9 @@ ### CAN API V3 Testing with GoogleTest -_Copyright © 2004-2023 Uwe Vogt, UV Software, Berlin (info@uv-software.com)_ \ +_Copyright © 2004-2023 Uwe Vogt, UV Software, Berlin (info@uv-software.com)_ \ _All rights reserved._ -Version $Rev: 1201 $ +Version $Rev: 1205 $ # CAN Interface Wrapper Specification diff --git a/Tests/Testcases/TC03_StartController.cc b/Tests/Testcases/TC03_StartController.cc index f891482..f33e6ac 100644 --- a/Tests/Testcases/TC03_StartController.cc +++ b/Tests/Testcases/TC03_StartController.cc @@ -462,6 +462,11 @@ TEST_F(StartController, GTEST_TESTCASE(WithValidCanBitrateIndex, GTEST_ENABLED)) #if (FEATURE_BITRATE_5K != FEATURE_SUPPORTED) if (bitrate.index == CANBTR_INDEX_5K) continue; +#endif +#if (TC03_7_ISSUE_RUSOKU_BITRATE_10K != WORKAROUND_DISABLED) + // @! issue(MacCAN-TouCAN): 10kbps hardware bug (known issue) + if (bitrate.index == CANBTR_INDEX_10K) + continue; #endif // @pre: // printf("[ SUB%-3i ] ...\n", (i + 1)); @@ -2308,4 +2313,4 @@ TEST_F(StartController, GTEST_TESTCASE(WithCanFdBitrateSettingsInCan20Mode, GTES } #endif // (CAN_FD_SUPPORTED == FEATURE_SUPPORTED) -// $Id: TC03_StartController.cc 1193 2023-09-06 10:21:35Z haumea $ Copyright (c) UV Software, Berlin. +// $Id: TC03_StartController.cc 1204 2023-09-24 15:26:57Z makemake $ Copyright (c) UV Software, Berlin. diff --git a/Tests/Testcases/TC11_GetBitrate.cc b/Tests/Testcases/TC11_GetBitrate.cc index 52ad058..3f95c90 100644 --- a/Tests/Testcases/TC11_GetBitrate.cc +++ b/Tests/Testcases/TC11_GetBitrate.cc @@ -480,6 +480,11 @@ TEST_F(GetBitrate, GTEST_TESTCASE(WithVariousCanBitrateSettings, GTEST_ENABLED)) case 7: BITRATE_10K(bitrate); break; default: return; // Get out of here! } +#if (TC11_10_ISSUE_RUSOKU_BITRATE_10K != WORKAROUND_DISABLED) + // @! issue(MacCAN-TouCAN): 10kbps hardware bug (known issue) + if (i == 7) + continue; +#endif // @pre: // @- initialize DUT1 in CAN 2.0 operation mode #if (OPTION_CAN_2_0_ONLY == 0) @@ -657,4 +662,4 @@ TEST_F(GetBitrate, GTEST_TESTCASE(WithVariousCanFdBitrateSettings, GTEST_ENABLED } #endif // (CAN_FD_SUPPORTED == FEATURE_SUPPORTED) -// $Id: TC11_GetBitrate.cc 1188 2023-09-01 18:21:43Z haumea $ Copyright (c) UV Software, Berlin. +// $Id: TC11_GetBitrate.cc 1204 2023-09-24 15:26:57Z makemake $ Copyright (c) UV Software, Berlin. diff --git a/Tests/Version.h b/Tests/Version.h index 3936153..0522042 100644 --- a/Tests/Version.h +++ b/Tests/Version.h @@ -47,8 +47,8 @@ // #ifndef VERSION_H_INCLUDED #define VERSION_H_INCLUDED -// SVN revision number (update with each commit: IV) -#define REVISION_NO "$Rev: 1201 $" +// SVN revision number (update with each commit: V) +#define REVISION_NO "$Rev: 1205 $" #endif // VERSION_H_INCLUDED -// $Id: Version.h 1201 2023-09-13 11:09:28Z makemake $ Copyright (c) UV Software, Berlin // +// $Id: Version.h 1205 2023-09-24 15:30:34Z makemake $ Copyright (c) UV Software, Berlin // From ce543f78f1d02e8688a35426e10fc52970f7cbda Mon Sep 17 00:00:00 2001 From: Uwe Vogt Date: Wed, 4 Oct 2023 19:21:59 +0200 Subject: [PATCH 3/8] Update CAN API V3 sources to rev. 1212 Relates to [CANAPI-56] --- Sources/CANAPI/CANAPI.h | 6 +++--- Sources/CANAPI/CANAPI_Types.h | 11 +++++++---- Sources/CANAPI/README.md | 4 ++-- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/Sources/CANAPI/CANAPI.h b/Sources/CANAPI/CANAPI.h index 1fe073c..bc9894b 100644 --- a/Sources/CANAPI/CANAPI.h +++ b/Sources/CANAPI/CANAPI.h @@ -75,7 +75,7 @@ /// /// \author $Author: haumea $ // -/// \version $Rev: 1143 $ +/// \version $Rev: 1212 $ // /// \defgroup can_api CAN Interface API, Version 3 /// \{ @@ -357,7 +357,7 @@ class CANCPP CCanApi { // /// \returns 0 if successful, or a negative value on error. // - virtual CANAPI_Return_t ReadMessage(CANAPI_Message_t &message, uint16_t timeout = CANREAD_INFINITE) = 0; + virtual CANAPI_Return_t ReadMessage(CANAPI_Message_t &message, uint16_t timeout = CANWAIT_INFINITE) = 0; /// \brief retrieves the status register of the CAN interface. // @@ -478,4 +478,4 @@ class CANCPP CCanApi { /// \} #endif // CANAPI_H_INCLUDED /// \} -// $Id: CANAPI.h 1143 2023-08-13 17:50:24Z haumea $ Copyright (c) UV Software // +// $Id: CANAPI.h 1212 2023-10-04 15:41:24Z haumea $ Copyright (c) UV Software // diff --git a/Sources/CANAPI/CANAPI_Types.h b/Sources/CANAPI/CANAPI_Types.h index e1db952..205eb5d 100644 --- a/Sources/CANAPI/CANAPI_Types.h +++ b/Sources/CANAPI/CANAPI_Types.h @@ -51,7 +51,7 @@ * * @author $Author: haumea $ * - * @version $Rev: 1128 $ + * @version $Rev: 1212 $ * * @addtogroup can_api * @{ @@ -290,11 +290,14 @@ extern "C" { #define CANBRD_NOT_TESTABLE (-2) /**< CAN board not testable (e.g. legacy API) */ /** @} */ -/** @name Blocking Read - * @brief Control of blocking read +/** @name Blocking Operations + * @brief Control of blocking operations * @{ */ -#define CANREAD_INFINITE 65535U /**< infinite time-out (blocking read) */ +#define CANWAIT_INFINITE 65535U /**< infinite time-out (blocking operation) */ #define CANKILL_ALL (-1) /**< to signal all waiting event objects */ +/* aliases (legacy names) */ +#define CANREAD_INFINITE CANWAIT_INFINITE /**< blocking read */ +#define CANWRITE_INFINITE CANWAIT_INFINITE /**< blocking write */ /** @} */ /** @name Property IDs diff --git a/Sources/CANAPI/README.md b/Sources/CANAPI/README.md index a430948..d411f13 100644 --- a/Sources/CANAPI/README.md +++ b/Sources/CANAPI/README.md @@ -1,9 +1,9 @@ ### CAN Interface API, Version 3 -_Copyright © 2004-2023 Uwe Vogt, UV Software, Berlin (info@uv-software.com)_ \ +_Copyright © 2004-2023 Uwe Vogt, UV Software, Berlin (info@uv-software.com)_ \ _All rights reserved._ -Version $Rev: 1187 $ +Version $Rev: 1212 $ # A CAN Interface Wrapper Specification From a7adff110bd11da91b703607e81d78dc9dfea7ed Mon Sep 17 00:00:00 2001 From: Uwe Vogt Date: Wed, 4 Oct 2023 19:35:20 +0200 Subject: [PATCH 4/8] Update the trial program Relates to [CANAPI-56] --- Trial/Sources/main.cpp | 55 ++++++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/Trial/Sources/main.cpp b/Trial/Sources/main.cpp index c553f81..8b46b34 100644 --- a/Trial/Sources/main.cpp +++ b/Trial/Sources/main.cpp @@ -72,6 +72,10 @@ #define OPTION_TIME_ABS (2) #define OPTION_TIME_REL (3) +#define CHANNEL PCAN_USB1 + +typedef CPeakCAN CCanDriver; + #if defined(_WIN32) || defined(_WIN64) static void usleep(unsigned int usec); /* useconds_t: to be compatible with macOS */ @@ -83,9 +87,9 @@ static void verbose(const can_mode_t &mode, const can_bitrate_t &bitrate, const static volatile int running = 1; -static CPeakCAN myDriver = CPeakCAN(); +static CCanDriver myDriver = CCanDriver(); #ifdef SECOND_CHANNEL - static CPeakCAN mySecond = CPeakCAN(); + static CCanDriver mySecond = CCanDriver(); #endif int main(int argc, const char * argv[]) { @@ -111,9 +115,10 @@ int main(int argc, const char * argv[]) { message.timestamp.tv_sec = 0; message.timestamp.tv_nsec = 0; CANAPI_Return_t retVal = 0; - int32_t channel = (int32_t)PCAN_USB1; - uint16_t timeout = CANREAD_INFINITE; - useconds_t delay = 0U; + int32_t channel = (int32_t)CHANNEL; + uint16_t rxTimeout = CANWAIT_INFINITE; + uint16_t txTimeout = 0U; + useconds_t txDelay = 0U; CCanApi::SChannelInfo info; CCanApi::EChannelState state; // int32_t clocks[CANPROP_MAX_BUFFER_SIZE/sizeof(int32_t)]; @@ -195,12 +200,14 @@ int main(int argc, const char * argv[]) { if (!strcmp(argv[i], "BR:500K")) BITRATE_FD_500K(bitrate); if (!strcmp(argv[i], "BR:1M")) BITRATE_FD_1M(bitrate); /* asynchronous IO */ - if (!strcmp(argv[i], "POLLING")) timeout = 0U; - if (!strcmp(argv[i], "BLOCKING")) timeout = CANREAD_INFINITE; + if (!strcmp(argv[i], "POLLING")) rxTimeout = 0U; + if (!strcmp(argv[i], "BLOCKING")) rxTimeout = CANWAIT_INFINITE; + if (!strncmp(argv[i], "R:", 2) && sscanf(argv[i], "R:%i", &opt) == 1) rxTimeout = (useconds_t)opt; /* transmit messages */ if ((sscanf(argv[i], "%i", &opt) == 1) && (opt > 0)) option_transmit = opt; - if (!strncmp(argv[i], "C:", 2) && sscanf(argv[i], "C:%i", &opt) == 1) delay = (useconds_t)opt * 1000U; - if (!strncmp(argv[i], "U:", 2) && sscanf(argv[i], "U:%i", &opt) == 1) delay = (useconds_t)opt; +// if (!strncmp(argv[i], "T:", 2) && sscanf(argv[i], "T:%i", &opt) == 1) txTimeout = (useconds_t)opt; + if (!strncmp(argv[i], "C:", 2) && sscanf(argv[i], "C:%i", &opt) == 1) txDelay = (useconds_t)opt * 1000U; + if (!strncmp(argv[i], "U:", 2) && sscanf(argv[i], "U:%i", &opt) == 1) txDelay = (useconds_t)opt; /* receive messages */ if (!strcmp(argv[i], "STOP")) option_stop = OPTION_YES; #if (ISSUE_198 == 0) @@ -234,7 +241,7 @@ int main(int argc, const char * argv[]) { if (!strcmp(argv[i], "XTD:OFF")) opMode.nxtd = 1; if (!strcmp(argv[i], "RTR:OFF")) opMode.nrtr = 1; } - fprintf(stdout, ">>> %s\n", CPeakCAN::GetVersion()); + fprintf(stdout, ">>> %s\n", CCanDriver::GetVersion()); if ((signal(SIGINT, sigterm) == SIG_ERR) || #if !defined(_WIN32) && !defined(_WIN64) (signal(SIGHUP, sigterm) == SIG_ERR) || @@ -287,11 +294,11 @@ int main(int argc, const char * argv[]) { if (option_list) { int n = 0; #if (1) - bool result = CPeakCAN::GetFirstChannel(info); + bool result = CCanDriver::GetFirstChannel(info); while (result) { fprintf(stdout, ">>> CCanAPI::Get%sChannel(): %i = \'%s\' (%i = \'%s\')\n", !n ? "First" : "Next", info.m_nChannelNo, info.m_szDeviceName, info.m_nLibraryId, info.m_szVendorName); - result = CPeakCAN::GetNextChannel(info); + result = CCanDriver::GetNextChannel(info); n++; } #else @@ -332,22 +339,22 @@ int main(int argc, const char * argv[]) { /* channel tester */ if (option_test) { #if (1) - bool result = CPeakCAN::GetFirstChannel(info); + bool result = CCanDriver::GetFirstChannel(info); while (result) { - retVal = CPeakCAN::ProbeChannel(info.m_nChannelNo, opMode, state); + retVal = CCanDriver::ProbeChannel(info.m_nChannelNo, opMode, state); fprintf(stdout, ">>> CCanAPI::ProbeChannel(%i): state = %s", info.m_nChannelNo, (state == CCanApi::ChannelOccupied) ? "occupied" : (state == CCanApi::ChannelAvailable) ? "available" : (state == CCanApi::ChannelNotAvailable) ? "not available" : "not testable"); fprintf(stdout, "%s", (retVal == CCanApi::IllegalParameter) ? " (warning: Op.-Mode not supported)\n" : "\n"); - result = CPeakCAN::GetNextChannel(info); + result = CCanDriver::GetNextChannel(info); } #else retVal = myDriver.SetProperty(CANPROP_SET_FIRST_CHANNEL, (void *)NULL, 0U); while (retVal == CCanApi::NoError) { retVal = myDriver.GetProperty(CANPROP_GET_CHANNEL_NO, (void *)&i32Val, sizeof(int32_t)); if (retVal == CCanApi::NoError) { - retVal = CPeakCAN::ProbeChannel(i32Val, opMode, state); + retVal = CCanDriver::ProbeChannel(i32Val, opMode, state); fprintf(stdout, ">>> CCanApi::ProbeChannel(%i): state = %s", i32Val, (state == CCanApi::ChannelOccupied) ? "occupied" : (state == CCanApi::ChannelAvailable) ? "available" : @@ -490,13 +497,13 @@ int main(int argc, const char * argv[]) { retVal = mySecond.StartController(bitrate); if (retVal != CCanApi::NoError) fprintf(stderr, "+++ error: mySecond.StartController returned %i\n", retVal); - retVal = mySecond.WriteMessage(message); + retVal = mySecond.WriteMessage(message, txTimeout); if (retVal != CCanApi::NoError) fprintf(stderr, "+++ error: mySecond.WriteMessage returned %i\n", retVal); #endif /* transmit messages */ if (option_transmit) { -// if (!option_retry) +// if ((txTimeout == 0U) && !option_retry) // fprintf(stdout, "Attention: The program will be aborted when the transmitter is busy.\n" // " Use progrsm option RETRY to avoid this.\n"); fprintf(stdout, "Press Ctrl+C to abort..."); fflush(stdout); @@ -522,15 +529,15 @@ int main(int argc, const char * argv[]) { message.data[6] = (uint8_t)(((uint64_t)frames & 0x00FF000000000000) >> 48); message.data[7] = (uint8_t)(((uint64_t)frames & 0xFF00000000000000) >> 56); retry_write: - retVal = myDriver.WriteMessage(message); + retVal = myDriver.WriteMessage(message, txTimeout); if ((retVal == CCanApi::TransmitterBusy) && option_retry) goto retry_write; else if (retVal != CCanApi::NoError) { fprintf(stderr, "\n+++ error: myDriver.WriteMessage returned %i\n", retVal); goto teardown; } - if (delay) - usleep(delay); + if (txDelay) + usleep(txDelay); frames++; } fprintf(stdout, "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); @@ -543,7 +550,7 @@ int main(int argc, const char * argv[]) { fprintf(stdout, "Press Ctrl+C to abort...\n"); frames = 0; while (running) { - if ((retVal = myDriver.ReadMessage(message, timeout)) == CCanApi::NoError) { + if ((retVal = myDriver.ReadMessage(message, rxTimeout)) == CCanApi::NoError) { if (option_echo) { fprintf(stdout, ">>> %i\t", frames++); fprintf(stdout, "%7li.%04li\t", (long)message.timestamp.tv_sec, message.timestamp.tv_nsec / 100000); @@ -594,7 +601,7 @@ int main(int argc, const char * argv[]) { for (uint8_t i = 0; i < CCanApi::Dlc2Len(message.dlc); i++) message.data[i] = message.data[i] ^ 0xFFU; retry_reply: - retVal = myDriver.WriteMessage(message); + retVal = myDriver.WriteMessage(message, txTimeout); if ((retVal == CCanApi::TransmitterBusy) && option_retry) goto retry_reply; else if (retVal != CCanApi::NoError) { @@ -621,7 +628,7 @@ int main(int argc, const char * argv[]) { if (message.sts) fprintf(stdout, " <<< status frame"); else if (option_repeat) { - retVal = myDriver.WriteMessage(message); + retVal = myDriver.WriteMessage(message, txTimeout); if (retVal != CCanApi::NoError) { fprintf(stderr, "+++ error: mySecond.WriteMessage returned %i\n", retVal); goto teardown; From 859eebf81cc7dfa9d360802194ac6f8ea1ebd2a8 Mon Sep 17 00:00:00 2001 From: Uwe Vogt Date: Sun, 22 Oct 2023 12:39:24 +0200 Subject: [PATCH 5/8] Update PCANBasic DLL (version 4.8.0) Relates to [CANAPI-56] --- Sources/PCANBasic/PCANBasic.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Sources/PCANBasic/PCANBasic.h b/Sources/PCANBasic/PCANBasic.h index 1a467b2..4ac61b8 100644 --- a/Sources/PCANBasic/PCANBasic.h +++ b/Sources/PCANBasic/PCANBasic.h @@ -8,7 +8,7 @@ // // ------------------------------------------------------------------ // Author : Keneth Wagner -// Last change: 2023-06-01 +// Last change: 2023-08-28 // // Language: ANSI-C // ------------------------------------------------------------------ @@ -183,6 +183,7 @@ #define PCAN_ATTACHED_CHANNELS 0x2BU // Get information about PCAN channels attached to a system #define PCAN_ALLOW_ECHO_FRAMES 0x2CU // Echo messages reception status within a PCAN-Channel #define PCAN_DEVICE_PART_NUMBER 0x2DU // Get the part number associated to a device +#define PCAN_HARD_RESET_STATUS 0x2EU // Activation status of hard reset processing via CAN_Reset calls // DEPRECATED parameters // From 8ccd4a6157b959a091b98e4a5a31074e82c48647 Mon Sep 17 00:00:00 2001 From: Uwe Vogt Date: Sun, 5 Nov 2023 20:50:33 +0100 Subject: [PATCH 6/8] Update CAN API V3 testing sources to rev. 1219 Relates to [CANAPI-55] --- Tests/README.md | 2 +- Tests/Sources/Device.cpp | 32 ++- Tests/Sources/Device.h | 5 +- Tests/Sources/Progress.cpp | 2 +- Tests/Sources/Progress.h | 2 +- Tests/Sources/Settings.h | 6 +- Tests/Sources/Timer.cpp | 47 +++- Tests/Sources/Timer.h | 4 +- Tests/Sources/Timer64.cpp | 261 +++++++++++++++++++++++ Tests/Sources/Timer64.h | 91 ++++++++ Tests/Sources/pch.h | 2 +- Tests/Testcases/TC00_SmokeTest.cc | 12 +- Tests/Testcases/TC01_ProbeChannel.cc | 6 +- Tests/Testcases/TC03_StartController.cc | 14 +- Tests/Testcases/TC04_ReadMessage.cc | 57 +++-- Tests/Testcases/TC05_WriteMessage.cc | 13 +- Tests/Testcases/TC09_GetStatus.cc | 72 ++++--- Tests/Testcases/TCx2_BitrateConverter.cc | 14 +- Tests/Version.h | 6 +- Tests/pcb_testing.vcxproj | 4 +- Tests/pcb_testing.vcxproj.filters | 12 +- 21 files changed, 538 insertions(+), 126 deletions(-) create mode 100644 Tests/Sources/Timer64.cpp create mode 100644 Tests/Sources/Timer64.h diff --git a/Tests/README.md b/Tests/README.md index d1a43b8..f8bbf7c 100644 --- a/Tests/README.md +++ b/Tests/README.md @@ -3,7 +3,7 @@ _Copyright © 2004-2023 Uwe Vogt, UV Software, Berlin (info@uv-software.com)_ \ _All rights reserved._ -Version $Rev: 1205 $ +Version $Rev: 1219 $ # CAN Interface Wrapper Specification diff --git a/Tests/Sources/Device.cpp b/Tests/Sources/Device.cpp index 847e269..a7fc5d4 100644 --- a/Tests/Sources/Device.cpp +++ b/Tests/Sources/Device.cpp @@ -61,8 +61,6 @@ #define MESSAGE(n,i,l,d) do{ }while(0) #endif -#define DIFF_TIME(t1,t2) (((t1.tv_sec * 1000000000) + t1.tv_nsec) - ((t2.tv_sec * 1000000000) + t2.tv_nsec)) - CCanDevice::CCanDevice(int32_t library, int32_t channel, CANAPI_OpMode_t opMode, CANAPI_Bitrate_t bitRate, void *param) { m_nLibraryId = library; m_nChannelNo = channel; @@ -191,7 +189,7 @@ int32_t CCanDevice::SendAndReceiveFrames(CCanDevice *sender, CCanDevice *receive struct timespec m0 = {}; struct timespec m1 = {}; // get current time: start of transmission - clock_gettime(CLOCK_MONOTONIC, &t0); + t0 = CTimer::GetTime(); #endif // send the messages CProgress progress = CProgress(frames); @@ -248,15 +246,15 @@ int32_t CCanDevice::SendAndReceiveFrames(CCanDevice *sender, CCanDevice *receive } #if (DEVICE_DEBUG != 0) // get current time: end of transmission - clock_gettime(CLOCK_MONOTONIC, &t1); + t1 = CTimer::GetTime(); #endif // finish the plate int32_t remaining = (int32_t)(frames - n); #if (0) //defined(_WIN32) || defined(_WIN64) - uint32_t timeout = ((uint32_t)remaining * DEVICE_LOOP_TIMEOUT * CTimer::MSEC); // FIXME: does not work for all bit-rates + uint32_t timeout = ((uint64_t)remaining * DEVICE_LOOP_TIMEOUT * CTimer::MSEC); // FIXME: does not work for all bit-rates #else - uint32_t timeout = ((TransmissionTime(receiver->GetBitrate(), (remaining + DEVICE_LOOP_EXTRA)) - * DEVICE_LOOP_FACTOR) / DEVICE_LOOP_DIVISOR); // bit-rate dependent timeout + uint64_t timeout = (((uint64_t)TransmissionTime(receiver->GetBitrate(), (remaining + DEVICE_LOOP_EXTRA)) + * (uint64_t)DEVICE_LOOP_FACTOR) / (uint64_t)DEVICE_LOOP_DIVISOR); // bit-rate dependent timeout #endif if (n < frames) { CTimer timer = CTimer(timeout); @@ -300,17 +298,17 @@ int32_t CCanDevice::SendAndReceiveFrames(CCanDevice *sender, CCanDevice *receive } #if (DEVICE_DEBUG != 0) // get current time: end of reception - clock_gettime(CLOCK_MONOTONIC, &t2); + t2 = CTimer::GetTime(); #endif // return the number of received messages progress.Clear(); #if (DEVICE_DEBUG != 0) if (frames > 0) { - std::cout << " " << frames << " total sent frames in " << ((float)TimeDifference(t0, t1) / 1000.f) << "ms"; + std::cout << " " << frames << " total sent frames in " << ((float)CTimer::DiffTime(t0, t1) * 1000.f) << "ms"; if (remaining > 0) - std::cout << " + " << remaining << " remaining frames in " << ((float)TimeDifference(t1, t2) / 1000.f) << "ms w/ timeout " << ((float)timeout / 1000.f) << "ms"; + std::cout << " + " << remaining << " remaining frames in " << ((float)CTimer::DiffTime(t1, t2) * 1000.f) << "ms w/ timeout " << ((float)timeout / 1000.f) << "ms"; if (remaining > 1) - std::cout << " : reception of " << n << " frames in " << ((float)TimeDifference(m0, m1) / 1000.f) << "ms"; + std::cout << " : reception of " << n << " frames in " << ((float)CTimer::DiffTime(m0, m1) * 1000.f) << "ms"; std::cout << std::endl; } #endif @@ -438,7 +436,7 @@ bool CCanDevice::CompareBitrates(CANAPI_Bitrate_t bitRate1, CANAPI_Bitrate_t bit return true; } -uint32_t CCanDevice::TransmissionTime(CANAPI_Bitrate_t bitRate, int32_t frames, uint8_t payload) { +uint64_t CCanDevice::TransmissionTime(CANAPI_Bitrate_t bitRate, int32_t frames, uint8_t payload) { float time_per_bit = 100.f; // assume the slowest bit-rate (10kbps) float bits_per_msg = 1.f + 11.f + 7.f + ((float)payload * 8.f) + 15.f + 1.f + 2.f + 7.f + 3.f; @@ -446,19 +444,15 @@ uint32_t CCanDevice::TransmissionTime(CANAPI_Bitrate_t bitRate, int32_t frames, if (CCanDevice::MapBitrate2Speed(bitRate, speed) == CCanApi::NoError) time_per_bit = 1000000.f / speed.nominal.speed; - uint32_t usec = (uint32_t)((float)frames * bits_per_msg * time_per_bit); + uint64_t usec = (uint64_t)((float)frames * bits_per_msg * time_per_bit); return (usec < 100U) ? 100U : usec; // FIXME: CTimer::Delay calls Sleep(0) if t < 100us } -long CCanDevice::TimeDifference(struct timespec &start, struct timespec &stop) { - return (long)(DIFF_TIME(stop, start) / 1000); -} - void CCanDevice::ShowTimeDifference(const char *prefix, struct timespec &start, struct timespec &stop) { if (prefix) std::cout << prefix << ' '; - std::cout << "dt=" << ((float)TimeDifference(start, stop) / 1000.f) << "ms" << std::endl; + std::cout << "dt=" << ((float)CTimer::DiffTime(start, stop) * 1000.f) << "ms" << std::endl; } void CCanDevice::ShowLibrayInformation(const char *prefix) { @@ -596,4 +590,4 @@ void CCanDevice::ShowChannelCapabilities(const char* prefix) { std::cout << std::endl; } -// $Id: Device.cpp 1185 2023-08-29 10:42:03Z haumea $ Copyright (c) UV Software, Berlin // +// $Id: Device.cpp 1217 2023-10-10 19:28:31Z haumea $ Copyright (c) UV Software, Berlin // diff --git a/Tests/Sources/Device.h b/Tests/Sources/Device.h index 6f7c21d..7df3d3e 100644 --- a/Tests/Sources/Device.h +++ b/Tests/Sources/Device.h @@ -160,8 +160,7 @@ class CCanDevice : public CCanDriver { // special stuff static bool CompareMessages(CANAPI_Message_t message1, CANAPI_Message_t message2, bool esiFlag = false); static bool CompareBitrates(CANAPI_Bitrate_t bitRate1, CANAPI_Bitrate_t bitRate2, bool dataPhase = false); - static uint32_t TransmissionTime(CANAPI_Bitrate_t bitRate, int32_t frames = 1, uint8_t payload = 8U); - static long TimeDifference(struct timespec &start, struct timespec &stop); + static uint64_t TransmissionTime(CANAPI_Bitrate_t bitRate, int32_t frames = 1, uint8_t payload = 8U); static void ShowTimeDifference(const char *prefix, struct timespec &start, struct timespec &stop); private: int32_t SendAndReceiveFrames(CCanDevice *sender, CCanDevice *receiver, int32_t frames); @@ -171,4 +170,4 @@ class CCanDevice : public CCanDriver { #endif // DEVICE_H_INCLUDED -// $Id: Device.h 1185 2023-08-29 10:42:03Z haumea $ Copyright (c) UV Software, Berlin. +// $Id: Device.h 1217 2023-10-10 19:28:31Z haumea $ Copyright (c) UV Software, Berlin. diff --git a/Tests/Sources/Progress.cpp b/Tests/Sources/Progress.cpp index 9d3e052..650e6e5 100644 --- a/Tests/Sources/Progress.cpp +++ b/Tests/Sources/Progress.cpp @@ -138,4 +138,4 @@ void CCounter::Increment() { #endif } -// $Id$ Copyright (c) UV Software, Berlin // +// $Id: Progress.cpp 798 2023-10-07 19:01:13Z makemake $ Copyright (c) UV Software, Berlin // diff --git a/Tests/Sources/Progress.h b/Tests/Sources/Progress.h index dea388e..1c04a81 100644 --- a/Tests/Sources/Progress.h +++ b/Tests/Sources/Progress.h @@ -80,4 +80,4 @@ class CCounter { #endif // PROGRESS_H_INCLUDED -// $Id$ Copyright (c) UV Software, Berlin // +// $Id: Progress.h 798 2023-10-07 19:01:13Z makemake $ Copyright (c) UV Software, Berlin // diff --git a/Tests/Sources/Settings.h b/Tests/Sources/Settings.h index dacbc6a..869d0a8 100644 --- a/Tests/Sources/Settings.h +++ b/Tests/Sources/Settings.h @@ -123,14 +123,14 @@ #if (PCBUSB_INIT_DELAY_WORKAROUND != WORKAROUND_DISABLED) // - When initializing two PCAN-USB devices then a delay of 100ms is required // before sending messages. The receiver swallows the first few (issue #291) -#define PCBUSB_INIT_DELAY() do { CTimer::Delay(100U * CTimer::MSEC); } while(0) +#define PCBUSB_INIT_DELAY() do { CTimer::Delay((uint64_t)100 * CTimer::MSEC); } while(0) #else #define PCBUSB_INIT_DELAY() while(0) #endif #if (PCBUSB_QXMTFULL_WORKAROUND != WORKAROUND_DISABLED) // - Up to now no solution found to catch QXMTFULL event when sending a lot of // messages back to back with buffered transfer (no acknowledge, issue #101) -#define PCBUSB_QXMT_DELAY() do { CTimer::Delay(0U * CTimer::MSEC); } while(0) +#define PCBUSB_QXMT_DELAY() do { CTimer::Delay((uint64_t)0 * CTimer::MSEC); } while(0) #else #define PCBUSB_QXMT_DELAY() while(0) #endif @@ -158,4 +158,4 @@ #endif #endif // SETTINGS_H_INCLUDED -// $Id: Settings.h 1188 2023-09-01 18:21:43Z haumea $ Copyright (c) UV Software, Berlin. +// $Id: Settings.h 1217 2023-10-10 19:28:31Z haumea $ Copyright (c) UV Software, Berlin. diff --git a/Tests/Sources/Timer.cpp b/Tests/Sources/Timer.cpp index c5c0c0b..42858d6 100644 --- a/Tests/Sources/Timer.cpp +++ b/Tests/Sources/Timer.cpp @@ -52,17 +52,26 @@ static char THIS_FILE[]=__FILE__; #include "Timer.h" #if !defined(_WIN32) && !defined(_WIN64) +#include #include #include #endif +#define POSIX_DEPRECATED 0 /* set to non-zero value to use 'gettimeofday' and 'usleep'*/ -// TODO: replace `gettimeofday' by `clock_gettime' and `usleep' by `clock_nanosleep' CTimer::CTimer(uint32_t u32Microseconds) { #if !defined(_WIN32) && !defined(_WIN64) +#if (POSIX_DEPRECATED != 0) struct timeval tv; gettimeofday(&tv, NULL); - m_u64UntilStop = ((uint64_t)tv.tv_sec * (uint64_t)1000000) + (uint64_t)tv.tv_usec \ + m_u64UntilStop = ((uint64_t)tv.tv_sec * (uint64_t)1000000) + (uint64_t)tv.tv_usec + ((uint64_t)u32Microseconds); +#else + struct timespec now = { 0, 0 }; + clock_gettime(CLOCK_MONOTONIC, &now); + m_u64UntilStop = ((uint64_t)now.tv_sec * (uint64_t)1000000) + + ((uint64_t)now.tv_nsec / (uint64_t)1000) + + ((uint64_t)u32Microseconds); +#endif #else LARGE_INTEGER largeCounter; // high-resolution performance counter @@ -80,10 +89,18 @@ CTimer::CTimer(uint32_t u32Microseconds) { bool CTimer::Restart(uint32_t u32Microseconds) { #if !defined(_WIN32) && !defined(_WIN64) +#if (POSIX_DEPRECATED != 0) struct timeval tv; gettimeofday(&tv, NULL); - m_u64UntilStop = ((uint64_t)tv.tv_sec * (uint64_t)1000000) + (uint64_t)tv.tv_usec \ + m_u64UntilStop = ((uint64_t)tv.tv_sec * (uint64_t)1000000) + (uint64_t)tv.tv_usec + + ((uint64_t)u32Microseconds); +#else + struct timespec now = { 0, 0 }; + clock_gettime(CLOCK_MONOTONIC, &now); + m_u64UntilStop = ((uint64_t)now.tv_sec * (uint64_t)1000000) + + ((uint64_t)now.tv_nsec / (uint64_t)1000) + ((uint64_t)u32Microseconds); +#endif return true; #else LARGE_INTEGER largeCounter; // high-resolution performance counter @@ -101,9 +118,16 @@ bool CTimer::Restart(uint32_t u32Microseconds) { bool CTimer::Timeout() { #if !defined(_WIN32) && !defined(_WIN64) uint64_t u64Now; +#if (POSIX_DEPRECATED != 0) struct timeval tv; gettimeofday(&tv, NULL); u64Now = ((uint64_t)tv.tv_sec * (uint64_t)1000000) + (uint64_t)tv.tv_usec; +#else + struct timespec now = { 0, 0 }; + clock_gettime(CLOCK_MONOTONIC, &now); + u64Now = ((uint64_t)now.tv_sec * (uint64_t)1000000) + + ((uint64_t)now.tv_nsec / (uint64_t)1000); +#endif if(u64Now < this->m_u64UntilStop) return false; else @@ -124,7 +148,20 @@ bool CTimer::Timeout() { bool CTimer::Delay(uint32_t u32Microseconds) { #if !defined(_WIN32) && !defined(_WIN64) +#if (POSIX_DEPRECATED != 0) return (usleep((useconds_t)u32Microseconds) != 0) ? false : true; +#else + int rc; + struct timespec delay; + delay.tv_sec = (time_t)(u32Microseconds / CTimer::SEC); + delay.tv_nsec = (long)((u32Microseconds % CTimer::SEC) * (uint32_t)1000); + errno = 0; + while ((rc = nanosleep(&delay, &delay))) { + if (errno != EINTR) + break; + } + return (rc != 0) ? false : true; +#endif #else # ifndef CTIMER_WAITABLE_TIMER LARGE_INTEGER largeFrequency; // frequency in counts per second @@ -176,7 +213,7 @@ bool CTimer::Delay(uint32_t u32Microseconds) { struct timespec CTimer::GetTime() { struct timespec now = { 0, 0 }; #if !defined(_WIN32) && !defined(_WIN64) - clock_gettime(CLOCK_MONOTONIC, &now); + clock_gettime(CLOCK_REALTIME, &now); #else static bool fInitialied = false; // initialization flag static struct timespec tsStartTime; // time at first call (UTC) @@ -219,4 +256,4 @@ double CTimer::DiffTime(struct timespec start, struct timespec stop) { ((double)start.tv_sec + ((double)start.tv_nsec / 1000000000.f))); } -// $Id: Timer.cpp 1166 2023-08-22 13:34:30Z haumea $ Copyright (c) UV Software, Berlin // +// $Id: Timer.cpp 1213 2023-10-07 19:43:58Z makemake $ Copyright (c) UV Software, Berlin // diff --git a/Tests/Sources/Timer.h b/Tests/Sources/Timer.h index 02dd5fb..5f0ebc5 100644 --- a/Tests/Sources/Timer.h +++ b/Tests/Sources/Timer.h @@ -2,7 +2,7 @@ // // Software for Industrial Communication, Motion Control and Automation // -// Copyright (c) 2002-2022 Uwe Vogt, UV Software, Berlin (info@uv-software.com) +// Copyright (c) 2002-2023 Uwe Vogt, UV Software, Berlin (info@uv-software.com) // All rights reserved. // // This class is dual-licensed under the BSD 2-Clause "Simplified" License and @@ -88,4 +88,4 @@ class CTimer { #endif // TIMER_H_INCLUDED -// $Id: Timer.h 710 2021-05-25 15:35:30Z eris $ Copyright (c) UV Software, Berlin // +// $Id: Timer.h 799 2023-10-07 19:15:23Z makemake $ Copyright (c) UV Software, Berlin // diff --git a/Tests/Sources/Timer64.cpp b/Tests/Sources/Timer64.cpp new file mode 100644 index 0000000..9e855de --- /dev/null +++ b/Tests/Sources/Timer64.cpp @@ -0,0 +1,261 @@ +// SPDX-License-Identifier: BSD-2-Clause OR GPL-3.0-or-later +// +// Software for Industrial Communication, Motion Control and Automation +// +// Copyright (c) 2002-2023 Uwe Vogt, UV Software, Berlin (info@uv-software.com) +// All rights reserved. +// +// This class is dual-licensed under the BSD 2-Clause "Simplified" License and +// under the GNU General Public License v3.0 (or any later version). +// You can choose between one of them if you use this class. +// +// BSD 2-Clause "Simplified" License: +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS CLASS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS CLASS, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// GNU General Public License v3.0 or later: +// This class 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. +// +// This class 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 should have received a copy of the GNU General Public License +// along with this class. If not, see . +// +#ifdef _DEBUG +#undef THIS_FILE +static char THIS_FILE[]=__FILE__; +#define new DEBUG_NEW +#endif + +#include "Timer64.h" + +#if !defined(_WIN32) && !defined(_WIN64) +#include +#include +#include +#endif +#define POSIX_DEPRECATED 0 /* set to non-zero value to use 'gettimeofday' and 'usleep'*/ + +CTimer::CTimer(uint64_t u64Microseconds) { +#if !defined(_WIN32) && !defined(_WIN64) +#if (POSIX_DEPRECATED != 0) + struct timeval tv; + gettimeofday(&tv, NULL); + m_u64UntilStop = ((uint64_t)tv.tv_sec * (uint64_t)1000000) + (uint64_t)tv.tv_usec + + ((uint64_t)u64Microseconds); +#else + struct timespec now = { 0, 0 }; + clock_gettime(CLOCK_MONOTONIC, &now); + m_u64UntilStop = ((uint64_t)now.tv_sec * (uint64_t)1000000) + + ((uint64_t)now.tv_nsec / (uint64_t)1000) + + ((uint64_t)u64Microseconds); +#endif +#else + LARGE_INTEGER largeCounter; // high-resolution performance counter + + m_llUntilStop = (LONGLONG)0; // counter value for the desired time-out + + // retrieve the frequency of the high-resolution performance counter + if(!QueryPerformanceFrequency(&m_largeFrequency)) + return; + // retrieve the current value of the high-resolution performance counter + if(!QueryPerformanceCounter(&largeCounter)) + return; + // calculate the counter value for the desired time-out + m_llUntilStop = largeCounter.QuadPart + ((m_largeFrequency.QuadPart * (LONGLONG)u64Microseconds) + / (LONGLONG)1000000); +#endif +} + +bool CTimer::Restart(uint64_t u64Microseconds) { +#if !defined(_WIN32) && !defined(_WIN64) +#if (POSIX_DEPRECATED != 0) + struct timeval tv; + gettimeofday(&tv, NULL); + m_u64UntilStop = ((uint64_t)tv.tv_sec * (uint64_t)1000000) + (uint64_t)tv.tv_usec + + ((uint64_t)u64Microseconds); +#else + struct timespec now = { 0, 0 }; + clock_gettime(CLOCK_MONOTONIC, &now); + m_u64UntilStop = ((uint64_t)now.tv_sec * (uint64_t)1000000) + + ((uint64_t)now.tv_nsec / (uint64_t)1000) + + ((uint64_t)u64Microseconds); +#endif + return true; +#else + LARGE_INTEGER largeCounter; // high-resolution performance counter + + // retrieve the current value of the high-resolution performance counter + if(!QueryPerformanceCounter(&largeCounter)) + return false; + // calculate the counter value for the desired time-out + m_llUntilStop = largeCounter.QuadPart + ((m_largeFrequency.QuadPart * (LONGLONG)u64Microseconds) + / (LONGLONG)1000000); + return true; +#endif +} + +bool CTimer::Timeout() { +#if !defined(_WIN32) && !defined(_WIN64) + uint64_t u64Now; +#if (POSIX_DEPRECATED != 0) + struct timeval tv; + gettimeofday(&tv, NULL); + u64Now = ((uint64_t)tv.tv_sec * (uint64_t)1000000) + (uint64_t)tv.tv_usec; +#else + struct timespec now = { 0, 0 }; + clock_gettime(CLOCK_MONOTONIC, &now); + u64Now = ((uint64_t)now.tv_sec * (uint64_t)1000000) + + ((uint64_t)now.tv_nsec / (uint64_t)1000); +#endif + if(u64Now < this->m_u64UntilStop) + return false; + else + return true; +#else + LARGE_INTEGER largeCounter; // high-resolution performance counter + + // retrieve the current value of the high-resolution performance counter + if(!QueryPerformanceCounter(&largeCounter)) + return false; + // a time-out occurred, if the counter overruns the time-out value + if(largeCounter.QuadPart < m_llUntilStop) + return false; + else + return true; +#endif +} + +bool CTimer::Delay(uint64_t u64Microseconds) { +#if !defined(_WIN32) && !defined(_WIN64) +#if (POSIX_DEPRECATED != 0) + return (usleep((useconds_t)u64Microseconds) != 0) ? false : true; +#else + int rc; + struct timespec delay; + delay.tv_sec = (time_t)(u64Microseconds / CTimer::SEC); + delay.tv_nsec = (long)((u64Microseconds % CTimer::SEC) * (uint32_t)1000); + errno = 0; + while ((rc = nanosleep(&delay, &delay))) { + if (errno != EINTR) + break; + } + return (rc != 0) ? false : true; +#endif +#else +# ifndef CTIMER_WAITABLE_TIMER + LARGE_INTEGER largeFrequency; // frequency in counts per second + LARGE_INTEGER largeCounter; // high-resolution performance counter + LONGLONG llUntilStop; // counter value for the desired delay + + // retrieve the current value of the high-resolution performance counter + if(!QueryPerformanceCounter(&largeCounter)) + return false; + // retrieve the frequency of the high-resolution performance counter + if(!QueryPerformanceFrequency(&largeFrequency)) + return false; + // calculate the counter value for the desired delay + llUntilStop = largeCounter.QuadPart + ((largeFrequency.QuadPart * (LONGLONG)u64Microseconds) + / (LONGLONG)1000000); + // wait until the counter overruns the delay time + for(;;) + { + if(!QueryPerformanceCounter(&largeCounter)) + return false; + if(largeCounter.QuadPart >= llUntilStop) + return true; + } +# else + HANDLE timer; + LARGE_INTEGER ft; + + ft.QuadPart = -(10 * (LONGLONG)u64Microseconds); // Convert to 100 nanosecond interval, negative value indicates relative time + + if(u64Microseconds >= 100) { // FIXME: Who made this decision? + if ((timer = CreateWaitableTimer(NULL, TRUE, NULL)) != NULL) { + SetWaitableTimer(timer, &ft, 0, NULL, NULL, 0); + WaitForSingleObject(timer, INFINITE); + CloseHandle(timer); + } + } + else { + // According to MSDN's documentation for Sleep: + // | A value of zero causes the thread to relinquish the remainder of its time slice to any other + // | thread that is ready to run.If there are no other threads ready to run, the function returns + // | immediately, and the thread continues execution. + Sleep(0); + } + return true; +# endif +#endif +} + +struct timespec CTimer::GetTime() { + struct timespec now = { 0, 0 }; +#if !defined(_WIN32) && !defined(_WIN64) + clock_gettime(CLOCK_REALTIME, &now); +#else + static bool fInitialied = false; // initialization flag + static struct timespec tsStartTime; // time at first call (UTC) + static LARGE_INTEGER largeFrequency; // frequency in counts per second + static LARGE_INTEGER largeStartCounter; // high-resolution performance counter + LARGE_INTEGER largeCurrentCounter; + + if (!fInitialied) { + // retrieve the frequency of the high-resolution performance counter + if (!QueryPerformanceFrequency(&largeFrequency)) + return now; + // retrieve the value of the high-resolution performance counter + if (!QueryPerformanceCounter(&largeStartCounter)) + return now; + // retrieve the time as struct timespec + if (!timespec_get(&tsStartTime, TIME_UTC)) + return now; + fInitialied = true; + } + // retrieve the current value of the high-resolution performance counter + if (!QueryPerformanceCounter(&largeCurrentCounter)) + return now; + // calculate the current time with nanosecond resolution + largeCurrentCounter.QuadPart -= largeStartCounter.QuadPart; + time_t sec = largeCurrentCounter.QuadPart / largeFrequency.QuadPart; + long nsec = (long)(((largeCurrentCounter.QuadPart - (sec * largeFrequency.QuadPart)) + * 1000000000UL) / largeFrequency.QuadPart); + now.tv_sec = tsStartTime.tv_sec + sec; + now.tv_nsec = tsStartTime.tv_nsec + nsec; + if (now.tv_nsec >= 1000000000UL) { + now.tv_sec += 1; + now.tv_nsec -= 1000000000UL; + } +#endif + return now; +} + +double CTimer::DiffTime(struct timespec start, struct timespec stop) { + return (((double)stop.tv_sec + ((double)stop.tv_nsec / 1000000000.f)) - + ((double)start.tv_sec + ((double)start.tv_nsec / 1000000000.f))); +} + +// $Id$ Copyright (c) UV Software, Berlin // diff --git a/Tests/Sources/Timer64.h b/Tests/Sources/Timer64.h new file mode 100644 index 0000000..df83a6d --- /dev/null +++ b/Tests/Sources/Timer64.h @@ -0,0 +1,91 @@ +// SPDX-License-Identifier: BSD-2-Clause OR GPL-3.0-or-later +// +// Software for Industrial Communication, Motion Control and Automation +// +// Copyright (c) 2002-2023 Uwe Vogt, UV Software, Berlin (info@uv-software.com) +// All rights reserved. +// +// This class is dual-licensed under the BSD 2-Clause "Simplified" License and +// under the GNU General Public License v3.0 (or any later version). +// You can choose between one of them if you use this class. +// +// BSD 2-Clause "Simplified" License: +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS CLASS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS CLASS, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// GNU General Public License v3.0 or later: +// This class 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. +// +// This class 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 should have received a copy of the GNU General Public License +// along with this class. If not, see . +// +#ifndef TIMER_H_INCLUDED +#define TIMER_H_INCLUDED + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include +#include +#if defined(_WIN32) || defined(_WIN64) +#include +#endif + +#if defined(_WIN32) || defined(_WIN64) +#define CTIMER_WAITABLE_TIMER // a Windows alternative for usleep() +#endif + +class CTimer { +public: + static const uint64_t USEC = 1U; // 1 microsecond + static const uint64_t MSEC = 1000U; // 1 millisecond + static const uint64_t SEC = 1000000U; // 1 second + static const uint64_t MIN = 60000000U; // 1 minute +private: +#if !defined(_WIN32) && !defined(_WIN64) + uint64_t m_u64UntilStop; // counter value for the desired time-out +#else + LARGE_INTEGER m_largeFrequency; // frequency in counts per second + LONGLONG m_llUntilStop; // counter value for the desired time-out +#endif +public: + CTimer(uint64_t u64Microseconds = 0); + virtual ~CTimer() {}; + + bool Restart(uint64_t u64Microseconds); // restart the timer! + bool Timeout(); // time-out occurred? + + static bool Delay(uint64_t u64Microseconds); // delay timer + + static struct timespec GetTime(); // time with nanosecond resolution + static double DiffTime(struct timespec start, struct timespec stop); +}; + +#endif // TIMER_H_INCLUDED + +// $Id$ Copyright (c) UV Software, Berlin // diff --git a/Tests/Sources/pch.h b/Tests/Sources/pch.h index 6614a7d..3216ecc 100644 --- a/Tests/Sources/pch.h +++ b/Tests/Sources/pch.h @@ -28,7 +28,7 @@ #include "Bitrates.h" #include "Properties.h" #include "Progress.h" -#include "Timer.h" +#include "Timer64.h" #include "Version.h" #endif // PRECOMPILED_HEADERS_INCLUDED diff --git a/Tests/Testcases/TC00_SmokeTest.cc b/Tests/Testcases/TC00_SmokeTest.cc index 23442f5..e7d13b4 100644 --- a/Tests/Testcases/TC00_SmokeTest.cc +++ b/Tests/Testcases/TC00_SmokeTest.cc @@ -62,20 +62,20 @@ TEST_F(SmokeTest, GTEST_TESTCASE(CheckGoogleTest, GTEST_DISABLED)) { TEST_F(SmokeTest, GTEST_TESTCASE(CheckTimer, GTEST_DISABLED)) { time_t now = time(NULL); CCounter counter = CCounter(true); - CTimer timer((uint32_t)2 * CTimer::SEC); + CTimer timer((uint64_t)2 * CTimer::SEC); counter.Increment(); while (!timer.Timeout()); EXPECT_GE(time(NULL), now + 1); counter.Increment(); - CTimer::Delay((uint32_t)1 * CTimer::SEC); + CTimer::Delay((uint64_t)1 * CTimer::SEC); EXPECT_GE(time(NULL), now + 2); counter.Reset(true); struct timespec t0 = {}, t1 = {}; t0 = CTimer::GetTime(); - uint32_t delay = 100U * CTimer::MSEC; - uint32_t times = 10u; - for (uint32_t dt = 0U; dt < (times * delay); dt += delay) { + uint64_t delay = 100U * CTimer::MSEC; + uint64_t times = 10U; + for (uint64_t dt = 0U; dt < (times * delay); dt += delay) { counter.Increment(); CTimer::Delay(delay); t1 = CTimer::GetTime(); @@ -300,4 +300,4 @@ TEST_F(SmokeTest, DefaultScenario) { // @end. } -// $Id: TC00_SmokeTest.cc 1185 2023-08-29 10:42:03Z haumea $ Copyright (c) UV Software, Berlin. +// $Id: TC00_SmokeTest.cc 1217 2023-10-10 19:28:31Z haumea $ Copyright (c) UV Software, Berlin. diff --git a/Tests/Testcases/TC01_ProbeChannel.cc b/Tests/Testcases/TC01_ProbeChannel.cc index 2426725..161275a 100644 --- a/Tests/Testcases/TC01_ProbeChannel.cc +++ b/Tests/Testcases/TC01_ProbeChannel.cc @@ -256,9 +256,9 @@ TEST_F(ProbeChannel, GTEST_TESTCASE(WithValidChannelNo, GTEST_ENABLED)) { EXPECT_EQ(CCanApi::NoError, retVal); // @ note: state can take all possible values. if ((state == CCanApi::ChannelAvailable) || (state == CCanApi::ChannelOccupied)) - CTimer::Delay(300U * CTimer::MSEC); + CTimer::Delay((uint64_t)300 * CTimer::MSEC); else - CTimer::Delay(100U * CTimer::MSEC); + CTimer::Delay((uint64_t)100 * CTimer::MSEC); // next please found = CCanDevice::GetNextChannel(info); } @@ -1031,4 +1031,4 @@ TEST_F(ProbeChannel, GTEST_TESTCASE(WithInvalidLibraryId, GTEST_DISABLED)) { } #endif // (OPTION_CANAPI_LIBRARY != OPTION_DISBALED) -// $Id: TC01_ProbeChannel.cc 1165 2023-08-22 06:57:25Z haumea $ Copyright (c) UV Software, Berlin. +// $Id: TC01_ProbeChannel.cc 1217 2023-10-10 19:28:31Z haumea $ Copyright (c) UV Software, Berlin. diff --git a/Tests/Testcases/TC03_StartController.cc b/Tests/Testcases/TC03_StartController.cc index f33e6ac..9d75f80 100644 --- a/Tests/Testcases/TC03_StartController.cc +++ b/Tests/Testcases/TC03_StartController.cc @@ -2097,11 +2097,11 @@ TEST_F(StartController, GTEST_TESTCASE(WithCanBitrateIndexInCanFdMode, GTEST_ENA // @expected: CANERR_BAUDRATE (requires solely SJA1000 bit rates in CAN 2.0, e.g. PCAN-USB w/o FD) // #if (FEATURE_BITRATE_SJA1000 != FEATURE_UNSUPPORTED) -#define GTEST_SJA1000_IN_CAN_FD GTEST_ENABLED +#define GTEST_TC03_28_ENABLED GTEST_ENABLED #else -#define GTEST_SJA1000_IN_CAN_FD GTEST_DISABLED +#define GTEST_TC03_28_ENABLED GTEST_DISABLED #endif -TEST_F(StartController, GTEST_TESTCASE(WithCanBitrateSettingsInCanFdMode, GTEST_SJA1000_IN_CAN_FD)) { +TEST_F(StartController, GTEST_TESTCASE(WithCanBitrateSettingsInCanFdMode, GTEST_TC03_28_ENABLED)) { CCanDevice dut1 = CCanDevice(TEST_DEVICE(DUT1)); CCanDevice dut2 = CCanDevice(TEST_DEVICE(DUT2)); CANAPI_Bitrate_t bitrate = { CANBTR_INDEX_1M }; @@ -2209,11 +2209,11 @@ TEST_F(StartController, GTEST_TESTCASE(WithCanBitrateSettingsInCanFdMode, GTEST_ // @expected: CANERR_BAUDRATE (requires solely SJA1000 bit rates in CAN 2.0, e.g. PCAN-USB w/o FD) // #if (FEATURE_BITRATE_SJA1000 != FEATURE_UNSUPPORTED) -#define GTEST_CAN_FD_IN_CAN_CLASSIC GTEST_ENABLED +#define GTEST_TC03_29_ENABLED GTEST_ENABLED #else -#define GTEST_CAN_FD_IN_CAN_CLASSIC GTEST_DISABLED +#define GTEST_TC03_29_ENABLED GTEST_DISABLED #endif -TEST_F(StartController, GTEST_TESTCASE(WithCanFdBitrateSettingsInCan20Mode, GTEST_CAN_FD_IN_CAN_CLASSIC)) { +TEST_F(StartController, GTEST_TESTCASE(WithCanFdBitrateSettingsInCan20Mode, GTEST_TC03_29_ENABLED)) { CCanDevice dut1 = CCanDevice(TEST_DEVICE(DUT1)); CCanDevice dut2 = CCanDevice(TEST_DEVICE(DUT2)); CANAPI_Bitrate_t bitrate = { CANBTR_INDEX_1M }; @@ -2313,4 +2313,4 @@ TEST_F(StartController, GTEST_TESTCASE(WithCanFdBitrateSettingsInCan20Mode, GTES } #endif // (CAN_FD_SUPPORTED == FEATURE_SUPPORTED) -// $Id: TC03_StartController.cc 1204 2023-09-24 15:26:57Z makemake $ Copyright (c) UV Software, Berlin. +// $Id: TC03_StartController.cc 1218 2023-10-14 12:18:19Z makemake $ Copyright (c) UV Software, Berlin. diff --git a/Tests/Testcases/TC04_ReadMessage.cc b/Tests/Testcases/TC04_ReadMessage.cc index d73b8be..7ebb399 100644 --- a/Tests/Testcases/TC04_ReadMessage.cc +++ b/Tests/Testcases/TC04_ReadMessage.cc @@ -671,11 +671,11 @@ TEST_F(ReadMessage, GTEST_TESTCASE(IfReceiveQueueEmpty, GTEST_ENABLED)) { // @expected: CANERR_NOERROR but status bit 'queue_overrun' set // #if (FEATURE_SIZE_RECEIVE_QUEUE != 0) -#define GTEST_RECEIVE_QUEUE_FULL GTEST_ENABLED +#define GTEST_TC04_8_ENABLED GTEST_ENABLED #else -#define GTEST_RECEIVE_QUEUE_FULL GTEST_DISABLED +#define GTEST_TC04_8_ENABLED GTEST_DISABLED #endif -TEST_F(ReadMessage, GTEST_TESTCASE(IfReceiveQueueFull, GTEST_RECEIVE_QUEUE_FULL)) { +TEST_F(ReadMessage, GTEST_TESTCASE(IfReceiveQueueFull, GTEST_TC04_8_ENABLED)) { CCanDevice dut1 = CCanDevice(TEST_DEVICE(DUT1)); CCanDevice dut2 = CCanDevice(TEST_DEVICE(DUT2)); CANAPI_Message_t trmMsg = {}; @@ -760,11 +760,20 @@ TEST_F(ReadMessage, GTEST_TESTCASE(IfReceiveQueueFull, GTEST_RECEIVE_QUEUE_FULL) trmMsg.data[7] = (uint8_t)((uint64_t)i >> 56); if ((uint64_t)i > (uint64_t)0x0FFFFFFFFFFFFFF) trmMsg.dlc = 8U; // send one message (w/ delay calculated from bit-rate and data length) do { - retVal = dut2.WriteMessage(trmMsg, DEVICE_SEND_TIMEOUT); + retVal = dut2.WriteMessage(trmMsg, 0U); if (retVal == CCanApi::TransmitterBusy) PCBUSB_QXMT_DELAY(); } while (retVal == CCanApi::TransmitterBusy); - CTimer::Delay(dut2.TransmissionTime(dut2.GetBitrate(), 1, CCanApi::Dlc2Len(trmMsg.dlc))); + // wait for transmission to complete + uint64_t delay = dut2.TransmissionTime(dut2.GetBitrate(), 1, CCanApi::Dlc2Len(trmMsg.dlc)); +#if (TC04_8_ISSUE_PCBUSB_TRANSMIT_COMPLETE == WORKAROUND_ENABLED) + // @- issue(PCBUSB.TNG): PCAN-USB devices need more time as estimated + CANAPI_OpMode_t opCapa = { CANMODE_DEFAULT }; + retVal = dut1.GetOpCapabilities(opCapa); + if ((CCanApi::NoError == retVal) && !opCapa.fdoe) + delay *= 2U; +#endif + CTimer::Delay(delay); // on error abort ASSERT_EQ(CCanApi::NoError, retVal) << "[ ERROR! ] dut2.WriteMessage() failed with error code " << retVal; progress.Update(i + 1, 0); @@ -774,11 +783,11 @@ TEST_F(ReadMessage, GTEST_TESTCASE(IfReceiveQueueFull, GTEST_RECEIVE_QUEUE_FULL) t1 = CTimer::GetTime();; #endif // @- an additional delay to ensure that the last message is received by DUT1 - uint32_t delay = dut2.TransmissionTime(dut2.GetBitrate(), 10, CCanApi::Dlc2Len(trmMsg.dlc)); + uint64_t delay = dut2.TransmissionTime(dut2.GetBitrate(), 10, CCanApi::Dlc2Len(trmMsg.dlc)); CTimer::Delay(delay); // @- DUT1 read them all to empty the reception queue CTimer timer = CTimer(((dut1.TransmissionTime(dut1.GetBitrate(), (spam + DEVICE_LOOP_EXTRA)) * - DEVICE_LOOP_FACTOR) / DEVICE_LOOP_DIVISOR)); // bit-rate dependent timeout + (uint64_t)DEVICE_LOOP_FACTOR) / (uint64_t)DEVICE_LOOP_DIVISOR)); // bit-rate dependent timeout int32_t rcv = 0, sts = 0; do { // read message by message (with time-out) @@ -800,9 +809,15 @@ TEST_F(ReadMessage, GTEST_TESTCASE(IfReceiveQueueFull, GTEST_RECEIVE_QUEUE_FULL) EXPECT_EQ((spam - TEST_QRCVFULL), (rcv + sts)); #if (1) // @- DUT2 send / DUT1 read one more message to catch the overrun flag - timer.Restart((DEVICE_SEND_TIMEOUT + DEVICE_SEND_TIMEOUT) * CTimer::MSEC); + trmMsg.dlc = 5U; + trmMsg.data[0] = (uint8_t)'E'; + trmMsg.data[1] = (uint8_t)'x'; + trmMsg.data[2] = (uint8_t)'t'; + trmMsg.data[3] = (uint8_t)'r'; + trmMsg.data[4] = (uint8_t)'a'; + timer.Restart((uint64_t)((TEST_READ_TIMEOUT * DEVICE_LOOP_FACTOR) / DEVICE_LOOP_DIVISOR) * CTimer::MSEC); do { - retVal = dut2.WriteMessage(trmMsg, DEVICE_SEND_TIMEOUT); + retVal = dut2.WriteMessage(trmMsg, 0U); if (retVal == CCanApi::TransmitterBusy) PCBUSB_QXMT_DELAY(); } while ((retVal == CCanApi::TransmitterBusy) && !timer.Timeout()); @@ -810,7 +825,7 @@ TEST_F(ReadMessage, GTEST_TESTCASE(IfReceiveQueueFull, GTEST_RECEIVE_QUEUE_FULL) // read message by message (with time-out) retVal = dut1.ReadMessage(rcvMsg, TEST_READ_TIMEOUT); } while ((retVal == CCanApi::ReceiverEmpty) && !timer.Timeout()); - // @- todo: check if this also works with PeakCAN driver/wrapper! + // @- todo: check why this extra message is required #endif // @- get status of DUT1 and check if bit 'queue_overrun' is set retVal = dut1.GetStatus(status); @@ -819,8 +834,9 @@ TEST_F(ReadMessage, GTEST_TESTCASE(IfReceiveQueueFull, GTEST_RECEIVE_QUEUE_FULL) // @post: progress.Clear(); #if (TC04_8_DEBUG != 0) - uint64_t ovfl = 0U; // PCAN_EXT_RX_QUE_OVERRUN (0x84): receive queue overrun counter (optional) - if (dut1.GetProperty((CANPROP_GET_VENDOR_PROP + 0x84U), (void*)&ovfl, sizeof(ovfl)) == CCanApi::NoError) + uint64_t ovfl = 0U; + if ((dut1.GetProperty(CANPROP_GET_RCV_QUEUE_OVFL, (void*)&ovfl, sizeof(ovfl)) == CCanApi::NoError) || + (dut1.GetProperty(CANPROP_GET_VENDOR_PROP + 0x84U, (void*)&ovfl, sizeof(ovfl)) == CCanApi::NoError)) std::cout << "[ RCVQ ] ov=" << ovfl << std::endl; dut2.ShowTimeDifference("[ SEND ]", t0, t1); std::cout << "[ ] + " << ((float)delay / 1000.f) << "ms" << std::endl; @@ -1349,7 +1365,12 @@ TEST_F(ReadMessage, GTEST_TESTCASE(WithFlagRtrInOperationModeNoRtr, GTEST_ENABLE // // @expected: CANERR_NOERROR but status bit 'warning_level' is set and no status frame in the receive queue // -TEST_F(ReadMessage, GTEST_TESTCASE(WithFlagStsInOperationModeNoErr, GTEST_ENABLED)) { +#if defined(__MAC_11_0) +#define GTEST_TC04_15_ENABLED GTEST_ENABLED +#else +#define GTEST_TC04_15_ENABLED GTEST_DISABLED +#endif +TEST_F(ReadMessage, GTEST_TESTCASE(WithFlagStsInOperationModeNoErr, GTEST_TC04_15_ENABLED)) { CCanDevice dut1 = CCanDevice(TEST_DEVICE(DUT1)); CCanDevice dut2 = CCanDevice(TEST_DEVICE(DUT2)); CANAPI_Bitrate_t newBtr1 = {}, oldBtr1 = {}; @@ -1507,12 +1528,12 @@ TEST_F(ReadMessage, GTEST_TESTCASE(WithFlagStsInOperationModeNoErr, GTEST_ENABLE // // @expected: CANERR_NOERROR but status bit 'warning_level' is set and a status frame in the receive queue // -#if (FEATURE_ERROR_FRAMES != FEATURE_UNSUPPORTED) -#define GTEST_STATUS_MESSAGE GTEST_ENABLED +#if (FEATURE_ERROR_FRAMES != FEATURE_UNSUPPORTED) && defined(__MAC_11_0) +#define GTEST_TC04_16_ENABLED GTEST_ENABLED #else -#define GTEST_STATUS_MESSAGE GTEST_DISABLED +#define GTEST_TC04_16_ENABLED GTEST_DISABLED #endif -TEST_F(ReadMessage, GTEST_TESTCASE(WithFlagStsInOperationModeErr, GTEST_STATUS_MESSAGE)) { +TEST_F(ReadMessage, GTEST_TESTCASE(WithFlagStsInOperationModeErr, GTEST_TC04_16_ENABLED)) { CCanDevice dut1 = CCanDevice(TEST_DEVICE(DUT1)); CCanDevice dut2 = CCanDevice(TEST_DEVICE(DUT2)); CANAPI_Bitrate_t newBtr1 = {}, oldBtr1 = {}; @@ -1957,4 +1978,4 @@ TEST_F(ReadMessage, GTEST_TESTCASE(WithDifferentTimeoutValues, GTEST_ENABLED)) { // @todo: (1) blocking read // @todo: (2) test reentrancy -// $Id: TC04_ReadMessage.cc 1201 2023-09-13 11:09:28Z makemake $ Copyright (c) UV Software, Berlin. +// $Id: TC04_ReadMessage.cc 1218 2023-10-14 12:18:19Z makemake $ Copyright (c) UV Software, Berlin. diff --git a/Tests/Testcases/TC05_WriteMessage.cc b/Tests/Testcases/TC05_WriteMessage.cc index aa40d0c..cf01e66 100644 --- a/Tests/Testcases/TC05_WriteMessage.cc +++ b/Tests/Testcases/TC05_WriteMessage.cc @@ -1982,11 +1982,11 @@ TEST_F(WriteMessage, GTEST_TESTCASE(WithFlagSts, GTEST_ENABLED)) { // @expected: CANERR_TX_BUSY and status bit 'transmitter_busy' is set // #if (FEATURE_SIZE_TRANSMIT_QUEUE != 0) -#define GTEST_TRANSMITTER_BUSY GTEST_ENABLED +#define GTEST_TC04_19_ENABLED GTEST_ENABLED #else -#define GTEST_TRANSMITTER_BUSY GTEST_DISABLED +#define GTEST_TC04_19_ENABLED GTEST_DISABLED #endif -TEST_F(WriteMessage, GTEST_TESTCASE(IfTransmitterBusy, GTEST_TRANSMITTER_BUSY)) { +TEST_F(WriteMessage, GTEST_TESTCASE(IfTransmitterBusy, GTEST_TC04_19_ENABLED)) { CCanDevice dut1 = CCanDevice(TEST_DEVICE(DUT1)); CCanDevice dut2 = CCanDevice(TEST_DEVICE(DUT2)); CANAPI_Message_t trmMsg = {}; @@ -2070,7 +2070,7 @@ TEST_F(WriteMessage, GTEST_TESTCASE(IfTransmitterBusy, GTEST_TRANSMITTER_BUSY)) // @- DUT2 read them all to empty the reception queue n = i; i = 0; - CTimer timer = CTimer(((dut2.TransmissionTime(dut2.GetBitrate(), n) * 25U) / 10U)); + CTimer timer = CTimer(((dut2.TransmissionTime(dut2.GetBitrate(), n) * (uint64_t)DEVICE_LOOP_FACTOR) / (uint64_t)DEVICE_LOOP_DIVISOR)); do { // read message by message (with time-out) retVal = dut2.ReadMessage(rcvMsg, TEST_READ_TIMEOUT); @@ -2202,4 +2202,7 @@ TEST_F(WriteMessage, GTEST_TESTCASE(WithFlagEsi, GTEST_ENABLED)) { } #endif // (OPTION_CAN_2_0_ONLY == 0) -// $Id: TC05_WriteMessage.cc 1193 2023-09-06 10:21:35Z haumea $ Copyright (c) UV Software, Berlin. +// @todo: (1) blocking write +// @todo: (2) test reentrancy + +// $Id: TC05_WriteMessage.cc 1218 2023-10-14 12:18:19Z makemake $ Copyright (c) UV Software, Berlin. diff --git a/Tests/Testcases/TC09_GetStatus.cc b/Tests/Testcases/TC09_GetStatus.cc index 5758c52..03516c1 100644 --- a/Tests/Testcases/TC09_GetStatus.cc +++ b/Tests/Testcases/TC09_GetStatus.cc @@ -698,11 +698,11 @@ TEST_F(GetStatus, GTEST_TESTCASE(IfWarningLevelReached, GTEST_ENABLED)) { // @expected: CANERR_NOERROR but status bit 'bus_error' is set // #if (FEATURE_ERROR_CODE_CAPTURE != FEATURE_UNSUPPORTED) -#define GTEST_ERRORS_ON_BUS GTEST_ENABLED +#define GTEST_TC09_10_ENABLED GTEST_ENABLED #else -#define GTEST_ERRORS_ON_BUS GTEST_DISABLED +#define GTEST_TC09_10_ENABLED GTEST_DISABLED #endif -TEST_F(GetStatus, GTEST_TESTCASE(IfErrorsOnBus, GTEST_ERRORS_ON_BUS)) { +TEST_F(GetStatus, GTEST_TESTCASE(IfErrorsOnBus, GTEST_TC09_10_ENABLED)) { CCanDevice dut1 = CCanDevice(TEST_DEVICE(DUT1)); CCanDevice dut2 = CCanDevice(TEST_DEVICE(DUT2)); CANAPI_Bitrate_t newBtr1 = {}, oldBtr1 = {}; @@ -875,11 +875,11 @@ TEST_F(GetStatus, GTEST_TESTCASE(IfErrorsOnBus, GTEST_ERRORS_ON_BUS)) { // @disabled: This test is already covered by TC05.19 (WriteMessage.IfTransmitterBusy)! // #if (FEATURE_SIZE_TRANSMIT_QUEUE != 0) -#define GTEST_TRANSMITTER_BUSY GTEST_DISABLED +#define GTEST_TC09_11_ENABLED GTEST_DISABLED #else -#define GTEST_TRANSMITTER_BUSY GTEST_DISABLED +#define GTEST_TC09_11_ENABLED GTEST_DISABLED #endif -TEST_F(GetStatus, GTEST_TESTCASE(IfTransmitterBusy, GTEST_TRANSMITTER_BUSY)) { +TEST_F(GetStatus, GTEST_TESTCASE(IfTransmitterBusy, GTEST_TC09_11_ENABLED)) { CCanDevice dut1 = CCanDevice(TEST_DEVICE(DUT1)); CCanDevice dut2 = CCanDevice(TEST_DEVICE(DUT2)); CANAPI_Message_t trmMsg = {}; @@ -963,10 +963,12 @@ TEST_F(GetStatus, GTEST_TESTCASE(IfTransmitterBusy, GTEST_TRANSMITTER_BUSY)) { // @- DUT2 read them all to empty the reception queue n = i; i = 0; - CTimer timer = CTimer(((dut2.TransmissionTime(dut2.GetBitrate(), n) * 25U) / 10U)); + CTimer timer = CTimer(((dut2.TransmissionTime(dut2.GetBitrate(), n) * (uint64_t)DEVICE_LOOP_FACTOR) / (uint64_t)DEVICE_LOOP_DIVISOR)); do { + // read message by message (with time-out) retVal = dut2.ReadMessage(rcvMsg, TEST_READ_TIMEOUT); if (retVal == CCanApi::NoError) { + // ignore status messages/error frames if (!rcvMsg.sts) progress.Update(n, i++); } @@ -1007,7 +1009,6 @@ TEST_F(GetStatus, GTEST_TESTCASE(IfTransmitterBusy, GTEST_TRANSMITTER_BUSY)) { TEST_F(GetStatus, GTEST_TESTCASE(IfReceiveQueueEmpty, GTEST_DISABLED)) { CCanDevice dut1 = CCanDevice(TEST_DEVICE(DUT1)); CCanDevice dut2 = CCanDevice(TEST_DEVICE(DUT2)); - CCanApi::EChannelState state; CANAPI_Message_t trmMsg = {}; CANAPI_Message_t rcvMsg = {}; CANAPI_Status_t status = {}; @@ -1028,17 +1029,6 @@ TEST_F(GetStatus, GTEST_TESTCASE(IfReceiveQueueEmpty, GTEST_DISABLED)) { memset(trmMsg.data, 0, CANFD_MAX_LEN); #endif // @pre: - // @- probe if DUT1 is present and not occupied - retVal = dut1.ProbeChannel(state); - ASSERT_EQ(CCanApi::NoError, retVal) << "[ ERROR! ] dut1.ProbeChannel() failed with error code " << retVal; - ASSERT_EQ(CCanApi::ChannelAvailable, state) << "[ ERROR! ] " << g_Options.GetDeviceName(DUT1) << " is not available"; - // @- probe if DUT2 is present and not occupied - retVal = dut2.ProbeChannel(state); - ASSERT_EQ(CCanApi::NoError, retVal) << "[ ERROR! ] dut2.ProbeChannel() failed with error code " << retVal; - ASSERT_EQ(CCanApi::ChannelAvailable, state) << "[ ERROR! ] " << g_Options.GetDeviceName(DUT2) << " is not available"; - // @- check if different channels have been selected - ASSERT_TRUE((g_Options.GetChannelNo(DUT1) != g_Options.GetChannelNo(DUT2)) || \ - (g_Options.GetLibraryId(DUT1) != g_Options.GetLibraryId(DUT2))) << "[ ERROR! ] same channel selected twice"; // @- initialize DUT1 with configured settings retVal = dut1.InitializeChannel(); ASSERT_EQ(CCanApi::NoError, retVal) << "[ ERROR! ] dut1.InitializeChannel() failed with error code " << retVal; @@ -1132,11 +1122,11 @@ TEST_F(GetStatus, GTEST_TESTCASE(IfMessageLost, GTEST_DISABLED)) { // @disabled: This test is already covered by TC04.8 (ReadMessage.IfReceiveQueueFull)! // #if (FEATURE_SIZE_RECEIVE_QUEUE != 0) -#define GTEST_RECEIVE_QUEUE_FULL GTEST_DISABLED +#define GTEST_TC09_14_ENABLED GTEST_DISABLED #else -#define GTEST_RECEIVE_QUEUE_FULL GTEST_DISABLED +#define GTEST_TC09_14_ENABLED GTEST_DISABLED #endif -TEST_F(GetStatus, GTEST_TESTCASE(IfReceiveQueueFull, GTEST_RECEIVE_QUEUE_FULL)) { +TEST_F(GetStatus, GTEST_TESTCASE(IfReceiveQueueFull, GTEST_TC09_14_ENABLED)) { CCanDevice dut1 = CCanDevice(TEST_DEVICE(DUT1)); CCanDevice dut2 = CCanDevice(TEST_DEVICE(DUT2)); CANAPI_Message_t trmMsg = {}; @@ -1144,7 +1134,7 @@ TEST_F(GetStatus, GTEST_TESTCASE(IfReceiveQueueFull, GTEST_RECEIVE_QUEUE_FULL)) CANAPI_Status_t status = {}; CANAPI_Return_t retVal; // CAN message - trmMsg.id = 0x513U; + trmMsg.id = 0x408U; trmMsg.xtd = 0; trmMsg.rtr = 0; trmMsg.sts = 0; @@ -1221,11 +1211,20 @@ TEST_F(GetStatus, GTEST_TESTCASE(IfReceiveQueueFull, GTEST_RECEIVE_QUEUE_FULL)) trmMsg.data[7] = (uint8_t)((uint64_t)i >> 56); if ((uint64_t)i > (uint64_t)0x0FFFFFFFFFFFFFF) trmMsg.dlc = 8U; // send one message (w/ delay calculated from bit-rate and data length) do { - retVal = dut2.WriteMessage(trmMsg, DEVICE_SEND_TIMEOUT); + retVal = dut2.WriteMessage(trmMsg, 0U); if (retVal == CCanApi::TransmitterBusy) PCBUSB_QXMT_DELAY(); } while (retVal == CCanApi::TransmitterBusy); - CTimer::Delay(dut2.TransmissionTime(dut2.GetBitrate(), 1, CCanApi::Dlc2Len(trmMsg.dlc))); + // wait for transmission to complete + uint64_t delay = dut2.TransmissionTime(dut2.GetBitrate(), 1, CCanApi::Dlc2Len(trmMsg.dlc)); +#if (TC04_8_ISSUE_PCBUSB_TRANSMIT_COMPLETE == WORKAROUND_ENABLED) + // @- issue(PCBUSB.TNG): PCAN-USB devices need more time as estimated + CANAPI_OpMode_t opCapa = { CANMODE_DEFAULT }; + retVal = dut1.GetOpCapabilities(opCapa); + if ((CCanApi::NoError == retVal) && !opCapa.fdoe) + delay *= 2U; +#endif + CTimer::Delay(delay); // on error abort ASSERT_EQ(CCanApi::NoError, retVal) << "[ ERROR! ] dut2.WriteMessage() failed with error code " << retVal; progress.Update(i + 1, 0); @@ -1235,11 +1234,11 @@ TEST_F(GetStatus, GTEST_TESTCASE(IfReceiveQueueFull, GTEST_RECEIVE_QUEUE_FULL)) t1 = CTimer::GetTime();; #endif // @- an additional delay to ensure that the last message is received by DUT1 - uint32_t delay = dut2.TransmissionTime(dut2.GetBitrate(), 10, CCanApi::Dlc2Len(trmMsg.dlc)); + uint64_t delay = dut2.TransmissionTime(dut2.GetBitrate(), 10, CCanApi::Dlc2Len(trmMsg.dlc)); CTimer::Delay(delay); // @- DUT1 read them all to empty the reception queue CTimer timer = CTimer(((dut1.TransmissionTime(dut1.GetBitrate(), (spam + DEVICE_LOOP_EXTRA)) * - DEVICE_LOOP_FACTOR) / DEVICE_LOOP_DIVISOR)); // bit-rate dependent timeout + (uint64_t)DEVICE_LOOP_FACTOR) / (uint64_t)DEVICE_LOOP_DIVISOR)); // bit-rate dependent timeout int32_t rcv = 0, sts = 0; do { // read message by message (with time-out) @@ -1261,9 +1260,15 @@ TEST_F(GetStatus, GTEST_TESTCASE(IfReceiveQueueFull, GTEST_RECEIVE_QUEUE_FULL)) EXPECT_EQ((spam - TEST_QRCVFULL), (rcv + sts)); #if (1) // @- DUT2 send / DUT1 read one more message to catch the overrun flag - timer.Restart((DEVICE_SEND_TIMEOUT + DEVICE_SEND_TIMEOUT) * CTimer::MSEC); + trmMsg.dlc = 5U; + trmMsg.data[0] = (uint8_t)'E'; + trmMsg.data[1] = (uint8_t)'x'; + trmMsg.data[2] = (uint8_t)'t'; + trmMsg.data[3] = (uint8_t)'r'; + trmMsg.data[4] = (uint8_t)'a'; + timer.Restart((uint64_t)((TEST_READ_TIMEOUT * DEVICE_LOOP_FACTOR) / DEVICE_LOOP_DIVISOR) * CTimer::MSEC); do { - retVal = dut2.WriteMessage(trmMsg, DEVICE_SEND_TIMEOUT); + retVal = dut2.WriteMessage(trmMsg, 0U); if (retVal == CCanApi::TransmitterBusy) PCBUSB_QXMT_DELAY(); } while ((retVal == CCanApi::TransmitterBusy) && !timer.Timeout()); @@ -1271,7 +1276,7 @@ TEST_F(GetStatus, GTEST_TESTCASE(IfReceiveQueueFull, GTEST_RECEIVE_QUEUE_FULL)) // read message by message (with time-out) retVal = dut1.ReadMessage(rcvMsg, TEST_READ_TIMEOUT); } while ((retVal == CCanApi::ReceiverEmpty) && !timer.Timeout()); - // @- todo: check if this also works with PeakCAN driver/wrapper! + // @- todo: check why this extra message is required #endif // @- get status of DUT1 and check if bit 'queue_overrun' is set retVal = dut1.GetStatus(status); @@ -1280,8 +1285,9 @@ TEST_F(GetStatus, GTEST_TESTCASE(IfReceiveQueueFull, GTEST_RECEIVE_QUEUE_FULL)) // @post: progress.Clear(); #if (TC04_8_DEBUG != 0) - uint64_t ovfl = 0U; // PCAN_EXT_RX_QUE_OVERRUN (0x84): receive queue overrun counter (optional) - if (dut1.GetProperty((CANPROP_GET_VENDOR_PROP + 0x84U), (void*)&ovfl, sizeof(ovfl)) == CCanApi::NoError) + uint64_t ovfl = 0U; + if ((dut1.GetProperty(CANPROP_GET_RCV_QUEUE_OVFL, (void*)&ovfl, sizeof(ovfl)) == CCanApi::NoError) || + (dut1.GetProperty(CANPROP_GET_VENDOR_PROP + 0x84U, (void*)&ovfl, sizeof(ovfl)) == CCanApi::NoError)) std::cout << "[ RCVQ ] ov=" << ovfl << std::endl; dut2.ShowTimeDifference("[ SEND ]", t0, t1); std::cout << "[ ] + " << ((float)delay / 1000.f) << "ms" << std::endl; @@ -1312,4 +1318,4 @@ TEST_F(GetStatus, GTEST_TESTCASE(IfReceiveQueueFull, GTEST_RECEIVE_QUEUE_FULL)) // @end. } -// $Id: TC09_GetStatus.cc 1201 2023-09-13 11:09:28Z makemake $ Copyright (c) UV Software, Berlin. +// $Id: TC09_GetStatus.cc 1218 2023-10-14 12:18:19Z makemake $ Copyright (c) UV Software, Berlin. diff --git a/Tests/Testcases/TCx2_BitrateConverter.cc b/Tests/Testcases/TCx2_BitrateConverter.cc index 07c3596..bea3b22 100644 --- a/Tests/Testcases/TCx2_BitrateConverter.cc +++ b/Tests/Testcases/TCx2_BitrateConverter.cc @@ -632,11 +632,11 @@ TEST_F(BitrateConverter, GTEST_TESTCASE(BitrateToSpeedWithDivisonByZero, GTEST_E // @expected: CANERR_NOERROR // #if (FEATURE_BITRATE_SJA1000 != FEATURE_UNSUPPORTED) -#define GTEST_SJA1000_INDEXES_TO_BITRATE GTEST_ENABLED +#define GTEST_TCx2_4_1_ENABLED GTEST_ENABLED #else -#define GTEST_SJA1000_INDEXES_TO_BITRATE GTEST_DISABLED +#define GTEST_TCx2_4_1_ENABLED GTEST_DISABLED #endif -TEST_F(BitrateConverter, GTEST_TESTCASE(IndexToBitrateWithValidIndexes, GTEST_SJA1000_INDEXES_TO_BITRATE)) { +TEST_F(BitrateConverter, GTEST_TESTCASE(IndexToBitrateWithValidIndexes, GTEST_TCx2_4_1_ENABLED)) { CANAPI_Bitrate_t bitrate; CANAPI_BusSpeed_t speed; CANAPI_Return_t retVal; @@ -926,11 +926,11 @@ TEST_F(BitrateConverter, GTEST_TESTCASE(StringToBitrateWithNullPointerForString, // @expected: CANERR_NOERROR // #if (FEATURE_BITRATE_SJA1000 != FEATURE_UNSUPPORTED) -#define GTEST_SJA1000_INDEXES_TO_STRING GTEST_ENABLED +#define GTEST_TCx2_7_1_ENABLED GTEST_ENABLED #else -#define GTEST_SJA1000_INDEXES_TO_STRING GTEST_DISABLED +#define GTEST_TCx2_7_1_ENABLED GTEST_DISABLED #endif -TEST_F(BitrateConverter, GTEST_TESTCASE(BitrateToStringFromValidIndexes, GTEST_SJA1000_INDEXES_TO_STRING)) { +TEST_F(BitrateConverter, GTEST_TESTCASE(BitrateToStringFromValidIndexes, GTEST_TCx2_7_1_ENABLED)) { CANAPI_Bitrate_t source = {}; CANAPI_Bitrate_t target = {}; CANAPI_Return_t retVal; @@ -1603,4 +1603,4 @@ TEST_F(BitrateConverter, GTEST_TESTCASE(BitrateToStringWithNullPointerForString, // // @note: passing a pointer for 'btr0btr1' is not possible with the C++ API! -// $Id: TCx2_BitrateConverter.cc 1201 2023-09-13 11:09:28Z makemake $ Copyright (c) UV Software, Berlin. +// $Id: TCx2_BitrateConverter.cc 1218 2023-10-14 12:18:19Z makemake $ Copyright (c) UV Software, Berlin. diff --git a/Tests/Version.h b/Tests/Version.h index 0522042..fdd12b6 100644 --- a/Tests/Version.h +++ b/Tests/Version.h @@ -47,8 +47,8 @@ // #ifndef VERSION_H_INCLUDED #define VERSION_H_INCLUDED -// SVN revision number (update with each commit: V) -#define REVISION_NO "$Rev: 1205 $" +// SVN revision number (update with each commit: VII) +#define REVISION_NO "$Rev: 1219 $" #endif // VERSION_H_INCLUDED -// $Id: Version.h 1205 2023-09-24 15:30:34Z makemake $ Copyright (c) UV Software, Berlin // +// $Id: Version.h 1219 2023-10-14 12:23:07Z makemake $ Copyright (c) UV Software, Berlin // diff --git a/Tests/pcb_testing.vcxproj b/Tests/pcb_testing.vcxproj index 02481dd..398b6ef 100644 --- a/Tests/pcb_testing.vcxproj +++ b/Tests/pcb_testing.vcxproj @@ -164,7 +164,7 @@ NotUsing - + NotUsing NotUsing NotUsing @@ -201,7 +201,7 @@ - + diff --git a/Tests/pcb_testing.vcxproj.filters b/Tests/pcb_testing.vcxproj.filters index 916c376..4169747 100644 --- a/Tests/pcb_testing.vcxproj.filters +++ b/Tests/pcb_testing.vcxproj.filters @@ -48,9 +48,6 @@ Source Files - - Source Files - Source Files\Testcases @@ -87,6 +84,9 @@ Source Files\Testcases + + Source Files + @@ -131,14 +131,14 @@ Header Files - - Header Files - Header Files Header Files + + Header Files + \ No newline at end of file From 3da2f067ed88b410aa7221ff5bfebd7511b207a2 Mon Sep 17 00:00:00 2001 From: Uwe Vogt Date: Sun, 5 Nov 2023 21:57:47 +0100 Subject: [PATCH 7/8] Update Deployment.md Relates to [CANAPI-51] --- Deployment.md | 43 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/Deployment.md b/Deployment.md index 1f71d57..ceb0122 100644 --- a/Deployment.md +++ b/Deployment.md @@ -13,16 +13,16 @@ _All rights reserved._ ### Preparation -1. Update the PCANBasic DLL in `$(PROJROOT)\Sources\PCANBasic` from PEAK�s website - when required and commit them with commit comment: +1. If necessary, update the PCANBasic DLL in `$(PROJROOT)\Sources\PCANBasic` + from PEAK's website and commit it with commit comment: - `Update PEAK's PCANBasic DLL (version `_n_`.`_n_`.`_n_`)` \ `- `_list of major changes (optional)_ -2. Update the CAN API V3 sources in `$(PROJROOT)\Sources\CANAPI` from SVN repo - when required and commit them with commit comment: +2. If necessary, update the CAN API V3 sources in `$(PROJROOT)\Sources\CANAPI` + from the SVN repo and commit them with commit comment: - `Update CAN API V3 sources to rev. `_nnn_ \ `- `_list of major changes (optional)_ -3. Update the CAN API V3 testing sources in `$(PROJROOT)\Tests` from SVN repo - when required and commit them with commit comment: +3. If necessary, update the CAN API V3 testing sources in `$(PROJROOT)\Tests` + from the SVN repo and commit them with commit comment: - `Update CAN API V3 testing sources to rev. `_nnn_ \ `- `_list of major changes (optional)_ 4. Check and update the version and date information in the following files: @@ -37,13 +37,13 @@ _All rights reserved._ ### Procedure 1. Check the working directory for uncommitted changes. - - _**There should not be any uncommitted change.**_ - - _If there are uncommitted changes then commit them or revert them._ + - _**There should not be any uncommitted changes.**_ + - _If there are uncommitted changes then commit or undo them._ 2. Open the trial program with Visual Studio and run a code analysis. - _**There should not be any serious finding.**_ - _If there are findings then fix them or create an issue in the repo._ 3. Run `x86_build.bat` and `x64_build.bat` in the project root directory. - - _**There should be absolute no compiler or linker error!**_ + - _**There should be absolutely no compiler or linker error!**_ - _If there are compiler or linker warnings then think twice._ 4. Try out the trial program with different options. - _**There should be no crash, hangup, or any other error.**_ @@ -51,14 +51,14 @@ _All rights reserved._ 5. Try out the utilities with different options. - _**There should be no crash, hangup, or any other error.**_ - _If there is an error then fix it or create an issue in the repo._ -6. Build and try out the examples (repair them if necessary); +6. Build and try out the examples (fix them if necessary); - `$(PROJROOT)\Examples\C++` - `$(PROJROOT)\Examples\Python` ### Pull Request 1. Update the `README.md` (e.g. development environment, supported devices, etc.). -2. Push the feature branch onto the remote repo. +2. Push the feature branch to the remote repo. 3. Create a pull request and name it somehow like '**Release Candidate _n_ for** ...'. 4. Review the changes and merge the feature branch into the default branch. @@ -77,18 +77,18 @@ _All rights reserved._ 4. Build the CAN API V3 GoogleTest program: - `C:\Users\haumea>cd C:\Projects\CAN\Drivers\PeakCAN\Tests` - `C:\Projects\CAN\Drivers\PeakCAN\Tests>x86_build.bat` -5. Run the CAN API V3 GoogleTest with two PCAN-USB device: +5. Run the CAN API V3 GoogleTest program with two PCAN-USB devices: - `C:\Projects\CAN\Drivers\PeakCAN\Tests>Debug\pcb_testing --can_dut1=PCAN-USB1 --can_dut2=PCAN-USB2 --gtest_output=xml:TestReport_PCAN-USB.xml --run_all=YES --smoketest_frames=100000` [...] - _If there is any error then **stop** here or create an issue for each error in the repo._ - - Copy the test report into the binaries directory `$(PROJROOT)\Binaries`. -6. Run the CAN API V3 GoogleTest with two PCAN-USB FD device: + - Copy the test report into the binary's directory `$(PROJROOT)\Binaries`. +6. Run the CAN API V3 GoogleTest program with two PCAN-USB FD devices: - `C:\Projects\CAN\Drivers\PeakCAN\Tests>Debug\pcb_testing --can_dut1=PCAN-USB3 --can_dut2=PCAN-USB4 --gtest_output=xml:TestReport_PCAN-USB_FD.xml --run_all=YES --smoketest_frames=100000` [...] - _If there is any error then **stop** here or create an issue for each error in the repo._ - - Copy the test report into the binaries directory `$(PROJROOT)\Binaries`. -6. Run the CAN API V3 GoogleTest with the dual-channel PCAN-USB Pro FD device: + - Copy the test report into the binary's directory `$(PROJROOT)\Binaries`. +6. Run the CAN API V3 GoogleTest program with the dual-channel PCAN-USB Pro FD device: - `C:\Projects\CAN\Drivers\PeakCAN\Tests>Debug\pcb_testing --can_dut1=PCAN-USB5 --can_dut2=PCAN-USB6 --gtest_output=xml:TestReport_PCAN-USB_Pro_FD.xml --run_all=YES --smoketest_frames=100000` [...] - _If there is any error then **stop** here or create an issue for each error in the repo._ - - Copy the test report into the binaries directory `$(PROJROOT)\Binaries`. + - Copy the test report into the binary's directory `$(PROJROOT)\Binaries`. 7. Pack the artifacts into a .zip-archive, e.g. `artifacts.zip`: - `$(PROJROOT)\Binaries\*.*` - `$(PROJROOT)\Includes\*.*` @@ -100,20 +100,19 @@ _All rights reserved._ 1. Click on `Draft a new release` in the [GitHub](https://github.com/uv-software/PeakCAN-Wrapper) repo. 2. Fill out all required fields: - - Tag version: e.g `v0.4.5` (cf. semantic versioning) + - Tag version: e.g `v0.4.6` (cf. semantic versioning) - Target: `main` (default branch) - - Release title: e.g. `Release of August 25, 2023` + - Release title: e.g. `Release of November 5, 2023` - Change-log: list all major changes, e.g. from commit comments - Assets: drag and drop the artifacts archive (see above) 3. Click on `Publish release`. -4. That�s all folks! +4. That's all folks! ### Announcement 1. Create a new post with the change-log in the `mac-can.github.io` repo. -2. Update the PCANBasic page in the `mac-can.github.io` repo. +2. Update the PCANBasic-Wrapper page in the `mac-can.github.io` repo. 3. Post the new release on [Twitter](https://twitter.com/uv_software), -[LinkedIn](https://linkedin.com/in/uwe-vogt-software), [Facebook](https://facebook.com/uvsoftware.berlin), etc. From f287703131ca69f4439984f71fbdc3f5baee70ec Mon Sep 17 00:00:00 2001 From: Uwe Vogt Date: Wed, 8 Nov 2023 20:19:27 +0100 Subject: [PATCH 8/8] Set version numbers for release Relates to [CANAPI-51] --- Libraries/CANAPI/Resource.rc | Bin 4800 -> 4800 bytes Libraries/PeakCAN/Resource.rc | Bin 4776 -> 4776 bytes Sources/PeakCAN.cpp | 4 ++-- Sources/Wrapper/can_api.c | 4 ++-- Utilities/can_moni/Driver.h | 2 +- Utilities/can_moni/README.md | 2 +- Utilities/can_test/Driver.h | 2 +- Utilities/can_test/README.md | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Libraries/CANAPI/Resource.rc b/Libraries/CANAPI/Resource.rc index 1bcd1295590ee0c78649a94ea3264e25e327c315..d7dedce596666f0f542b15b220a20ef35dfcfc8b 100644 GIT binary patch delta 38 rcmX@0dO&qU6$hjFM)S>UIntSdoP~VSn+MzhUpIntSdoP~VSn+M)S>UIntR~%^CC<3??7s*4^yJMzhUpIntR~%^36;3??7s*4^yJ3k diff --git a/Sources/PeakCAN.cpp b/Sources/PeakCAN.cpp index 218b216..71f65cb 100644 --- a/Sources/PeakCAN.cpp +++ b/Sources/PeakCAN.cpp @@ -49,11 +49,11 @@ #ifdef _MSC_VER #define VERSION_MAJOR 0 #define VERSION_MINOR 4 -#define VERSION_PATCH 99 +#define VERSION_PATCH 7 #else #define VERSION_MAJOR 0 #define VERSION_MINOR 2 -#define VERSION_PATCH 99 +#define VERSION_PATCH 7 #endif #define VERSION_BUILD BUILD_NO #define VERSION_STRING TOSTRING(VERSION_MAJOR) "." TOSTRING(VERSION_MINOR) "." TOSTRING(VERSION_PATCH) " (" TOSTRING(BUILD_NO) ")" diff --git a/Sources/Wrapper/can_api.c b/Sources/Wrapper/can_api.c index 369da0f..a415270 100644 --- a/Sources/Wrapper/can_api.c +++ b/Sources/Wrapper/can_api.c @@ -53,11 +53,11 @@ #ifdef _MSC_VER #define VERSION_MAJOR 0 #define VERSION_MINOR 4 -#define VERSION_PATCH 99 +#define VERSION_PATCH 7 #else #define VERSION_MAJOR 0 #define VERSION_MINOR 2 -#define VERSION_PATCH 99 +#define VERSION_PATCH 7 #endif #define VERSION_BUILD BUILD_NO #define VERSION_STRING TOSTRING(VERSION_MAJOR) "." TOSTRING(VERSION_MINOR) "." TOSTRING(VERSION_PATCH) " (" TOSTRING(BUILD_NO) ")" diff --git a/Utilities/can_moni/Driver.h b/Utilities/can_moni/Driver.h index 75a70a1..5e30439 100644 --- a/Utilities/can_moni/Driver.h +++ b/Utilities/can_moni/Driver.h @@ -22,7 +22,7 @@ #include "build_no.h" #define VERSION_MAJOR 0 #define VERSION_MINOR 4 -#define VERSION_PATCH 99 +#define VERSION_PATCH 7 #define VERSION_BUILD BUILD_NO #define VERSION_STRING TOSTRING(VERSION_MAJOR) "." TOSTRING(VERSION_MINOR) "." TOSTRING(VERSION_PATCH) " (" TOSTRING(BUILD_NO) ")" #if defined(_WIN64) diff --git a/Utilities/can_moni/README.md b/Utilities/can_moni/README.md index 72038e2..a294e9d 100644 --- a/Utilities/can_moni/README.md +++ b/Utilities/can_moni/README.md @@ -1,4 +1,4 @@ -__CAN Monitor for Peak-System PCAN Interfaces, Version 0.4.6__ \ +__CAN Monitor for Peak-System PCAN Interfaces, Version 0.4.7__ \ Copyright © 2007,2017-2023 by Uwe Vogt, UV Software, Berlin ``` diff --git a/Utilities/can_test/Driver.h b/Utilities/can_test/Driver.h index bd11205..fb66dda 100644 --- a/Utilities/can_test/Driver.h +++ b/Utilities/can_test/Driver.h @@ -22,7 +22,7 @@ #include "build_no.h" #define VERSION_MAJOR 0 #define VERSION_MINOR 4 -#define VERSION_PATCH 99 +#define VERSION_PATCH 7 #define VERSION_BUILD BUILD_NO #define VERSION_STRING TOSTRING(VERSION_MAJOR) "." TOSTRING(VERSION_MINOR) "." TOSTRING(VERSION_PATCH) " (" TOSTRING(BUILD_NO) ")" #if defined(_WIN64) diff --git a/Utilities/can_test/README.md b/Utilities/can_test/README.md index 39ebbe6..88562fb 100644 --- a/Utilities/can_test/README.md +++ b/Utilities/can_test/README.md @@ -1,4 +1,4 @@ -__CAN Tester for Peak-System PCAN Interfaces, Version 0.4.6__ \ +__CAN Tester for Peak-System PCAN Interfaces, Version 0.4.7__ \ Copyright © 2008-2010,2014-2023 by Uwe Vogt, UV Software, Berlin ```