From 9e715ee32c97ee3397339c3e57c4ae279fdb33fb Mon Sep 17 00:00:00 2001 From: 3minbe Date: Wed, 22 Jan 2025 09:03:21 +0900 Subject: [PATCH 1/7] =?UTF-8?q?=EC=B0=BD=20=ED=81=AC=EA=B8=B0=20=EC=A1=B0?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DBC_Converter.py | 2 +- settings.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DBC_Converter.py b/DBC_Converter.py index d8467e4..a13b87b 100644 --- a/DBC_Converter.py +++ b/DBC_Converter.py @@ -421,7 +421,7 @@ class MainView(QtWidgets.QMainWindow): elif size == "large": self.resize(1200, 1000) elif size == "default": - self.resize(1000, 600) + self.resize(1250, 600) elif size == "auto": self.adjustSize() diff --git a/settings.json b/settings.json index df662c3..656cc45 100644 --- a/settings.json +++ b/settings.json @@ -2,6 +2,6 @@ "theme": "light", "default_save_path": "C:/Users/MSI/Desktop", "file_paths": [], - "last_opened_dir": "C:/Users/MSI/SynologyDrive/3min_be/한자연/!사업/초안전/#Debug/DBC", + "last_opened_dir": "C:/Users/MSI/SynologyDrive/3min_be/한자연/!과제/초안전/#Debug/DBC", "channel_info": {} } \ No newline at end of file From 4178fd686a35e9b4c11bf0675a8b123576c5eb38 Mon Sep 17 00:00:00 2001 From: 3minbe Date: Wed, 22 Jan 2025 09:36:29 +0900 Subject: [PATCH 2/7] =?UTF-8?q?DBC=20=ED=8C=8C=EC=9D=BC=20=EB=A1=9C?= =?UTF-8?q?=EB=93=9C=20=EC=8B=9C=20=EC=9D=B8=EC=9E=90=20=EC=B2=98=EB=A6=AC?= =?UTF-8?q?=20=EB=B0=8F=20=EC=B6=9C=EB=A0=A5=20=ED=98=95=EC=8B=9D=20?= =?UTF-8?q?=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Data_Parsing.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/Data_Parsing.py b/Data_Parsing.py index 8e095af..0483a6a 100644 --- a/Data_Parsing.py +++ b/Data_Parsing.py @@ -1,4 +1,4 @@ -import re +import re, sys def load_dbc_file(file_path): try: @@ -59,13 +59,11 @@ def load_dbc_file(file_path): return None if __name__ == "__main__": - file_path = 'C:/Users/MSI/Desktop/python/motorola_tx/MOTOROLA_V2.dbc' + file_path = sys.argv[1] messages = load_dbc_file(file_path) - print(messages) - print("\n") - - # if messages: - # for message_name, message_info in messages.items(): - # print(f"[INFO] Message: {message_name}, Info: {message_info['id']}, {message_info['dlc']}, {message_info['tx_ecu_name']}") - # for signal in message_info['signals']: - # print(f" Signal: {signal}") \ No newline at end of file + + if messages: + for message_name, message_info in messages.items(): + print(f"[INFO] Message: {message_name}, Info: {message_info['ID']}, {message_info['DLC']}, {message_info['TX ECU name']}") + for signal in message_info['Signals']: + print(f" └ Signal: {signal}") \ No newline at end of file From 42707cd97e02b5202635d03bd6ed8c033f78559e Mon Sep 17 00:00:00 2001 From: 3minbe Date: Wed, 5 Feb 2025 09:36:06 +0900 Subject: [PATCH 3/7] =?UTF-8?q?DBC=20=ED=8C=8C=EC=9D=BC=20=EB=A1=9C?= =?UTF-8?q?=EB=93=9C=20=EA=B8=B0=EB=8A=A5=EC=9D=84=20=EC=9C=84=ED=95=9C=20?= =?UTF-8?q?=EC=83=88=EB=A1=9C=EC=9A=B4=20=ED=8C=8C=EC=9D=BC=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=EB=B0=8F=20=EC=8B=A0=ED=98=B8=20=ED=8C=A8=ED=84=B4?= =?UTF-8?q?=EC=97=90=20RX=20ECU=20=EC=9D=B4=EB=A6=84=20=ED=95=84=EB=93=9C?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DBC_Converter_RX.py | 0 DBC_Converter_TX.py | 0 DBC_to_C_RX.py | 69 ++++++++--------------- Data_Parsing.py | 9 ++- __pycache__/Data_Parsing.cpython-313.pyc | Bin 0 -> 3296 bytes 5 files changed, 31 insertions(+), 47 deletions(-) create mode 100644 DBC_Converter_RX.py create mode 100644 DBC_Converter_TX.py create mode 100644 __pycache__/Data_Parsing.cpython-313.pyc diff --git a/DBC_Converter_RX.py b/DBC_Converter_RX.py new file mode 100644 index 0000000..e69de29 diff --git a/DBC_Converter_TX.py b/DBC_Converter_TX.py new file mode 100644 index 0000000..e69de29 diff --git a/DBC_to_C_RX.py b/DBC_to_C_RX.py index 154c2be..753afbb 100644 --- a/DBC_to_C_RX.py +++ b/DBC_to_C_RX.py @@ -3,6 +3,7 @@ import sys import cantools from datetime import datetime import json +import os def parse_dbc_file(file_path): signals = [] @@ -95,12 +96,12 @@ def parse_dbc_file(file_path): return signals -def generate_vcu_rx_function_with_factors(dbc_path, output_file, channel_info): +def generate_vcu_rx_function_with_factors(dbc_path, output_file): # Load the DBC file db = cantools.database.load_file(dbc_path) # Initialize the header of the C file - c_file_content = f""" + c_file_content = """ #include "can.h" // Declare Factors and Offsets for signals @@ -130,10 +131,9 @@ def generate_vcu_rx_function_with_factors(dbc_path, output_file, channel_info): # Check if "VCU" is in the receivers list if "VCU" in message.receivers: # Define the temporary struct - channel = channel_info.get(str(message.frame_id), "CH0") # 기본 채널 설정 - temp_struct_name = f"{channel}_MV1_0x{message.frame_id:X}_temp" + temp_struct_name = f"CH0_MV1_0x{message.frame_id:X}_temp" c_file_content += f""" -void Receive_{message.name}_{channel}_0x{message.frame_id:X}(void) +void Receive_{message.name}_CH0_0x{message.frame_id:X}(void) {{ struct {{ """ @@ -153,16 +153,16 @@ void Receive_{message.name}_{channel}_0x{message.frame_id:X}(void) start_byte = signal.start // 8 start_bit = signal.start % 8 signal_length = signal.length - shift_expr = f"(CAN_ch[{channel}].rx.buf[{start_byte}] >> shift{start_bit})" + shift_expr = f"(CAN_ch[0].rx.buf[{start_byte}] >> shift{start_bit})" if signal_length > 8: # Handle multi-byte signals multi_byte_expr = [] for i in range((signal_length + 7) // 8): byte_shift = i * 8 if i == 0: - multi_byte_expr.append(f"(CAN_ch[{channel}].rx.buf[{start_byte + i}] >> shift{start_bit})") + multi_byte_expr.append(f"(CAN_ch[0].rx.buf[{start_byte + i}] >> shift{start_bit})") else: - multi_byte_expr.append(f"(CAN_ch[{channel}].rx.buf[{start_byte + i}] << shift{byte_shift})") + multi_byte_expr.append(f"(CAN_ch[0].rx.buf[{start_byte + i}] << shift{byte_shift})") shift_expr = " | ".join(multi_byte_expr) c_file_content += f" {temp_struct_name}.{signal.name}_temp = ({shift_expr}) & _{signal_length}bit;\n" @@ -171,14 +171,14 @@ void Receive_{message.name}_{channel}_0x{message.frame_id:X}(void) # Assign to final ECU variables for signal in message.signals: factor_name = f"Factor_{str(signal.scale).replace('.', '_')}" - offset_name = f"Offset_m_{abs(signal.offset)::.0f}" + offset_name = f"Offset_m_{abs(signal.offset):.0f}" factor = f" * {factor_name}" if signal.scale != 1 else "" offset = f" + {offset_name}" if signal.offset != 0 else "" temp_var = f"{temp_struct_name}.{signal.name}_temp" if signal.is_signed: - c_file_content += f" VCU.RX.{channel}_{message.name}_0x{message.frame_id:X}.{signal.name} = ({temp_var}{factor}){offset};\n" + c_file_content += f" ECU3.RX.CH0_{message.name}_0x{message.frame_id:X}.{signal.name} = ({temp_var}{factor}){offset};\n" else: - c_file_content += f" VCU.RX.{channel}_{message.name}_0x{message.frame_id:X}.{signal.name} = {temp_var}{factor}{offset};\n" + c_file_content += f" ECU3.RX.CH0_{message.name}_0x{message.frame_id:X}.{signal.name} = {temp_var}{factor}{offset};\n" c_file_content += "}\n" @@ -188,7 +188,7 @@ void Receive_{message.name}_{channel}_0x{message.frame_id:X}(void) print(f"Generated RX function C file with Factors and Offsets: {output_file}") -def generate_input_functions(signals, output_file, channel_info): +def generate_input_functions(signals, output_file): if not signals: print("[WARNING] No signals to generate Input functions for.") return @@ -196,16 +196,15 @@ def generate_input_functions(signals, output_file, channel_info): with open(output_file, 'w') as f: for message in signals: hex_id = f"0x{int(message['id']):X}" - channel = channel_info.get(str(message['id']), "CH0") - function_name = f"void Input_Data_Set_{message['name']}_{channel}_{hex_id}(void)" + function_name = f"void Input_Data_Set_{message['name']}_CH0_{hex_id}(void)" f.write(f"{function_name}\n{{\n") for signal in message["signals"]: - f.write(f" GV_{signal['name']} = VCU.RX.{channel}_RX_{message['name']}_{hex_id}.{signal['name']};\n") + f.write(f" GV_{signal['name']} = ECU3.RX.CH0_RX_{message['name']}_{hex_id}.{signal['name']};\n") f.write("}\n\n") print(f"[INFO] Input functions written to {output_file}") -def generate_structs(signals, output_file, channel_info): +def generate_structs(signals, output_file): if not signals: print("[WARNING] No signals to generate structs for.") return @@ -217,19 +216,18 @@ def generate_structs(signals, output_file, channel_info): for message in signals: hex_id = f"0x{int(message['id']):X}" - channel = channel_info.get(str(message['id']), "CH0") f.write(f"typedef struct\n{{\n") for signal in message["signals"]: if signal["size"] <= 32: f.write(f" uint32_t {signal['name']} : {signal['size']};\n") else: f.write(f" float {signal['name']};\n") - f.write(f"}} {channel}_RX_{message['name']}_{hex_id};\n\n") + f.write(f"}} CH0_RX_{message['name']}_{hex_id};\n\n") f.write("#endif // GENERATED_STRUCTS_H\n") print(f"[INFO] Structs written to {output_file}") -def generate_globals(signals, output_file, header_file, channel_info): +def generate_globals(signals, output_file, header_file): if not signals: print("[WARNING] No signals to generate globals for.") return @@ -238,7 +236,6 @@ def generate_globals(signals, output_file, header_file, channel_info): f.write("#include \n") for message in signals: - channel = channel_info.get(str(message['id']), "CH0") for signal in message["signals"]: if signal["size"] > 32: f.write(f"float GV_{signal['name']} = 0.0f;\n") @@ -250,7 +247,6 @@ def generate_globals(signals, output_file, header_file, channel_info): f.write("#define GENERATED_GLOBALS_H\n\n") f.write("#include \n\n") for message in signals: - channel = channel_info.get(str(message['id']), "CH0") for signal in message["signals"]: if signal["size"] > 32: f.write(f"extern float GV_{signal['name']};\n") @@ -260,17 +256,16 @@ def generate_globals(signals, output_file, header_file, channel_info): print(f"[INFO] Globals and extern declarations written to {output_file} and {header_file}") -def generate_initialization(signals, output_file, channel_info): +def generate_initialization(signals, output_file): if not signals: print("[WARNING] No signals to generate initialization for.") return with open(output_file, 'w') as f: - f.write("void VCU_Data_Init(void)\n{\n") + f.write("void ECU3_Data_Init(void)\n{\n") for message in signals: hex_id = f"0x{int(message['id']):X}" - channel = channel_info.get(str(message['id']), "CH0") - struct_prefix = f"VCU.RX.{channel}_RX_{message['name']}_{hex_id}" + struct_prefix = f"ECU3.RX.CH0_RX_{message['name']}_{hex_id}" for signal in message["signals"]: if signal["offset"] != 0.0: if signal["size"] <= 32: @@ -290,20 +285,6 @@ def generate_initialization(signals, output_file, channel_info): if __name__ == "__main__": dbc_file_path = sys.argv[1] output_dir = sys.argv[2] - channel_info_path = sys.argv[3] - - with open(channel_info_path, 'r', encoding='cp1252') as f: - try: - channel_info = json.load(f) - # Convert channel info to int - for key in channel_info: - channel_info[key] = int(channel_info[key].replace("CH", "")) - except json.JSONDecodeError as e: - print(f"[ERROR] Error decoding JSON: {e}") - sys.exit(1) - except Exception as e: - print(f"[ERROR] Error reading channel info file: {e}") - sys.exit(1) output_c_file = f"{output_dir}/generated_receive.c" output_input_file = f"{output_dir}/generated_input.c" @@ -313,8 +294,8 @@ if __name__ == "__main__": output_initialization_file = f"{output_dir}/generated_init.c" signals = parse_dbc_file(dbc_file_path) - generate_vcu_rx_function_with_factors(dbc_file_path, output_c_file, channel_info) - generate_input_functions(signals, output_input_file, channel_info) - generate_structs(signals, output_structs_file, channel_info) - generate_globals(signals, output_globals_file, output_globals_header, channel_info) - generate_initialization(signals, output_initialization_file, channel_info) \ No newline at end of file + generate_vcu_rx_function_with_factors(dbc_file_path, output_c_file) + generate_input_functions(signals, output_input_file) + generate_structs(signals, output_structs_file) + generate_globals(signals, output_globals_file, output_globals_header) + generate_initialization(signals, output_initialization_file) \ No newline at end of file diff --git a/Data_Parsing.py b/Data_Parsing.py index 0483a6a..5d10fbc 100644 --- a/Data_Parsing.py +++ b/Data_Parsing.py @@ -8,7 +8,7 @@ def load_dbc_file(file_path): # 메시지와 시그널을 추출하는 정규 표현식 message_pattern = re.compile(r'BO_\s+(\d+)\s+(\w+)\s*:\s*(\d+)\s+(\w+)') - signal_pattern = re.compile(r'SG_\s+(\w+)\s*:\s*(\d+)\|(\d+)@(\d+)\+\s*\(([^,]+),\s*([^)]+)\)') + signal_pattern = re.compile(r'SG_\s+(\w+)\s*:\s*(\d+)\|(\d+)@(\d+)\+\s*\(([^,]+),\s*([^)]+)\)\s*\[[^\]]+\]\s*\"[^\"]*\"\s+(\w+)') # 메시지와 시그널 매칭 messages = {} @@ -43,13 +43,15 @@ def load_dbc_file(file_path): byte_order = int(signal_match.group(4)) factor = float(signal_match.group(5)) offset = float(signal_match.group(6)) + rx_ecu_name = signal_match.group(7) messages[current_message]["Signals"].append({ "Signal name": signal_name, "msb": msb, "Length": length, "Byte order": byte_order, "Factor": factor, - "Offset": offset + "Offset": offset, + "RX ECU name": rx_ecu_name }) return messages @@ -59,7 +61,8 @@ def load_dbc_file(file_path): return None if __name__ == "__main__": - file_path = sys.argv[1] + # file_path = sys.argv[1] + file_path = 'C:/Users/MSI/SynologyDrive/3min_be/한자연/!과제/초안전/#Debug/DBC/241007_primary_HyperSafe4.dbc' messages = load_dbc_file(file_path) if messages: diff --git a/__pycache__/Data_Parsing.cpython-313.pyc b/__pycache__/Data_Parsing.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6eb6682ddf9128d211a449c920759b8aca9daa74 GIT binary patch literal 3296 zcmai0O>7&-6`tMYpZG74qHXGjOUjl+{ZSI7$flJhHfdW*EXn426Bk^WSdmL=8*)kP zQm!TRU=%IDQ^6oHECfN#-t1EeB!?V&Y74|i5;RPDD6jh-Da%8|ja_J1orEJ%( zM&iCVZ@%|4@6Ej31CvP);5hU3ACiAI0PqhqQHHU_9Q+G1cK`(_>_Z?nDJEhR?gS#v z5EK!(4gkvnK&eC(gL?p@n#G#BqMA_;x6H6B05IyXsWp9x%(i$NSO@^Hfde3FMIF=O z0hF52ngOL@bd**NQIOX`zT+ic-{k!|#U}|M!hodEo*CNGH!K+$y&3rNL)4NL00SVw z(tML9G4$s(?V@OwW33&a34{Saz~8|&70N_Eh_qK}n3Y)=F&a1!Fd7RZx+JESlJ?T7{9NGzf3PEbt(K}`Wc^D!RoIJBp5N<21j30wFr0D_j* zhS4rx8ww7sD|L*+h>_(b7XUQzrh3xab{sldr|7Xf01=DgfYyaO75~lN;$y>ByfW<(5@1^?FpO&F4!#)ZuxKT5-yOy+#upmY-<5~9Nr^GXyxn2C>i8}yfmjs)QE71Zo@N8HwERLY6^BnMmXYv${IUtfGkrPCToSDsFdChm-NiTQV`} zzrKq)+%9TtyQp7zRWiO9l8Mme;E#rD*U1Y(niSYHCu=D_DX=MN7ZqR^HMCtVe2B0O z1Fv?=&|Gd}iL|sPYc6v_GPk~^Kfjsd$cz~0L|Jo@jpZ_st|Sr?m)kOg4?S#oA{WBp zmGCNgk>yidoXlm&EGtSJ89E;%6HpW&y(U?e$#R0M5;-<5<06bJmPu#fqO6y)DL$9t z1x}LHQcmQvvO3M?V(T)&3prVx6f+x8lt^XRoUCE9&`ezJxNs}RWpjK+kkwfc;=IS? z4&*DEWpnGY3bDwAkmH~YOPZ4;HrZIraiSobrAAT^xG~qY0FrEpZHOY&iMAxN3PmQH z6bsGB^l>i6r`c4LkIR~M?iQj(1=2`65l_WrL+)0Ti)}<35@X9}(}JNjLrY>8tc9#e zHS#X&*I?eGt-L2%dCxTRE*r#`3}T#g3@Vau9`gBMfT1N$l$a%IkqKpD8)>*NiTOAq zenMs07{?^}90O|<4Q7O!oCp)agxDM#y#kBJ3(1M>rfh;qk4NKcu_#KY2tNfHFI}k% z9=_XPA3vkE@0dCZ-filU$z8lwcR26zpYor5lE3tV0A|l~J?QDXH}b_u`P53)c_nYz zIni^^`Gs>IfK!Y30RYYq@Vt3n1MH5xuI}v5Tb|l`YWBg3eXwR9&WGx@V|N3e20ok5 zhrY8Nt9u3umM7NZPkTpey;GImsnW@6?_7TAJ4^3QA6e|Hxo0ZwnbOs&d#>7dx}dN3 z^lks*zOCFhUOq8V(9~UHHP>{-HC>vjx@HT;9mk37@tSkI;vB!vR-Kbo$5er+_m9^4 zrz-tZC3m%dreLUhCJL6PPO{$9UmuvLyWGz@)Z<+RUDfJ+VFX?7f~)Qtuetmcm%kLM zy3Q1g-`iY;d8k(N%v3xm8qZwe!yRYecB?*}?}qeV*ccZD6)CFk51)1E;HfXCU%T!q*+w z?Y$NI_INW%E0abaOiv+fVyyxbUNN7M_n^8yD2z zcb%8~#J%7+WdCY)pyxD&7{ zzjr6USNx4{AjGY0Bz^FJ`=)26CMV~juu-I0aWlHGndL-^O>i?4@Mv#YBa6!yS60cT zW|IhzTe>lFQAlJ0q=-Jiw(v1hL|@(_`cQ5(&JEN(N%HTXe@-_0Cv0&B5x#AJOh}tj z=PJ5IPuiFd3*7RrFZ-1Rm;%rg@0--^^xg6 zPCS@+JQAoF2lJP=$DSBF%XWCoip!7B?R`rwW=U*6wX{@n&(o?C?FdP96}T XXZi;<7(KgB0G)N;08~!#JdFFlCcf@q literal 0 HcmV?d00001 From f372bf5bcacd54f7e7b544dd851624eca866f9c5 Mon Sep 17 00:00:00 2001 From: 3minbe Date: Thu, 13 Feb 2025 16:01:38 +0900 Subject: [PATCH 4/7] =?UTF-8?q?DBC=20=EB=B3=80=ED=99=98=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B0=9C=EC=84=A0:=20=EA=B3=B5=ED=86=B5=20?= =?UTF-8?q?=EC=B6=9C=EB=A0=A5=20=EB=94=94=EB=A0=89=ED=86=A0=EB=A6=AC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EB=B3=80=ED=99=98=20=EC=8A=A4?= =?UTF-8?q?=ED=81=AC=EB=A6=BD=ED=8A=B8=20=EC=9D=B4=EB=A6=84=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DBC_Converter.py | 7 +- DBC_Converter_Common.py | 77 +++++ ...arsing.py => DBC_Converter_Data_Parsing.py | 13 +- DBC_Converter_RX.py | 212 ++++++++++++ DBC_Converter_TX.py | 186 ++++++++++ DBC_to_C_RX.py | 301 ---------------- DBC_to_C_TX.py | 323 ------------------ ...DBC_Converter_Data_Parsing.cpython-313.pyc | Bin 0 -> 3324 bytes __pycache__/Data_Parsing.cpython-313.pyc | Bin 3296 -> 3373 bytes 9 files changed, 487 insertions(+), 632 deletions(-) create mode 100644 DBC_Converter_Common.py rename Data_Parsing.py => DBC_Converter_Data_Parsing.py (86%) delete mode 100644 DBC_to_C_RX.py delete mode 100644 DBC_to_C_TX.py create mode 100644 __pycache__/DBC_Converter_Data_Parsing.cpython-313.pyc diff --git a/DBC_Converter.py b/DBC_Converter.py index a13b87b..fc32371 100644 --- a/DBC_Converter.py +++ b/DBC_Converter.py @@ -489,15 +489,18 @@ class MainView(QtWidgets.QMainWindow): file_name = os.path.splitext(os.path.basename(file_path))[0] rx_output_dir = os.path.join(base_output_dir, file_name, "RX") tx_output_dir = os.path.join(base_output_dir, file_name, "TX") + common_output_dir = os.path.join(base_output_dir, file_name, "Common") dbc_output_dir = os.path.join(base_output_dir, "#DBC") # DBC 파일 저장 경로 설정 os.makedirs(rx_output_dir, exist_ok=True) os.makedirs(tx_output_dir, exist_ok=True) + os.makedirs(common_output_dir, exist_ok=True) os.makedirs(dbc_output_dir, exist_ok=True) # DBC 파일 저장 경로 생성 channel_info = self.settings.get("channel_info", {}).get(os.path.basename(file_path), "CH0") try: shutil.copy(file_path, dbc_output_dir) # DBC 파일 복사 - subprocess.run(["python", "DBC_to_C_RX.py", file_path, rx_output_dir, json.dumps({os.path.basename(file_path): channel_info})], check=True) - subprocess.run(["python", "DBC_to_C_TX.py", file_path, tx_output_dir, json.dumps({os.path.basename(file_path): channel_info})], check=True) + subprocess.run(["python", "DBC_Converter_RX.py", file_path, rx_output_dir, json.dumps({os.path.basename(file_path): channel_info})], check=True) + subprocess.run(["python", "DBC_Converter_TX.py", file_path, tx_output_dir, json.dumps({os.path.basename(file_path): channel_info})], check=True) + subprocess.run(["python", "DBC_Converter_Common.py", file_path, common_output_dir, json.dumps({os.path.basename(file_path): channel_info})], check=True) self.updateAlertText(f"변환 성공", [file_path]) except subprocess.CalledProcessError as e: self.updateAlertText(f"변환 실패: {e}", [file_path]) diff --git a/DBC_Converter_Common.py b/DBC_Converter_Common.py new file mode 100644 index 0000000..fdf3301 --- /dev/null +++ b/DBC_Converter_Common.py @@ -0,0 +1,77 @@ +import os +import sys +from DBC_Converter_Data_Parsing import load_dbc_file + +def generate_structs(signals, output_file): + if not signals: + print("[WARNING] No signals to generate structs for.") + return + + # Ensure the output directory exists + output_dir = os.path.dirname(output_file) + if not os.path.exists(output_dir): + os.makedirs(output_dir) + + with open(output_file, 'w') as f: + f.write("#ifndef GENERATED_STRUCTS_H\n") + f.write("#define GENERATED_STRUCTS_H\n\n") + f.write("#include \n\n") + + tx_structs = {} + rx_structs = {} + + for message_name, message_info in signals.items(): + hex_id = message_info["ID"] + + if message_info["TX ECU name"] == "VCU": + struct_name = f"{message_name}_{hex_id}" + tx_structs[struct_name] = [] + for signal in message_info["Signals"]: + if signal["Length"] <= 32: + tx_structs[struct_name].append(f" uint32_t {signal['Signal name']} : {signal['Length']};") + else: + tx_structs[struct_name].append(f" float {signal['Signal name']};") + + for signal in message_info["Signals"]: + if signal["RX ECU name"] == "VCU": + struct_name = f"{message_name}_{hex_id}" + if struct_name not in rx_structs: + rx_structs[struct_name] = [] + if signal["Length"] <= 32: + rx_structs[struct_name].append(f" uint32_t {signal['Signal name']} : {signal['Length']};") + else: + rx_structs[struct_name].append(f" float {signal['Signal name']};") + + f.write("typedef struct {\n") + f.write(" typedef struct {\n") + for struct_name, fields in tx_structs.items(): + f.write(f" typedef struct {{\n") + for field in fields: + f.write(f" {field}\n") + f.write(f" }} {struct_name};\n\n") + f.write(" } TX;\n\n") + + f.write(" typedef struct {\n") + for struct_name, fields in rx_structs.items(): + f.write(f" typedef struct {{\n") + for field in fields: + f.write(f" {field}\n") + f.write(f" }} {struct_name};\n\n") + f.write(" } RX;\n") + f.write("} VCU;\n\n") + + f.write("#endif // GENERATED_STRUCTS_H\n") + print(f"[INFO] Structs written to {output_file}") + +if __name__ == "__main__": + dbc_file_path = sys.argv[1] + output_dir = sys.argv[2] + + output_structs_file = f"{output_dir}/generated_structs.h" + + signals = load_dbc_file(dbc_file_path) + if signals is None: + print(f"[ERROR] Failed to load DBC file: {dbc_file_path}") + sys.exit(1) + + generate_structs(signals, output_structs_file) \ No newline at end of file diff --git a/Data_Parsing.py b/DBC_Converter_Data_Parsing.py similarity index 86% rename from Data_Parsing.py rename to DBC_Converter_Data_Parsing.py index 5d10fbc..79b02ee 100644 --- a/Data_Parsing.py +++ b/DBC_Converter_Data_Parsing.py @@ -8,7 +8,7 @@ def load_dbc_file(file_path): # 메시지와 시그널을 추출하는 정규 표현식 message_pattern = re.compile(r'BO_\s+(\d+)\s+(\w+)\s*:\s*(\d+)\s+(\w+)') - signal_pattern = re.compile(r'SG_\s+(\w+)\s*:\s*(\d+)\|(\d+)@(\d+)\+\s*\(([^,]+),\s*([^)]+)\)\s*\[[^\]]+\]\s*\"[^\"]*\"\s+(\w+)') + signal_pattern = re.compile(r'SG_\s+(\w+)\s*:\s*(\d+)\|(\d+)@(\d+)([+-])\s*\(([^,]+),\s*([^)]+)\)\s*\[[^\]]+\]\s*\"[^\"]*\"\s+(\w+)') # 메시지와 시그널 매칭 messages = {} @@ -41,14 +41,16 @@ def load_dbc_file(file_path): msb = int(signal_match.group(2)) length = int(signal_match.group(3)) byte_order = int(signal_match.group(4)) - factor = float(signal_match.group(5)) - offset = float(signal_match.group(6)) - rx_ecu_name = signal_match.group(7) + sign = signal_match.group(5) + factor = float(signal_match.group(6)) + offset = float(signal_match.group(7)) + rx_ecu_name = signal_match.group(8) messages[current_message]["Signals"].append({ "Signal name": signal_name, "msb": msb, "Length": length, "Byte order": byte_order, + "Sign": sign, "Factor": factor, "Offset": offset, "RX ECU name": rx_ecu_name @@ -61,8 +63,7 @@ def load_dbc_file(file_path): return None if __name__ == "__main__": - # file_path = sys.argv[1] - file_path = 'C:/Users/MSI/SynologyDrive/3min_be/한자연/!과제/초안전/#Debug/DBC/241007_primary_HyperSafe4.dbc' + file_path = sys.argv[1] messages = load_dbc_file(file_path) if messages: diff --git a/DBC_Converter_RX.py b/DBC_Converter_RX.py index e69de29..2037220 100644 --- a/DBC_Converter_RX.py +++ b/DBC_Converter_RX.py @@ -0,0 +1,212 @@ +import sys +from DBC_Converter_Data_Parsing import load_dbc_file + + +#============================== Generate Globals ==============================# +def generate_globals(signals, C_file, header_file): + if not signals: + print("[WARNING] No signals to generate globals for.") + return + + with open(C_file, 'w') as f: + f.write("#include \n") + + for message_name, message_info in signals.items(): + for signal in message_info["Signals"]: + if signal["Length"] > 32: + f.write(f"float GV_{signal['Signal name']} = 0.0f;\n") + else: + f.write(f"uint32_t GV_{signal['Signal name']} = 0;\n") + + with open(header_file, 'w') as f: + f.write("#ifndef GENERATED_GLOBALS_H\n") + f.write("#define GENERATED_GLOBALS_H\n\n") + f.write("#include \n\n") + for message_name, message_info in signals.items(): + for signal in message_info["Signals"]: + if signal["Length"] > 32: + f.write(f"extern float GV_{signal['Signal name']};\n") + else: + f.write(f"extern uint32_t GV_{signal['Signal name']};\n") + f.write("\n#endif // GENERATED_GLOBALS_H\n") + print(f"[INFO] Globals and extern declarations written to {C_file} and {header_file}") + + +#============================== Generate VCU RX Function ==============================# +def generate_vcu_rx_function_with_factors(signals, output_file): + if not signals: + print("[ERROR] No signals to generate VCU RX functions for.") + return + + # Initialize the header of the C file + c_file_content = """ +#include "can.h" + +// Declare Factors and Offsets for signals +""" + + # Collect unique Factors and Offsets + factors_offsets = {} + for message_name, message_info in signals.items(): + for signal in message_info["Signals"]: + factor_name = f"Factor_{str(signal['Factor']).replace('.', '_')}" + offset_name = f"Offset_m_{abs(signal['Offset']):.0f}" + if signal['Factor'] != 1: + factors_offsets[factor_name] = signal['Factor'] + if signal['Offset'] != 0: + factors_offsets[offset_name] = signal['Offset'] + + # Add Factor and Offset variable declarations + for name, value in factors_offsets.items(): + c_file_content += f"const float {name} = {value};\n" + + # Add a newline for separation + c_file_content += "\n" + + # Iterate through all messages in the signals + for message_name, message_info in signals.items(): + # Define the temporary struct + temp_struct_name = f"{message_name}_temp" + + # Check if any signal in the message has RX ECU name as VCU + has_vcu_signal = any(signal["RX ECU name"] == "VCU" for signal in message_info["Signals"]) + if not has_vcu_signal: + continue # Skip this message if no signal has RX ECU name as VCU + + c_file_content += f""" +void {message_name}_RX_{message_info['ID']}(void) +{{ + struct {{ +""" + + # Add temporary variables to the struct + for signal in message_info["Signals"]: + if signal["RX ECU name"] != "VCU": + continue # RX ECU name이 VCU가 아닌 경우 건너뜁니다. + if signal["Sign"] == "-": + signal_type = "signed int" + elif signal["Sign"] == "+": + signal_type = "unsigned int" + + c_file_content += f" {signal_type} {signal['Signal name']}_temp : {signal['Length']};\n" + + c_file_content += f" }} {temp_struct_name};\n\n" + + # Add temp assignments + for signal in message_info["Signals"]: + if signal["RX ECU name"] != "VCU": + continue # RX ECU name이 VCU가 아닌 경우 건너뜁니다. + start_byte = signal["msb"] // 8 + start_bit = signal["msb"] % 8 + signal_length = signal["Length"] + if signal["Byte order"] == 0: # Motorola (Big Endian) + shift_expr = f"(CAN_ch[0].rx.buf[{start_byte}] >> shift{start_bit})" + if signal_length > 8: + # Handle multi-byte signals + multi_byte_expr = [] + for i in range((signal_length + 7) // 8): + byte_shift = i * 8 + if i == 0: + multi_byte_expr.append(f"(CAN_ch[0].rx.buf[{start_byte + i}] >> shift{start_bit})") + else: + multi_byte_expr.append(f"(CAN_ch[0].rx.buf[{start_byte + i}] << shift{byte_shift})") + shift_expr = " | ".join(multi_byte_expr) + else: # Intel (Little Endian) + shift_expr = f"(CAN_ch[0].rx.buf[{start_byte}] >> shift{start_bit})" + if signal_length > 8: + # Handle multi-byte signals + multi_byte_expr = [] + for i in range((signal_length + 7) // 8): + byte_shift = i * 8 + if i == 0: + multi_byte_expr.append(f"(CAN_ch[0].rx.buf[{start_byte + i}] >> shift{start_bit})") + else: + multi_byte_expr.append(f"(CAN_ch[0].rx.buf[{start_byte + i}] << shift{byte_shift})") + shift_expr = " | ".join(multi_byte_expr) + c_file_content += f" {temp_struct_name}.{signal['Signal name']}_temp = ({shift_expr}) & _{signal_length}bit;\n" + + c_file_content += "\n" + + # Assign to final ECU variables + for signal in message_info["Signals"]: + if signal["RX ECU name"] != "VCU": + continue # RX ECU name이 VCU가 아닌 경우 건너뜁니다. + factor_name = f"Factor_{str(signal['Factor']).replace('.', '_')}" + offset_name = f"Offset_m_{abs(signal['Offset']):.0f}" + factor = f" * {factor_name}" if signal['Factor'] != 1 else "" + offset = f" + {offset_name}" if signal['Offset'] != 0 else "" + temp_var = f"{temp_struct_name}.{signal['Signal name']}_temp" + if signal["Byte order"] == 1: + c_file_content += f" VCU.RX.{message_name}_{message_info['ID']}.{signal['Signal name']} = ({temp_var}{factor}){offset};\n" + else: + c_file_content += f" VCU.RX.{message_name}_{message_info['ID']}.{signal['Signal name']} = {temp_var}{factor}{offset};\n" + + c_file_content += "}\n" + + # Write the generated code to a single C file + with open(output_file, "w") as c_file: + c_file.write(c_file_content) + print(f"Generated RX function C file with Factors and Offsets: {output_file}") + + +#============================== Generate Input Function ==============================# +def generate_input_functions(signals, output_file): + if not signals: + print("[WARNING] No signals to generate Input functions for.") + return + + with open(output_file, 'w') as f: + for message_name, message_info in signals.items(): + hex_id = message_info["ID"] + function_name = f"void Input_Data_Set_{message_name}_CH0_{hex_id}(void)" + f.write(f"{function_name}\n{{\n") + for signal in message_info["Signals"]: + f.write(f" GV_{signal['Signal name']} = VCU.RX.CH0_RX_{message_name}_{hex_id}.{signal['Signal name']};\n") + f.write("}\n\n") + print(f"[INFO] Input functions written to {output_file}") + + +#============================== Generate Initialization ==============================# +def generate_initialization(signals, output_file): + if not signals: + print("[WARNING] No signals to generate initialization for.") + return + + with open(output_file, 'w') as f: + f.write("void VCU_Data_Init(void)\n{\n") + for message_name, message_info in signals.items(): + hex_id = message_info["ID"] + struct_prefix = f"VCU.RX.CH0_RX_{message_name}_{hex_id}" + for signal in message_info["Signals"]: + if signal["Offset"] != 0.0: + if signal["Length"] <= 32: + f.write(f" {struct_prefix}.{signal['Signal name']} = {signal['Offset']};\n") + else: + f.write(f" {struct_prefix}.{signal['Signal name']} = {signal['Offset']}f;\n") + else: + if signal["Length"] <= 32: + f.write(f" {struct_prefix}.{signal['Signal name']} = 0;\n") + else: + f.write(f" {struct_prefix}.{signal['Signal name']} = 0.0f;\n") + f.write("\n") + f.write("}\n") + print(f"[INFO] Initialization function written to {output_file}") + + +#============================== Main ==============================# +if __name__ == "__main__": + dbc_file_path = sys.argv[1] + output_dir = sys.argv[2] + + output_globals_C_file = f"{output_dir}/generated_globals.c" + output_globals_header_file = f"{output_dir}/generated_globals.h" + output_c_file = f"{output_dir}/generated_receive.c" + output_input_file = f"{output_dir}/generated_input.c" + output_initialization_file = f"{output_dir}/generated_init.c" + + signals = load_dbc_file(dbc_file_path) + + generate_globals(signals, output_globals_C_file, output_globals_header_file) + generate_vcu_rx_function_with_factors(signals, output_c_file) + generate_input_functions(signals, output_input_file) + generate_initialization(signals, output_initialization_file) \ No newline at end of file diff --git a/DBC_Converter_TX.py b/DBC_Converter_TX.py index e69de29..54ae71c 100644 --- a/DBC_Converter_TX.py +++ b/DBC_Converter_TX.py @@ -0,0 +1,186 @@ +import sys +from DBC_Converter_Data_Parsing import load_dbc_file + + + +#============================== Generate TX Globals ==============================# +def generate_tx_globals(signals, output_file, header_file): + if not signals: + print("[WARNING] No signals to generate TX globals for.") + return + + with open(output_file, 'w') as f: + for message_name, message_info in signals.items(): + for signal in message_info["Signals"]: + if signal["Length"] > 32: + f.write(f"float GV_{signal['Signal name']} = 0.0f;\n") + else: + f.write(f"uint32_t GV_{signal['Signal name']} = 0;\n") + + with open(header_file, 'w') as f: + f.write("#ifndef GENERATED_TX_GLOBALS_H\n") + f.write("#define GENERATED_TX_GLOBALS_H\n\n") + f.write("#include \n\n") + for message_name, message_info in signals.items(): + for signal in message_info["Signals"]: + if signal["Length"] > 32: + f.write(f"extern float GV_{signal['Signal name']};\n") + else: + f.write(f"extern uint32_t GV_{signal['Signal name']};\n") + f.write("\n#endif // GENERATED_TX_GLOBALS_H\n") + print(f"[INFO] TX globals written to {output_file} and {header_file}") + + +#============================== Generate TX Functions ==============================# +def generate_tx_functions(signals, output_file): + if not signals: + print("[WARNING] No signals to generate TX functions for.") + return + + with open(output_file, 'w') as f: + for message_name, message_info in signals.items(): + hex_id = message_info["ID"] + function_name = f"void Output_Data_Set_{message_name}_CH0_{hex_id}(void)" + f.write(f"{function_name}\n{{\n") + for signal in message_info["Signals"]: + factor_str = f"/ {signal['Factor']}" if signal["Factor"] != 1.0 else "" + offset_str = f"- {signal['Offset']}" if signal["Offset"] != 0.0 else "" + mask = f"_{signal['Length']}bit" + f.write( + f" VCU.TX.CH0_{message_name}_{hex_id}.{signal['Signal name']} = " + f"(int)((GV_{signal['Signal name']} {offset_str}) {factor_str}) & {mask};\n" + ) + f.write("}\n\n") + print(f"[INFO] TX functions written to {output_file}") + + +#============================== Generate TX Initialization ==============================# +def generate_tx_initialization(signals, output_file): + if not signals: + print("[WARNING] No TX signals found for initialization generation.") + return + + with open(output_file, 'w') as f: + f.write("void Initialize_TX_Signals(void)\n{\n") + for message_name, message_info in signals.items(): + hex_id = message_info["ID"] + f.write(f" // {message_name} ({hex_id})\n") + for signal in message_info["Signals"]: + f.write(f" VCU.TX.CH0_{message_name}_{hex_id}.{signal['Signal name']} = 0;\n") + f.write("\n") + f.write("}\n") + print(f"[INFO] TX initialization function written to {output_file}") + + +#============================== Generate TX Enum ==============================# +def generate_tx_enum(signals, output_file, cycle): + if not signals: + print("[WARNING] No TX messages found for enum generation.") + return + + with open(output_file, 'w') as f: + f.write("typedef enum {\n") + for idx, message_name in enumerate(signals.keys()): + enum_name = f"VCU_CH0_TX_{message_name}_{cycle}" + f.write(f" {enum_name} = {idx},\n") + f.write(" NUMBER_OF_VCU_CH0_TX_MESSAGE,\n") + f.write("} VCU_CH0_TX;\n") + print(f"[INFO] TX enum written to {output_file}") + + +#============================== Generate TX C File ==============================# +def generate_vcu_can_transmit_single_c_file(signals, output_file): + if not signals: + print("[ERROR] No signals to generate VCU CAN transmit functions for.") + return + + # Initialize the header of the C file + c_file_content = """ +#include "can.h" +""" + + # Iterate through all messages in the signals + for message_name, message_info in signals.items(): + # Check if any signal in the message has RX ECU name as VCU + has_vcu_signal = any(signal["RX ECU name"] == "VCU" for signal in message_info["Signals"]) + if not has_vcu_signal: + continue # Skip this message if no signal has RX ECU name as VCU + + # Add the function definition for the message + c_file_content += f""" +void Transmit_{message_name}_CH0_{message_info['ID']}(void) +{{ +""" + + # Iterate through signals and generate bit-packing logic + buffer_assignments = [""] * message_info["DLC"] + for signal in message_info["Signals"]: + start_byte = signal["msb"] // 8 + start_bit = signal["msb"] % 8 + signal_length = signal["Length"] + signal_name = f"VCU.TX.CH0_{message_name}_{message_info['ID']}.{signal['Signal name']}" + + # Handle 8-bit chunks + while signal_length > 0: + bits_in_byte = min(8 - start_bit, signal_length) + shift_amount = (signal["Length"] - signal_length) + shift_expr = f"({signal_name} >> shift{shift_amount}) << shift{start_bit}" if start_bit > 0 else f"({signal_name} >> shift{shift_amount})" + buffer_index = start_byte + + # Ensure buffer_index is within the range of buffer_assignments + if buffer_index >= len(buffer_assignments): + print(f"[ERROR] Buffer index {buffer_index} out of range for message {message_name}") + break + + # Add to the buffer assignments + if buffer_assignments[buffer_index]: + buffer_assignments[buffer_index] += f"\n | {shift_expr}" + else: + buffer_assignments[buffer_index] = f"{shift_expr}" + + # Update pointers + signal_length -= bits_in_byte + start_byte += 1 + start_bit = 0 + + # Write buffer assignments to the function + for i, assignment in enumerate(buffer_assignments): + if assignment: + c_file_content += f" CAN_ch[0].tx.buf[{i}] = ({assignment}) & _8bit;\n" + + # Add the send function call + c_file_content += f""" + can_send_config(CAN_INST_0, g_messageObjectConf_VCU_0ch_TX[VCU_CH0_TX_{message_name}_10ms]); +}} +""" + + # Write the generated code to a single C file + with open(output_file, "w") as c_file: + c_file.write(c_file_content) + print(f"Generated C file with all VCU messages: {output_file}") + + +#============================== Main ==============================# +if __name__ == "__main__": + dbc_file_path = sys.argv[1] + output_dir = sys.argv[2] + + output_structs_file = f"{output_dir}/generated_tx_structs.h" + output_globals_file = f"{output_dir}/generated_tx_globals.c" + output_globals_header = f"{output_dir}/generated_tx_globals.h" + output_tx_functions_file = f"{output_dir}/generated_tx_functions.c" + output_tx_initialization = f"{output_dir}/generated_tx_initialization.c" + output_enum_file = f"{output_dir}/generated_tx_enum.h" + output_c_file = f"{output_dir}/Transmit_All_VCU_Messages.c" # Replace with your desired output file name + cycle_time = "10ms" + + signals = load_dbc_file(dbc_file_path) + if signals is None: + print(f"[ERROR] Failed to load DBC file: {dbc_file_path}") + sys.exit(1) + + generate_tx_globals(signals, output_globals_file, output_globals_header) + generate_tx_functions(signals, output_tx_functions_file) + generate_tx_initialization(signals, output_tx_initialization) + generate_tx_enum(signals, output_enum_file, cycle_time) + generate_vcu_can_transmit_single_c_file(signals, output_c_file) \ No newline at end of file diff --git a/DBC_to_C_RX.py b/DBC_to_C_RX.py deleted file mode 100644 index 753afbb..0000000 --- a/DBC_to_C_RX.py +++ /dev/null @@ -1,301 +0,0 @@ -import re -import sys -import cantools -from datetime import datetime -import json -import os - -def parse_dbc_file(file_path): - signals = [] - current_message = None - try: - with open(file_path, 'r', encoding='cp1252') as f: - lines = f.readlines() - print(f"[INFO] Read {len(lines)} lines from DBC file.") - - start_parsing = False - for line in lines: - line = line.strip() - if not line: - continue - - if not start_parsing: - if line.startswith("BO_"): - start_parsing = True - else: - continue - - if line.startswith("BO_"): - if current_message and current_message["signals"]: - signals.append(current_message) - print(f"[INFO] Added message: {current_message['name']} with {len(current_message['signals'])} signals.") - - parts = line.split() - if len(parts) < 5: - print(f"[WARNING] Skipping malformed BO_ line: {line}") - continue - - current_message = { - "id": parts[1], - "name": parts[2].replace(":", ""), - "dlc": parts[3], - "transmitter": parts[4], - "signals": [] - } - print(f"[INFO] Found message: {current_message['name']}") - - elif line.startswith("SG_") and current_message: - try: - parts = line.split(":") - if len(parts) < 2: - print(f"[WARNING] Skipping malformed SG_ line: {line}") - continue - - signal_name = parts[0].split()[1].strip() - bit_info = parts[1].split()[0] - receiver = parts[1].split()[-1] - - if receiver != "VCU": - continue - - byte_offset, rest = bit_info.split("|") - bit_offset = int(rest.split("@")[0]) - size = int(re.search(r'\d+', rest.split("@")[0]).group()) - factor_offset_match = re.search(r'\(([^)]+)\)', line) - if not factor_offset_match: - print(f"[WARNING] Skipping signal with missing factor/offset: {line}") - continue - - factor_offset = factor_offset_match.group(1).split(",") - factor = float(factor_offset[0]) - offset = float(factor_offset[1]) - - current_message["signals"].append({ - "name": signal_name, - "byte_offset": int(byte_offset) // 8, - "bit_offset": bit_offset, - "size": size, - "factor": factor, - "offset": offset, - "signed": '-' in rest.split("@")[1] - }) - print(f"[INFO] Added signal: {signal_name}") - except (ValueError, IndexError, AttributeError) as e: - print(f"[ERROR] Error parsing signal: {line}, {e}") - continue - - if current_message and current_message["signals"]: - signals.append(current_message) - print(f"[INFO] Added last message: {current_message['name']} with {len(current_message['signals'])} signals.") - - except Exception as e: - print(f"[ERROR] Error while parsing DBC file: {e}") - return [] - - print(f"[INFO] Parsed {len(signals)} messages.") - return signals - - -def generate_vcu_rx_function_with_factors(dbc_path, output_file): - # Load the DBC file - db = cantools.database.load_file(dbc_path) - - # Initialize the header of the C file - c_file_content = """ -#include "can.h" - -// Declare Factors and Offsets for signals -""" - - # Collect unique Factors and Offsets - factors_offsets = {} - for message in db.messages: - if "VCU" in message.receivers: - for signal in message.signals: - factor_name = f"Factor_{str(signal.scale).replace('.', '_')}" - offset_name = f"Offset_m_{abs(signal.offset):.0f}" - if signal.scale != 1: - factors_offsets[factor_name] = signal.scale - if signal.offset != 0: - factors_offsets[offset_name] = signal.offset - - # Add Factor and Offset variable declarations - for name, value in factors_offsets.items(): - c_file_content += f"const float {name} = {value};\n" - - # Add a newline for separation - c_file_content += "\n" - - # Iterate through all messages in the DBC file - for message in db.messages: - # Check if "VCU" is in the receivers list - if "VCU" in message.receivers: - # Define the temporary struct - temp_struct_name = f"CH0_MV1_0x{message.frame_id:X}_temp" - c_file_content += f""" -void Receive_{message.name}_CH0_0x{message.frame_id:X}(void) -{{ - struct {{ -""" - - # Add temporary variables to the struct - for signal in message.signals: - if signal.is_signed: - signal_type = "signed int" - else: - signal_type = "unsigned int" - c_file_content += f" {signal_type} {signal.name}_temp : {signal.length};\n" - - c_file_content += f" }} {temp_struct_name};\n\n" - - # Add temp assignments - for signal in message.signals: - start_byte = signal.start // 8 - start_bit = signal.start % 8 - signal_length = signal.length - shift_expr = f"(CAN_ch[0].rx.buf[{start_byte}] >> shift{start_bit})" - if signal_length > 8: - # Handle multi-byte signals - multi_byte_expr = [] - for i in range((signal_length + 7) // 8): - byte_shift = i * 8 - if i == 0: - multi_byte_expr.append(f"(CAN_ch[0].rx.buf[{start_byte + i}] >> shift{start_bit})") - else: - multi_byte_expr.append(f"(CAN_ch[0].rx.buf[{start_byte + i}] << shift{byte_shift})") - shift_expr = " | ".join(multi_byte_expr) - c_file_content += f" {temp_struct_name}.{signal.name}_temp = ({shift_expr}) & _{signal_length}bit;\n" - - c_file_content += "\n" - - # Assign to final ECU variables - for signal in message.signals: - factor_name = f"Factor_{str(signal.scale).replace('.', '_')}" - offset_name = f"Offset_m_{abs(signal.offset):.0f}" - factor = f" * {factor_name}" if signal.scale != 1 else "" - offset = f" + {offset_name}" if signal.offset != 0 else "" - temp_var = f"{temp_struct_name}.{signal.name}_temp" - if signal.is_signed: - c_file_content += f" ECU3.RX.CH0_{message.name}_0x{message.frame_id:X}.{signal.name} = ({temp_var}{factor}){offset};\n" - else: - c_file_content += f" ECU3.RX.CH0_{message.name}_0x{message.frame_id:X}.{signal.name} = {temp_var}{factor}{offset};\n" - - c_file_content += "}\n" - - # Write the generated code to a single C file - with open(output_file, "w") as c_file: - c_file.write(c_file_content) - print(f"Generated RX function C file with Factors and Offsets: {output_file}") - - -def generate_input_functions(signals, output_file): - if not signals: - print("[WARNING] No signals to generate Input functions for.") - return - - with open(output_file, 'w') as f: - for message in signals: - hex_id = f"0x{int(message['id']):X}" - function_name = f"void Input_Data_Set_{message['name']}_CH0_{hex_id}(void)" - f.write(f"{function_name}\n{{\n") - for signal in message["signals"]: - f.write(f" GV_{signal['name']} = ECU3.RX.CH0_RX_{message['name']}_{hex_id}.{signal['name']};\n") - f.write("}\n\n") - print(f"[INFO] Input functions written to {output_file}") - - -def generate_structs(signals, output_file): - if not signals: - print("[WARNING] No signals to generate structs for.") - return - - with open(output_file, 'w') as f: - f.write("#ifndef GENERATED_STRUCTS_H\n") - f.write("#define GENERATED_STRUCTS_H\n\n") - f.write("#include \n\n") - - for message in signals: - hex_id = f"0x{int(message['id']):X}" - f.write(f"typedef struct\n{{\n") - for signal in message["signals"]: - if signal["size"] <= 32: - f.write(f" uint32_t {signal['name']} : {signal['size']};\n") - else: - f.write(f" float {signal['name']};\n") - f.write(f"}} CH0_RX_{message['name']}_{hex_id};\n\n") - f.write("#endif // GENERATED_STRUCTS_H\n") - print(f"[INFO] Structs written to {output_file}") - - -def generate_globals(signals, output_file, header_file): - if not signals: - print("[WARNING] No signals to generate globals for.") - return - - with open(output_file, 'w') as f: - f.write("#include \n") - - for message in signals: - for signal in message["signals"]: - if signal["size"] > 32: - f.write(f"float GV_{signal['name']} = 0.0f;\n") - else: - f.write(f"uint32_t GV_{signal['name']} = 0;\n") - - with open(header_file, 'w') as f: - f.write("#ifndef GENERATED_GLOBALS_H\n") - f.write("#define GENERATED_GLOBALS_H\n\n") - f.write("#include \n\n") - for message in signals: - for signal in message["signals"]: - if signal["size"] > 32: - f.write(f"extern float GV_{signal['name']};\n") - else: - f.write(f"extern uint32_t GV_{signal['name']};\n") - f.write("\n#endif // GENERATED_GLOBALS_H\n") - print(f"[INFO] Globals and extern declarations written to {output_file} and {header_file}") - - -def generate_initialization(signals, output_file): - if not signals: - print("[WARNING] No signals to generate initialization for.") - return - - with open(output_file, 'w') as f: - f.write("void ECU3_Data_Init(void)\n{\n") - for message in signals: - hex_id = f"0x{int(message['id']):X}" - struct_prefix = f"ECU3.RX.CH0_RX_{message['name']}_{hex_id}" - for signal in message["signals"]: - if signal["offset"] != 0.0: - if signal["size"] <= 32: - f.write(f" {struct_prefix}.{signal['name']} = {signal['offset']};\n") - else: - f.write(f" {struct_prefix}.{signal['name']} = {signal['offset']}f;\n") - else: - if signal["size"] <= 32: - f.write(f" {struct_prefix}.{signal['name']} = 0;\n") - else: - f.write(f" {struct_prefix}.{signal['name']} = 0.0f;\n") - f.write("\n") - f.write("}\n") - print(f"[INFO] Initialization function written to {output_file}") - - -if __name__ == "__main__": - dbc_file_path = sys.argv[1] - output_dir = sys.argv[2] - - output_c_file = f"{output_dir}/generated_receive.c" - output_input_file = f"{output_dir}/generated_input.c" - output_structs_file = f"{output_dir}/generated_structs.h" - output_globals_file = f"{output_dir}/generated_globals.c" - output_globals_header = f"{output_dir}/generated_globals.h" - output_initialization_file = f"{output_dir}/generated_init.c" - - signals = parse_dbc_file(dbc_file_path) - generate_vcu_rx_function_with_factors(dbc_file_path, output_c_file) - generate_input_functions(signals, output_input_file) - generate_structs(signals, output_structs_file) - generate_globals(signals, output_globals_file, output_globals_header) - generate_initialization(signals, output_initialization_file) \ No newline at end of file diff --git a/DBC_to_C_TX.py b/DBC_to_C_TX.py deleted file mode 100644 index e87753c..0000000 --- a/DBC_to_C_TX.py +++ /dev/null @@ -1,323 +0,0 @@ -import re -import sys -import cantools -import os -from datetime import datetime - -def parse_dbc_file(file_path): - signals = [] - current_message = None - try: - with open(file_path, 'r', encoding='cp1252') as f: - lines = f.readlines() - print(f"[INFO] Read {len(lines)} lines from DBC file.") - - start_parsing = False - for line in lines: - line = line.strip() - if not line: - continue - - if not start_parsing: - if line.startswith("BO_"): - start_parsing = True - else: - continue - - if line.startswith("BO_"): - if current_message and current_message["signals"]: - signals.append(current_message) - print(f"[INFO] Added message: {current_message['name']} with {len(current_message['signals'])} signals.") - - parts = line.split() - if len(parts) < 5: - print(f"[WARNING] Skipping malformed BO_ line: {line}") - continue - - current_message = { - "id": parts[1], - "name": parts[2].replace(":", ""), - "dlc": parts[3], - "transmitter": parts[4], - "signals": [] - } - print(f"[INFO] Found message: {current_message['name']}") - - elif line.startswith("SG_") and current_message: - try: - parts = line.split(":") - if len(parts) < 2: - print(f"[WARNING] Skipping malformed SG_ line: {line}") - continue - - signal_name = parts[0].split()[1].strip() - bit_info = parts[1].split()[0] - receiver = parts[1].split()[-1] - - if current_message["transmitter"] != "VCU": - continue - - byte_offset, rest = bit_info.split("|") - bit_offset = int(rest.split("@")[0]) - size = int(re.search(r'\d+', rest.split("@")[0]).group()) - factor_offset_match = re.search(r'\(([^)]+)\)', line) - if not factor_offset_match: - print(f"[WARNING] Skipping signal with missing factor/offset: {line}") - continue - - factor_offset = factor_offset_match.group(1).split(",") - factor = float(factor_offset[0]) - offset = float(factor_offset[1]) - - current_message["signals"].append({ - "name": signal_name, - "byte_offset": int(byte_offset) // 8, - "bit_offset": bit_offset, - "size": size, - "factor": factor, - "offset": offset, - "signed": '-' in rest.split("@")[1] - }) - print(f"[INFO] Added signal: {signal_name}") - except (ValueError, IndexError, AttributeError) as e: - print(f"[ERROR] Error parsing signal: {line}, {e}") - continue - - if current_message and current_message["signals"]: - signals.append(current_message) - print(f"[INFO] Added last message: {current_message['name']} with {len(current_message['signals'])} signals.") - - except Exception as e: - print(f"[ERROR] Error while parsing DBC file: {e}") - return [] - - print(f"[INFO] Parsed {len(signals)} messages.") - return signals - - -def generate_tx_structs(signals, output_file): - if not signals: - print("[WARNING] No signals to generate TX structs for.") - return - - with open(output_file, 'w') as f: - f.write("#ifndef GENERATED_TX_STRUCTS_H\n") - f.write("#define GENERATED_TX_STRUCTS_H\n\n") - f.write("#include \n\n") - - for message in signals: - hex_id = f"0x{int(message['id']):X}" - f.write(f"typedef struct\n{{\n") - for signal in message["signals"]: - if signal["size"] <= 32: - f.write(f" uint32_t {signal['name']} : {signal['size']};\n") - else: - f.write(f" float {signal['name']};\n") - f.write(f"}} CH0_{message['name']}_{hex_id};\n\n") - f.write("#endif // GENERATED_TX_STRUCTS_H\n") - print(f"[INFO] TX structs written to {output_file}") - - -def generate_tx_globals(signals, output_file, header_file): - if not signals: - print("[WARNING] No signals to generate TX globals for.") - return - - with open(output_file, 'w') as f: - for message in signals: - for signal in message["signals"]: - if signal["size"] > 32: - f.write(f"float GV_{signal['name']} = 0.0f;\n") - else: - f.write(f"uint32_t GV_{signal['name']} = 0;\n") - - with open(header_file, 'w') as f: - f.write("#ifndef GENERATED_TX_GLOBALS_H\n") - f.write("#define GENERATED_TX_GLOBALS_H\n\n") - f.write("#include \n\n") - for message in signals: - for signal in message["signals"]: - if signal["size"] > 32: - f.write(f"extern float GV_{signal['name']};\n") - else: - f.write(f"extern uint32_t GV_{signal['name']};\n") - f.write("\n#endif // GENERATED_TX_GLOBALS_H\n") - print(f"[INFO] TX globals written to {output_file} and {header_file}") - - -def generate_tx_functions(signals, output_file): - if not signals: - print("[WARNING] No signals to generate TX functions for.") - return - - with open(output_file, 'w') as f: - for message in signals: - hex_id = f"0x{int(message['id']):X}" - function_name = f"void Output_Data_Set_{message['name']}_CH0_{hex_id}(void)" - f.write(f"{function_name}\n{{\n") - for signal in message["signals"]: - factor_str = f"/ {signal['factor']}" if signal["factor"] != 1.0 else "" - offset_str = f"- {signal['offset']}" if signal["offset"] != 0.0 else "" - mask = f"_{signal['size']}bit" - f.write( - f" VCU.TX.CH0_{message['name']}_{hex_id}.{signal['name']} = " - f"(int)((GV_{signal['name']} {offset_str}) {factor_str}) & {mask};\n" - ) - f.write("}\n\n") - print(f"[INFO] TX functions written to {output_file}") - -def generate_tx_initialization(signals, output_file): - if not signals: - print("[WARNING] No TX signals found for initialization generation.") - return - - with open(output_file, 'w') as f: - f.write("void Initialize_TX_Signals(void)\n{\n") - for message in signals: - hex_id = f"0x{int(message['id']):X}" - f.write(f" // {message['name']} ({hex_id})\n") - for signal in message["signals"]: - f.write(f" VCU.TX.CH0_{message['name']}_{hex_id}.{signal['name']} = 0;\n") - f.write("\n") - f.write("}\n") - print(f"[INFO] TX initialization function written to {output_file}") - -def parse_dbc_for_tx_messages(file_path): - tx_messages = [] - try: - with open(file_path, 'r', encoding='cp1252') as f: - lines = f.readlines() - print(f"[INFO] Read {len(lines)} lines from DBC file.") - - for line in lines: - line = line.strip() - if not line: - continue - - if line.startswith("BO_"): - parts = line.split() - if len(parts) < 5: - print(f"[WARNING] Skipping malformed BO_ line: {line}") - continue - - message_id = int(parts[1]) # ID for sorting - message_name = parts[2].replace(":", "") - transmitter = parts[4] - - # Only include messages transmitted by VCU - if transmitter == "VCU": - tx_messages.append((message_id, message_name)) - print(f"[INFO] Found TX message: {message_name} (ID: {message_id})") - - except Exception as e: - print(f"[ERROR] Error while parsing DBC file: {e}") - - # Sort messages by message name or ID - tx_messages.sort(key=lambda x: x[0]) # Sort by message ID - return [message[1] for message in tx_messages] - - -def generate_tx_enum(tx_messages, output_file, cycle): - if not tx_messages: - print("[WARNING] No TX messages found for enum generation.") - return - - with open(output_file, 'w') as f: - f.write("typedef enum {\n") - for idx, message in enumerate(tx_messages): - enum_name = f"VCU_CH0_TX_{message}_{cycle}" - f.write(f" {enum_name} = {idx},\n") - f.write(" NUMBER_OF_VCU_CH0_TX_MESSAGE,\n") - f.write("} VCU_CH0_TX;\n") - print(f"[INFO] TX enum written to {output_file}") - -def generate_vcu_can_transmit_single_c_file(dbc_path, output_file): - # Load the DBC file - db = cantools.database.load_file(dbc_path) - - # Initialize the header of the C file - c_file_content = """ -#include "can.h" -""" - - # Iterate through all messages in the DBC file - for message in db.messages: - # Check if the message's sending node is "VCU" - if "VCU" in message.senders: - # Add the function definition for the message - c_file_content += f""" -void Transmit_{message.name}_CH0_0x{message.frame_id:X}(void) -{{ -""" - - # Iterate through signals and generate bit-packing logic - buffer_assignments = [""] * message.length - for signal in message.signals: - start_byte = signal.start // 8 - start_bit = signal.start % 8 - signal_length = signal.length - signal_name = f"VCU.TX.CH0_{message.name}_0x{message.frame_id:X}.{signal.name}" - - # Handle 8-bit chunks - while signal_length > 0: - bits_in_byte = min(8 - start_bit, signal_length) - shift_amount = (signal.length - signal_length) - shift_expr = f"({signal_name} >> shift{shift_amount}) << shift{start_bit}" if start_bit > 0 else f"({signal_name} >> shift{shift_amount})" - buffer_index = start_byte - - # Ensure buffer_index is within the range of buffer_assignments - if buffer_index >= len(buffer_assignments): - print(f"[ERROR] Buffer index {buffer_index} out of range for message {message.name}") - break - - # Add to the buffer assignments - if buffer_assignments[buffer_index]: - buffer_assignments[buffer_index] += f"\n | {shift_expr}" - else: - buffer_assignments[buffer_index] = f"{shift_expr}" - - # Update pointers - signal_length -= bits_in_byte - start_byte += 1 - start_bit = 0 - - # Write buffer assignments to the function - for i, assignment in enumerate(buffer_assignments): - if assignment: - c_file_content += f" CAN_ch[0].tx.buf[{i}] = ({assignment}) & _8bit;\n" - - # Add the send function call - c_file_content += f""" - can_send_config(CAN_INST_0, g_messageObjectConf_VCU_0ch_TX[VCU_CH0_TX_{message.name}_10ms]); -}} -""" - - # Write the generated code to a single C file - with open(output_file, "w") as c_file: - c_file.write(c_file_content) - print(f"Generated C file with all VCU messages: {output_file}") - - -if __name__ == "__main__": - dbc_file_path = sys.argv[1] - output_dir = sys.argv[2] - - output_structs_file = f"{output_dir}/generated_tx_structs.h" - output_globals_file = f"{output_dir}/generated_tx_globals.c" - output_globals_header = f"{output_dir}/generated_tx_globals.h" - output_tx_functions_file = f"{output_dir}/generated_tx_functions.c" - output_tx_initialization = f"{output_dir}/generated_tx_initialization.c" - output_enum_file = f"{output_dir}/generated_tx_enum.h" - cycle_time = "10ms" - output_c_file = f"{output_dir}/Transmit_All_VCU_Messages.c" # Replace with your desired output file name - - generate_vcu_can_transmit_single_c_file(dbc_file_path, output_c_file) - - - signals = parse_dbc_file(dbc_file_path) - generate_tx_structs(signals, output_structs_file) - generate_tx_globals(signals, output_globals_file, output_globals_header) - generate_tx_functions(signals, output_tx_functions_file) - generate_tx_initialization(signals, output_tx_initialization) - tx_messages = parse_dbc_for_tx_messages(dbc_file_path) - generate_tx_enum(tx_messages, output_enum_file, cycle_time) diff --git a/__pycache__/DBC_Converter_Data_Parsing.cpython-313.pyc b/__pycache__/DBC_Converter_Data_Parsing.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..de1648f72df2a5b679ab035937dd70f03796b595 GIT binary patch literal 3324 zcmai0O>7&-6`tKCspUT@Qj$eV;*$EM{-WQ=rj)w2X#F&%WOKcV3a(77$rZ&$ToSvK zD-$^wJ@Hh~O$rOXSm?<<6xA_6j_E;15;V;9LP(4jD4;_DIWk}%xpao)QnnIRBXQoF zH{bi2H*X&H#B4SII41t`_r%|f0Q?&*)M2VKCpZScUjYqh>{B4tC?;Yw?gApt5;PH5 z1Ar3%V6iZ%DxXqXqlF7m%i=!3YNw$sG(;V%8>q2>TZOv1u(iH?k4)Ej2UrRKu#H1K zQq;2sAE31?X#up3)zeMLKIBQr>)+!IHGYy*eNq4-j7SRYS)eUr)sl%dTEHZJiVE2P zFaipM=4v#7p+CR*2t~6JtDgWZ0Ll>oeHSnGebS0 zfW!R4KUISQ5oobC!a9{Zr7#1Hhy~(8ETNuG(2M~=O9MgoIUd%Z+EY0-9tT*&mL3Bj zG%-zKSQ%%BibMPAJ;q_g$a2U707Hb$XLX>osSyXskg6V+1R&D5eTEF%f2m1pR85r% zdRoiqX`L0`onSae>(rm|LJy5PX?QT5V^!Zkm>Hv>V+@RmF@FST!>DHMvwj$SXb+yX zQQvV`1)=9qqPZX^7RI9Hq^k2B)Uo{kYzWr(&h_iqMh+TL+b-1kWiIR&>NK*_@Y8%w z^u`9l5pk$@eGb;7VpS?QFVr!sSd|Jb=UBHi5Up#Uq0T^C(Hw43qdKLGm9a5)rkQat zPNs!vrEQ~)EK%^agr3y81*7c&UN8(AHwin!22KGF>?jDg^50Jg57@xGAkwN@ZvxyU z_}1DY?W%;fGi@JsB@cRAZP(fob-ICVfSM(L^NNCrx&G^`QC1onVBqG21Liymr zw+^Z5`UrJG1s~f{h_T7FBh(3xPy;+dea){?@a3RF1aHp&WW2LR-I!-6flKj96P-*5 z+?I5NuHgtZzN02Ik#G`W&jx-nXRKjr3Peh}r|53-LL$4FGhBa=<*Bq7=S4+>P>ODW zi)GWIqFdeAkoauQ7(R8D^F?li!>i$SYJp2`@o_4frZSu;@l^2oJhcHu0m^SyH0ca4 zC>oLH;tDRp5M$|725u?_DYKQ#ZY2d?QnXT5OlA~qip$0}6(T8Q6>UOHZ$r_>R+`Hy zIxYjv#1;LGofx0VCewnV&4>`^zoh7quV{wLZYmnYA{RoIhc>J!UXr*(bu-J0f?|=X z`9a|7nydpP#TwfdMW_?4OB4-?Ofjn#YLOY@d@PybwxY?nqTA$m5H+cg>J1R_t(aoW z?nL?6cC;!n)qU1180#yvC8F1>=(eiaR}A-H_M`ReBb1`ssAoT2&Awt3-!qHx5-fT^ zoimhM^8uETcu`_Q^fDVv$F@`OcoO@0TKs~}a50`uB(p5Ms_1-LxX+6)A0MuwK`zTh zZ^0W)3W?Fo1H}w)A|8$3i$zhE#ZRDjRFP6IEY64E7@yTT56$+1f0uq?_U_%0TV0Qn zkCI<~kzagA0E_Rf0k}J#4n7$y_O6y)xANA*cK1`)6W1{Sy&?Pr0M`nhw;bz$vo%l3 zuCBcGwbNa3_LZD{73V-cC_CC72Ob5!n#%{jceKgAzJm3Y?b7Rxp-RVisbhS*S zU^;AV-yNyAMoO-cXI$AeR&E_H5OUX0rE9#@HNNjHcTE+HvTw9teeI%TcbD8fDto+d z^xBc;0$H~C-q~P;nPD`=k8Xe zYpm2Ywr?+YO_p6#g?SWoN5wl?@=oqwD|fx5>E!NX49-dv@7y3{?r&y~9`mpiXO&0iCq4McW!l$;~ak|pQmit}p8 zc~$P8kUc)xHz4`^As1%(PBJ&>wJ zjohH;8I39$PE6bvdy)1a!f2COJ|&4`h;O|6B=jiuAd#;2xSs=9%}@n?00V`bOQqx6 zTl{atMYu#=UHTSI#{`C9KLE>*nmNpQ{3Ql7rhKkUw97WfWAYKXYky>Xxcti6vHSb7 zwg2JLf10fF;KV;hpO3yA43tcL`J21LuT1u$6Bfwc%KpGNa|fEzY^WGmIk;E6yu#DX|nZDKbNaV+3(0WdG(va4_J!3)=TLHEkmvTND9 izqeUz{ph7_?1TXBi66CKX!e)@r0rM_G%j%g#{WO84Bhwu literal 0 HcmV?d00001 diff --git a/__pycache__/Data_Parsing.cpython-313.pyc b/__pycache__/Data_Parsing.cpython-313.pyc index 6eb6682ddf9128d211a449c920759b8aca9daa74..db8933556062867ead6cbbe79fa284db7a1f2753 100644 GIT binary patch delta 632 zcmYLHO=uHA6n?XR*{;bZX?`|8V3LxUrX?}0t&*CmrE2$55!OgC$P(=)29izLjnIOi z$KpYR5fm?icu-J5auTl|aur2GF74HWm>Qv=7iZMyF!Q~i?|YAV!|aA%MC75%B>`C* zSD)8n&R236Nlp^7EH+r8gJAWwXBC4PS2zz?M9V+!2ysyzE>Ijbu0))S;SwHzU) z%S)=?(RGW|S0uH-b`!EX$9Cs_UvC&Etg|Gf epTh1C7_bPT9gx3qMdTmcK)~Sz=VR^+p?(2Y9+N@< delta 543 zcmYLGO=uHA6n?Y2v%A?en>3nD(o5`WO=C5*rcx42u?ERn5QJDMq;`pP6GM{?>_)IB zy@)w^c}EYT9>jx!#G7~#p*eaGk%-uf;4w8qK`+jr;A7^!@8``hk9j_|m(<6hkOnOB zuO2nt24Ct)q6HZh*&biP1@eL1?aRVBL8uj$ z{3RWaR>E233}Kwb5h#;OJzS(|@)B*@33>dk7L<#^7+`9(p9#zm+|<@jnzNtSN}t{j zt1HAf05ulhFG4Icx=bLF=!FlO1a$LbX!`fh7Jk#_mMGkxEa$|BrBfD#cM*f<6D5_E z-JE6#%5IV40oAOuI0);ODGp3(rLi2W(#3`O`6YZBtlduVAw+-2_xMAHs%^Wqwqx7g zQAWL4uF+=KY5QK5 Date: Thu, 13 Feb 2025 18:36:01 +0900 Subject: [PATCH 5/7] =?UTF-8?q?=EB=A9=94=EB=89=B4=EC=97=90=20=EA=B8=B0?= =?UTF-8?q?=EB=B3=B8=20=EC=B0=BD=20=ED=81=AC=EA=B8=B0=20=EC=98=B5=EC=85=98?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20RX=20=ED=95=A8=EC=88=98=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DBC_Converter.py | 2 +- DBC_Converter_RX.py | 20 ++++++------------ ...DBC_Converter_Data_Parsing.cpython-313.pyc | Bin 3324 -> 3324 bytes 3 files changed, 7 insertions(+), 15 deletions(-) diff --git a/DBC_Converter.py b/DBC_Converter.py index fc32371..2146ba7 100644 --- a/DBC_Converter.py +++ b/DBC_Converter.py @@ -160,10 +160,10 @@ class MainView(QtWidgets.QMainWindow): # 보기 메뉴 항목 추가 size_menu = view_menu.addMenu("창크기") + size_menu.addAction("기본", lambda: self.setWindowSize("default")).setShortcut('Ctrl+0') size_menu.addAction("작게", lambda: self.setWindowSize("small")).setShortcut('Ctrl+1') size_menu.addAction("보통", lambda: self.setWindowSize("medium")).setShortcut('Ctrl+2') size_menu.addAction("크게", lambda: self.setWindowSize("large")).setShortcut('Ctrl+3') - size_menu.addAction("기본", lambda: self.setWindowSize("default")).setShortcut('Ctrl+0') size_menu.addAction("자동", lambda: self.setWindowSize("auto")).setShortcut('Ctrl+4') sort_menu = view_menu.addMenu("정렬") diff --git a/DBC_Converter_RX.py b/DBC_Converter_RX.py index 2037220..2a45b88 100644 --- a/DBC_Converter_RX.py +++ b/DBC_Converter_RX.py @@ -1,7 +1,6 @@ import sys from DBC_Converter_Data_Parsing import load_dbc_file - #============================== Generate Globals ==============================# def generate_globals(signals, C_file, header_file): if not signals: @@ -31,7 +30,6 @@ def generate_globals(signals, C_file, header_file): f.write("\n#endif // GENERATED_GLOBALS_H\n") print(f"[INFO] Globals and extern declarations written to {C_file} and {header_file}") - #============================== Generate VCU RX Function ==============================# def generate_vcu_rx_function_with_factors(signals, output_file): if not signals: @@ -74,7 +72,7 @@ def generate_vcu_rx_function_with_factors(signals, output_file): continue # Skip this message if no signal has RX ECU name as VCU c_file_content += f""" -void {message_name}_RX_{message_info['ID']}(void) +void Receive_{message_name}_{message_info['ID']}(void) {{ struct {{ """ @@ -100,16 +98,16 @@ void {message_name}_RX_{message_info['ID']}(void) start_bit = signal["msb"] % 8 signal_length = signal["Length"] if signal["Byte order"] == 0: # Motorola (Big Endian) - shift_expr = f"(CAN_ch[0].rx.buf[{start_byte}] >> shift{start_bit})" + shift_expr = f"(CAN_ch[0].rx.buf[{start_byte}] << shift{7 - start_bit})" if signal_length > 8: # Handle multi-byte signals multi_byte_expr = [] for i in range((signal_length + 7) // 8): - byte_shift = i * 8 + byte_shift = (7 - start_bit) + (i * 8) if i == 0: - multi_byte_expr.append(f"(CAN_ch[0].rx.buf[{start_byte + i}] >> shift{start_bit})") + multi_byte_expr.append(f"(CAN_ch[0].rx.buf[{start_byte + i}] << shift{7 - start_bit})") else: - multi_byte_expr.append(f"(CAN_ch[0].rx.buf[{start_byte + i}] << shift{byte_shift})") + multi_byte_expr.append(f"(CAN_ch[0].rx.buf[{start_byte + i}] >> shift{byte_shift})") shift_expr = " | ".join(multi_byte_expr) else: # Intel (Little Endian) shift_expr = f"(CAN_ch[0].rx.buf[{start_byte}] >> shift{start_bit})" @@ -136,10 +134,7 @@ void {message_name}_RX_{message_info['ID']}(void) factor = f" * {factor_name}" if signal['Factor'] != 1 else "" offset = f" + {offset_name}" if signal['Offset'] != 0 else "" temp_var = f"{temp_struct_name}.{signal['Signal name']}_temp" - if signal["Byte order"] == 1: - c_file_content += f" VCU.RX.{message_name}_{message_info['ID']}.{signal['Signal name']} = ({temp_var}{factor}){offset};\n" - else: - c_file_content += f" VCU.RX.{message_name}_{message_info['ID']}.{signal['Signal name']} = {temp_var}{factor}{offset};\n" + c_file_content += f" VCU.RX.{message_name}_{message_info['ID']}.{signal['Signal name']} = ({temp_var}{factor}){offset};\n" c_file_content += "}\n" @@ -148,7 +143,6 @@ void {message_name}_RX_{message_info['ID']}(void) c_file.write(c_file_content) print(f"Generated RX function C file with Factors and Offsets: {output_file}") - #============================== Generate Input Function ==============================# def generate_input_functions(signals, output_file): if not signals: @@ -165,7 +159,6 @@ def generate_input_functions(signals, output_file): f.write("}\n\n") print(f"[INFO] Input functions written to {output_file}") - #============================== Generate Initialization ==============================# def generate_initialization(signals, output_file): if not signals: @@ -192,7 +185,6 @@ def generate_initialization(signals, output_file): f.write("}\n") print(f"[INFO] Initialization function written to {output_file}") - #============================== Main ==============================# if __name__ == "__main__": dbc_file_path = sys.argv[1] diff --git a/__pycache__/DBC_Converter_Data_Parsing.cpython-313.pyc b/__pycache__/DBC_Converter_Data_Parsing.cpython-313.pyc index de1648f72df2a5b679ab035937dd70f03796b595..f9d1021668c8da0de87bbbf69038a3739a4d54de 100644 GIT binary patch delta 19 Zcmew(`A3rLGcPX}0}y Date: Mon, 17 Feb 2025 17:21:44 +0900 Subject: [PATCH 6/7] =?UTF-8?q?RX=20=EB=B3=80=ED=99=98=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B0=9C=EC=84=A0:=20Motorola=20=EB=B0=A9=EC=8B=9D?= =?UTF-8?q?=EC=9D=98=20=EC=8B=A0=ED=98=B8=20=EC=B2=98=EB=A6=AC=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DBC_Converter_RX.py | 5 ++++- DBC_Converter_TX.py | 10 ++++++++-- settings.json | 2 +- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/DBC_Converter_RX.py b/DBC_Converter_RX.py index 2a45b88..970a1ab 100644 --- a/DBC_Converter_RX.py +++ b/DBC_Converter_RX.py @@ -98,9 +98,10 @@ void Receive_{message_name}_{message_info['ID']}(void) start_bit = signal["msb"] % 8 signal_length = signal["Length"] if signal["Byte order"] == 0: # Motorola (Big Endian) - shift_expr = f"(CAN_ch[0].rx.buf[{start_byte}] << shift{7 - start_bit})" + lsb = signal["msb"] + 8*(signal_length // 8) - (signal_length % 8 - 1) if signal_length > 8: # Handle multi-byte signals + shift_expr = f"(CAN_ch[0].rx.buf[{start_byte}] << shift{7 - start_bit})" multi_byte_expr = [] for i in range((signal_length + 7) // 8): byte_shift = (7 - start_bit) + (i * 8) @@ -109,6 +110,8 @@ void Receive_{message_name}_{message_info['ID']}(void) else: multi_byte_expr.append(f"(CAN_ch[0].rx.buf[{start_byte + i}] >> shift{byte_shift})") shift_expr = " | ".join(multi_byte_expr) + else : + shift_expr = f"(CAN_ch[0].rx.buf[{start_byte}] >> shift{lsb % 8})" else: # Intel (Little Endian) shift_expr = f"(CAN_ch[0].rx.buf[{start_byte}] >> shift{start_bit})" if signal_length > 8: diff --git a/DBC_Converter_TX.py b/DBC_Converter_TX.py index 54ae71c..252d68d 100644 --- a/DBC_Converter_TX.py +++ b/DBC_Converter_TX.py @@ -102,7 +102,7 @@ def generate_vcu_can_transmit_single_c_file(signals, output_file): # Iterate through all messages in the signals for message_name, message_info in signals.items(): # Check if any signal in the message has RX ECU name as VCU - has_vcu_signal = any(signal["RX ECU name"] == "VCU" for signal in message_info["Signals"]) + has_vcu_signal = any(signal["RX ECU name"] != "VCU" for signal in message_info["Signals"]) if not has_vcu_signal: continue # Skip this message if no signal has RX ECU name as VCU @@ -124,7 +124,13 @@ void Transmit_{message_name}_CH0_{message_info['ID']}(void) while signal_length > 0: bits_in_byte = min(8 - start_bit, signal_length) shift_amount = (signal["Length"] - signal_length) - shift_expr = f"({signal_name} >> shift{shift_amount}) << shift{start_bit}" if start_bit > 0 else f"({signal_name} >> shift{shift_amount})" + if signal["Byte order"] == 0: # Motorola (Big Endian) + if bits_in_byte == 8: + shift_expr = f"({signal_name} >> shift{shift_amount})" + else: + shift_expr = f"({signal_name} << shift{start_bit})" if start_bit > 0 else f"({signal_name} >> shift{shift_amount})" + else: # Intel (Little Endian) + shift_expr = f"({signal_name} >> shift{shift_amount}) << shift{start_bit}" if start_bit > 0 else f"({signal_name} >> shift{shift_amount})" buffer_index = start_byte # Ensure buffer_index is within the range of buffer_assignments diff --git a/settings.json b/settings.json index 656cc45..3771384 100644 --- a/settings.json +++ b/settings.json @@ -2,6 +2,6 @@ "theme": "light", "default_save_path": "C:/Users/MSI/Desktop", "file_paths": [], - "last_opened_dir": "C:/Users/MSI/SynologyDrive/3min_be/한자연/!과제/초안전/#Debug/DBC", + "last_opened_dir": "C:/Users/MSI/Desktop/python/motorola_tx", "channel_info": {} } \ No newline at end of file From c7d94f4cd5cf0fbadc8cddc84b8d9fac0b7ce843 Mon Sep 17 00:00:00 2001 From: 3minbe Date: Mon, 17 Feb 2025 18:24:20 +0900 Subject: [PATCH 7/7] =?UTF-8?q?=EC=B1=84=EB=84=90=20=EC=84=A0=ED=83=9D=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80:=20=EB=93=9C=EB=A1=AD?= =?UTF-8?q?=EB=8B=A4=EC=9A=B4=20=EB=A9=94=EB=89=B4=20=EB=B0=8F=20=EC=84=A0?= =?UTF-8?q?=ED=83=9D=20=EB=B3=80=EA=B2=BD=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DBC_Converter.py | 39 ++++++++++++++++++++++++++++++++++++++- settings.json | 2 +- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/DBC_Converter.py b/DBC_Converter.py index 2146ba7..8697794 100644 --- a/DBC_Converter.py +++ b/DBC_Converter.py @@ -89,12 +89,13 @@ class MainView(QtWidgets.QMainWindow): self.default_save_path = os.path.join(os.path.expanduser("~"), "Desktop") # 바탕화면 경로 설정 self.file_paths = [] # 파일 경로 저장 리스트 self.channel_info = {} # 채널 정보 초기화 + self.channel_options = ["CH0", "CH1", "CH2", "CH3", "CH4", "CH5"] # 채널 옵션 설정 self.loadSettings() # 설정 로드 self.setupUI(base_path) # UI 설정 self.centerWindow() # 창을 화면 중앙에 위치 self.sortTreeView(0, True) # 기본 파일명 오름차순 정렬 - self.channel_options = ["CH0", "CH1", "CH2", "CH3", "CH4", "CH5"] # 채널 옵션 설정 self.setupCloseEvent() # 프로그램 종료 이벤트 설정 + self.tree.itemSelectionChanged.connect(self.onFileSelectionChanged) def loadSettings(self): self.settings_file = "settings.json" @@ -288,10 +289,46 @@ class MainView(QtWidgets.QMainWindow): settings_label = QtWidgets.QLabel("설정") settings_label.setAlignment(QtCore.Qt.AlignCenter) + settings_label.setStyleSheet("font-weight: bold; font-size: 14px;") # 글자를 굵게 하고 크기를 16px로 설정 settings_layout.addWidget(settings_label) + # 설정 라벨과 채널 선택 라벨 사이에 작은 간격 추가 + settings_layout.addSpacing(20) # 10 픽셀 간격 추가 + + # 채널 선택 드롭다운 메뉴 추가 + channel_label = QtWidgets.QLabel("# 채널 선택") + channel_label.setAlignment(QtCore.Qt.AlignLeft) + settings_layout.addWidget(channel_label) + + self.channel_combo = QtWidgets.QComboBox() + self.channel_combo.addItems(self.channel_options) + self.channel_combo.setEnabled(False) # 초기에는 비활성화 + self.channel_combo.currentIndexChanged.connect(self.onChannelChanged) + settings_layout.addWidget(self.channel_combo) + + # 상단 정렬을 위해 빈 공간 추가 + settings_layout.addStretch() + return settings_panel + def onFileSelectionChanged(self): + selected_items = self.tree.selectedItems() + if selected_items: + self.channel_combo.setEnabled(True) + current_channel = selected_items[0].text(2) + self.channel_combo.setCurrentText(current_channel) + else: + self.channel_combo.setEnabled(False) + + def onChannelChanged(self): + selected_items = self.tree.selectedItems() + if selected_items: + new_channel = self.channel_combo.currentText() + for item in selected_items: + item.setText(2, new_channel) + self.updateChannelInfo(item.text(1), item.text(0), new_channel) + self.updateAlertText(f"채널 변경", [f"{item.text(0)}의 채널이 {new_channel}(으)로 변경되었습니다." for item in selected_items]) + def selectSavePath(self): selected_path = QtWidgets.QFileDialog.getExistingDirectory(self, "저장 경로 선택", self.default_save_path) if selected_path: diff --git a/settings.json b/settings.json index 3771384..656cc45 100644 --- a/settings.json +++ b/settings.json @@ -2,6 +2,6 @@ "theme": "light", "default_save_path": "C:/Users/MSI/Desktop", "file_paths": [], - "last_opened_dir": "C:/Users/MSI/Desktop/python/motorola_tx", + "last_opened_dir": "C:/Users/MSI/SynologyDrive/3min_be/한자연/!과제/초안전/#Debug/DBC", "channel_info": {} } \ No newline at end of file