From 9b3e84549b51e3333cf91f3e2795f7d6966fc62c Mon Sep 17 00:00:00 2001 From: calumroy Date: Tue, 6 Aug 2024 18:34:03 +0800 Subject: [PATCH 01/12] WIP: testing to fix multiplex signal pack functiins. --- src/CMakeLists.txt | 10 ++- src/codegen/c-main-generator.cpp | 53 +++++++++++-- src/codegen/c-sigprinter.cpp | 123 ++++++++++++++++++++++++++++--- src/codegen/c-sigprinter.h | 5 +- src/parser/dbclineparser.cpp | 3 + src/types/c-expr.h | 15 ++++ src/types/message.h | 2 + 7 files changed, 191 insertions(+), 20 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b3996bb..7773dde 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,6 +6,14 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) +# Set the build type to Debug if not specified +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Debug) +endif() + +# Add debug flags +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g") + add_executable(coderdbc ${CMAKE_CURRENT_SOURCE_DIR}/codegen/c-main-generator.cpp ${CMAKE_CURRENT_SOURCE_DIR}/codegen/mon-generator.cpp @@ -23,7 +31,6 @@ add_executable(coderdbc ${CMAKE_CURRENT_SOURCE_DIR}/maincli.cpp ) - include(FetchContent) FetchContent_Declare( googletest @@ -54,7 +61,6 @@ target_link_libraries( include(GoogleTest) gtest_discover_tests(cctest) - add_library( dummy OBJECT ${CMAKE_CURRENT_SOURCE_DIR}/../test/gencode/usr/testdb-fmon.c diff --git a/src/codegen/c-main-generator.cpp b/src/codegen/c-main-generator.cpp index dc9c5ae..4703028 100644 --- a/src/codegen/c-main-generator.cpp +++ b/src/codegen/c-main-generator.cpp @@ -794,7 +794,7 @@ void CiMainGenerator::PrintPackCommonText(const std::string& arrtxt, const CiExp { // this function will print body of packing function - // pring array content clearin loop + // print array content clearing loop fwriter.Append(" uint8_t i; for (i = 0u; i < %s(%s_DLC); %s[i++] = %s);", prt_dlcValidateMacroName.c_str(), sgs->msg.Name.c_str(), arrtxt.c_str(), @@ -842,6 +842,18 @@ void CiMainGenerator::PrintPackCommonText(const std::string& arrtxt, const CiExp fwriter.Append(); } + // Find the master multiplex signal (if any) + const SignalDescriptor_t* masterSignal = nullptr; + for (const auto& sig : sgs->msg.Signals) + { + if (sig.Multiplex == MultiplexType::kMaster) + { + masterSignal = &sig; + break; + } + } + + // Generate packing code for each byte in the CAN message for (size_t i = 0; i < sgs->to_bytes.size(); i++) { if (sgs->to_bytes[i].size() < 2) @@ -849,7 +861,39 @@ void CiMainGenerator::PrintPackCommonText(const std::string& arrtxt, const CiExp continue; } - fwriter.Append(" %s[%d] |= (uint8_t) ( %s );", arrtxt.c_str(), i, sgs->to_bytes[i].c_str()); + fwriter.Append(" // Packing byte %d", i); + + if (masterSignal) + { + bool first = true; + for (size_t mux_idx = 0; mux_idx < sgs->mux_values.size(); ++mux_idx) + { + int mux_val = sgs->mux_values[mux_idx]; + if (sgs->to_bytes_mux[i].size() > mux_idx && !sgs->to_bytes_mux[i][mux_idx].empty()) + { + if (first) + { + fwriter.Append(" if (_m->%s == %d) {", masterSignal->Name.c_str(), mux_val); + first = false; + } + else + { + fwriter.Append(" else if (_m->%s == %d) {", masterSignal->Name.c_str(), mux_val); + } + fwriter.Append(" %s[%d] |= (uint8_t) (%s);", arrtxt.c_str(), i, sgs->to_bytes_mux[i][mux_idx].c_str()); + fwriter.Append(" }"); + } + } + } + + // Handle non-multiplexed signals + for (const auto& sig : sgs->msg.Signals) + { + if (sig.Multiplex == MultiplexType::kNone) + { + fwriter.Append(" %s[%d] |= (uint8_t) (%s);", arrtxt.c_str(), i, sgs->to_bytes[i].c_str()); + } + } } fwriter.Append(""); @@ -863,10 +907,9 @@ void CiMainGenerator::PrintPackCommonText(const std::string& arrtxt, const CiExp sgs->msg.CsmSig->Name.c_str(), arrtxt.c_str(), sgs->msg.Name.c_str(), sgs->msg.Name.c_str(), sgs->msg.CsmMethod.c_str(), sgs->msg.CsmOp); - fwriter.Append(" %s[%d] |= (uint8_t) ( %s );", arrtxt.c_str(), sgs->msg.CsmByteNum, sgs->msg.CsmToByteExpr.c_str()); + fwriter.Append(" %s[%d] |= (uint8_t) (%s);", arrtxt.c_str(), sgs->msg.CsmByteNum, sgs->msg.CsmToByteExpr.c_str()); fwriter.Append("#endif // %s", fdesc->gen.usecsm_def.c_str()); fwriter.Append(); } -} - +} \ No newline at end of file diff --git a/src/codegen/c-sigprinter.cpp b/src/codegen/c-sigprinter.cpp index 3ea51cd..3bb53b4 100644 --- a/src/codegen/c-sigprinter.cpp +++ b/src/codegen/c-sigprinter.cpp @@ -1,5 +1,6 @@ #include #include +#include // For std::find #include "c-sigprinter.h" #include "helpers/formatter.h" #include "conf-and-limits.h" @@ -42,6 +43,9 @@ void CSigPrinter::LoadMessage(const MessageDescriptor_t& message) nexpr->msg = message; + // Find the multiplexor master signal in the message + FindMultiplexorValues(message, nexpr->mux_values); + // do for this new expr to_byte and to_field expression building, // add them to dedicated members, set signal stdint type // and push it to vector @@ -130,7 +134,14 @@ int32_t CSigPrinter::BuildCConvertExprs(CiExpr_t* msgprinter) msgprinter->to_bytes.clear(); msgprinter->to_signals.clear(); + msgprinter->to_bytes_mux.clear(); msgprinter->to_bytes.resize(msgprinter->msg.DLC); + // Resize the to_bytes_mux vector to the number of bytes in the message for the first dimension + // and the number of multiplexor values msgprinter->mux_values.size() for the second dimension. + for (size_t i = 0; i < msgprinter->msg.DLC; i++) + { + msgprinter->to_bytes_mux.push_back(std::vector(msgprinter->mux_values.size())); + } // for each signal specific to_signal expression must be defined, // and during all signals processing, for each byte to_byte expression @@ -154,22 +165,35 @@ int32_t CSigPrinter::BuildCConvertExprs(CiExpr_t* msgprinter) // // bytes expression is saved to vector @to_bytes, where id is the // byte number in frame payload (i.e. to_bytes.size() == frame.DLC) - msgprinter->to_signals.push_back(PrintSignalExpr(&msgprinter->msg.Signals[i], msgprinter->to_bytes)); + msgprinter->to_signals.push_back(PrintSignalExpr(&msgprinter->msg.Signals[i], msgprinter->mux_values, msgprinter->to_bytes, msgprinter->to_bytes_mux)); } if (msgprinter->msg.CsmSig != nullptr) { std::vector v(8); + std::vector> v2(8); + // resize the v2 vector to the number of multiplex values + for (size_t i = 0; i < 8; i++) + { + v2[i].resize(msgprinter->mux_values.size()); + } - PrintSignalExpr(msgprinter->msg.CsmSig, v); + PrintSignalExpr(msgprinter->msg.CsmSig, msgprinter->mux_values, v, v2); for (uint8_t i = 0; i < v.size() && i < 8; i++) { - if (v[i].size() > 0) + // As long as the checksum signal is not a multiplex signal. + if (msgprinter->msg.CsmSig->Multiplex != MultiplexType::kMulValue) { - msgprinter->msg.CsmToByteExpr = v[i]; - msgprinter->msg.CsmByteNum = i; - break; + if (v[i].size() > 0) + { + msgprinter->msg.CsmToByteExpr = v[i]; + msgprinter->msg.CsmByteNum = i; + break; + } + } else { + printf("Error in DBC file !!!! Checksum signal cannot be a multiplexor signal."); + ret = -1; } } } @@ -177,14 +201,14 @@ int32_t CSigPrinter::BuildCConvertExprs(CiExpr_t* msgprinter) return ret; } -std::string CSigPrinter::PrintSignalExpr(const SignalDescriptor_t* sig, std::vector& to_bytes) +std::string CSigPrinter::PrintSignalExpr(const SignalDescriptor_t* sig, const std::vector mux_values, std::vector& to_bytes, std::vector>& to_bytes_mux) { // value for collecting expression (to_signal) std::string tosigexpr; if (to_bytes.size() == 0) { - // return empty line is bytes count somehow equals 0 + // return empty line if bytes count somehow equals 0 return "Error in DBC file !!!! Dlc of this message must be greater."; } @@ -206,9 +230,20 @@ std::string CSigPrinter::PrintSignalExpr(const SignalDescriptor_t* sig, std::vec return to_bytes[0]; } + // Find the multiplexor index if the signal is multiplexed + int mux_ind = -1; + if (sig->Multiplex == MultiplexType::kMulValue) + { + auto it = std::find(mux_values.begin(), mux_values.end(), sig->MultiplexValue); + if (it != mux_values.end()) + { + mux_ind = std::distance(mux_values.begin(), it); + } + } + // set valid to_byte prefix - int32_t bbc = (startb % 8) + 1; - int32_t slen = sig->LengthBit; + int32_t bbc = (startb % 8) + 1; // Byte bit + int32_t slen = sig->LengthBit; // Signal length in bits if (bbc > slen) { @@ -217,6 +252,8 @@ std::string CSigPrinter::PrintSignalExpr(const SignalDescriptor_t* sig, std::vec snprintf(workbuff, WBUFF_LEN, "((_m->%s & (%s)) << %dU)", sig->Name.c_str(), msk[slen].c_str(), bbc - slen); AppendToByteLine(to_bytes[bn], workbuff); + + AppendToAllMuxValues(to_bytes_mux[bn], mux_ind, workbuff); } else if (bbc == slen) { @@ -226,6 +263,8 @@ std::string CSigPrinter::PrintSignalExpr(const SignalDescriptor_t* sig, std::vec snprintf(workbuff, WBUFF_LEN, "(_m->%s & (%s))", sig->Name.c_str(), msk[slen].c_str()); AppendToByteLine(to_bytes[bn], workbuff); + + AppendToAllMuxValues(to_bytes_mux[bn], mux_ind, workbuff); } else { @@ -243,6 +282,8 @@ std::string CSigPrinter::PrintSignalExpr(const SignalDescriptor_t* sig, std::vec snprintf(workbuff, WBUFF_LEN, "((_m->%s >> %dU) & (%s))", sig->Name.c_str(), slen, msk[bbc].c_str()); AppendToByteLine(to_bytes[bn], workbuff); + AppendToAllMuxValues(to_bytes_mux[bn], mux_ind, workbuff); + while ((slen - 8) >= 0) { t64.clear(); @@ -270,6 +311,7 @@ std::string CSigPrinter::PrintSignalExpr(const SignalDescriptor_t* sig, std::vec snprintf(workbuff, WBUFF_LEN, "(_m->%s & (%s))", sig->Name.c_str(), msk[8].c_str()); AppendToByteLine(to_bytes[bn], workbuff); + AppendToAllMuxValues(to_bytes_mux[bn], mux_ind, workbuff); } else { @@ -283,6 +325,8 @@ std::string CSigPrinter::PrintSignalExpr(const SignalDescriptor_t* sig, std::vec snprintf(workbuff, WBUFF_LEN, "((_m->%s >> %dU) & (%s))", sig->Name.c_str(), slen, msk[8].c_str()); AppendToByteLine(to_bytes[bn], workbuff); + + AppendToAllMuxValues(to_bytes_mux[bn], mux_ind, workbuff); } } @@ -293,15 +337,32 @@ std::string CSigPrinter::PrintSignalExpr(const SignalDescriptor_t* sig, std::vec snprintf(workbuff, WBUFF_LEN, " | ((_d[%d] >> %dU) & (%s))", bn, 8 - slen, msk[slen].c_str()); tosigexpr += workbuff; - snprintf(workbuff, WBUFF_LEN, "((_m->%s & (%s)) << %dU)", sig->Name.c_str(), msk[slen].c_str(), - 8 - slen); + snprintf(workbuff, WBUFF_LEN, "((_m->%s & (%s)) << %dU)", sig->Name.c_str(), msk[slen].c_str(), 8 - slen); AppendToByteLine(to_bytes[bn], workbuff); + + AppendToAllMuxValues(to_bytes_mux[bn], mux_ind, workbuff); } } return tosigexpr; } +void CSigPrinter::AppendToAllMuxValues(std::vector& to_bytes_mux, int mux_ind, const std::string& workbuff) +{ + if (mux_ind >= 0) + { + AppendToByteLine(to_bytes_mux[mux_ind], workbuff); + } + else + { + // Append to all multiplexor values if the signal is not multiplexed + for (size_t i = 0; i < to_bytes_mux.size(); ++i) + { + AppendToByteLine(to_bytes_mux[i], workbuff); + } + } +} + void CSigPrinter::AppendToByteLine(std::string& expr, std::string str) { if (expr.size() > 0) @@ -315,3 +376,41 @@ void CSigPrinter::AppendToByteLine(std::string& expr, std::string str) expr = str; } } + +void CSigPrinter::FindMultiplexorValues(const MessageDescriptor_t& message, std::vector& mux_values) +{ + // Clear the vectors to ensure they are empty before filling them + mux_values.clear(); + + // First, find the master multiplexor signal + SignalDescriptor_t* master_signal = nullptr; + for (const auto& signal : message.Signals) + { + if (signal.Multiplex == MultiplexType::kMaster) + { + master_signal = const_cast(&signal); + break; + } + } + + // If there's no master multiplexor signal, return + if (!master_signal) + { + return; + } + + // Now find all multiplex values + for (const auto& signal : message.Signals) + { + if (signal.Multiplex == MultiplexType::kMulValue) + { + // Extract and add to the list of total possible multiplex values for the CAN message. + int mux_value = signal.MultiplexValue; // Extract the multiplexor value this signal corresponds to + // If the multiplexor value is not already in the list, add it + if (std::find(mux_values.begin(), mux_values.end(), mux_value) == mux_values.end()) + { + mux_values.push_back(mux_value); + } + } + } +} \ No newline at end of file diff --git a/src/codegen/c-sigprinter.h b/src/codegen/c-sigprinter.h index 7f19b8b..a7094b0 100644 --- a/src/codegen/c-sigprinter.h +++ b/src/codegen/c-sigprinter.h @@ -18,8 +18,11 @@ class CSigPrinter { private: int32_t BuildCConvertExprs(CiExpr_t* msg); - std::string PrintSignalExpr(const SignalDescriptor_t* sig, std::vector& to_bytes); + std::string PrintSignalExpr(const SignalDescriptor_t* sig, const std::vector mux_values, std::vector& to_bytes, std::vector>& to_bytes_mux); + + void AppendToAllMuxValues(std::vector& to_bytes_mux, int mux_ind, const std::string& workbuff); void AppendToByteLine(std::string& expr, std::string str); + void FindMultiplexorValues(const MessageDescriptor_t& message, std::vector& mux_values); }; diff --git a/src/parser/dbclineparser.cpp b/src/parser/dbclineparser.cpp index d676f16..8703c8d 100644 --- a/src/parser/dbclineparser.cpp +++ b/src/parser/dbclineparser.cpp @@ -212,6 +212,9 @@ bool DbcLineParser::ParseSignalLine(SignalDescriptor_t* sig, const std::string& else { sig->Multiplex = MultiplexType::kMulValue; + // Multiplex value e.g m0, m1, m2... + // Convert to integer + sig->MultiplexValue = atoi(halfs[2].c_str() + 1); } } } diff --git a/src/types/c-expr.h b/src/types/c-expr.h index 996cca8..25f0a48 100644 --- a/src/types/c-expr.h +++ b/src/types/c-expr.h @@ -18,4 +18,19 @@ typedef struct // frame fields to data bytes std::vector to_bytes; + // another field containing expressions for converting + // frame fields to data bytes, but includes a different expression + // for each potential multiplexor value. + // i.e if the master multiplexor signal is 0, the first expression + // should be used, if it is 1, the second expression is used, etc. + // First dimension is the byte index, second dimension is the multiplexor value. + std::vector> to_bytes_mux; + // Store the corresponding multiplexor values for each expression + // since multiplexor values are not necessarily contiguous, we need + // to store the values explicitly. This vector should have the same + // size as the second dim of the to_bytes_mux and each element corresponds to the multiplexor + // value for the corresponding expression in to_bytes_mux. + // i.e to_bytes_mux[0 to 7].size() == mux_values.size() + std::vector mux_values; + } CiExpr_t; \ No newline at end of file diff --git a/src/types/message.h b/src/types/message.h index 275b9fc..fe284c0 100644 --- a/src/types/message.h +++ b/src/types/message.h @@ -91,6 +91,8 @@ typedef struct MultiplexType Multiplex; + uint32_t MultiplexValue; + } SignalDescriptor_t; typedef struct From ca43dbc9f84ddb5679d695d240e316c573c2c024 Mon Sep 17 00:00:00 2001 From: calumroy Date: Wed, 7 Aug 2024 09:49:06 +0800 Subject: [PATCH 02/12] Fixed case where only the master multiplexor exists and no other mux signals are in a CAN msg. Filter out bytes that have no signals in them. --- src/codegen/c-main-generator.cpp | 53 ++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/src/codegen/c-main-generator.cpp b/src/codegen/c-main-generator.cpp index 4703028..0be3cce 100644 --- a/src/codegen/c-main-generator.cpp +++ b/src/codegen/c-main-generator.cpp @@ -856,42 +856,49 @@ void CiMainGenerator::PrintPackCommonText(const std::string& arrtxt, const CiExp // Generate packing code for each byte in the CAN message for (size_t i = 0; i < sgs->to_bytes.size(); i++) { - if (sgs->to_bytes[i].size() < 2) - { - continue; - } - - fwriter.Append(" // Packing byte %d", i); if (masterSignal) { bool first = true; - for (size_t mux_idx = 0; mux_idx < sgs->mux_values.size(); ++mux_idx) + // Handle the case where only a master multiplexor signal exists and there are no other kMulValue signal types in the CAN msg. + // There may or may not be other normal signals in the CAN msg. + if (sgs->mux_values.size() == 0) { - int mux_val = sgs->mux_values[mux_idx]; - if (sgs->to_bytes_mux[i].size() > mux_idx && !sgs->to_bytes_mux[i][mux_idx].empty()) + // Filter out any empty bytes in the CAN msg. + if ( !sgs->to_bytes[i].empty() ) { - if (first) - { - fwriter.Append(" if (_m->%s == %d) {", masterSignal->Name.c_str(), mux_val); - first = false; - } - else + fwriter.Append(" %s[%d] |= (uint8_t) ( %s );", arrtxt.c_str(), i, sgs->to_bytes[i].c_str()); + } + } + else + { + // handle the case where there is a mux master and kMulValue (and other normal signals) in the CAN msg. + for (size_t mux_idx = 0; mux_idx < sgs->mux_values.size(); ++mux_idx) + { + int mux_val = sgs->mux_values[mux_idx]; + if (sgs->to_bytes_mux[i].size() > mux_idx && !sgs->to_bytes_mux[i][mux_idx].empty()) { - fwriter.Append(" else if (_m->%s == %d) {", masterSignal->Name.c_str(), mux_val); + if (first) + { + fwriter.Append(" if (_m->%s == %d) {", masterSignal->Name.c_str(), mux_val); + first = false; + } + else + { + fwriter.Append(" else if (_m->%s == %d) {", masterSignal->Name.c_str(), mux_val); + } + fwriter.Append(" %s[%d] |= (uint8_t) ( %s );", arrtxt.c_str(), i, sgs->to_bytes_mux[i][mux_idx].c_str()); + fwriter.Append(" }"); } - fwriter.Append(" %s[%d] |= (uint8_t) (%s);", arrtxt.c_str(), i, sgs->to_bytes_mux[i][mux_idx].c_str()); - fwriter.Append(" }"); } } } - - // Handle non-multiplexed signals - for (const auto& sig : sgs->msg.Signals) + else { - if (sig.Multiplex == MultiplexType::kNone) + // Handle for when there is no master multiplexor signal. Just pack the signal values from all signals making up this byte. + if ( !sgs->to_bytes[i].empty() ) { - fwriter.Append(" %s[%d] |= (uint8_t) (%s);", arrtxt.c_str(), i, sgs->to_bytes[i].c_str()); + fwriter.Append(" %s[%d] |= (uint8_t) ( %s );", arrtxt.c_str(), i, sgs->to_bytes[i].c_str()); } } } From fbcc74156fe6f4416bdeb2aa792cf4991b068d78 Mon Sep 17 00:00:00 2001 From: calumroy Date: Wed, 7 Aug 2024 09:53:02 +0800 Subject: [PATCH 03/12] Revert a small change to formatting. --- src/codegen/c-main-generator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/codegen/c-main-generator.cpp b/src/codegen/c-main-generator.cpp index 0be3cce..d7c8bc3 100644 --- a/src/codegen/c-main-generator.cpp +++ b/src/codegen/c-main-generator.cpp @@ -914,7 +914,7 @@ void CiMainGenerator::PrintPackCommonText(const std::string& arrtxt, const CiExp sgs->msg.CsmSig->Name.c_str(), arrtxt.c_str(), sgs->msg.Name.c_str(), sgs->msg.Name.c_str(), sgs->msg.CsmMethod.c_str(), sgs->msg.CsmOp); - fwriter.Append(" %s[%d] |= (uint8_t) (%s);", arrtxt.c_str(), sgs->msg.CsmByteNum, sgs->msg.CsmToByteExpr.c_str()); + fwriter.Append(" %s[%d] |= (uint8_t) ( %s );", arrtxt.c_str(), sgs->msg.CsmByteNum, sgs->msg.CsmToByteExpr.c_str()); fwriter.Append("#endif // %s", fdesc->gen.usecsm_def.c_str()); fwriter.Append(); From 0e8b893c3f5a703ecfbc558e1efdbd95f32f32ec Mon Sep 17 00:00:00 2001 From: calumroy Date: Wed, 7 Aug 2024 10:22:46 +0800 Subject: [PATCH 04/12] Added example dbc that shows the issues with multiplex signals. --- test/testdb2.dbc | 109 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 test/testdb2.dbc diff --git a/test/testdb2.dbc b/test/testdb2.dbc new file mode 100644 index 0000000..edb2890 --- /dev/null +++ b/test/testdb2.dbc @@ -0,0 +1,109 @@ +VERSION "" + + +NS_ : + NS_DESC_ + CM_ + BA_DEF_ + BA_ + VAL_ + CAT_DEF_ + CAT_ + FILTER + BA_DEF_DEF_ + EV_DATA_ + ENVVAR_DATA_ + SGTYPE_ + SGTYPE_VAL_ + BA_DEF_SGTYPE_ + BA_SGTYPE_ + SIG_TYPE_REF_ + VAL_TABLE_ + SIG_GROUP_ + SIG_VALTYPE_ + SIGTYPE_VALTYPE_ + BO_TX_BU_ + BA_DEF_REL_ + BA_REL_ + BA_DEF_DEF_REL_ + BU_SG_REL_ + BU_EV_REL_ + BU_BO_REL_ + SG_MUL_VAL_ + +BS_: + +BU_: MCU VMU + + +BO_ 1096 MUX_SIG_TEST1: 8 MCU + SG_ mux8_sig1 m8 : 8|8@1+ (1,0) [1|3] "" VMU + SG_ mux8_sig2 m8 : 16|15@1+ (0.125,0) [0|4090] "V" VMU + SG_ mux7_sig1 m7 : 8|8@1+ (1,0) [1|3] "" VMU + SG_ mux7_sig2 m7 : 16|15@1+ (0.125,0) [0|4090] "V" VMU + SG_ mux6_sig1 m6 : 8|48@1+ (1,0) [0|0] "" VMU + SG_ mux0_sig1 m0 : 32|8@1+ (1,0) [0|0] "" VMU + SG_ mux0_sig2 m0 : 24|8@1+ (1,0) [0|0] "" VMU + SG_ mux5_sig1 m5 : 8|48@1+ (1,0) [0|0] "" VMU + SG_ mux4_sig4 m4 : 8|32@1+ (1,0) [0|0] "" VMU + SG_ mux4_sig3 m3 : 24|16@1+ (1,0) [0|0] "" VMU + SG_ mux0_sig3 m0 : 16|8@1+ (1,0) [0|0] "" VMU + SG_ mux0_sig4 m0 : 8|8@1+ (1,0) [0|0] "" VMU + SG_ mux2_sig1 m2 : 8|16@1+ (1,-32767) [0|32760] "RPM" VMU + SG_ mux1_sig1 m1 : 8|15@1+ (0.125,0) [0|4090] "Nm" VMU + SG_ mux3_sig1 m3 : 16|8@1+ (1,0) [0|0] "" VMU + SG_ mux3_sig2 m3 : 8|8@1+ (1,0) [0|0] "" VMU + SG_ mux_master M : 0|7@1+ (1,0) [0|0] "" VMU + SG_ signal1 : 7|1@1+ (1,0) [0|0] "" VMU + +BO_ 1091 SIG_TEST1: 5 MCU + SG_ signal1 : 36|4@1+ (1,0) [0|15] "" VMU + SG_ signal2 : 0|16@1+ (1,0) [0|65535] "" VMU + +BO_ 66 MUX_SIG_TEST2: 5 VMU + SG_ mux4_sig1 m4 : 16|16@1+ (1,-32767) [4294934536|32760] "RPM" Vector__XXX + SG_ mux4_sig2 m4 : 0|16@1+ (0.125,-4096) [4294963206|4090] "Nm" Vector__XXX + SG_ mux1_sig1 m1 : 0|16@1+ (0.125,-4096) [4294963206|4090] "Nm" MCU + SG_ mux3_sig3 m3 : 0|16@1+ (0.125,-4096) [0|4090] "V" MCU + SG_ signal1 : 36|4@1+ (1,0) [0|15] "" MCU + SG_ mux2_sig1 m2 : 16|16@1+ (1,-32767) [4294934536|32760] "RPM" MCU + SG_ mux_master M : 32|3@1+ (1,0) [1|7] "" MCU + +BO_ 65 MUX_SIG_TEST3: 6 VMU + SG_ signal1 : 6|1@1+ (1,0) [0|0] "" Vector__XXX + SG_ max_master M : 7|1@1+ (1,0) [0|1] "" Vector__XXX + SG_ mux1_sig1 m1 : 3|2@1+ (1,0) [0|3] "" Vector__XXX + SG_ signal2 : 5|1@1+ (1,0) [0|0] "" Vector__XXX + SG_ signal3 : 24|16@1+ (1,-32767) [4294934536|32760] "RPM" Vector__XXX + SG_ mux1_sig2 m1 : 8|16@1+ (0.125,-4096) [4294963206|4090] "Nm" Vector__XXX + SG_ mux0_sig1 m0 : 6|1@1+ (1,0) [0|0] "" MCU + SG_ mux0_sig2 m0 : 8|16@1+ (0.125,-4096) [0|4090] "V" MCU + SG_ mux0_sig3 m0 : 3|2@1+ (1,0) [1|3] "" MCU + SG_ signal4 : 44|4@1+ (1,0) [0|15] "" MCU + SG_ mux0_sig4 m0 : 8|16@1+ (0.125,-4096) [4294963206|4090] "Nm" MCU + SG_ signal5 : 0|3@1+ (1,0) [0|3] "" MCU + +BO_ 1093 SIG_TEST2: 3 MCU + SG_ mux_master M : 0|7@1+ (1,0) [0|127] "" VMU + + + +BA_DEF_ EV_ "Version" STRING ; +BA_DEF_ "BusType" STRING ; +BA_DEF_DEF_ "Version" "1.0"; +BA_DEF_DEF_ "BusType" ""; +BA_ "BusType" "CAN"; +VAL_ 1096 mux8_sig1 1 "Mode1" 2 "Mode2" 3 "Mode3" ; +VAL_ 1096 mux7_sig1 1 "Mode1" 2 "Mode2" 3 "Mode3" ; +VAL_ 1096 mux_master 0 "Mode0" 1 "Mode1" 2 "Mode2" 3 "Mode3" 4 "Mode4" 5 "Mode5" 6 "Mode6" 7 "Mode7" 8 "Mode8" ; +VAL_ 1096 signal1 0 "Mode0" 1 "Mode1" ; +VAL_ 66 mux_master 1 "Mode1" 2 "Mode2" 3 "Mode3" 4 "Mode4" 5 "Reserved" 6 "Reserved" 7 "Reserved" ; +VAL_ 65 signal1 0 "mode0" 1 "mode1" ; +VAL_ 65 max_master 1 "ON" 0 "OFF" ; +VAL_ 65 mux1_sig1 1 "Mode1" ; +VAL_ 65 signal2 0 "mode0" 1 "mode1" ; +VAL_ 65 mux0_sig1 1 "invalid" 0 "valid" ; +VAL_ 65 mux0_sig3 1 "mode1" 2 "mode2" 3 "mode3" ; +VAL_ 65 signal5 0 "mode0" 1 "mode1" 3 "mode3" 4 "mode4" ; +VAL_ 1093 mux_master 0 "mode0" ; + From 69eda88eef3e944223159f596ef908d28cb2eaf1 Mon Sep 17 00:00:00 2001 From: calumroy Date: Wed, 7 Aug 2024 11:11:22 +0800 Subject: [PATCH 05/12] Revert changes to the CMakeLists.txt --- src/CMakeLists.txt | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7773dde..b3996bb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,14 +6,6 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) -# Set the build type to Debug if not specified -if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE Debug) -endif() - -# Add debug flags -set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g") - add_executable(coderdbc ${CMAKE_CURRENT_SOURCE_DIR}/codegen/c-main-generator.cpp ${CMAKE_CURRENT_SOURCE_DIR}/codegen/mon-generator.cpp @@ -31,6 +23,7 @@ add_executable(coderdbc ${CMAKE_CURRENT_SOURCE_DIR}/maincli.cpp ) + include(FetchContent) FetchContent_Declare( googletest @@ -61,6 +54,7 @@ target_link_libraries( include(GoogleTest) gtest_discover_tests(cctest) + add_library( dummy OBJECT ${CMAKE_CURRENT_SOURCE_DIR}/../test/gencode/usr/testdb-fmon.c From 25671de74921c66c1c96253f116725caab680384 Mon Sep 17 00:00:00 2001 From: calumroy Date: Tue, 13 Aug 2024 18:12:59 +0800 Subject: [PATCH 06/12] Fixed the case where the multiplex master value does not equal any of the expected multiplex values. In this case just encode all signals for the byte since none of them are technically valid as they don't correspond to the master multiplexor value. --- src/codegen/c-main-generator.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/codegen/c-main-generator.cpp b/src/codegen/c-main-generator.cpp index d7c8bc3..a372d03 100644 --- a/src/codegen/c-main-generator.cpp +++ b/src/codegen/c-main-generator.cpp @@ -891,6 +891,16 @@ void CiMainGenerator::PrintPackCommonText(const std::string& arrtxt, const CiExp fwriter.Append(" }"); } } + // Add the final else block for the case where no expected multiplex value matches. Just encode all signals in the byte. + if (!first) + { + fwriter.Append(" else {"); + if ( !sgs->to_bytes[i].empty() ) + { + fwriter.Append(" %s[%d] |= (uint8_t) ( %s );", arrtxt.c_str(), i, sgs->to_bytes[i].c_str()); + } + fwriter.Append(" }"); + } } } else From bdfe0210a52e4ca5951f3ef57083da04db2eb694 Mon Sep 17 00:00:00 2001 From: calumroy Date: Wed, 14 Aug 2024 18:32:01 +0800 Subject: [PATCH 07/12] Try fixing the unpack multiplexed signals. --- src/codegen/c-main-generator.cpp | 86 ++++++++++++++++++++++---------- 1 file changed, 61 insertions(+), 25 deletions(-) diff --git a/src/codegen/c-main-generator.cpp b/src/codegen/c-main-generator.cpp index a372d03..456c6c2 100644 --- a/src/codegen/c-main-generator.cpp +++ b/src/codegen/c-main-generator.cpp @@ -678,55 +678,94 @@ void CiMainGenerator::WriteSigStructField(const SignalDescriptor_t& sig, bool bi void CiMainGenerator::WriteUnpackBody(const CiExpr_t* sgs) { + // Find the master multiplex signal (if any) + const SignalDescriptor_t* masterSignal = nullptr; + for (const auto& sig : sgs->msg.Signals) + { + if (sig.Multiplex == MultiplexType::kMaster) + { + masterSignal = &sig; + break; + } + } + + // If there's a master multiplex signal, unpack it first to get its value + if (masterSignal) + { + const char* masterSname = masterSignal->Name.c_str(); + auto masterExpr = sgs->to_signals[masterSignal->StartBit / 8]; // Assume the start bit gives the correct index for expression + fwriter.Append(" _m->%s = (%s) %s;", masterSname, + PrintType((int)masterSignal->TypeRo).c_str(), masterExpr.c_str()); + } + for (size_t num = 0; num < sgs->to_signals.size(); num++) { + const auto& signal = sgs->msg.Signals[num]; auto expr = sgs->to_signals[num]; + // Skip the master signal as we've already handled it + if (&signal == masterSignal) + { + continue; + } // for code shortening - const char* sname = sgs->msg.Signals[num].Name.c_str(); + const char* sname = signal.Name.c_str(); - if (sgs->msg.Signals[num].Signed) + // Check if the signal is multiplexed + if (signal.Multiplex == MultiplexType::kMulValue) + { + fwriter.Append(" if (_m->%s == %d) {", masterSignal->Name.c_str(), signal.MultiplexValue); + } + + // Unpack the signal + if (signal.Signed) { fwriter.Append(" _m->%s = (%s) %s(( %s ), %d);", - sname, PrintType((int)sgs->msg.Signals[num].TypeRo).c_str(), - ext_sig_func_name, expr.c_str(), (int32_t)sgs->msg.Signals[num].LengthBit); + sname, PrintType((int)signal.TypeRo).c_str(), + ext_sig_func_name, expr.c_str(), (int32_t)signal.LengthBit); } else { fwriter.Append(" _m->%s = (%s) ( %s );", sname, - PrintType((int)sgs->msg.Signals[num].TypeRo).c_str(), expr.c_str()); + PrintType((int)signal.TypeRo).c_str(), expr.c_str()); } - // print sigfloat conversion - if (!sgs->msg.Signals[num].IsSimpleSig) + // Handle physical value conversion if needed + if (!signal.IsSimpleSig) { fwriter.Append("#ifdef %s", fdesc->gen.usesigfloat_def.c_str()); - if (sgs->msg.Signals[num].IsDoubleSig) + if (signal.IsDoubleSig) { // for double signals (sigfloat_t) type cast fwriter.Append(" _m->%s = (sigfloat_t)(%s_%s_fromS(_m->%s));", - sgs->msg.Signals[num].NameFloat.c_str(), fdesc->gen.DRVNAME.c_str(), sname, sname); + signal.NameFloat.c_str(), fdesc->gen.DRVNAME.c_str(), sname, sname); } else { - fwriter.Append(" _m->%s = (%s) %s_%s_fromS(_m->%s);", - sgs->msg.Signals[num].NameFloat.c_str(), - PrintType((int)sgs->msg.Signals[num].TypePhys).c_str(), - fdesc->gen.DRVNAME.c_str(), sname, sname); - } - - fwriter.Append("#endif // %s", fdesc->gen.usesigfloat_def.c_str()); - fwriter.Append(); + fwriter.Append(" _m->%s = (%s) %s_%s_fromS(_m->%s);", + signal.NameFloat.c_str(), + PrintType((int)signal.TypePhys).c_str(), + fdesc->gen.DRVNAME.c_str(), sname, sname); } - else if (num + 1 == sgs->to_signals.size()) - { - // last signal without phys part, put \n manually - fwriter.Append(""); - } + fwriter.Append("#endif // %s", fdesc->gen.usesigfloat_def.c_str()); + } + + // Close the if statement if the signal was multiplexed + if (signal.Multiplex == MultiplexType::kMulValue) + { + fwriter.Append(" }"); + } + + // Add a newline after processing the last signal + if (num + 1 == sgs->to_signals.size()) + { + fwriter.Append(""); + } } + // Additional monitor and checksum logic, unchanged fwriter.Append("#ifdef %s", fdesc->gen.usemon_def.c_str()); fwriter.Append(" _m->mon1.dlc_error = (dlc_ < %s_DLC);", sgs->msg.Name.c_str()); fwriter.Append(" _m->mon1.last_cycle = GetSystemTick();"); @@ -735,20 +774,17 @@ void CiMainGenerator::WriteUnpackBody(const CiExpr_t* sgs) if (sgs->msg.RollSig != nullptr) { - // Put rolling monitor here fwriter.Append("#ifdef %s", fdesc->gen.useroll_def.c_str()); fwriter.Append(" _m->mon1.roll_error = (_m->%s != _m->%s_expt);", sgs->msg.RollSig->Name.c_str(), sgs->msg.RollSig->Name.c_str()); fwriter.Append(" _m->%s_expt = (_m->%s + 1) & (0x%02XU);", sgs->msg.RollSig->Name.c_str(), sgs->msg.RollSig->Name.c_str(), (1 << sgs->msg.RollSig->LengthBit) - 1); - // Put rolling monitor here fwriter.Append("#endif // %s", fdesc->gen.useroll_def.c_str()); fwriter.Append(); } if (sgs->msg.CsmSig != nullptr) { - // Put checksum check function call here fwriter.Append("#ifdef %s", fdesc->gen.usecsm_def.c_str()); fwriter.Append(" _m->mon1.csm_error = (((uint8_t)GetFrameHash(_d, %s_DLC, %s_CANID, %s, %d)) != (_m->%s));", sgs->msg.Name.c_str(), sgs->msg.Name.c_str(), sgs->msg.CsmMethod.c_str(), From a01262ed20257d9e948392c28ad6cea7b7869d75 Mon Sep 17 00:00:00 2001 From: calumroy Date: Wed, 14 Aug 2024 18:41:50 +0800 Subject: [PATCH 08/12] Indentation fixed in unpack functions under the new if statements for unpack depending on multiplexed master value. --- src/codegen/c-main-generator.cpp | 57 +++++++++++++++++--------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/src/codegen/c-main-generator.cpp b/src/codegen/c-main-generator.cpp index 456c6c2..e652c8c 100644 --- a/src/codegen/c-main-generator.cpp +++ b/src/codegen/c-main-generator.cpp @@ -694,7 +694,7 @@ void CiMainGenerator::WriteUnpackBody(const CiExpr_t* sgs) { const char* masterSname = masterSignal->Name.c_str(); auto masterExpr = sgs->to_signals[masterSignal->StartBit / 8]; // Assume the start bit gives the correct index for expression - fwriter.Append(" _m->%s = (%s) %s;", masterSname, + fwriter.Append(" _m->%s = (%s) ( %s );", masterSname, PrintType((int)masterSignal->TypeRo).c_str(), masterExpr.c_str()); } @@ -708,26 +708,30 @@ void CiMainGenerator::WriteUnpackBody(const CiExpr_t* sgs) { continue; } - // for code shortening + const char* sname = signal.Name.c_str(); // Check if the signal is multiplexed - if (signal.Multiplex == MultiplexType::kMulValue) + bool isMultiplexed = (signal.Multiplex == MultiplexType::kMulValue); + if (isMultiplexed) { fwriter.Append(" if (_m->%s == %d) {", masterSignal->Name.c_str(), signal.MultiplexValue); } + // Set the indentation level based on whether the signal is multiplexed + const char* indent = isMultiplexed ? " " : " "; + // Unpack the signal if (signal.Signed) { - fwriter.Append(" _m->%s = (%s) %s(( %s ), %d);", - sname, PrintType((int)signal.TypeRo).c_str(), + fwriter.Append("%s_m->%s = (%s) %s(( %s ), %d);", + indent, sname, PrintType((int)signal.TypeRo).c_str(), ext_sig_func_name, expr.c_str(), (int32_t)signal.LengthBit); } else { - fwriter.Append(" _m->%s = (%s) ( %s );", sname, - PrintType((int)signal.TypeRo).c_str(), expr.c_str()); + fwriter.Append("%s_m->%s = (%s) ( %s );", indent, + sname, PrintType((int)signal.TypeRo).c_str(), expr.c_str()); } // Handle physical value conversion if needed @@ -737,32 +741,31 @@ void CiMainGenerator::WriteUnpackBody(const CiExpr_t* sgs) if (signal.IsDoubleSig) { - // for double signals (sigfloat_t) type cast - fwriter.Append(" _m->%s = (sigfloat_t)(%s_%s_fromS(_m->%s));", - signal.NameFloat.c_str(), fdesc->gen.DRVNAME.c_str(), sname, sname); + fwriter.Append("%s_m->%s = (sigfloat_t)(%s_%s_fromS(_m->%s));", + indent, signal.NameFloat.c_str(), fdesc->gen.DRVNAME.c_str(), sname, sname); } else { - fwriter.Append(" _m->%s = (%s) %s_%s_fromS(_m->%s);", - signal.NameFloat.c_str(), - PrintType((int)signal.TypePhys).c_str(), - fdesc->gen.DRVNAME.c_str(), sname, sname); - } + fwriter.Append("%s_m->%s = (%s) %s_%s_fromS(_m->%s);", + indent, signal.NameFloat.c_str(), + PrintType((int)signal.TypePhys).c_str(), + fdesc->gen.DRVNAME.c_str(), sname, sname); + } - fwriter.Append("#endif // %s", fdesc->gen.usesigfloat_def.c_str()); - } + fwriter.Append("#endif // %s", fdesc->gen.usesigfloat_def.c_str()); + } - // Close the if statement if the signal was multiplexed - if (signal.Multiplex == MultiplexType::kMulValue) - { - fwriter.Append(" }"); - } + // Close the if statement if the signal was multiplexed + if (isMultiplexed) + { + fwriter.Append(" }"); + } - // Add a newline after processing the last signal - if (num + 1 == sgs->to_signals.size()) - { - fwriter.Append(""); - } + // Add a newline after processing the last signal + if (num + 1 == sgs->to_signals.size()) + { + fwriter.Append(""); + } } // Additional monitor and checksum logic, unchanged From 6a0bf8d4acc00aef085b8a904ba4a3b8fc8f64c8 Mon Sep 17 00:00:00 2001 From: calumroy Date: Wed, 14 Aug 2024 18:46:50 +0800 Subject: [PATCH 09/12] Added back in additional new line. --- src/codegen/c-main-generator.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/codegen/c-main-generator.cpp b/src/codegen/c-main-generator.cpp index e652c8c..41bef44 100644 --- a/src/codegen/c-main-generator.cpp +++ b/src/codegen/c-main-generator.cpp @@ -753,6 +753,7 @@ void CiMainGenerator::WriteUnpackBody(const CiExpr_t* sgs) } fwriter.Append("#endif // %s", fdesc->gen.usesigfloat_def.c_str()); + fwriter.Append(""); } // Close the if statement if the signal was multiplexed From 5df33a0f6b824cda0c0355ba78dbb8f96d90bb2c Mon Sep 17 00:00:00 2001 From: calumroy Date: Thu, 15 Aug 2024 09:25:23 +0800 Subject: [PATCH 10/12] Removed unnecessary additional new line being added. --- src/codegen/c-main-generator.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/codegen/c-main-generator.cpp b/src/codegen/c-main-generator.cpp index 41bef44..6f7a6a8 100644 --- a/src/codegen/c-main-generator.cpp +++ b/src/codegen/c-main-generator.cpp @@ -697,7 +697,8 @@ void CiMainGenerator::WriteUnpackBody(const CiExpr_t* sgs) fwriter.Append(" _m->%s = (%s) ( %s );", masterSname, PrintType((int)masterSignal->TypeRo).c_str(), masterExpr.c_str()); } - + + // Unpack the rest of the signals for (size_t num = 0; num < sgs->to_signals.size(); num++) { const auto& signal = sgs->msg.Signals[num]; @@ -765,7 +766,10 @@ void CiMainGenerator::WriteUnpackBody(const CiExpr_t* sgs) // Add a newline after processing the last signal if (num + 1 == sgs->to_signals.size()) { - fwriter.Append(""); + // No newline if the last signal was a multiplexed signal, as it already has a newline + if (signal.IsSimpleSig) { + fwriter.Append(""); + } } } From bc9d54bc852b9a7bd380eaeb321be138df1aa89d Mon Sep 17 00:00:00 2001 From: calumroy Date: Thu, 15 Aug 2024 11:15:02 +0800 Subject: [PATCH 11/12] Added command line option to turn on or off the code generation based on multiplexor master signal values for multiplexed signals. By default it is off so this new code has no affect. --- src/app.cpp | 11 ++++------- src/codegen/c-main-generator.cpp | 24 +++++++++++++++--------- src/codegen/c-main-generator.h | 4 +++- src/options-parser.cpp | 4 ++++ src/options-parser.h | 3 +++ 5 files changed, 29 insertions(+), 17 deletions(-) diff --git a/src/app.cpp b/src/app.cpp index 4810d9b..1d464e8 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -145,7 +145,7 @@ void CoderApp::GenerateCode() if (ret) { - cigen.Generate(scanner.dblist, fscreator.FS); + cigen.Generate(scanner.dblist, fscreator.FS, Params.is_multiplex_enabled); } else { @@ -283,8 +283,8 @@ void CoderApp::PrintHelp() std::cout << " -nofmon:\t no ***-fmon.c generation" << std::endl; std::cout << std::endl; std::cout << " -driverdir\t the output path (-out) will be appended by driver name" << std::endl; - std::cout << " -gendate\t the generation date will be included in the header comment section of the source file." << - std::endl; + std::cout << " -gendate\t the generation date will be included in the header comment section of the source file." << std::endl; + std::cout << " -multiplex or -muxgen\t enable multiplex signal packing/unpacking code generation based on multiplexor master signal values for multiplexed signals." << std::endl; std::cout << std::endl; std::cout << "examples:" << std::endl; @@ -295,10 +295,7 @@ void CoderApp::PrintHelp() << std::endl; std::cout << "./dbccoder -dbc /home/user/docs/driveshaft.dbc -out /home/user/docs/gen/ -drvname drivedb -nodeutils -rw" << std::endl; - - std::cout << - "./dbccoder -dbc /home/user/docs/driveshaft.dbc -out /home/user/docs/gen/ -drvname drivedb -nodeutils" << std::endl; - + std::cout << "./dbccoder -dbc /home/user/docs/driveshaft.dbc -out /home/user/docs/gen/ -drvname drivedb -nodeutils" << std::endl; std::cout << "./dbccoder -dbc /home/user/docs/driveshaft.dbc -out /home/user/docs/gen/ -drvname drivedb" << std::endl; std::cout << std::endl; } diff --git a/src/codegen/c-main-generator.cpp b/src/codegen/c-main-generator.cpp index 6f7a6a8..af94d53 100644 --- a/src/codegen/c-main-generator.cpp +++ b/src/codegen/c-main-generator.cpp @@ -31,8 +31,11 @@ const char* extend_func_body = " return ((val ^ m) - m);\n" "}\n\n"; -void CiMainGenerator::Generate(DbcMessageList_t& dlist, const AppSettings_t& fsd) +void CiMainGenerator::Generate(DbcMessageList_t& dlist, const AppSettings_t& fsd, bool mux_enabled) { + // set multiplexor master signal values is enabled for multiplexed signals + is_multiplex_enabled = mux_enabled; + // Load income messages to sig printer sigprt.LoadMessages(dlist.msgs); @@ -714,13 +717,15 @@ void CiMainGenerator::WriteUnpackBody(const CiExpr_t* sgs) // Check if the signal is multiplexed bool isMultiplexed = (signal.Multiplex == MultiplexType::kMulValue); - if (isMultiplexed) + + // Generate the if statement only if multiplex is enabled + if (is_multiplex_enabled && isMultiplexed) { fwriter.Append(" if (_m->%s == %d) {", masterSignal->Name.c_str(), signal.MultiplexValue); } // Set the indentation level based on whether the signal is multiplexed - const char* indent = isMultiplexed ? " " : " "; + const char* indent = (is_multiplex_enabled && isMultiplexed) ? " " : " "; // Unpack the signal if (signal.Signed) @@ -757,8 +762,8 @@ void CiMainGenerator::WriteUnpackBody(const CiExpr_t* sgs) fwriter.Append(""); } - // Close the if statement if the signal was multiplexed - if (isMultiplexed) + // Close the if statement if the signal was multiplexed and if multiplexing is enabled + if (is_multiplex_enabled && isMultiplexed) { fwriter.Append(" }"); } @@ -811,6 +816,7 @@ void CiMainGenerator::WriteUnpackBody(const CiExpr_t* sgs) fwriter.Append(" return %s_CANID;", sgs->msg.Name.c_str()); } + void CiMainGenerator::WritePackStructBody(const CiExpr_t* sgs) { fwriter.Append("{"); @@ -836,7 +842,7 @@ void CiMainGenerator::WritePackArrayBody(const CiExpr_t* sgs) void CiMainGenerator::PrintPackCommonText(const std::string& arrtxt, const CiExpr_t* sgs) { - // this function will print body of packing function + // this function will print the body of the packing function // print array content clearing loop fwriter.Append(" uint8_t i; for (i = 0u; i < %s(%s_DLC); %s[i++] = %s);", @@ -900,8 +906,7 @@ void CiMainGenerator::PrintPackCommonText(const std::string& arrtxt, const CiExp // Generate packing code for each byte in the CAN message for (size_t i = 0; i < sgs->to_bytes.size(); i++) { - - if (masterSignal) + if (is_multiplex_enabled && masterSignal) { bool first = true; // Handle the case where only a master multiplexor signal exists and there are no other kMulValue signal types in the CAN msg. @@ -949,7 +954,8 @@ void CiMainGenerator::PrintPackCommonText(const std::string& arrtxt, const CiExp } else { - // Handle for when there is no master multiplexor signal. Just pack the signal values from all signals making up this byte. + // Handle for when there is no master multiplexor signal or when multiplexing is disabled. + // Just pack the signal values from all signals making up this byte. if ( !sgs->to_bytes[i].empty() ) { fwriter.Append(" %s[%d] |= (uint8_t) ( %s );", arrtxt.c_str(), i, sgs->to_bytes[i].c_str()); diff --git a/src/codegen/c-main-generator.h b/src/codegen/c-main-generator.h index 33cbc96..c56edc4 100644 --- a/src/codegen/c-main-generator.h +++ b/src/codegen/c-main-generator.h @@ -10,7 +10,7 @@ class CiMainGenerator { public: - void Generate(DbcMessageList_t& dlist, const AppSettings_t& fsd); + void Generate(DbcMessageList_t& dlist, const AppSettings_t& fsd, bool mux_enabled); private: @@ -39,4 +39,6 @@ class CiMainGenerator { // Macro for frame DLC validation std::string prt_dlcValidateMacroName; const AppSettings_t* fdesc; + // Bool to turn on or off code generation based on multiplexor master signal values is enabled for multiplexed signals. + bool is_multiplex_enabled; }; diff --git a/src/options-parser.cpp b/src/options-parser.cpp index ee77391..499569d 100644 --- a/src/options-parser.cpp +++ b/src/options-parser.cpp @@ -86,6 +86,10 @@ OptionsParser::GenOptions OptionsParser::GetOptions(int argc, char** argv) { retpairs.add_gen_date = true; } + else if (temppairs[i].first.compare("-multiplex") == 0 || temppairs[i].first.compare("-muxgen") == 0) + { + retpairs.is_multiplex_enabled = true; + } } return retpairs; diff --git a/src/options-parser.h b/src/options-parser.h index d2b1c8d..aaa800d 100644 --- a/src/options-parser.h +++ b/src/options-parser.h @@ -48,6 +48,9 @@ class OptionsParser { /// @brief help is requested bool is_help{false}; + + /// @brief Code generation based on multiplexor master signal values is enabled for multiplexed signals. + bool is_multiplex_enabled{false}; }; /// @brief Parses arguments and theirs optional values From f40854338e4ae595b76719bd932269214bf0ee4e Mon Sep 17 00:00:00 2001 From: calumroy Date: Fri, 4 Oct 2024 22:15:17 +0800 Subject: [PATCH 12/12] Fixed bug where the incorrect expr was being selected and written out in the Unpack body for the multiplex master signals. This is fixed now. --- src/codegen/c-main-generator.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/codegen/c-main-generator.cpp b/src/codegen/c-main-generator.cpp index af94d53..b6440fa 100644 --- a/src/codegen/c-main-generator.cpp +++ b/src/codegen/c-main-generator.cpp @@ -683,11 +683,13 @@ void CiMainGenerator::WriteUnpackBody(const CiExpr_t* sgs) { // Find the master multiplex signal (if any) const SignalDescriptor_t* masterSignal = nullptr; - for (const auto& sig : sgs->msg.Signals) + size_t masterSignalIndex = 0; + for (size_t i = 0; i < sgs->msg.Signals.size(); ++i) { - if (sig.Multiplex == MultiplexType::kMaster) + if (sgs->msg.Signals[i].Multiplex == MultiplexType::kMaster) { - masterSignal = &sig; + masterSignal = &sgs->msg.Signals[i]; + masterSignalIndex = i; break; } } @@ -696,7 +698,7 @@ void CiMainGenerator::WriteUnpackBody(const CiExpr_t* sgs) if (masterSignal) { const char* masterSname = masterSignal->Name.c_str(); - auto masterExpr = sgs->to_signals[masterSignal->StartBit / 8]; // Assume the start bit gives the correct index for expression + auto masterExpr = sgs->to_signals[masterSignalIndex]; fwriter.Append(" _m->%s = (%s) ( %s );", masterSname, PrintType((int)masterSignal->TypeRo).c_str(), masterExpr.c_str()); }