@@ -178,9 +178,78 @@ def selector(self, start_element, selector):
178
178
return sorted (result_list , key = lambda element : element .sourceline )
179
179
180
180
181
+ def get_signals_for_pdu (fe , pdu , overall_startbit = 0 ):
182
+ signals = []
183
+ ecus = []
184
+ for signal_instance in fe .selector (pdu , "//SIGNAL-INSTANCE" ):
185
+ byte_order_element = fe .selector (signal_instance , "/IS-HIGH-LOW-BYTE-ORDER" )
186
+ if byte_order_element [0 ].text == "false" :
187
+ is_little_endian = True
188
+ else :
189
+ is_little_endian = False
190
+
191
+ start_bit = int (fe .selector (signal_instance , "/BIT-POSITION" )[0 ].text , 0 ) + overall_startbit
192
+ signal = fe .selector (signal_instance , ">SIGNAL-REF" )[0 ]
193
+ ecu_instance_refs = fe .selector (signal_instance , "<<ECU" )
194
+ receiver_ecus = []
195
+ for ecu_instance_ref in ecu_instance_refs :
196
+ if len (fe .selector (ecu_instance_ref , "^INPUT-PORT" )) > 0 :
197
+ ecu_name = fe .sn (fe .get_referencable_parent (ecu_instance_ref ))
198
+ receiver_ecus .append (ecu_name )
199
+ ecus .append (canmatrix .Ecu (name = ecu_name .strip ()))
200
+
201
+ signal_name = fe .sn (signal )
202
+ coding = fe .selector (signal , ">CODING-REF" )[0 ]
203
+ bit_length = int (fe .selector (coding , "/!BIT-LENGTH" )[0 ].text )
204
+ compu_methods = fe .selector (coding , "/!COMPU-METHOD" )
205
+ sig = canmatrix .Signal (name = signal_name )
206
+
207
+ for compu_method in compu_methods :
208
+ category = fe .selector (compu_method , "/!CATEGORY" )
209
+ if len (category ) > 0 and category [0 ].text == "LINEAR" :
210
+ numerator = fe .selector (compu_method , "/!COMPU-NUMERATOR" )[0 ]
211
+ denominator = fe .selector (compu_method , "/!COMPU-DENOMINATOR" )[0 ]
212
+ teiler = decimal .Decimal (fe .selector (denominator , "/!V" )[0 ].text )
213
+ [offset , factor ] = [decimal .Decimal (a .text ) for a in fe .selector (numerator , "/!V" )]
214
+ [offset , factor ] = [a / teiler for a in [offset , factor ]]
215
+ sig .offset = offset
216
+ sig .factor = factor
217
+ try :
218
+ sig .min = decimal .Decimal (fe .selector (compu_method , "!PHYS-CONSTRS!LOWER-LIMIT" )[0 ].text )
219
+ sig .max = decimal .Decimal (fe .selector (compu_method , "!PHYS-CONSTRS!UPPER-LIMIT" )[0 ].text )
220
+ except :
221
+ pass
222
+ unit = fe .selector (compu_method , ">!UNIT-REF" )
223
+ if len (unit ) > 0 :
224
+ try :
225
+ sig .unit = fe .selector (unit [0 ], "!DISPLAY-NAME" )[0 ].text
226
+ except :
227
+ pass
228
+ elif len (category ) > 0 and category [0 ].text == "TEXTTABLE" :
229
+ for compu_scale in fe .selector (compu_method , "/!COMPU-SCALE" ):
230
+ try :
231
+ value_name = fe .selector (compu_scale , "!COMPU-CONST!VT" )[0 ].text
232
+ except IndexError :
233
+ value_name = fe .get_desc_or_longname (compu_scale )
234
+ value_value = fe .selector (compu_scale , "!LOWER-LIMIT" )[0 ].text
235
+ sig .add_values (value_value , value_name )
236
+ sig .is_little_endian = is_little_endian
237
+ if not sig .is_little_endian :
238
+ sig .set_startbit (start_bit , bitNumbering = 1 )
239
+ else :
240
+ sig .start_bit = start_bit
241
+ sig .size = bit_length
242
+ sig .receivers = list (set (receiver_ecus ))
243
+
244
+ sig .add_comment (fe .get_desc_or_longname (signal ))
245
+ signals .append (sig )
246
+ return signals , ecus
247
+
248
+
181
249
def load (f , ** _options ):
182
250
fe = Fe (f )
183
251
result = {}
252
+ sig_group_counter = 0
184
253
185
254
clusters = fe .selector (fe .root , "//CLUSTER" )
186
255
names = [fe .sn (a ) for a in clusters ]
@@ -204,11 +273,35 @@ def load(f, **_options):
204
273
extended = arbitration_id_element .attrib .get ("EXTENDED-ADDRESSING" , 'false' ) == 'true'
205
274
frame_element = fe .selector (ft , ">FRAME-REF" )[0 ]
206
275
frame_size = int (fe .selector (frame_element , "/BYTE-LENGTH" )[0 ].text )
207
- pdu = fe .selector (frame_element , ">>PDU-REF" )[0 ]
208
276
209
- frame_name = fe .sn (pdu )
210
- # fe.selector(pdu, "<<!PDU-TRIGGERING")
211
- frame = canmatrix .Frame (name = frame_name )
277
+ pdu_instances = fe .selector (frame_element , "//PDU-INSTANCE" )
278
+
279
+ if len (pdu_instances ) > 1 :
280
+ frame_name = fe .sn (frame_element )
281
+ frame = canmatrix .Frame (name = frame_name )
282
+ for pdu_instance in pdu_instances :
283
+ pdu = fe .selector (pdu_instance , ">PDU-REF" )[0 ]
284
+ pdu_startbit_position = int (fe .selector (pdu_instance , "/BIT-POSITION" )[0 ].text , 0 )
285
+ signals , ecus = get_signals_for_pdu (fe , pdu , pdu_startbit_position )
286
+ for sig in signals :
287
+ frame .add_signal (sig )
288
+ for ecu in ecus :
289
+ db .add_ecu (ecu )
290
+
291
+ frame .add_signal_group (fe .sn (pdu ), sig_group_counter , [sig .name for sig in signals ])
292
+ sig_group_counter += 1
293
+ else :
294
+ pdu = fe .selector (pdu_instances [0 ], ">PDU-REF" )[0 ]
295
+ frame_name = fe .sn (pdu )
296
+ frame = canmatrix .Frame (name = frame_name )
297
+
298
+ signals , ecus = get_signals_for_pdu (fe , pdu )
299
+ for sig in signals :
300
+ frame .add_signal (sig )
301
+ for ecu in ecus :
302
+ db .add_ecu (ecu )
303
+
304
+ # fe.selector(pdu, "<<!PDU-TRIGGERING")
212
305
frame .size = frame_size
213
306
if len (output_ports ) > 0 :
214
307
pdu_triggerings = fe .selector (output_ports [0 ], ">>PDU-TRIGGERING-REF" )
@@ -231,69 +324,7 @@ def load(f, **_options):
231
324
if "CAN-FD" in [a .text for a in
232
325
fe .selector (ft , "//CAN-FRAME-TX-BEHAVIOR" ) + fe .selector (ft , "//CAN-FRAME-RX-BEHAVIOR" )]:
233
326
frame .is_fd = True
234
- for signal_instance in fe .selector (pdu , "//SIGNAL-INSTANCE" ):
235
- byte_order_element = fe .selector (signal_instance , "/IS-HIGH-LOW-BYTE-ORDER" )
236
- if byte_order_element [0 ].text == "false" :
237
- is_little_endian = True
238
- else :
239
- is_little_endian = False
240
-
241
- start_bit = int (fe .selector (signal_instance , "/BIT-POSITION" )[0 ].text , 0 )
242
- signal = fe .selector (signal_instance , ">SIGNAL-REF" )[0 ]
243
- ecu_instance_refs = fe .selector (signal_instance , "<<ECU" )
244
- receiver_ecus = []
245
- for ecu_instance_ref in ecu_instance_refs :
246
- if len (fe .selector (ecu_instance_ref , "^INPUT-PORT" )) > 0 :
247
- ecu_name = fe .sn (fe .get_referencable_parent (ecu_instance_ref ))
248
- receiver_ecus .append (ecu_name )
249
- db .add_ecu (canmatrix .Ecu (ecu_name ))
250
-
251
- signal_name = fe .sn (signal )
252
- coding = fe .selector (signal , ">CODING-REF" )[0 ]
253
- bit_length = int (fe .selector (coding , "/!BIT-LENGTH" )[0 ].text )
254
- compu_methods = fe .selector (coding , "/!COMPU-METHOD" )
255
- sig = canmatrix .Signal (name = signal_name )
256
-
257
- for compu_method in compu_methods :
258
- category = fe .selector (compu_method , "/!CATEGORY" )
259
- if len (category ) > 0 and category [0 ].text == "LINEAR" :
260
- numerator = fe .selector (compu_method , "/!COMPU-NUMERATOR" )[0 ]
261
- denominator = fe .selector (compu_method , "/!COMPU-DENOMINATOR" )[0 ]
262
- teiler = decimal .Decimal (fe .selector (denominator , "/!V" )[0 ].text )
263
- [offset , factor ] = [decimal .Decimal (a .text ) for a in fe .selector (numerator , "/!V" )]
264
- [offset , factor ] = [a / teiler for a in [offset , factor ]]
265
- sig .offset = offset
266
- sig .factor = factor
267
- try :
268
- sig .min = decimal .Decimal (fe .selector (compu_method , "!PHYS-CONSTRS!LOWER-LIMIT" )[0 ].text )
269
- sig .max = decimal .Decimal (fe .selector (compu_method , "!PHYS-CONSTRS!UPPER-LIMIT" )[0 ].text )
270
- except :
271
- pass
272
- unit = fe .selector (compu_method , ">!UNIT-REF" )
273
- if len (unit ) > 0 :
274
- try :
275
- sig .unit = fe .selector (unit [0 ],"!DISPLAY-NAME" )[0 ].text
276
- except :
277
- pass
278
- elif len (category ) > 0 and category [0 ].text == "TEXTTABLE" :
279
- for compu_scale in fe .selector (compu_method , "/!COMPU-SCALE" ):
280
- try :
281
- value_name = fe .selector (compu_scale , "!COMPU-CONST!VT" )[0 ].text
282
- except IndexError :
283
- value_name = fe .get_desc_or_longname (compu_scale )
284
- value_value = fe .selector (compu_scale , "!LOWER-LIMIT" )[0 ].text
285
- sig .add_values (value_value , value_name )
286
- sig .is_little_endian = is_little_endian
287
- if not sig .is_little_endian :
288
- sig .set_startbit (start_bit , bitNumbering = 1 )
289
- else :
290
- sig .start_bit = start_bit
291
- sig .size = bit_length
292
- sig .receivers = list (set (receiver_ecus ))
293
-
294
- sig .add_comment (fe .get_desc_or_longname (signal ))
295
327
296
- frame .add_signal (sig )
297
328
db .add_frame (frame )
298
329
return result
299
330
0 commit comments