Index: run.update_package.py =================================================================== diff -u -r5b6f3d91478d1da65e094cdb802d6c19ab4385d8 -ra99d0580e0f14cdf80321e963a7121a2225d2c4f --- run.update_package.py (.../run.update_package.py) (revision 5b6f3d91478d1da65e094cdb802d6c19ab4385d8) +++ run.update_package.py (.../run.update_package.py) (revision a99d0580e0f14cdf80321e963a7121a2225d2c4f) @@ -19,7 +19,7 @@ '######') # TODO update input_arguments_status = False - if input_arguments_status is True: + if input_arguments_status: stack = sys.argv[2] if sys.argv[2] != '' else None Index: scripts/update_package_script/update_package.py =================================================================== diff -u -r5b6f3d91478d1da65e094cdb802d6c19ab4385d8 -ra99d0580e0f14cdf80321e963a7121a2225d2c4f --- scripts/update_package_script/update_package.py (.../update_package.py) (revision 5b6f3d91478d1da65e094cdb802d6c19ab4385d8) +++ scripts/update_package_script/update_package.py (.../update_package.py) (revision a99d0580e0f14cdf80321e963a7121a2225d2c4f) @@ -1,12 +1,29 @@ import os import re -from scripts.base.base import Base, SWUpdateTargets +from enum import Enum, unique from scripts.update_package_script.utilities import Utilities, SWUpdateCommands, CanCommStatus +# TODO remove the base class -class SoftwareUpdateScript(Base): +class SWUpdateEnum(Enum): + @classmethod + def has_value(cls, value): + return value in cls._value2member_map_ + +@unique +class SWUpdateTargets(SWUpdateEnum): + TARGET_TD = 0 + TARGET_TD_FPGA = 1 + TARGET_DD = 2 + TARGET_DD_FPGA = 3 + TARGET_RO = 4 + TARGET_RO_FPGA = 5 + NUM_OF_TARGETS = 6 + +class SoftwareUpdateScript: + _DECODED_BYTES_KEY_NAME = 'decoded_bytes' _CUR_DATA_INDEX_KEY_NAME = 'cur_data_index' _CUR_INSERT_DATA_INDEX_KEY_NAME = 'cur_insert_index' @@ -27,13 +44,16 @@ _XML_REPORT_END_TAG = "" _XML_REPORT_HEADER_SIZE = 2 + SW_UPDATE_FLASH_BUFFER_SIZE = 256 + _SW_UPDATE_STACK = 'stack_name' + _BINARY_FILE_SIZE = 'file_size' + _WRITTEN_BYTE_COUNT = 'byte_count' + def __init__(self): - super().__init__() - self._signature_start_in_bytes = bytes(self.SIGNATURE_START, 'utf-8') - self._signature_end_in_bytes = bytes(self.SIGNATURE_END, 'utf-8') - self._decode_data_status = dict() - self._xml_report_values = dict() + self._decode_data_status = dict() # TODO remove + self._xml_report_values = dict() # tODO remove + self._sw_update_status = dict() self._utilities = Utilities() def _reset_variables(self): @@ -61,18 +81,33 @@ self._xml_report_values[self._XML_REPORT_BIN_SIZE_KEY_NAME] = 0 self._xml_report_values['raw'] = '' + self._sw_update_status[self._SW_UPDATE_STACK] = 0 + self._sw_update_status[self._BINARY_FILE_SIZE] = 0 + self._sw_update_status[self._WRITTEN_BYTE_COUNT] = 0 + self._utilities.clear_msg_ack_nack_status(self._utilities.SEND_MSG_ACK_STATUS_KEY_NAME) self._utilities.clear_msg_ack_nack_status(self._utilities.UPDATE_MSG_ACK_STATUS_KEY_NAME) - def _verify_signature(self, signature: bytes): - # TODO fill up - pass + def _prepare_for_sw_update(self, stack_to_update: str, file_path: str): - def _verify_key(self): - pass + status = True + self._reset_variables() + # TODO how to read from a manifest file. Right now it is passed directly + stack_to_update = 'TARGET_' + stack_to_update.upper() + self._sw_update_status[self._SW_UPDATE_STACK] = SWUpdateTargets[stack_to_update].value + self._sw_update_status[self._BINARY_FILE_SIZE] = os.path.getsize(file_path) - def _get_decode_variables(self, line_bytes: bytes): + send_ack_status = self._utilities.get_msg_ack_nack_status(self._utilities.SEND_MSG_ACK_STATUS_KEY_NAME) + if send_ack_status == CanCommStatus.CAN_COMM_NOT_STARTED.value: + self._utilities.send_command_msg(SWUpdateCommands.SW_UPDATE_START.value, + self._sw_update_status[self._SW_UPDATE_STACK]) + # TODO create a wait for response back + # TODO check for status + return status + + def _get_decode_variables(self, line_bytes: bytes): # TODO remove + if len(self._decode_data_status[self._RESIDUAL_BYTES_KEY_NAME]) != 0: line_bytes = self._decode_data_status[self._RESIDUAL_BYTES_KEY_NAME] + line_bytes @@ -90,7 +125,7 @@ print("Breaking {} {} {} {} {}".format(code, convert, s, a, b)) break - def _decode_line(self, line_bytes: bytes): + def _decode_line(self, line_bytes: bytes): # TODO remove start_index = 0 @@ -124,7 +159,7 @@ self._decode_data_status[self._DECODED_BYTES_KEY_NAME].append(line_bytes[d]) self._decode_data_status[self._CUR_DATA_INDEX_KEY_NAME] += 1 - def _process_read_line(self, line: bytes): + def _process_read_line_OBSOLETE(self, line: bytes): if self._signature_start_in_bytes in line: if self._signature_end_in_bytes: @@ -147,6 +182,26 @@ self._get_decode_variables(line) if self._decode_data_status['decode_values_found'] is False else None self._decode_line(line) + def _process_binary_file(self, file_path: str): + + # TODO add a timeout (e.g. 10 minutes that is very long) to make sure we are not stuck + f = open(file_path, 'rb') + + while True: + line = None + update_ack_status = self._utilities.get_msg_ack_nack_status(self._utilities.UPDATE_MSG_ACK_STATUS_KEY_NAME) + + if update_ack_status == CanCommStatus.CAN_COMM_READY.value: + line = f.read(self.SW_UPDATE_FLASH_BUFFER_SIZE) + target = self._sw_update_status[self._SW_UPDATE_STACK] + self._utilities.send_software_update_msg(target, line, self.SW_UPDATE_FLASH_BUFFER_SIZE) + + if line == b'': break + + f.close() + + + def _handle_processed_data(self): send_ack_status = self._utilities.get_msg_ack_nack_status(self._utilities.SEND_MSG_ACK_STATUS_KEY_NAME) @@ -200,7 +255,7 @@ if self._utilities.get_msg_ack_nack_status(self._utilities.UPDATE_MSG_ACK_STATUS_KEY_NAME) == 2: #TODO change to successful self._decode_data_status[self._SIG_MSG_SEND_COMPLETE_KEY_NAME] = True - def _process_remaining_data(self): + def _process_remaining_data(self): # TODO remvoe while True: self._handle_processed_data() @@ -227,24 +282,21 @@ # 8. Show progress for file in os.listdir(packages_dir): - if file.endswith(".bin"): - with open(os.path.join(packages_dir, file), 'rb') as f: - # Get ready for the next binary file - self._reset_variables() - for line in f: - self._process_read_line(line) - self._handle_processed_data() + if not file.endswith(".bin"): continue + path = os.path.join(packages_dir, file) - self._process_remaining_data() + if self._prepare_for_sw_update(stack_to_update, path): + self._process_binary_file(path) - f.close() + #self._process_remaining_data() + # TODO for testing remove - print(self._decode_data_status[self._CUR_DATA_INDEX_KEY_NAME], - self._decode_data_status[self._DECODED_BYTES_KEY_NAME][0], - self._decode_data_status[self._DECODED_BYTES_KEY_NAME][-4], - self._decode_data_status[self._DECODED_BYTES_KEY_NAME][-3], - self._decode_data_status[self._DECODED_BYTES_KEY_NAME][-2], - self._decode_data_status[self._DECODED_BYTES_KEY_NAME][-1], - len(self._decode_data_status[self._DECODED_BYTES_KEY_NAME])) + #print(self._decode_data_status[self._CUR_DATA_INDEX_KEY_NAME], + # self._decode_data_status[self._DECODED_BYTES_KEY_NAME][0], + # self._decode_data_status[self._DECODED_BYTES_KEY_NAME][-4], + # self._decode_data_status[self._DECODED_BYTES_KEY_NAME][-3], + # self._decode_data_status[self._DECODED_BYTES_KEY_NAME][-2], + # self._decode_data_status[self._DECODED_BYTES_KEY_NAME][-1], + # len(self._decode_data_status[self._DECODED_BYTES_KEY_NAME])) # TODO remove Index: scripts/update_package_script/utilities.py =================================================================== diff -u -r5b6f3d91478d1da65e094cdb802d6c19ab4385d8 -ra99d0580e0f14cdf80321e963a7121a2225d2c4f --- scripts/update_package_script/utilities.py (.../utilities.py) (revision 5b6f3d91478d1da65e094cdb802d6c19ab4385d8) +++ scripts/update_package_script/utilities.py (.../utilities.py) (revision a99d0580e0f14cdf80321e963a7121a2225d2c4f) @@ -20,9 +20,10 @@ CAN_COMM_IN_PROGRESS = 1 CAN_COMM_SUCCESSFUL = 2 CAN_COMM_TIME_OUT = 3 - NUM_OF_CAN_COMM_STATES = 4 + CAN_COMM_READY = 4 + NUM_OF_CAN_COMM_STATES = 5 -class Utilities(Base): +class Utilities: _CRC32_TABLE = ( 0x00000000, 0x1EDC6F41, 0x3DB8DE82, 0x2364B1C3, 0x7B71BD04, 0x65ADD245, 0x46C96386, 0x58150CC7, @@ -74,7 +75,6 @@ def __init__(self): - super().__init__() self._can_bus = SocketcanBus(channel=self._CAN_INTERFACE) self._msg_id_count = 0 self._msg_sw_update_index = 0 @@ -105,12 +105,13 @@ self._send_can_message(self._SEND_CMD_MAIL_BOX, can_msg_bytes, self.SEND_MSG_ACK_STATUS_KEY_NAME, wait_for_resp_s=self._MIN_CAN_WAIT_FOR_RESP_S) - # TODO remove + # TODO remove for testing only sleep(0.7) self._msg_ack_nack_status[self.SEND_MSG_ACK_STATUS_KEY_NAME] = CanCommStatus.CAN_COMM_SUCCESSFUL.value + self._msg_ack_nack_status[self.UPDATE_MSG_ACK_STATUS_KEY_NAME] = CanCommStatus.CAN_COMM_READY.value # TODO remove - def send_software_update_msg(self, target: int, data: list, update_payload_len: int, signature_msg: bool = False): + def send_software_update_msg(self, target: int, data: bytes, update_payload_len: int, signature_msg: bool = False): mail_box = self._update_mail_boxes[target][0] time_out_s = self._update_mail_boxes[target][1] @@ -120,7 +121,7 @@ temp = bytes() can_msg_bytes = self._convert_data_to_bytes('