diff --git a/Examples/Python/CANAPI.py b/Examples/Python/CANAPI.py index 5b19731..c1decdd 100644 --- a/Examples/Python/CANAPI.py +++ b/Examples/Python/CANAPI.py @@ -52,9 +52,9 @@ Interface API for various CAN interfaces from different vendors running under multiple operating systems. - $Author: makemake $ + $Author: quaoar $ - $Rev: 1274 $ + $Rev: 1278 $ """ from ctypes import * import platform @@ -69,7 +69,7 @@ # CAN API V3 - Python Wrapper # -CAN_API_V3_PYTHON = {'major': 0, 'minor': 2, 'patch': 2} +CAN_API_V3_PYTHON = {'major': 0, 'minor': 3, 'patch': 1} # CAN Identifier Ranges # @@ -122,6 +122,13 @@ (49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64): c_uint8(0xF) } +# CAN Acceptance Filter: (code ^ id) & mask == 0 +# +CANACC_CODE_11BIT = 0x000 # mask for 11-bit acceptance code +CANACC_MASK_11BIT = 0x000 # mask for 11-bit acceptance mask +CANACC_CODE_29BIT = 0x00000000 # mask for 29-bit acceptance code +CANACC_MASK_29BIT = 0x00000000 # mask for 29-bit acceptance mask + # CAN 2.0 Predefined Bit-rates (as index acc. CiA) # CANBTR_INDEX_1M = c_int32(0) # bit-rate: 1000 kbit/s @@ -638,6 +645,70 @@ def bitrate(self): print('+++ exception: {}'.format(e)) raise + def filter11bit(self, code, mask): + """ + sets a 11-bit filter for the CAN controller. + + :param code: 11-bit code for the filter (or None) + :param mask: 11-bit mask for the filter (or None) + :return: result, code, mask + result: 0 if successful, or a negative value on error + code: 11-bit code for the filter + mask: 11-bit mask for the filter + """ + try: + # set the 11-bit filter (if code or mask are not None) + if code is not None or mask is not None: + __filter = c_uint64(0) + if code is not None: + __filter.value = code << 32 + if mask is not None: + __filter.value |= mask & 0xFFFFFFFF + result = self.__m_library.can_property(self.__m_handle, 42, byref(__filter), 8) + if result < 0: + return int(result), None, None + # get the 11-bit filter + __value = c_uint64(0) + result = self.__m_library.can_property(self.__m_handle, 40, byref(__value), 8) + if result < 0: + return int(result), None, None + return int(result), int(__filter.value >> 32), int(__filter.value & 0xFFFFFFFF) + except Exception as e: + print('+++ exception: {}'.format(e)) + raise + + def filter29bit(self, code, mask): + """ + sets a 29-bit filter for the CAN controller. + + :param code: 29-bit code for the filter (or None) + :param mask: 29-bit mask for the filter (or None) + :return: result, code, mask + result: 0 if successful, or a negative value on error + code: 29-bit code for the filter + mask: 29-bit mask for the filter + """ + try: + # set the 29-bit filter (if code or mask are not None) + if code is not None or mask is not None: + __filter = c_uint64(0) + if code is not None: + __filter.value = code << 32 + if mask is not None: + __filter.value |= mask & 0xFFFFFFFF + result = self.__m_library.can_property(self.__m_handle, 43, byref(__filter), 8) + if result < 0: + return int(result), None, None + # get the 29-bit filter + __value = c_uint64(0) + result = self.__m_library.can_property(self.__m_handle, 41, byref(__value), 8) + if result < 0: + return int(result), None, None + return int(result), int(__filter.value >> 32), int(__filter.value & 0xFFFFFFFF) + except Exception as e: + print('+++ exception: {}'.format(e)) + raise + def hardware(self): """ retrieves the hardware version of the CAN controller @@ -780,6 +851,20 @@ def len2dlc(length): else: print('>>> can.status() >>> 0x{:02X}'.format(status.byte)) + # set acceptance filter + code = CANACC_CODE_11BIT + mask = CANACC_MASK_11BIT + print('>>> can.filter11bit(0x{:03X}, 0x{:03X})'.format(code, mask)) + res, code, mask = can.filter11bit(code=code, mask=mask) + if res < CANERR_NOERROR: + print('+++ error: can.filter11bit returned {}'.format(res)) + code = CANACC_CODE_29BIT + mask = CANACC_MASK_29BIT + print('>>> can.filter29bit(0x{:08X}, 0x{:08X})'.format(code, mask)) + res, code, mask = can.filter29bit(code=code, mask=mask) + if res < CANERR_NOERROR: + print('+++ error: can.filter29bit returned {}'.format(res)) + # start the CAN controller if bitRate.index > 0: # FIXME: Expected type 'int', got 'c_int32[int]' instead print('>>> can.start([{},[{},{},{},{},{}],[{},{},{},{},])'.format(bitRate.btr.frequency, @@ -831,5 +916,5 @@ def len2dlc(length): # have a great time print('Bye, bye!') -# * $Id: CANAPI.py 1274 2024-04-21 17:34:21Z makemake $ *** (c) UV Software, Berlin *** +# * $Id: CANAPI.py 1278 2024-04-23 08:34:36Z quaoar $ *** (c) UV Software, Berlin *** # diff --git a/Examples/Python/can_recv.py b/Examples/Python/can_recv.py index 3546512..f4d7f40 100644 --- a/Examples/Python/can_recv.py +++ b/Examples/Python/can_recv.py @@ -10,10 +10,10 @@ # def sigterm(signo, frame): print() -# print('>>> can.kill()') -# result = can.kill() -# if result < 0: -# print('+++ error: can.kill returned {}'.format(result)) + print('>>> can.kill()') + result = can.kill() + if result < 0: + print('+++ error: can.kill returned {}'.format(result)) print('>>> can.exit()') result = can.exit() if result < 0: @@ -69,6 +69,20 @@ def sigterm(signo, frame): else: print('>>> can.status() >>> 0x{:02X}'.format(status.byte)) +# set acceptance filter +code = CANACC_CODE_11BIT +mask = CANACC_MASK_11BIT +print('>>> can.filter11bit(0x{:03X}, 0x{:03X})'.format(code, mask)) +res, code, mask = can.filter11bit(code=code, mask=mask) +if res < CANERR_NOERROR: + print('+++ error: can.filter11bit returned {}'.format(res)) +code = CANACC_CODE_29BIT +mask = CANACC_MASK_29BIT +print('>>> can.filter29bit(0x{:08X}, 0x{:08X})'.format(code, mask)) +res, code, mask = can.filter29bit(code=code, mask=mask) +if res < CANERR_NOERROR: + print('+++ error: can.filter29bit returned {}'.format(res)) + # start the CAN controller if int(bitRate.index) > 0: # FIXME: Expected type 'int', got 'c_int32[int]' instead print('>>> can.start([{},[{},{},{},{},{}],[{},{},{},{},])'.format(bitRate.btr.frequency, diff --git a/Examples/Python/can_send.py b/Examples/Python/can_send.py index 72f3a32..7514bfc 100644 --- a/Examples/Python/can_send.py +++ b/Examples/Python/can_send.py @@ -11,10 +11,10 @@ # def sigterm(signo, frame): print() -# print('>>> can.kill()') -# result = can.kill() -# if result < 0: -# print('+++ error: can.kill returned {}'.format(result)) + print('>>> can.kill()') + result = can.kill() + if result < 0: + print('+++ error: can.kill returned {}'.format(result)) print('>>> can.exit()') result = can.exit() if result < 0: diff --git a/Libraries/CANAPI/Makefile b/Libraries/CANAPI/Makefile index 9ef38ce..0b36277 100644 --- a/Libraries/CANAPI/Makefile +++ b/Libraries/CANAPI/Makefile @@ -135,7 +135,7 @@ ifeq ($(current_OS),Linux) # linux - libuvcanpcb.so LIBRARY = libuvcanpcb -SONAME = $(LIBRARY).so +SONAME = $(LIBRARY).so.1 TARGET = $(SONAME).$(VERSION) STATIC = $(LIBRARY).a @@ -225,8 +225,8 @@ ifeq ($(current_OS),Darwin) $(RM) $(INSTALL)/$(LIBRARY).dylib ; $(LN) $(INSTALL)/$(TARGET) $(INSTALL)/$(LIBRARY).dylib endif ifeq ($(current_OS),Linux) - $(RM) $(INSTALL)/$(SONAME) ; ln -s $(INSTALL)/$(TARGET) $(INSTALL)/$(SONAME) - $(RM) $(INSTALL)/$(LIBRARY).so ; ln -s $(INSTALL)/$(SONAME) $(INSTALL)/$(LIBRARY).so + $(RM) $(INSTALL)/$(SONAME) ; $(LN) $(INSTALL)/$(TARGET) $(INSTALL)/$(SONAME) + $(RM) $(INSTALL)/$(LIBRARY).so ; $(LN) $(INSTALL)/$(SONAME) $(INSTALL)/$(LIBRARY).so endif diff --git a/Libraries/PeakCAN/Makefile b/Libraries/PeakCAN/Makefile index 21a2cf5..7d45c97 100644 --- a/Libraries/PeakCAN/Makefile +++ b/Libraries/PeakCAN/Makefile @@ -136,7 +136,7 @@ ifeq ($(current_OS),Linux) # Linux - libpeakcan.so LIBRARY = libpeakcan -SONAME = $(LIBRARY).so +SONAME = $(LIBRARY).so.1 TARGET = $(SONAME).$(VERSION) STATIC = $(LIBRARY).a @@ -227,8 +227,8 @@ ifeq ($(current_OS),Darwin) $(RM) $(INSTALL)/$(LIBRARY).dylib ; $(LN) $(INSTALL)/$(TARGET) $(INSTALL)/$(LIBRARY).dylib endif ifeq ($(current_OS),Linux) - $(RM) $(INSTALL)/$(SONAME) ; ln -s $(INSTALL)/$(TARGET) $(INSTALL)/$(SONAME) - $(RM) $(INSTALL)/$(LIBRARY).so ; ln -s $(INSTALL)/$(SONAME) $(INSTALL)/$(LIBRARY).so + $(RM) $(INSTALL)/$(SONAME) ; $(LN) $(INSTALL)/$(TARGET) $(INSTALL)/$(SONAME) + $(RM) $(INSTALL)/$(LIBRARY).so ; $(LN) $(INSTALL)/$(SONAME) $(INSTALL)/$(LIBRARY).so endif diff --git a/Utilities/can_moni/Sources/Options.h b/Utilities/can_moni/Sources/Options.h index fdcd8b5..3e8aef2 100644 --- a/Utilities/can_moni/Sources/Options.h +++ b/Utilities/can_moni/Sources/Options.h @@ -68,6 +68,14 @@ struct SOptions { uint32_t m_u32Mask; } m_StdFilter, m_XtdFilter; char* m_szExcludeList; +#if (CAN_TRACE_SUPPORTED != 0) + enum { + eTraceOff, + eTraceBinary, + eTraceLogger, + eTraceVendor + } m_eTraceMode; +#endif bool m_fListBitrates; bool m_fListBoards; bool m_fTestBoards; diff --git a/Utilities/can_moni/Sources/Options_p.cpp b/Utilities/can_moni/Sources/Options_p.cpp index ed8b3cd..3eb700f 100644 --- a/Utilities/can_moni/Sources/Options_p.cpp +++ b/Utilities/can_moni/Sources/Options_p.cpp @@ -55,7 +55,6 @@ static const char* c_szWarranty = CAN_MONI_WARRANTY; static const char* c_szLicense = CAN_MONI_LICENSE; static const char* c_szBasename = CAN_MONI_PROGRAM; static const char* c_szInterface = "(unknown)"; -static const char* c_szExcludeList = "~0x00-0x7FF"; SOptions::SOptions() { // to have default bus speed from bit-timing index @@ -77,12 +76,14 @@ SOptions::SOptions() { m_StdFilter.m_u32Mask = CANACC_MASK_11BIT; m_XtdFilter.m_u32Code = CANACC_CODE_29BIT; m_XtdFilter.m_u32Mask = CANACC_MASK_29BIT; - m_szExcludeList = (char*)c_szExcludeList; + m_szExcludeList = (char*)NULL; +#if (CAN_TRACE_SUPPORTED != 0) + m_eTraceMode = SOptions::eTraceOff; +#endif m_fListBitrates = false; m_fListBoards = false; m_fTestBoards = false; m_fVerbose = false; - m_fVerbose = false; m_fExit = false; } @@ -110,6 +111,9 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) int optFmtWrap = 0; #endif int optExclude = 0; +#if (CAN_TRACE_SUPPORTED != 0) + int optTraceMode = 0; +#endif int optListBitrates = 0; int optListBoards = 0; int optTestBoards = 0; @@ -154,6 +158,7 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) {"wraparound", required_argument, 0, 'w'}, {"exclude", required_argument, 0, 'x'}, {"script", required_argument, 0, 's'}, + {"trace", required_argument, 0, 'y'}, {"list-bitrates", optional_argument, 0, 'l'}, #if (OPTION_CANAPI_LIBRARY != 0) {"list-boards", optional_argument, 0, 'L'}, @@ -179,9 +184,9 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) #endif // (2) scan command-line for options #if (OPTION_CANAPI_LIBRARY != 0) - while ((opt = getopt_long(argc, (char * const *)argv, "b:vp:m:t:i:d:a:w:x:s:lLTh", long_options, NULL)) != -1) { + while ((opt = getopt_long(argc, (char * const *)argv, "b:vp:m:t:i:d:a:w:x:s:y:lLTh", long_options, NULL)) != -1) { #else - while ((opt = getopt_long(argc, (char * const *)argv, "b:vm:t:i:d:a:w:x:s:lLTj:h", long_options, NULL)) != -1) { + while ((opt = getopt_long(argc, (char * const *)argv, "b:vm:t:i:d:a:w:x:s:y:lLTj:h", long_options, NULL)) != -1) { #endif switch (opt) { /* option '--baudrate=' (-b) */ @@ -323,8 +328,7 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) fprintf(err, "%s: illegal argument for option `--error-frames'\n", m_szBasename); return 1; } - m_OpMode.byte |= CANMODE_ERR; - + m_OpMode.byte |= CANMODE_ERR; break; /* option '--no-extended-frames' */ case 'X': @@ -336,7 +340,7 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) fprintf(err, "%s: illegal argument for option `--no-extended-frames'\n", m_szBasename); return 1; } - m_OpMode.byte |= CANMODE_NXTD; + m_OpMode.byte |= CANMODE_NXTD; break; /* option '--no-remote-frames' */ case 'R': @@ -348,7 +352,7 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) fprintf(err, "%s: missing argument for option `--no-remote-frames'\n", m_szBasename); return 1; } - m_OpMode.byte |= CANMODE_NRTR; + m_OpMode.byte |= CANMODE_NRTR; break; /* option '--code=<11-bit-code>' */ case '1': @@ -430,6 +434,36 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) } m_XtdFilter.m_u32Mask = (uint32_t)intarg; break; + /* option '--trace=(ON|OFF)' (-y) */ +#if (CAN_TRACE_SUPPORTED != 0) + case 'y': + if (optTraceMode++) { + fprintf(err, "%s: duplicated option `--trace'\n", m_szBasename); + return 1; + } + if (optarg == NULL) { + fprintf(err, "%s: missing argument for option `--trace'\n", m_szBasename); + return 1; + } +#if (CAN_TRACE_SUPPORTED == 1) + if (!strcasecmp(optarg, "OFF") || !strcasecmp(optarg, "NO") || !strcasecmp(optarg, "n") || !strcasecmp(optarg, "0")) + m_eTraceMode = SOptions::eTraceOff; + else if (!strcasecmp(optarg, "ON") || !strcasecmp(optarg, "YES") || !strcasecmp(optarg, "y") || !strcasecmp(optarg, "1")) + m_eTraceMode = SOptions::eTraceVendor; +#else + if (!strcasecmp(optarg, "BIN") || !strcasecmp(optarg, "BINARY") || !strcasecmp(optarg, "default")) + m_eTraceMode = SOptions::eTraceBinary; + else if (!strcasecmp(optarg, "CSV") || !strcasecmp(optarg, "logger") || !strcasecmp(optarg, "log")) + m_eTraceMode = SOptions::eTraceLogger; + else if (!strcasecmp(optarg, "TRC") || !strcasecmp(optarg, "vendor")) + m_eTraceMode = SOptions::eTraceVendor; +#endif + else { + fprintf(err, "%s: illegal argument for option `--trace'\n", m_szBasename); + return 1; + } + break; +#endif /* option '--time=(ABS|REL|ZERO)' (-t) */ case 't': if (optFmtTime++) { @@ -761,6 +795,9 @@ void SOptions::ShowUsage(FILE* stream, bool args) { fprintf(stream, " -b, --baudrate= CAN bit-timing in kbps (default=250), or\n"); fprintf(stream, " --bitrate= CAN bit-rate settings (as key/value list)\n"); fprintf(stream, " -v, --verbose show detailed bit-rate settings\n"); +#if (CAN_TRACE_SUPPORTED != 0) + fprintf(stream, " -y, --trace=(ON|OFF) write a trace file (default=OFF)\n"); +#endif #if (CAN_FD_SUPPORTED != 0) fprintf(stream, " --list-bitrates[=] list standard bit-rate settings and exit\n"); #else diff --git a/Utilities/can_moni/Sources/Options_w.cpp b/Utilities/can_moni/Sources/Options_w.cpp index 3a232f0..ded83b4 100644 --- a/Utilities/can_moni/Sources/Options_w.cpp +++ b/Utilities/can_moni/Sources/Options_w.cpp @@ -29,6 +29,13 @@ extern "C" { #include "dosopt.h" } +#if defined(_WIN64) +#define PLATFORM "x64" +#elif defined(_WIN32) +#define PLATFORM "x86" +#else +#error Platform not supported +#endif #ifdef _MSC_VER //not #if defined(_WIN32) || defined(_WIN64) because we have strncasecmp in mingw #define strncasecmp _strnicmp @@ -74,19 +81,21 @@ extern "C" { #define XTD_MASK_CHR 32 #define SCRIPT_STR 33 #define SCRIPT_CHR 34 -#define LISTBITRATES_STR 35 -#define LISTBOARDS_STR 36 -#define LISTBOARDS_CHR 37 -#define TESTBOARDS_STR 38 -#define TESTBOARDS_CHR 39 -#define JSON_STR 40 -#define JSON_CHR 41 -#define HELP 42 -#define QUESTION_MARK 43 -#define ABOUT 44 -#define CHARACTER_MJU 45 -#define VERSION 46 -#define MAX_OPTIONS 47 +#define TRACEFILE_STR 35 +#define TRACEFILE_CHR 36 +#define LISTBITRATES_STR 37 +#define LISTBOARDS_STR 38 +#define LISTBOARDS_CHR 39 +#define TESTBOARDS_STR 40 +#define TESTBOARDS_CHR 41 +#define JSON_STR 42 +#define JSON_CHR 43 +#define HELP 44 +#define QUESTION_MARK 45 +#define ABOUT 46 +#define CHARACTER_MJU 47 +#define VERSION 48 +#define MAX_OPTIONS 49 static char* option[MAX_OPTIONS] = { (char*)"BAUDRATE", (char*)"bd", @@ -107,6 +116,7 @@ static char* option[MAX_OPTIONS] = { (char*)"CODE", (char*)"MASK", (char*)"XTD-CODE", (char*)"XTD-MASK", (char*)"SCRIPT", (char*)"s", + (char*)"TRACE", (char*)"trc", (char*)"LIST-BITRATES", (char*)"LIST-BOARDS", (char*)"list", (char*)"TEST-BOARDS", (char*)"test", @@ -125,14 +135,13 @@ static const char* c_szWarranty = CAN_MONI_WARRANTY; static const char* c_szLicense = CAN_MONI_LICENSE; static const char* c_szBasename = CAN_MONI_PROGRAM; static const char* c_szInterface = "(unknown)"; -static const char* c_szExcludeList = "~0x00-0x7FF"; #if (USE_BASENAME != 0) static char* basename(char* path); #endif SOptions::SOptions() { - // to have dault bus speed from bit-timing index + // to have default bus speed from bit-timing index (void)CCanDriver::MapIndex2Bitrate(DEFAULT_BAUDRATE, m_Bitrate); (void)CCanDriver::MapBitrate2Speed(m_Bitrate, m_BusSpeed); // initialization @@ -151,12 +160,14 @@ SOptions::SOptions() { m_StdFilter.m_u32Mask = CANACC_MASK_11BIT; m_XtdFilter.m_u32Code = CANACC_CODE_29BIT; m_XtdFilter.m_u32Mask = CANACC_MASK_29BIT; - m_szExcludeList = (char*)c_szExcludeList; + m_szExcludeList = (char*)NULL; +#if (CAN_TRACE_SUPPORTED != 0) + m_eTraceMode = SOptions::eTraceOff; +#endif m_fListBitrates = false; m_fListBoards = false; m_fTestBoards = false; m_fVerbose = false; - m_fVerbose = false; m_fExit = false; } @@ -174,16 +185,21 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) int optErrorFrames = 0; int optExtendedFrames = 0; int optRemoteFrames = 0; - int optTime = 0; - int optId = 0; - int optData = 0; - int optAscii = 0; - int optWrap = 0; - int optExclude = 0; - int optCode = 0; - int optMask = 0; + int optStdCode = 0; + int optStdMask = 0; int optXtdCode = 0; int optXtdMask = 0; + int optFmtTime = 0; + int optFmtId = 0; + int optFmtData = 0; + int optFmtAscii = 0; +#if (CAN_FD_SUPPORTED != 0) + int optFmtWrap = 0; +#endif + int optExclude = 0; +#if (CAN_TRACE_SUPPORTED != 0) + int optTraceMode = 0; +#endif int optListBitrates = 0; int optListBoards = 0; int optTestBoards = 0; @@ -193,16 +209,16 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) int optJson = 0; #endif /* default format options */ - CCanMessage::EFormatTimestamp modeTime = CCanMessage::OptionZero; - CCanMessage::EFormatNumber modeId = CCanMessage::OptionHex; - CCanMessage::EFormatNumber modeData = CCanMessage::OptionHex; - CCanMessage::EFormatOption modeAscii = CCanMessage::OptionOn; - CCanMessage::EFormatWraparound wraparound = CCanMessage::OptionWraparoundNo; - (void)CCanMessage::SetTimestampFormat(modeTime); - (void)CCanMessage::SetIdentifierFormat(modeId); - (void)CCanMessage::SetDataFormat(modeData); - (void)CCanMessage::SetAsciiFormat(modeAscii); - (void)CCanMessage::SetWraparound(wraparound); + CCanMessage::EFormatTimestamp fmtModeTime = CCanMessage::OptionZero; + CCanMessage::EFormatNumber fmtModeId = CCanMessage::OptionHex; + CCanMessage::EFormatNumber fmtModeData = CCanMessage::OptionHex; + CCanMessage::EFormatOption fmtModeAscii = CCanMessage::OptionOn; + CCanMessage::EFormatWraparound fmtWraparound = CCanMessage::OptionWraparoundNo; + (void)CCanMessage::SetTimestampFormat(fmtModeTime); + (void)CCanMessage::SetIdentifierFormat(fmtModeId); + (void)CCanMessage::SetDataFormat(fmtModeData); + (void)CCanMessage::SetAsciiFormat(fmtModeAscii); + (void)CCanMessage::SetWraparound(fmtWraparound); // (0) sanity check if ((argc <= 0) || (argv == NULL)) @@ -211,7 +227,7 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) return (-1); // (1) get basename from command-line #if (USE_BASENAME != 0) - m_szBasename = Basename(argv[0]); + m_szBasename = basename((char*)argv[0]); #endif // (2) scan command-line for options while ((optind = getOption(argc, (char**)argv, MAX_OPTIONS, option)) != EOF) { @@ -287,7 +303,7 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) m_fVerbose = true; break; #if (OPTION_CANAPI_LIBRARY != 0) - /* option '--path' (-p) */ + /* option '--path=' (-p) */ case JSON_STR: case JSON_CHR: if ((optPath++)) { @@ -438,10 +454,121 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) return 1; } break; + /* option '--code=<11-bit-code>' */ + case STD_CODE_STR: + if ((optStdCode++)) { + fprintf(err, "%s: duplicated option /CODE\n", m_szBasename); + return 1; + } + if ((optarg = getOptionParameter()) == NULL) { + fprintf(err, "%s: missing argument for option /CODE\n", m_szBasename); + return 1; + } + if (sscanf_s(optarg, "%lli", &intarg) != 1) { + fprintf(err, "%s: illegal argument for option /CODE\n", m_szBasename); + return 1; + } + if ((intarg & ~CAN_MAX_STD_ID) != 0) { + fprintf(err, "%s: illegal argument for option /CODE\n", m_szBasename); + return 1; + } + m_StdFilter.m_u32Code = (uint32_t)intarg; + break; + /* option '--mask=<11-bit-mask>' */ + case STD_MASK_CHR: + if ((optStdMask++)) { + fprintf(err, "%s: duplicated option /MASK\n", m_szBasename); + return 1; + } + if ((optarg = getOptionParameter()) == NULL) { + fprintf(err, "%s: missing argument for option /MASK\n", m_szBasename); + return 1; + } + if (sscanf_s(optarg, "%lli", &intarg) != 1) { + fprintf(err, "%s: illegal argument for option /MASK\n", m_szBasename); + return 1; + } + if ((intarg & ~CAN_MAX_STD_ID) != 0) { + fprintf(err, "%s: illegal argument for option /MASK\n", m_szBasename); + return 1; + } + m_StdFilter.m_u32Mask = (uint32_t)intarg; + break; + /* option '--xtd-code=<29-bit-code>' */ + case XTD_CODE_STR: + if ((optXtdCode++)) { + fprintf(err, "%s: duplicated option /XTD-CODE\n", m_szBasename); + return 1; + } + if ((optarg = getOptionParameter()) == NULL) { + fprintf(err, "%s: missing argument for option /XTD-CODE\n", m_szBasename); + return 1; + } + if (sscanf_s(optarg, "%lli", &intarg) != 1) { + fprintf(err, "%s: illegal argument for option /XTD-CODE\n", m_szBasename); + return 1; + } + if ((intarg & ~CAN_MAX_XTD_ID) != 0) { + fprintf(err, "%s: illegal argument for option /XTD-CODE\n", m_szBasename); + return 1; + } + m_XtdFilter.m_u32Code = (uint32_t)intarg; + break; + /* option '--xtd-mask=<29-bit-mask>' */ + case XTD_MASK_CHR: + if ((optXtdMask++)) { + fprintf(err, "%s: duplicated option /XTD-MASK\n", m_szBasename); + return 1; + } + if ((optarg = getOptionParameter()) == NULL) { + fprintf(err, "%s: missing argument for option /XTD-MASK\n", m_szBasename); + return 1; + } + if (sscanf_s(optarg, "%lli", &intarg) != 1) { + fprintf(err, "%s: illegal argument for option /XTD-MASK\n", m_szBasename); + return 1; + } + if ((intarg & ~CAN_MAX_XTD_ID) != 0) { + fprintf(err, "%s: illegal argument for option /XTD-MASK\n", m_szBasename); + return 1; + } + m_XtdFilter.m_u32Mask = (uint32_t)intarg; + break; + /* option '--trace=(ON|OFF)' (-y) */ +#if (CAN_TRACE_SUPPORTED != 0) + case TRACEFILE_STR: + case TRACEFILE_CHR: + if (optTraceMode++) { + fprintf(err, "%s: duplicated option /TRACE\n", m_szBasename); + return 1; + } + if ((optarg = getOptionParameter()) == NULL) { + fprintf(err, "%s: missing argument for option /TRACE\n", m_szBasename); + return 1; + } +#if (CAN_TRACE_SUPPORTED == 1) + if (!strcasecmp(optarg, "OFF") || !strcasecmp(optarg, "NO") || !strcasecmp(optarg, "n") || !strcasecmp(optarg, "0")) + m_eTraceMode = SOptions::eTraceOff; + else if (!strcasecmp(optarg, "ON") || !strcasecmp(optarg, "YES") || !strcasecmp(optarg, "y") || !strcasecmp(optarg, "1")) + m_eTraceMode = SOptions::eTraceVendor; +#else + if (!strcasecmp(optarg, "BIN") || !strcasecmp(optarg, "BINARY") || !strcasecmp(optarg, "default")) + m_eTraceMode = SOptions::eTraceBinary; + else if (!strcasecmp(optarg, "CSV") || !strcasecmp(optarg, "logger") || !strcasecmp(optarg, "log")) + m_eTraceMode = SOptions::eTraceLogger; + else if (!strcasecmp(optarg, "TRC") || !strcasecmp(optarg, "vendor")) + m_eTraceMode = SOptions::eTraceVendor; +#endif + else { + fprintf(err, "%s: illegal argument for option /TRACE\n", m_szBasename); + return 1; + } + break; +#endif /* option '--time=(ABS|REL|ZERO)' (-t) */ case MODE_TIME_STR: case MODE_TIME_CHR: - if ((optTime++)) { + if ((optFmtTime++)) { fprintf(err, "%s: duplicated option /TIME\n", m_szBasename); return 1; } @@ -450,16 +577,16 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) return 1; } if (!strcasecmp(optarg, "ABSOLUTE") || !strcasecmp(optarg, "ABS") || !strcasecmp(optarg, "a")) - modeTime = CCanMessage::OptionAbsolute; + fmtModeTime = CCanMessage::OptionAbsolute; else if (!strcasecmp(optarg, "RELATIVE") || !strcasecmp(optarg, "REL") || !strcasecmp(optarg, "r")) - modeTime = CCanMessage::OptionRelative; + fmtModeTime = CCanMessage::OptionRelative; else if (!strcasecmp(optarg, "ZERO") || !strcasecmp(optarg, "0") || !strcasecmp(optarg, "z")) - modeTime = CCanMessage::OptionZero; + fmtModeTime = CCanMessage::OptionZero; else { fprintf(err, "%s: illegal argument for option /TIME\n", m_szBasename); return 1; } - if (!CCanMessage::SetTimestampFormat(modeTime)) { + if (!CCanMessage::SetTimestampFormat(fmtModeTime)) { fprintf(err, "%s: illegal argument for option /TIME\n", m_szBasename); return 1; } @@ -467,7 +594,7 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) /* option '--id=(HEX|DEC|OCT)' (-i) */ case MODE_ID_STR: case MODE_ID_CHR: - if ((optId++)) { + if ((optFmtId++)) { fprintf(err, "%s: duplicated option /ID\n", m_szBasename); return 1; } @@ -476,16 +603,16 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) return 1; } if (!strcasecmp(optarg, "HEXADECIMAL") || !strcasecmp(optarg, "HEX") || !strcasecmp(optarg, "h") || !strcasecmp(optarg, "16")) - modeId = CCanMessage::OptionHex; + fmtModeId = CCanMessage::OptionHex; else if (!strcasecmp(optarg, "DECIMAL") || !strcasecmp(optarg, "DEC") || !strcasecmp(optarg, "d") || !strcasecmp(optarg, "10")) - modeId = CCanMessage::OptionDec; + fmtModeId = CCanMessage::OptionDec; else if (!strcasecmp(optarg, "OCTAL") || !strcasecmp(optarg, "OCT") || !strcasecmp(optarg, "o") || !strcasecmp(optarg, "8")) - modeId = CCanMessage::OptionOct; + fmtModeId = CCanMessage::OptionOct; else { fprintf(err, "%s: illegal argument for option /ID\n", m_szBasename); return 1; } - if (!CCanMessage::SetIdentifierFormat(modeId)) { + if (!CCanMessage::SetIdentifierFormat(fmtModeId)) { fprintf(err, "%s: illegal argument for option /ID\n", m_szBasename); return 1; } @@ -493,7 +620,7 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) /* option '--data=(HEX|DEC|OCT)' (-d) */ case MODE_DATA_STR: case MODE_DATA_CHR: - if ((optData++)) { + if ((optFmtData++)) { fprintf(err, "%s: duplicated option /DATA\n", m_szBasename); return 1; } @@ -502,16 +629,16 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) return 1; } if (!strcasecmp(optarg, "HEXADECIMAL") || !strcasecmp(optarg, "HEX") || !strcasecmp(optarg, "h") || !strcasecmp(optarg, "16")) - modeData = CCanMessage::OptionHex; + fmtModeData = CCanMessage::OptionHex; else if (!strcasecmp(optarg, "DECIMAL") || !strcasecmp(optarg, "DEC") || !strcasecmp(optarg, "d") || !strcasecmp(optarg, "10")) - modeData = CCanMessage::OptionDec; + fmtModeData = CCanMessage::OptionDec; else if (!strcasecmp(optarg, "OCTAL") || !strcasecmp(optarg, "OCT") || !strcasecmp(optarg, "o") || !strcasecmp(optarg, "8")) - modeData = CCanMessage::OptionOct; + fmtModeData = CCanMessage::OptionOct; else { fprintf(err, "%s: illegal argument for option /DATA\n", m_szBasename); return 1; } - if (!CCanMessage::SetDataFormat(modeData)) { + if (!CCanMessage::SetDataFormat(fmtModeData)) { fprintf(err, "%s: illegal argument for option /DATA\n", m_szBasename); return 1; } @@ -519,7 +646,7 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) /* option '--ascii=(ON|OFF)' (-a) */ case MODE_ASCII_STR: case MODE_ASCII_CHR: - if ((optAscii++)) { + if ((optFmtAscii++)) { fprintf(err, "%s: duplicated option /ASCII\n", m_szBasename); return 1; } @@ -528,14 +655,14 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) return 1; } if (!strcasecmp(optarg, "OFF") || !strcasecmp(optarg, "NO") || !strcasecmp(optarg, "n") || !strcasecmp(optarg, "0")) - modeAscii = CCanMessage::OptionOff; + fmtModeAscii = CCanMessage::OptionOff; else if (!strcasecmp(optarg, "ON") || !strcasecmp(optarg, "YES") || !strcasecmp(optarg, "y") || !strcasecmp(optarg, "1")) - modeAscii = CCanMessage::OptionOn; + fmtModeAscii = CCanMessage::OptionOn; else { fprintf(err, "%s: illegal argument for option /ASCII\n", m_szBasename); return 1; } - if (!CCanMessage::SetAsciiFormat(modeAscii)) { + if (!CCanMessage::SetAsciiFormat(fmtModeAscii)) { fprintf(err, "%s: illegal argument for option /ASCII\n", m_szBasename); return 1; } @@ -544,7 +671,7 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) /* option '--wrap=(No|8|10|16|32|64)' (-w) */ case WRAPAROUND_STR: case WRAPAROUND_CHR: - if ((optWrap++)) { + if ((optFmtWrap++)) { fprintf(err, "%s: duplicated option /WRAPAROUND\n", m_szBasename); return 1; } @@ -553,22 +680,22 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) return 1; } if (!strcasecmp(optarg, "NO") || !strcasecmp(optarg, "n") || !strcasecmp(optarg, "0")) - wraparound = CCanMessage::OptionWraparoundNo; + fmtWraparound = CCanMessage::OptionWraparoundNo; else if (!strcasecmp(optarg, "8")) - wraparound = CCanMessage::OptionWraparound8; + fmtWraparound = CCanMessage::OptionWraparound8; else if (!strcasecmp(optarg, "10")) - wraparound = CCanMessage::OptionWraparound10; + fmtWraparound = CCanMessage::OptionWraparound10; else if (!strcasecmp(optarg, "16")) - wraparound = CCanMessage::OptionWraparound16; + fmtWraparound = CCanMessage::OptionWraparound16; else if (!strcasecmp(optarg, "32")) - wraparound = CCanMessage::OptionWraparound32; + fmtWraparound = CCanMessage::OptionWraparound32; else if (!strcasecmp(optarg, "64")) - wraparound = CCanMessage::OptionWraparound64; + fmtWraparound = CCanMessage::OptionWraparound64; else { fprintf(err, "%s: illegal argument for option /WRAPAROUND\n", m_szBasename); return 1; } - if (!CCanMessage::SetWraparound(wraparound)) { + if (!CCanMessage::SetWraparound(fmtWraparound)) { fprintf(err, "%s: illegal argument for option /WRAPAROUND\n", m_szBasename); return 1; } @@ -587,86 +714,6 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) } m_szExcludeList = optarg; break; - /* option '--code=<11-bit-code>' */ - case STD_CODE_STR: - if ((optCode++)) { - fprintf(err, "%s: duplicated option /CODE\n", m_szBasename); - return 1; - } - if ((optarg = getOptionParameter()) == NULL) { - fprintf(err, "%s: missing argument for option /CODE\n", m_szBasename); - return 1; - } - if (sscanf_s(optarg, "%lli", &intarg) != 1) { - fprintf(err, "%s: illegal argument for option /CODE\n", m_szBasename); - return 1; - } - if ((intarg & ~CAN_MAX_STD_ID) != 0) { - fprintf(err, "%s: illegal argument for option /CODE\n", m_szBasename); - return 1; - } - m_StdFilter.m_u32Code = (uint32_t)intarg; - break; - /* option '--mask=<11-bit-mask>' */ - case STD_MASK_CHR: - if ((optMask++)) { - fprintf(err, "%s: duplicated option /MASK\n", m_szBasename); - return 1; - } - if ((optarg = getOptionParameter()) == NULL) { - fprintf(err, "%s: missing argument for option /MASK\n", m_szBasename); - return 1; - } - if (sscanf_s(optarg, "%lli", &intarg) != 1) { - fprintf(err, "%s: illegal argument for option /MASK\n", m_szBasename); - return 1; - } - if ((intarg & ~CAN_MAX_STD_ID) != 0) { - fprintf(err, "%s: illegal argument for option /MASK\n", m_szBasename); - return 1; - } - m_StdFilter.m_u32Mask = (uint32_t)intarg; - break; - /* option '--xtd-code=<29-bit-code>' */ - case XTD_CODE_STR: - if ((optXtdCode++)) { - fprintf(err, "%s: duplicated option /XTD-CODE\n", m_szBasename); - return 1; - } - if ((optarg = getOptionParameter()) == NULL) { - fprintf(err, "%s: missing argument for option /XTD-CODE\n", m_szBasename); - return 1; - } - if (sscanf_s(optarg, "%lli", &intarg) != 1) { - fprintf(err, "%s: illegal argument for option /XTD-CODE\n", m_szBasename); - return 1; - } - if ((intarg & ~CAN_MAX_XTD_ID) != 0) { - fprintf(err, "%s: illegal argument for option /XTD-CODE\n", m_szBasename); - return 1; - } - m_XtdFilter.m_u32Code = (uint32_t)intarg; - break; - /* option '--xtd-mask=<29-bit-mask>' */ - case XTD_MASK_CHR: - if ((optXtdMask++)) { - fprintf(err, "%s: duplicated option /XTD-MASK\n", m_szBasename); - return 1; - } - if ((optarg = getOptionParameter()) == NULL) { - fprintf(err, "%s: missing argument for option /XTD-MASK\n", m_szBasename); - return 1; - } - if (sscanf_s(optarg, "%lli", &intarg) != 1) { - fprintf(err, "%s: illegal argument for option /XTD-MASK\n", m_szBasename); - return 1; - } - if ((intarg & ~CAN_MAX_XTD_ID) != 0) { - fprintf(err, "%s: illegal argument for option /XTD-MASK\n", m_szBasename); - return 1; - } - m_XtdFilter.m_u32Mask = (uint32_t)intarg; - break; /* option '--list-bitrates[=(2.0|FDF[+BRS])]' */ case LISTBITRATES_STR: if ((optListBitrates++)) { @@ -708,7 +755,7 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) fprintf(err, "%s: option /PATH already set\n", m_szBasename); return 1; } - m_szSearchPath = optarg; + m_szSearchPath = optarg; // option '--list-boards=' (-L) } #endif m_fListBoards = true; @@ -727,7 +774,7 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) fprintf(err, "%s: option /PATH already set\n", m_szBasename); return 1; } - m_szSearchPath = optarg; + m_szSearchPath = optarg; // option '--test-boards=' (-L) } #endif m_fTestBoards = true; @@ -826,7 +873,10 @@ void SOptions::ShowUsage(FILE* stream, bool args) { fprintf(stream, " /MASK: acceptance mask for 11-bit IDs (default=0x%03lx)\n", CANACC_MASK_11BIT); fprintf(stream, " /XTD-CODE: acceptance code for 29-bit IDs (default=0x%08lx)\n", CANACC_CODE_29BIT); fprintf(stream, " /XTD-MASK: acceptance mask for 29-bit IDs (default=0x%08lx)\n", CANACC_MASK_29BIT); - // fprintf(stream, " /Script: execute a script file\n"); // TODO: script engine +// fprintf(stream, " /Script: execute a script file\n"); // TODO: script engine +#if (OPTION_CANAPI_LIBRARY != 0) + fprintf(stream, " /Path: search path for JSON configuration files\n"); +#endif #if (CAN_FD_SUPPORTED != 0) fprintf(stream, " /Mode:(2.0|FDf[+BRS]) CAN operation mode: CAN 2.0 or CAN FD mode\n"); #else @@ -839,10 +889,10 @@ void SOptions::ShowUsage(FILE* stream, bool args) { fprintf(stream, " /XTD:(Yes|No) allow extended frames (29-bit identifier)\n"); fprintf(stream, " /BauDrate: CAN bit-timing in kbps (default=250), or\n"); fprintf(stream, " /BitRate: CAN bit-rate settings (as key/value list)\n"); -#if (OPTION_CANAPI_LIBRARY != 0) - fprintf(stream, " /Path: search path for JSON configuration files\n"); -#endif fprintf(stream, " /Verbose show detailed bit-rate settings\n"); +#if (CAN_TRACE_SUPPORTED != 0) + fprintf(stream, " /TRaCe:(ON|OFF) write a trace file (default=OFF)\n"); +#endif #if (CAN_FD_SUPPORTED != 0) fprintf(stream, " /LIST-BITRATES[:(2.0|FDf[+BRS])] list standard bit-rate settings and exit\n"); #else diff --git a/Utilities/can_moni/Sources/main.cpp b/Utilities/can_moni/Sources/main.cpp index 92addd8..af6a759 100644 --- a/Utilities/can_moni/Sources/main.cpp +++ b/Utilities/can_moni/Sources/main.cpp @@ -85,7 +85,7 @@ int main(int argc, const char* argv[]) { CCanDevice::SLibraryInfo library = { (-1), "", "" }; #endif CANAPI_Return_t retVal = CANERR_FATAL; - char property[CANPROP_MAX_BUFFER_SIZE] = ""; + char property[CANPROP_MAX_BUFFER_SIZE + 1] = ""; char* string = NULL; /* device parameter */ @@ -313,9 +313,50 @@ int main(int argc, const char* argv[]) { fprintf(stderr, "+++ error: CAN Controller could not be started (%i)\n", retVal); goto teardown; } + /* - start trace session (if enabled) */ +#if (CAN_TRACE_SUPPORTED != 0) + if (opts.m_eTraceMode != SOptions::eTraceOff) { + /* -- set trace format */ + switch (opts.m_eTraceMode) { + case SOptions::eTraceVendor: + property[0] = CANPARA_TRACE_TYPE_VENDOR; + break; + case SOptions::eTraceLogger: + property[0] = CANPARA_TRACE_TYPE_LOGGER; + break; + case SOptions::eTraceBinary: + default: + property[0] = CANPARA_TRACE_TYPE_BINARY; + break; + } + (void)canDevice.SetProperty(CANPROP_SET_TRACE_TYPE, (void*)&property[0], sizeof(uint8_t)); + /* -- set trace active */ + property[0] = CANPARA_TRACE_ON; + retVal = canDevice.SetProperty(CANPROP_SET_TRACE_ACTIVE, (void*)&property[0], sizeof(uint8_t)); + if (retVal != CCanApi::NoError) { + fprintf(stdout, "FAILED!\n"); + fprintf(stderr, "+++ error: trace session could not be started (%i)\n", retVal); + goto teardown; + } + } +#endif fprintf(stdout, "OK!\n"); /* - reception loop */ canDevice.ReceptionLoop(); + /* - stop trace session (if enabled) */ +#if (CAN_TRACE_SUPPORTED != 0) + if (opts.m_eTraceMode != SOptions::eTraceOff) { + /* -- get trace file name */ + retVal = canDevice.GetProperty(CANPROP_GET_TRACE_FILE, (void*)property, CANPROP_MAX_BUFFER_SIZE); + if (retVal == CCanApi::NoError) { + property[CANPROP_MAX_BUFFER_SIZE] = '\0'; + fprintf(stdout, "Trace-file=%s\n", property); + } + /* -- set trace inactive */ + property[0] = CANPARA_TRACE_OFF; + (void)canDevice.SetProperty(CANPROP_SET_TRACE_ACTIVE, (void*)&property[0], sizeof(uint8_t)); + } +#endif /* - show interface information */ if ((string = canDevice.GetHardwareVersion()) != NULL) fprintf(stdout, "Hardware: %s\n", string); @@ -471,7 +512,6 @@ bool CCanDevice::IsBlacklisted(int32_t library, int32_t blacklist[]) { int CCanDevice::ListCanBitrates(CANAPI_OpMode_t opMode) { CANAPI_Bitrate_t bitrate[9]; CANAPI_BusSpeed_t speed; - CANAPI_Return_t retVal; char string[CANPROP_MAX_BUFFER_SIZE] = ""; bool hasDataPhase = false; @@ -519,7 +559,7 @@ int CCanDevice::ListCanBitrates(CANAPI_OpMode_t opMode) { hasNoSamp = true; } for (i = 0; i < n; i++) { - if ((retVal = CCanDevice::MapBitrate2Speed(bitrate[i], speed)) == CCanApi::NoError) { + if (CCanDevice::MapBitrate2Speed(bitrate[i], speed) == CCanApi::NoError) { fprintf(stdout, " %4.0fkbps@%.1f%%", speed.nominal.speed / 1000., speed.nominal.samplepoint * 100.); #if (CAN_FD_SUPPORTED != 0) if (opMode.brse) @@ -618,7 +658,7 @@ bool CCanDevice::WriteJsonFile(const char* filename) { " \"id\": %i,\n" " \"name\": \"%s%i\",\n" " \"alias\": \"%s%i\"\n", - CANDEV_SERIAL, + CANDEV_SERIAL, #if defined(_WIN32) || defined(_WIN64) MONITOR_TTYNAME, i + 1, #else @@ -647,7 +687,6 @@ bool CCanDevice::WriteJsonFile(const char* filename) { */ uint64_t CCanDevice::ReceptionLoop() { CANAPI_Message_t message; - CANAPI_Return_t retVal; uint64_t frames = 0U; char string[CANPROP_MAX_STRING_LENGTH+1]; @@ -655,7 +694,7 @@ uint64_t CCanDevice::ReceptionLoop() { fprintf(stderr, "\nPress ^C to abort.\n\n"); while(running) { - if ((retVal = ReadMessage(message)) == CCanApi::NoError) { + if (ReadMessage(message) == CCanApi::NoError) { if ((((message.id < MAX_ID) && can_id[message.id]) || ((message.id >= MAX_ID) && can_id_xtd))) { (void)CCanMessage::Format(message, ++frames, string, CANPROP_MAX_STRING_LENGTH); fprintf(stdout, "%s\n", string); @@ -729,9 +768,9 @@ static int get_exclusion(const char* arg) } if (inv) { for (i = 0; i < MAX_ID; i++) - can_id[i] = !can_id[i]; + can_id[i] = can_id[i] ? 0 : 1; } - can_id_xtd = !inv; + can_id_xtd = inv ? 0 : 1; return 1; } diff --git a/Utilities/can_test/README.md b/Utilities/can_test/README.md index 964d891..0754f30 100644 --- a/Utilities/can_test/README.md +++ b/Utilities/can_test/README.md @@ -13,6 +13,10 @@ Options for receiver test (default test mode): --error-frames allow reception of error frames --no-remote-frames suppress remote frames (RTR frames) --no-extended-frames suppress extended frames (29-bit identifier) + --code= acceptance code for 11-bit IDs (default=0x000) + --mask= acceptance mask for 11-bit IDs (default=0x000) + --xtd-code= acceptance code for 29-bit IDs (default=0x00000000) + --xtd-mask= acceptance mask for 29-bit IDs (default=0x00000000) -b, --baudrate= CAN bit-timing in kbps (default=250), or --bitrate= CAN bit-rate settings (as key/value list) -v, --verbose show detailed bit-rate settings diff --git a/Utilities/can_test/Sources/Options.h b/Utilities/can_test/Sources/Options.h index 44202bf..7a63fb7 100644 --- a/Utilities/can_test/Sources/Options.h +++ b/Utilities/can_test/Sources/Options.h @@ -84,6 +84,14 @@ struct SOptions { uint32_t m_nTxCanId; uint8_t m_nTxCanDlc; bool m_fTxXtdId; +#if (CAN_TRACE_SUPPORTED != 0) + enum { + eTraceOff, + eTraceBinary, + eTraceLogger, + eTraceVendor + } m_eTraceMode; +#endif bool m_fListBitrates; bool m_fListBoards; bool m_fTestBoards; diff --git a/Utilities/can_test/Sources/Options_p.cpp b/Utilities/can_test/Sources/Options_p.cpp index 9f14cd6..2da99fb 100644 --- a/Utilities/can_test/Sources/Options_p.cpp +++ b/Utilities/can_test/Sources/Options_p.cpp @@ -79,6 +79,9 @@ SOptions::SOptions() { m_StdFilter.m_u32Mask = CANACC_MASK_11BIT; m_XtdFilter.m_u32Code = CANACC_CODE_29BIT; m_XtdFilter.m_u32Mask = CANACC_MASK_29BIT; +#if (CAN_TRACE_SUPPORTED != 0) + m_eTraceMode = SOptions::eTraceOff; +#endif m_TestMode = SOptions::RxMODE; m_nStartNumber = (uint64_t)0; m_fCheckNumber = false; @@ -122,6 +125,9 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) int optDlc = 0; int optId = 0; int optXtd = 0; +#if (CAN_TRACE_SUPPORTED != 0) + int optTraceMode = 0; +#endif int optListBitrates = 0; int optListBoards = 0; int optTestBoards = 0; @@ -159,6 +165,7 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) {"id", required_argument, 0, 'i'}, {"xtd", no_argument, 0, 'e'}, {"extended", no_argument, 0, 'e'}, + {"trace", required_argument, 0, 'y'}, {"list-bitrates", optional_argument, 0, 'l'}, #if (OPTION_CANAPI_LIBRARY != 0) {"list-boards", optional_argument, 0, 'L'}, @@ -184,9 +191,9 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) #endif // (2) scan command-line for options #if (OPTION_CANAPI_LIBRARY != 0) - while ((opt = getopt_long(argc, (char * const *)argv, "b:vp:m:rn:st:f:R:c:u:d:i:elLaTh", long_options, NULL)) != -1) { + while ((opt = getopt_long(argc, (char * const *)argv, "b:vp:m:rn:st:f:R:c:u:d:i:ey:lLaTh", long_options, NULL)) != -1) { #else - while ((opt = getopt_long(argc, (char * const *)argv, "b:vm:rn:st:f:R:c:u:d:i:elLaTj:h", long_options, NULL)) != -1) { + while ((opt = getopt_long(argc, (char * const *)argv, "b:vm:rn:st:f:R:c:u:d:i:ey:lLaTj:h", long_options, NULL)) != -1) { #endif switch (opt) { /* option '--baudrate=' (-b) */ @@ -328,8 +335,8 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) fprintf(err, "%s: illegal argument for option `--error-frames'\n", m_szBasename); return 1; } - m_OpMode.byte |= CANMODE_ERR; - + m_OpMode.byte |= CANMODE_ERR; + break; /* option '--no-extended-frames' */ case 'X': @@ -341,7 +348,7 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) fprintf(err, "%s: illegal argument for option `--no-extended-frames'\n", m_szBasename); return 1; } - m_OpMode.byte |= CANMODE_NXTD; + m_OpMode.byte |= CANMODE_NXTD; break; /* option '--no-remote-frames' */ case 'R': @@ -353,7 +360,7 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) fprintf(err, "%s: missing argument for option `--no-remote-frames'\n", m_szBasename); return 1; } - m_OpMode.byte |= CANMODE_NRTR; + m_OpMode.byte |= CANMODE_NRTR; break; /* option '--code=<11-bit-code>' */ case '1': @@ -435,6 +442,36 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) } m_XtdFilter.m_u32Mask = (uint32_t)intarg; break; + /* option '--trace=(ON|OFF)' (-y) */ +#if (CAN_TRACE_SUPPORTED != 0) + case 'y': + if (optTraceMode++) { + fprintf(err, "%s: duplicated option `--trace'\n", m_szBasename); + return 1; + } + if (optarg == NULL) { + fprintf(err, "%s: missing argument for option `--trace'\n", m_szBasename); + return 1; + } +#if (CAN_TRACE_SUPPORTED == 1) + if (!strcasecmp(optarg, "OFF") || !strcasecmp(optarg, "NO") || !strcasecmp(optarg, "n") || !strcasecmp(optarg, "0")) + m_eTraceMode = SOptions::eTraceOff; + else if (!strcasecmp(optarg, "ON") || !strcasecmp(optarg, "YES") || !strcasecmp(optarg, "y") || !strcasecmp(optarg, "1")) + m_eTraceMode = SOptions::eTraceVendor; +#else + if (!strcasecmp(optarg, "BIN") || !strcasecmp(optarg, "BINARY") || !strcasecmp(optarg, "default")) + m_eTraceMode = SOptions::eTraceBinary; + else if (!strcasecmp(optarg, "CSV") || !strcasecmp(optarg, "logger") || !strcasecmp(optarg, "log")) + m_eTraceMode = SOptions::eTraceLogger; + else if (!strcasecmp(optarg, "TRC") || !strcasecmp(optarg, "vendor")) + m_eTraceMode = SOptions::eTraceVendor; +#endif + else { + fprintf(err, "%s: illegal argument for option `--trace'\n", m_szBasename); + return 1; + } + break; +#endif /* option '--receive' (-r) */ case 'r': if (optReceive++) { @@ -848,9 +885,16 @@ void SOptions::ShowUsage(FILE* stream, bool args) { fprintf(stream, " --error-frames allow reception of error frames\n"); fprintf(stream, " --no-remote-frames suppress remote frames (RTR frames)\n"); fprintf(stream, " --no-extended-frames suppress extended frames (29-bit identifier)\n"); + fprintf(stream, " --code= acceptance code for 11-bit IDs (default=0x%03x)\n", CANACC_CODE_11BIT); + fprintf(stream, " --mask= acceptance mask for 11-bit IDs (default=0x%03x)\n", CANACC_MASK_11BIT); + fprintf(stream, " --xtd-code= acceptance code for 29-bit IDs (default=0x%08x)\n", CANACC_CODE_29BIT); + fprintf(stream, " --xtd-mask= acceptance mask for 29-bit IDs (default=0x%08x)\n", CANACC_MASK_29BIT); fprintf(stream, " -b, --baudrate= CAN bit-timing in kbps (default=250), or\n"); fprintf(stream, " --bitrate= CAN bit-rate settings (as key/value list)\n"); fprintf(stream, " -v, --verbose show detailed bit-rate settings\n"); +#if (CAN_TRACE_SUPPORTED != 0) + fprintf(stream, " -y, --trace=(ON|OFF) write a trace file (default=OFF)\n"); +#endif fprintf(stream, "Options for transmitter test:\n"); fprintf(stream, " -t, --transmit=