From 20cc603922983f154d10b7d56c6b49e5e02997bd Mon Sep 17 00:00:00 2001 From: tao_z <tzj0429@163.com> Date: Mon, 06 Jun 2022 00:13:05 +0800 Subject: [PATCH] 初步bootloader实现。dbc解析存在解析值不正确问题。 --- dbc.py | 238 ++++++++++++++++++++++++++++++++--------------------------- 1 files changed, 128 insertions(+), 110 deletions(-) diff --git a/dbc.py b/dbc.py index 9e7a470..3bb643a 100644 --- a/dbc.py +++ b/dbc.py @@ -22,8 +22,10 @@ UNSIGNED = 0 SIGNED = 1 + def normalizeValueTable(table): return {int(k): v for k, v in table.items()} + @attr.s(cmp=False) class Frame: @@ -73,7 +75,7 @@ if sig.getStartbit() + int(sig.size) > maxBit: maxBit = sig.getStartbit() + int(sig.size) self.size = max(self.size, int(math.ceil(maxBit / 8))) - + def setFdType(self): """Try to guess and set the CAN type for every frame. If a Frame is longer than 8 bytes, it must be Flexible Data Rate frame (CAN-FD). @@ -92,7 +94,7 @@ bitfieldLe = [] bitfieldBe = [] - for i in range(0,64): + for i in range(0, 64): bitfieldBe.append(0) bitfieldLe.append(0) bitfield.append(0) @@ -100,21 +102,21 @@ for sig in self.signals: i += 1 - for bit in range(sig.getStartbit(), sig.getStartbit() + int(sig.size)): + for bit in range(sig.getStartbit(), + sig.getStartbit() + int(sig.size)): if sig.is_little_endian: bitfieldLe[bit] = i else: bitfieldBe[bit] = i - for i in range(0,8): - for j in range(0,8): - bitfield[i*8+j] = bitfieldLe[i*8+(7-j)] + for i in range(0, 8): + for j in range(0, 8): + bitfield[i * 8 + j] = bitfieldLe[i * 8 + (7 - j)] - for i in range(0,8): - for j in range(0,8): - if bitfield[i*8+j] == 0: - bitfield[i*8+j] = bitfieldBe[i*8+j] - + for i in range(0, 8): + for j in range(0, 8): + if bitfield[i * 8 + j] == 0: + bitfield[i * 8 + j] = bitfieldBe[i * 8 + j] return bitfield @@ -143,48 +145,51 @@ * _multiplex ('Multiplexor' or Number of Multiplex) """ - name = attr.ib(default = "") + name = attr.ib(default="") # float_factory = attr.ib(default=defaultFloatFactory) float_factory = defaultFloatFactory startBit = attr.ib(type=int, default=0) - size = attr.ib(type=int, default = 0) - is_little_endian = attr.ib(type=bool, default = True) - is_signed = attr.ib(type=bool, default = True) - offset = attr.ib(converter = float_factory, default = float_factory(0.0)) - factor = attr.ib(converter = float_factory, default = float_factory(1.0)) + size = attr.ib(type=int, default=0) + is_little_endian = attr.ib(type=bool, default=True) + is_signed = attr.ib(type=bool, default=True) + offset = attr.ib(converter=float_factory, default=float_factory(0.0)) + factor = attr.ib(converter=float_factory, default=float_factory(1.0)) # offset = attr.ib(converter = float_factory, default = 0.0) - min = attr.ib(converter=float_factory) + min = attr.ib(converter=float_factory) + @min.default def setDefaultMin(self): - return self.calcMin() + return self.calcMin() - max = attr.ib(converter = float_factory) + max = attr.ib(converter=float_factory) + @max.default def setDefaultMax(self): - return self.calcMax() + return self.calcMax() - unit = attr.ib(type=str, default ="") - receiver = attr.ib(default = attr.Factory(list)) - comment = attr.ib(default = None) - multiplex = attr.ib(default = None) + unit = attr.ib(type=str, default="") + receiver = attr.ib(default=attr.Factory(list)) + comment = attr.ib(default=None) + multiplex = attr.ib(default=None) - mux_value = attr.ib(default = None) + mux_value = attr.ib(default=None) is_float = attr.ib(type=bool, default=False) - enumeration = attr.ib(type=str, default = None) - comments = attr.ib(type=dict, default = attr.Factory(dict)) - attributes = attr.ib(type=dict, default = attr.Factory(dict)) - values = attr.ib(type=dict, converter=normalizeValueTable, default = attr.Factory(dict)) - calc_min_for_none = attr.ib(type=bool, default = True) - calc_max_for_none = attr.ib(type=bool, default = True) - muxValMax = attr.ib(default = 0) - muxValMin = attr.ib(default = 0) - muxerForSignal= attr.ib(type=str, default = None) + enumeration = attr.ib(type=str, default=None) + comments = attr.ib(type=dict, default=attr.Factory(dict)) + attributes = attr.ib(type=dict, default=attr.Factory(dict)) + values = attr.ib(type=dict, + converter=normalizeValueTable, + default=attr.Factory(dict)) + calc_min_for_none = attr.ib(type=bool, default=True) + calc_max_for_none = attr.ib(type=bool, default=True) + muxValMax = attr.ib(default=0) + muxValMin = attr.ib(default=0) + muxerForSignal = attr.ib(type=str, default=None) def __attrs_post_init__(self): self.multiplex = self.multiplexSetter(self.multiplex) - @property def spn(self): @@ -253,7 +258,8 @@ startBitInternal = startBitInternal + self.size - 1 # bit numbering not consistent with byte order. reverse if bitNumbering is not None and bitNumbering != self.is_little_endian: - startBitInternal = startBitInternal - (startBitInternal % 8) + 7 - (startBitInternal % 8) + startBitInternal = startBitInternal - ( + startBitInternal % 8) + 7 - (startBitInternal % 8) return int(startBitInternal) def calculateRawRange(self): @@ -261,7 +267,7 @@ :return: Signal range, i.e. (0, 15) for unsigned 4 bit Signal or (-8, 7) for signed one. :rtype: tuple """ - rawRange = 2 ** (self.size - (1 if self.is_signed else 0)) + rawRange = 2**(self.size - (1 if self.is_signed else 0)) return (self.float_factory(-rawRange if self.is_signed else 0), self.float_factory(rawRange - 1)) @@ -304,15 +310,12 @@ value = value_key break else: - raise ValueError( - "{} is invalid value choice for {}".format(value, self) - ) + raise ValueError("{} is invalid value choice for {}".format( + value, self)) if not (self.min <= value <= self.max): - print( - "Value {} is not valid for {}. Min={} and Max={}".format( - value, self, self.min, self.max) - ) + print("Value {} is not valid for {}. Min={} and Max={}".format( + value, self, self.min, self.max)) raw_value = (value - self.offset) / self.factor if not self.is_float: @@ -338,7 +341,9 @@ def __str__(self): return self.name + class DBC: + def __init__(self, dbcfile=None): self.filePath = dbcfile self.frames = self.__load() @@ -349,7 +354,7 @@ frameList = [] i = 0 frame = None - with open(self.filePath, mode='r', encoding='gb2312') as f: + with open(self.filePath, mode='r', encoding=dbcImportEncoding) as f: for line in f.readlines(): i = i + 1 l = line.strip() @@ -358,14 +363,14 @@ # logging.info(l) if l.startswith('BO_ '): # frames - regexp = re.compile("^BO\_ ([^\ ]+) ([^\ ]+) *: ([^\ ]+) ([^\ ]+)") + regexp = re.compile( + "^BO\_ ([^\ ]+) ([^\ ]+) *: ([^\ ]+) ([^\ ]+)") temp = regexp.match(l) # name, id, dlc, transmitters - frame = Frame( - temp.group(2), - id=int(temp.group(1)), - size=int(temp.group(3)), - transmitters=temp.group(4).split()) + frame = Frame(temp.group(2), + id=int(temp.group(1)), + size=int(temp.group(3)), + transmitters=temp.group(4).split()) frameList.append(frame) pass elif l.startswith('SG_ '): @@ -375,30 +380,34 @@ temp = regexp.match(l) if temp: extras = {} - receiver = list(map(str.strip, temp.group(11).split(','))) - tempSig = Signal( - temp.group(1), - startBit=int(temp.group(2)), - size=int(temp.group(3)), - is_little_endian=(int(temp.group(4)) == 1), - is_signed=(temp.group(5) == '-'), - factor=temp.group(6), - offset=temp.group(7), - min=temp.group(8), - max=temp.group(9), - unit=temp.group(10), - receiver=receiver, - **extras - ) + receiver = list( + map(str.strip, + temp.group(11).split(','))) + tempSig = Signal(temp.group(1), + startBit=int(temp.group(2)), + size=int(temp.group(3)), + is_little_endian=(int( + temp.group(4)) == 1), + is_signed=(temp.group(5) == '-'), + factor=temp.group(6), + offset=temp.group(7), + min=temp.group(8), + max=temp.group(9), + unit=temp.group(10), + receiver=receiver, + **extras) if not tempSig.is_little_endian: # startbit of motorola coded signals are MSB in dbc - tempSig.setStartbit(int(temp.group(2)), bitNumbering=1) + tempSig.setStartbit(int(temp.group(2)), + bitNumbering=1) frame.signals.append(tempSig) else: pattern = "^SG\_ +(\w+) +(\w+) *: *(\d+)\|(\d+)@(\d+)([\+|\-]) +\(([0-9.+\-eE]+),([0-9.+\-eE]+)\) +\[([0-9.+\-eE]+)\|([0-9.+\-eE]+)\] +\"(.*)\" +(.*)" regexp = re.compile(pattern) temp = regexp.match(l) - receiver = list(map(str.strip, temp.group(12).split(','))) + receiver = list( + map(str.strip, + temp.group(12).split(','))) multiplex = temp.group(2) is_complex_multiplexed = False @@ -413,25 +422,24 @@ try: multiplex = int(multiplex[1:]) except: - raise Exception('error decoding line',line) + raise Exception('error decoding line', line) extras = {} - tempSig = Signal( - temp.group(1), - startBit=int(temp.group(3)), - size=int(temp.group(4)), - is_little_endian=(int(temp.group(5)) == 1), - is_signed=(temp.group(6) == '-'), - factor=temp.group(7), - offset=temp.group(8), - min=temp.group(9), - max=temp.group(10), - unit=temp(11), - receiver=receiver, - multiplex=multiplex, - **extras - ) + tempSig = Signal(temp.group(1), + startBit=int(temp.group(3)), + size=int(temp.group(4)), + is_little_endian=(int( + temp.group(5)) == 1), + is_signed=(temp.group(6) == '-'), + factor=temp.group(7), + offset=temp.group(8), + min=temp.group(9), + max=temp.group(10), + unit=temp(11), + receiver=receiver, + multiplex=multiplex, + **extras) if is_complex_multiplexed: tempSig.is_multiplexer = True @@ -439,7 +447,8 @@ if not tempSig.is_little_endian: # startbit of motorola coded signals are MSB in dbc - tempSig.setStartbit(int(temp.group(3)), bitNumbering=1) + tempSig.setStartbit(int(temp.group(3)), + bitNumbering=1) frame.addSignal(tempSig) if is_complex_multiplexed: @@ -468,8 +477,10 @@ if testF.id == int(tmpId): for signal in testF.signals: if signal.name == signalName: - for i in range(math.floor(len(tempList) / 2)): - signal.values[tempList[i * 2].strip()] = tempList[i * 2 + 1].strip() + for i in range( + math.floor(len(tempList) / 2)): + signal.values[tempList[i * 2].strip( + )] = tempList[i * 2 + 1].strip() break break elif l.startswith("VAL_TABLE_ "): @@ -491,7 +502,8 @@ regexp = re.compile("^BA\_ +\"[A-Za-z0-9[\-_ .]+\" +(.+)") tempba = regexp.match(l) if tempba.group(1).strip().startswith("BO_ "): - regexp = re.compile(r"^BA_ +\"(.*)\" +BO_ +(\w+) +(.+);") + regexp = re.compile( + r"^BA_ +\"(.*)\" +BO_ +(\w+) +(.+);") temp = regexp.match(l) tempId = temp.group(2) for testF in frameList: @@ -501,10 +513,12 @@ tempCys = temp.group(3) frame.cycle = int(tempCys) elif l.startswith("SIG_GROUP_ "): - regexp = re.compile("^SIG\_GROUP\_ +(\w+) +(\w+) +(\w+) +\:(.*);") + regexp = re.compile( + "^SIG\_GROUP\_ +(\w+) +(\w+) +(\w+) +\:(.*);") temp = regexp.match(l) elif l.startswith("SIG_VALTYPE_ "): - regexp = re.compile("^SIG\_VALTYPE\_ +(\w+) +(\w+)\s*\:(.*);") + regexp = re.compile( + "^SIG\_VALTYPE\_ +(\w+) +(\w+)\s*\:(.*);") temp = regexp.match(l) elif l.startswith("BA_DEF_DEF_ "): pattern = "^BA\_DEF\_DEF\_ +\"([A-Za-z0-9\-_\.]+)\" +(.+)\;" @@ -516,7 +530,7 @@ pattern = "^EV_ +([A-Za-z0-9\-_]+) *\: +([0-9]+) +\[([0-9.+\-eE]+)\|([0-9.+\-eE]+)\] +\"(\w*)\" +([0-9.+\-eE]+) +([0-9.+\-eE]+) +([A-Za-z0-9\-_]+) +(.*);" regexp = re.compile(pattern) temp = regexp.match(l) - + return frameList def __setFdType(self): @@ -527,13 +541,13 @@ for frame in self.frames: # if frame.size == 0: frame.calcDLC() - print(frame.id, frame.size) + # print(frame.id, frame.size) if frame.size > 8: frame.is_fd = True - + def __setExtended(self): for frame in self.frames: - # extended-flag is implicite in canid, thus repair this: + # extended-flag is implicite in canid, thus repair this: if frame.id > 0x80000000: frame.id -= 0x80000000 frame.extended = 1 @@ -565,37 +579,37 @@ return test return None - def __getSignalVal(self, signal:Signal, data='00 01 02 03 04 05 06 07'): + def __getSignalVal(self, signal: Signal, data='00 01 02 03 04 05 06 07'): dataList = data.strip().split(' ') _startbit = signal.startBit _bitsize = signal.size - _little = signal.is_little_endian # (1: Intel, 0: Motorola) - _byteSize = math.ceil((signal.size + _startbit%8)/8) - _startByte = math.floor(_startbit/8) + _little = signal.is_little_endian # (1: Intel, 0: Motorola) + _byteSize = math.ceil((signal.size + _startbit % 8) / 8) + _startByte = math.floor(_startbit / 8) phyvalue = 0 rawvalue = '' - base = int('{0:0>8}'.format('1'*_bitsize+'0'*(_startbit%8)), 2) + base = int('{0:0>8}'.format('1' * _bitsize + '0' * (_startbit % 8)), 2) _byteNum = 0 - _byteList= [] + _byteList = [] while _byteNum < _byteSize: # tmpbase = (base >> (8*_byteNum)) & 0xff - _byteList.append(dataList[_startByte+_byteNum]) + _byteList.append(dataList[_startByte + _byteNum]) _byteNum += 1 if _little == 1: _byteList.reverse() for _byte in _byteList: rawvalue += _byte - rawvalue = ((int(rawvalue,16) & base) >> (_startbit%8)) + rawvalue = ((int(rawvalue, 16) & base) >> (_startbit % 8)) return {"phy": signal.raw2phys(rawvalue), "raw": rawvalue} # print(_startByte, _byteSize, _bitsize, int(dataList[_startByte], 16), int('{0:0>8}'.format('1'*_bitsize+'0'*(_startbit%8)), 2)) - + def analyzer(self, msgid=None, data='00 01 02 03 04 05 06 07'): - '''analysis given data - + '''analysis given data + Keyword Arguments: msgid {int} -- msg id (base 10) (default: {None}) data {str} -- given data (default: {'00 01 02 03 04 05 06 07'}) - + Returns: dict -- key sorted by signal index ''' @@ -615,7 +629,11 @@ break return ret + if __name__ == '__main__': - testDbc = DBC("data/SX7H.dbc") - abc=testDbc.analyzer(msgid=1056, data='40 01 C8 00 FF 00 00 00') - print(abc) \ No newline at end of file + testDbc = DBC("DBC/DFLZM.dbc") + abc = testDbc.analyzer(msgid=1056, data='40 01 C8 00 FF 00 00 00') + print(abc) + print(abc[5]["name"]) + print(abc[6]["name"]) + print(abc[4]["name"]) -- Gitblit v1.8.0