def test_create_three_threads_with_args(self): def modify_test_var_thread(val): self.mainw.test_var = val for i in range(3): thread = GuiThread(process=modify_test_var_thread, args=(i,)) self.mainw.fetch_thread(thread) self.mainw.start_thread() self.assertEquals(thread.t_id, i) self.assertEquals(self.mainw.test_var, i) self.assertEquals(GuiThread.num_of_threads(), 3)
def test_create_periodic_thread(self): def modify_test_var_thread(): try: self.mainw.test_var += 1 except AttributeError: self.mainw.test_var = 0 periodic_thread = GuiThread(process=modify_test_var_thread, period=0.5) self.mainw.fetch_thread(periodic_thread).start() time.sleep(2) periodic_thread.kill() self.assertEquals(self.mainw.test_var, 4)
def write_packets_procedure(self): self.send_rx_flush_req() self.disable_objects_for_transmission_signal.emit() time.sleep(0.5) t_start = time.time() bank_name_full = os.path.basename(self.bin_packets.bin_path) bank_name = os.path.splitext(bank_name_full)[0] self.progress_bar.set_title("SENDING: {}".format(bank_name_full)) to_signal(self.progress_bar.display).emit() tot_tx_bytes = 0 while self.progress_bar.isHidden(): time.sleep(0.1) packets = {p.b_address: p for p in self.bin_packets} packet = packets.get(packets.keys()[0]) max_timeout = len(packets) * self.__retx_timeout * 4 print "max timeout", max_timeout/60 debug("Sending bin with packetsize: {}".format(len(packet.payload))) while packets: if self.progress_bar.isHidden(): self.gui_communication_signal.emit("Upload procedure terminated") break self.check_resp_thr = GuiThread(self.check_repsonse, args=(MessageSender.context,)) self.check_resp_thr.start() self.send_packet(packet.payload, b_address=packet.b_address) while self.check_resp_thr.returned() is None: time.sleep(0.001) response = self.check_resp_thr.returned() if response == RxMessage.rx_id_tuple.index('ack'): self.tx_stats.ack() self.progress_bar.set_val_signal.emit(float(tot_tx_bytes) / self.bin_packets.packets_amount * 100) tot_tx_bytes += len(packet.payload) packets.pop(packet.b_address) try: packet = packets.get(packets.keys()[0]) except IndexError: pass elif response == RxMessage.rx_id_tuple.index('dtx'): self.tx_stats.dtx() else: self.tx_stats.nack() if time.time() - t_start > max_timeout: self.__tear_down() raise SendTimeout("TIMEOUT") else: if self.reload_sram(): self.parent_send_msg(MessageSender.ID.reload_sram) self.gui_communication_signal.emit("File transmitted in: {}".format(time.time() - t_start)) self.gui_communication_signal.emit(self.tx_stats) self.message_sender.send(m_id=MessageSender.ID.get_write_stats) self.set_bank_name(bank_name.replace('_sram', '')) to_signal(self.progress_bar.hide).emit() self.enable_objects_after_transmission_signal.emit()
def test_create_periodic_thread_with_delay(self): def modify_test_var_thread(): try: self.mainw.test_var += 1 except AttributeError: self.mainw.test_var = 0 period = 0.5 delay = 0.3 sleep = 2 periodic_thread = GuiThread(process=modify_test_var_thread, period=period, delay=delay) self.mainw.fetch_thread(periodic_thread).start() time.sleep(sleep) periodic_thread.kill() self.assertEquals(self.mainw.test_var, sleep/period - 1)
def test_create_single_thread(self): def modify_test_var_thread(): self.mainw.test_var = 99 thread = GuiThread(process=modify_test_var_thread) self.mainw.fetch_thread(thread) self.mainw.start_thread() self.assertEquals(self.mainw.test_var, 99) self.assertEquals(thread.t_id, 0)
def read_packets_procedure(self): self.disable_objects_for_transmission_signal.emit() self.message_sender.send(MessageSender.ID.rxflush) time.sleep(0.5) max_timeout = 20 t_start = time.time() self.progress_bar.set_title("RECEIVING") to_signal(self.progress_bar.display).emit() packet_num = 0 while self.progress_bar.isHidden(): time.sleep(0.1) while not self.receiver: if self.progress_bar.isHidden(): self.gui_communication_signal.emit("Read procedure terminated") break context = self.send_request(packet_num=packet_num) self.context_to_packet_map[context] = packet_num self.check_resp_thr = GuiThread(self.check_response, args=(context,)) self.check_resp_thr.start() while self.check_resp_thr.returned() is None: time.sleep(0.001) response = self.check_resp_thr.returned() if response == RxMessage.rx_id_tuple.index('ack'): self.tx_stats.ack() self.progress_bar.set_val_signal.emit(float(packet_num) / 16 * 100) packet_num += 1 else: self.tx_stats.nack() time.sleep(0.5) if time.time() - t_start > max_timeout: self.tear_down_on_fail() break else: self.gui_communication_signal.emit("File received in: {}".format(time.time() - t_start)) self.gui_communication_signal.emit(self.tx_stats) self.extra_teardown() to_signal(self.progress_bar.hide).emit() self.enable_objects_after_transmission_signal.emit() if self.auto_open(): self.event_handler.open_bin_file()
def test_periodic_thread_suspend_and_resume(self): def modify_test_var_thread(): try: self.mainw.test_var += 1 except AttributeError: self.mainw.test_var = 0 period = 0.5 suspend_time_units = 3 periodic_thread = GuiThread(process=modify_test_var_thread, period=period) self.mainw.fetch_thread(periodic_thread).start() t0 = time.time() time.sleep(period * 2) periodic_thread.suspend() time.sleep(period * suspend_time_units) periodic_thread.resume() time.sleep(period * 2) periodic_thread.kill() periodic_thread.wait() t_tot = round(time.time() - t0) self.assertEquals(self.mainw.test_var, t_tot/period - suspend_time_units - 1)
def test_suspend_all_threads(self): def modify_test_var_thread(): try: self.mainw.test_var += 1 except AttributeError: self.mainw.test_var = 0 period = 0.2 num_of_threads = 3 for i in range(num_of_threads): thread = GuiThread(process=modify_test_var_thread, period=period) self.mainw.fetch_thread(thread) thread.start() time.sleep(1) GuiThread.suspend_all_threads() time.sleep(1) GuiThread.kill_all_threads() self.assertEquals(self.mainw.test_var, 14) self.assertEquals(GuiThread.num_of_threads(), 0)
def __init__(self, parent, bin_packets, retx_timeout=0.5): self.__retx_timeout = retx_timeout self.rx_message_buffer = parent.rx_message_buffer self.message_sender = parent.message_sender self.gui_communication_signal = parent.gui_communication_signal self.progress_bar = parent.progress_bar self.bin_packets = bin_packets self.tx_stats = TransmissionStats() self.write_thread = GuiThread(self.write_packets_procedure) self.parent_send_msg = parent.send_message self.set_bank_name = parent.set_bank_name self.disable_objects_for_transmission_signal = parent.disable_objects_for_transmission_signal self.enable_objects_after_transmission_signal = parent.enable_objects_after_transmission_signal self.reload_sram = parent.emulation_panel.emulate_file_on_upload.isChecked
def apply_button_slot(self): try: self.bank_info.enable_digidiag = self.enable_digidiag_check_box.isChecked( ) self.bank_info.override_digidiag = self.override_digidiag_frames_check_box.isChecked( ) raw_frames = self.custom_frames_table.get() self.bank_info.frames_vector = raw_frames self.info_box.setText('') self.info_box.setText("Sending data...") msg_thread = self.message_sender( message_id=MessageSender.ID.update_bank_data, body=self.bank_info.raw_content, timeout=1, re_tx=3) self.apply_button.setDisabled(True) if self.__tmp_resp_msg_thread is not None: self.__tmp_resp_msg_thread.kill() self.__tmp_resp_msg_thread = GuiThread(self.watch_message, args=(msg_thread, )) self.__tmp_resp_msg_thread.start() except Exception as e: self.info_box.setText(e.message)
def __init__(self, parent, message_id, retx_timeout=1): self.__retx_timeout = retx_timeout self.message_id = message_id self.rx_message_buffer = parent.rx_message_buffer self.message_sender = parent.message_sender self.gui_communication_signal = parent.gui_communication_signal self.progress_bar = parent.progress_bar self.tx_stats = TransmissionStats() self.read_thread = GuiThread(self.read_packets_procedure) self.context_to_packet_map = {} self.receiver = BinReceiver(packet_size=256*8) self.get_bank_name = parent.banks_panel.get_bank_name_text self.update_file_list = parent.bin_file_panel.combo_box.moveOnTop self.disable_objects_for_transmission_signal = parent.disable_objects_for_transmission_signal self.enable_objects_after_transmission_signal = parent.enable_objects_after_transmission_signal self.auto_open = parent.emulation_panel.auto_open_checkbox.isChecked self.event_handler = parent.event_handler
class BankPropertyEditor(QtGui.QWidget, object): def __init__(self, bank_info, general_signal, message_sender, parent=None): """ :param name: bank name """ QtGui.QWidget.__init__(self) self.message_sender = message_sender self.general_signal = general_signal self.bank_info = BankInfo.from_instance(bank_info) # self.bank_num = self.bank_info.bank_number self.name = self.bank_info.bank_name self.setWindowTitle("Customize: {}".format(self.name)) self.x_siz, self.y_siz = 500, 600 self.resize(self.x_siz, self.y_siz) self.info_label = QLabel( "\nCustomize settings for selected bank.\nIt works only for Digifant1 programs" ) self.info_label.setStyleSheet("font: Courier New") self.label = QLabel("Bank name:\n{}".format(self.name)) self.label.setStyleSheet("font: 20pt Courier New; font-weight: bold") self.enable_digidiag_check_box = CheckBox( "enable digidiag", tip_msg="Enable Digifant diagnostic feedback for bank \"{}\"". format(self.name)) self.override_digidiag_frames_check_box = CheckBox( "override frames", tip_msg="If selected it will override default digidiag frames with\n" "values in Custom Digi Frames") self.custom_frames_label = QLabel("\nCustom Digi Frames") self.custom_frames_label.setStyleSheet( "font: 10pt Courier New; font-weight: bold") self.custom_frames_table = CustomFramesEditor( self.bank_info.frames_vector) self.apply_button = PushButton("Apply", tip_msg="Apply changes") self.cancel_button = PushButton("Cancel", tip_msg="Discard changes") self.info_box = QLabel(" ") self.apply_button.clicked.connect(self.apply_button_slot) self.cancel_button.clicked.connect(self.cancel_button_slot) #GRID mainGrid = QtGui.QGridLayout() mainGrid.setSpacing(10) mainGrid.addWidget(self.info_label, 0, 0, 2, 3) mainGrid.addWidget(self.label, 2, 0, 1, 3) mainGrid.addWidget(self.enable_digidiag_check_box, 3, 0) mainGrid.addWidget(self.override_digidiag_frames_check_box, 3, 1) mainGrid.addWidget(self.custom_frames_label, 4, 0, 1, 3) mainGrid.addWidget(self.custom_frames_table, 5, 0, 1, 3) mainGrid.addWidget(self.cancel_button, 6, 0) mainGrid.addWidget(self.apply_button, 6, 1) mainGrid.addWidget(self.info_box, 7, 0, 2, 3) self.setLayout(mainGrid) self.__tmp_resp_msg_thread = None #place window next to parent if parent: x_offset = 0 y_offset = 100 current_position_and_size = WindowGeometry(parent) x_pos = current_position_and_size.get_position_to_the_right() self.setGeometry(x_pos + x_offset, current_position_and_size.pos_y + y_offset, self.x_siz, self.y_siz) #self.show() @property def bank_info(self): return self.__bank_info @bank_info.setter def bank_info(self, bank_info): self.__bank_info = BankInfo.from_instance(bank_info) self.bank_num = self.bank_info.bank_number def update(self, bank_info): self.bank_info = BankInfo.from_instance(bank_info) self.name = self.bank_info.bank_name self.display_values() self.label.setText("Bank name:\n{}".format(self.bank_info.bank_name)) self.info_box.setText("Bank data received") self.setWindowTitle("Customize: {}".format(self.name)) self.enable_digidiag_check_box.update_tip_msg( "Enable Digifant diagnostic feedback for bank \"{}\"".format( self.name)) self.apply_button.setDisabled(False) def cancel_button_slot(self): self.display_values() self.close() def display_values(self): if self.bank_info.enable_digidiag: self.enable_digidiag_check_box.setChecked(True) else: self.enable_digidiag_check_box.setChecked(False) if self.bank_info.override_digidiag: self.override_digidiag_frames_check_box.setChecked(True) else: self.override_digidiag_frames_check_box.setChecked(False) self.custom_frames_table.update_values(self.bank_info.frames_vector) def clean_values(self): self.custom_frames_table.clean_table() self.enable_digidiag_check_box.setChecked(False) self.override_digidiag_frames_check_box.setChecked(False) def watch_message(self, thr): """ Will unlock apply button when thread is finished :param thr: :return: """ while thr.isRunning(): time.sleep(0.2) self.apply_button.setDisabled(False) def apply_button_slot(self): try: self.bank_info.enable_digidiag = self.enable_digidiag_check_box.isChecked( ) self.bank_info.override_digidiag = self.override_digidiag_frames_check_box.isChecked( ) raw_frames = self.custom_frames_table.get() self.bank_info.frames_vector = raw_frames self.info_box.setText('') self.info_box.setText("Sending data...") msg_thread = self.message_sender( message_id=MessageSender.ID.update_bank_data, body=self.bank_info.raw_content, timeout=1, re_tx=3) self.apply_button.setDisabled(True) if self.__tmp_resp_msg_thread is not None: self.__tmp_resp_msg_thread.kill() self.__tmp_resp_msg_thread = GuiThread(self.watch_message, args=(msg_thread, )) self.__tmp_resp_msg_thread.start() except Exception as e: self.info_box.setText(e.message)
class WritePackets: def __init__(self, parent, bin_packets, retx_timeout=0.5): self.__retx_timeout = retx_timeout self.rx_message_buffer = parent.rx_message_buffer self.message_sender = parent.message_sender self.gui_communication_signal = parent.gui_communication_signal self.progress_bar = parent.progress_bar self.bin_packets = bin_packets self.tx_stats = TransmissionStats() self.write_thread = GuiThread(self.write_packets_procedure) self.parent_send_msg = parent.send_message self.set_bank_name = parent.set_bank_name self.disable_objects_for_transmission_signal = parent.disable_objects_for_transmission_signal self.enable_objects_after_transmission_signal = parent.enable_objects_after_transmission_signal self.reload_sram = parent.emulation_panel.emulate_file_on_upload.isChecked def check_repsonse(self, context): retx_timeout = self.__retx_timeout t0 = time.time() while context not in self.rx_message_buffer: if time.time() - t0 > retx_timeout: return RxMessage.rx_id_tuple.index('dtx') time.sleep(0.001) else: result = self.rx_message_buffer.pop(context).id # gets message and returns id from buffer return result def send_packet(self, packet, b_address): msg_body = struct.pack('H', b_address) + packet _context = self.message_sender.send(MessageSender.ID.write_to_page, body=msg_body) return _context def __tear_down(self): self.gui_communication_signal.emit("Upload failed") to_signal(self.progress_bar.hide).emit() self.enable_objects_after_transmission_signal.emit() def send_rx_flush_req(self): retx = 3 def rx_flush(): context = self.message_sender.send(m_id=MessageSender.ID.rxflush) t0 = time.time() while context not in self.rx_message_buffer: if time.time() - t0 > 2: return time.sleep(0.1) return True while retx: if rx_flush(): break retx -= 1 if retx == 0: self.gui_communication_signal.emit("RX flush failed") return def write_packets_procedure(self): self.send_rx_flush_req() self.disable_objects_for_transmission_signal.emit() time.sleep(0.5) t_start = time.time() bank_name_full = os.path.basename(self.bin_packets.bin_path) bank_name = os.path.splitext(bank_name_full)[0] self.progress_bar.set_title("SENDING: {}".format(bank_name_full)) to_signal(self.progress_bar.display).emit() tot_tx_bytes = 0 while self.progress_bar.isHidden(): time.sleep(0.1) packets = {p.b_address: p for p in self.bin_packets} packet = packets.get(packets.keys()[0]) max_timeout = len(packets) * self.__retx_timeout * 4 print "max timeout", max_timeout/60 debug("Sending bin with packetsize: {}".format(len(packet.payload))) while packets: if self.progress_bar.isHidden(): self.gui_communication_signal.emit("Upload procedure terminated") break self.check_resp_thr = GuiThread(self.check_repsonse, args=(MessageSender.context,)) self.check_resp_thr.start() self.send_packet(packet.payload, b_address=packet.b_address) while self.check_resp_thr.returned() is None: time.sleep(0.001) response = self.check_resp_thr.returned() if response == RxMessage.rx_id_tuple.index('ack'): self.tx_stats.ack() self.progress_bar.set_val_signal.emit(float(tot_tx_bytes) / self.bin_packets.packets_amount * 100) tot_tx_bytes += len(packet.payload) packets.pop(packet.b_address) try: packet = packets.get(packets.keys()[0]) except IndexError: pass elif response == RxMessage.rx_id_tuple.index('dtx'): self.tx_stats.dtx() else: self.tx_stats.nack() if time.time() - t_start > max_timeout: self.__tear_down() raise SendTimeout("TIMEOUT") else: if self.reload_sram(): self.parent_send_msg(MessageSender.ID.reload_sram) self.gui_communication_signal.emit("File transmitted in: {}".format(time.time() - t_start)) self.gui_communication_signal.emit(self.tx_stats) self.message_sender.send(m_id=MessageSender.ID.get_write_stats) self.set_bank_name(bank_name.replace('_sram', '')) to_signal(self.progress_bar.hide).emit() self.enable_objects_after_transmission_signal.emit()
class ReadPackets: def __init__(self, parent, message_id, retx_timeout=1): self.__retx_timeout = retx_timeout self.message_id = message_id self.rx_message_buffer = parent.rx_message_buffer self.message_sender = parent.message_sender self.gui_communication_signal = parent.gui_communication_signal self.progress_bar = parent.progress_bar self.tx_stats = TransmissionStats() self.read_thread = GuiThread(self.read_packets_procedure) self.context_to_packet_map = {} self.receiver = BinReceiver(packet_size=256*8) self.get_bank_name = parent.banks_panel.get_bank_name_text self.update_file_list = parent.bin_file_panel.combo_box.moveOnTop self.disable_objects_for_transmission_signal = parent.disable_objects_for_transmission_signal self.enable_objects_after_transmission_signal = parent.enable_objects_after_transmission_signal self.auto_open = parent.emulation_panel.auto_open_checkbox.isChecked self.event_handler = parent.event_handler def extra_teardown(self): pass def check_response(self, context): retx_timeout = self.__retx_timeout t0 = time.time() while context not in self.rx_message_buffer: time.sleep(0.1) if time.time() - t0 > retx_timeout: return RxMessage.RxId.dtx else: msg = self.rx_message_buffer.pop(context) # gets message and returns id from buffer if msg.id == RxMessage.RxId.ack: packet_num = self.context_to_packet_map[context] self.context_to_packet_map.pop(context) self.receiver[packet_num] = msg.msg result = msg.id return result def send_request(self, packet_num): msg_body = struct.pack('B', packet_num) _context = self.message_sender.send(self.message_id, body=msg_body) return _context def tear_down_on_fail(self): self.gui_communication_signal.emit("Read failed") to_signal(self.progress_bar.hide).emit() self.enable_objects_after_transmission_signal.emit() def read_packets_procedure(self): self.disable_objects_for_transmission_signal.emit() self.message_sender.send(MessageSender.ID.rxflush) time.sleep(0.5) max_timeout = 20 t_start = time.time() self.progress_bar.set_title("RECEIVING") to_signal(self.progress_bar.display).emit() packet_num = 0 while self.progress_bar.isHidden(): time.sleep(0.1) while not self.receiver: if self.progress_bar.isHidden(): self.gui_communication_signal.emit("Read procedure terminated") break context = self.send_request(packet_num=packet_num) self.context_to_packet_map[context] = packet_num self.check_resp_thr = GuiThread(self.check_response, args=(context,)) self.check_resp_thr.start() while self.check_resp_thr.returned() is None: time.sleep(0.001) response = self.check_resp_thr.returned() if response == RxMessage.rx_id_tuple.index('ack'): self.tx_stats.ack() self.progress_bar.set_val_signal.emit(float(packet_num) / 16 * 100) packet_num += 1 else: self.tx_stats.nack() time.sleep(0.5) if time.time() - t_start > max_timeout: self.tear_down_on_fail() break else: self.gui_communication_signal.emit("File received in: {}".format(time.time() - t_start)) self.gui_communication_signal.emit(self.tx_stats) self.extra_teardown() to_signal(self.progress_bar.hide).emit() self.enable_objects_after_transmission_signal.emit() if self.auto_open(): self.event_handler.open_bin_file()