From cbc24d0ec273e4bc5fed1ece84c2096bd45bcbec Mon Sep 17 00:00:00 2001 From: Maxim Date: Fri, 22 Dec 2023 01:24:48 +0300 Subject: [PATCH] =?UTF-8?q?=D0=97=D0=B0=D0=B4=D0=B0=D1=87=D0=B0=20=D0=AF?= =?UTF-8?q?=D0=A3-07=20#2.=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D1=8B=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D0=B8=20par?= =?UTF-8?q?se=5Fblock=20=D0=B8=20send=5Fblock?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/yau07.gd | 102 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 74 insertions(+), 28 deletions(-) diff --git a/scripts/yau07.gd b/scripts/yau07.gd index aec65d17..9a43cc56 100644 --- a/scripts/yau07.gd +++ b/scripts/yau07.gd @@ -2,10 +2,10 @@ extends Node ## Протокол ячейки ЯУ-07 -const BUFFER_SIZE = 2048 ## Размер буфера для приёма датаграмм, байты -const ONLINE_TIMEOUT = 5000 ## Время ожидания пакета от ячейки, мс -const RESEND_TIMEOUT = 300 ## Задержка для повторной отправки команды, мс +const ONLINE_TIMEOUT = 5.0 ## Время ожидания пакета от ячейки, секунды +const RESEND_TIMEOUT = 0.3 ## Задержка для повторной отправки команды, секунды const RETRY_COUNT = 5 ## Количество повторных отправок +const BUFFER_SIZE = 2048 ## Размер буфера для приёма датаграмм ## Ячейка ЯУ-07 @@ -14,37 +14,41 @@ class YaU07: ## Коды выполняемых команд enum CmdCode { READ_ISA = 0, ## Код команды "читать порт ISA" ячейки ЯУ-07 - WRITE_ISA = 1 ## Код команды "записать порт ISA" ячейки ЯУ-07 + WRITE_ISA = 1, ## Код команды "записать порт ISA" ячейки ЯУ-07 + WRITE_BLOCK = 60, ## Код команды "записать блок данных ISA" внешней шины ячейки ЯУ-07 + READ_BLOCK = 61, ## Код команды "читать блок данных ISA" внешней шины ячейки ЯУ-07 } ## Состояние автомата выполнения команды enum CmdState { - DONE, ## Команда выполнена - FAIL, ## Команда не выполнена - SEND, ## Буфер готов для отправки UNCK, ## Номер команды не ининциирован - WAIT ## Ожидание выполнения + SEND, ## Буфер готов для отправки + WAIT, ## Ожидание выполнения + DONE, ## Команда выполнена + FAIL ## Команда не выполнена } signal line_changed(unit: YaU07) ## Вызывается когда меняется состояние связи с ячейкой signal command_done(unit: YaU07) ## Вызывается после выполнения команды signal command_fail(unit: YaU07) ## Вызывается если возникла ошибка при выполнении команды и команда не выполнена + signal parse_failed(unit: YaU07) - var cmd_data: = PackedByteArray() ## Данные команды. Устанавливается в ЯУ-07 + var name: = String() var cmd_num_rx: = 0 ## Номер команды принятый var cmd_num_tx: = 0 ## Номер команды переданный - var cmd_result: = 1 ## Результат выполнения команды. Устанавливается в ЯУ-07 - var cmd_retry = 0 ## Счётчик оставшихся попыток выполнить команду var cmd_state = CmdState.UNCK ## Состояние выполнения команды - var cmd_tick_rx = 0.0 ## Время последнего приёма команды - var cmd_tick_tx = 0.0 ## Время последней отправки команды - var isa_ports = {} ## Результат выполнения команды "читать порт" - var name: = String() ## Имя - var online = false ## Состояние связи с ячейкой - var status: = PackedByteArray() ## Поле "состояние прибора" + var cmd_result: = 1 ## Результат выполнения команды. Устанавливается в ЯУ-07 + var cmd_data: = PackedByteArray() ## Данные команды. Устанавливается в ЯУ-07 + var cmd_retry = 0 ## Счётчик оставшихся попыток выполнить команду var tick = 0.0 ## Текущее тик-время в мс + var cmd_tick_tx = 0.0 ## Время последней отправки команды + var cmd_tick_rx = 0.0 ## Время последнего приёма команды + var status: = PackedByteArray() ## Поле "состояние прибора" var tx_data: = PackedByteArray() ## Буфер отправленный var tx_len = 0 ## Длина последнего отправленного пакета + var isa_ports = {} ## Результат выполнения команды "читать порт" + var isa_block = {} ## Результат выполнения команды "читать массив из порта" + var online = false ## Состояние связи с ячейкой func _to_string() -> String: return String('яу07: %s %s' % [self.name, ['отключен', 'на связи'][int(online)]]) @@ -56,8 +60,8 @@ class YaU07: tick = 0.0 - func process(t: int): - tick = t + func process(delta: float): + tick += delta if online and ((tick - cmd_tick_rx) > ONLINE_TIMEOUT): online = false emit_signal('line_changed', self) @@ -107,17 +111,37 @@ class YaU07: cmd_state = CmdState.SEND return true + func send_block(cmd_code: int, block_len: int, port: Array) -> bool: + if (cmd_state == CmdState.WAIT) \ + or (cmd_state == CmdState.SEND) \ + or (cmd_state == CmdState.UNCK): + return false + if not ((cmd_code == CmdCode.READ_BLOCK) or (cmd_code == CmdCode.WRITE_BLOCK)): + return false + cmd_num_tx = (cmd_num_rx + 1) % 0xffff + + tx_len = 11 + tx_data.encode_u16(0, cmd_retry) # Исправление для сетевого стека "nm-callback" процессоров STM + tx_data.encode_u16(2, cmd_num_tx) + + if cmd_code == CmdCode.WRITE_BLOCK: + block_len /= 2 + tx_data[6] = cmd_code + tx_data.encode_u16(7, block_len) + + tx_data.encode_u16(9, int(port[0])) + cmd_state = CmdState.SEND + return true ## Возвращает код команды ЯУ-07 - ## [param rx_data] - Принятые данные[br] - ## Возвращает [b]null[/b] - Если код команды не найден[br] - ## Возвращает [b]0...255[/b] - Код команды + ## rx_data - Принятые данные + ## Возвращает - Код команды не найден, 0...255 - код команды func get_cmd_code(rx_data: PackedByteArray): var rx_data_len = rx_data.size() if rx_data_len < 7: return null - var status_len = rx_data.decode_u16(6) # Длина массива байтового "состояние прибора" + var status_len = rx_data.decode_u16(6) # Длина массива байтового "состояние прибора" if rx_data_len <= (status_len + 6): # Нет поля "ответ на команду", разбор пакета завершить return null var cmd_code_pos = status_len + 8 # Положение в приёмном буфере "кода команды" @@ -146,6 +170,19 @@ class YaU07: cmd_data = rx_data.slice(addr_pos, (addr_pos + ports_count * 4) - 1) return i > 0 + func parse_block(rx_data: PackedByteArray, status_len) -> bool: + var ports_count_pos = status_len + 7 # Положение в приёмном буфере количества портов + if rx_data.size() < ports_count_pos: + return false + var block_len = rx_data.decode_u16(ports_count_pos + 3) + var block_adr = rx_data.decode_u16(ports_count_pos + 5) + var block_data = [] + for i in block_len: + var shift: int = i * 2 + block_data.append(rx_data.decode_u16(ports_count_pos + 7 + shift)) + isa_block[block_adr] = block_data + return true + ## Заполняет состояние прибора данными прочитанными из портов ЯУ-07 ## для команд "читать порты" или "записать порты"[br] @@ -154,12 +191,14 @@ class YaU07: ## Возвращает [b]false[/b] - Данные не обработаны из за ошибки[br] func parse(rx_data: PackedByteArray) -> bool: + cmd_tick_rx = tick + if not online: online = true emit_signal('line_changed', self) var rx_data_len = rx_data.size() - if rx_data_len < 11: + if rx_data_len < 10: return false cmd_num_rx = rx_data.decode_u16(2) @@ -193,10 +232,17 @@ class YaU07: return false var cmd_code: CmdCode = rx_data[cmd_code_pos] as CmdCode # "код команды" + var rc = true if (cmd_code == CmdCode.READ_ISA) or (cmd_code == CmdCode.WRITE_ISA): - parse_isa(rx_data, status_len) + rc = parse_isa(rx_data, status_len) - if (cmd_state == CmdState.WAIT) and (cmd_num_rx == cmd_num_tx): - cmd_state = CmdState.DONE - emit_signal('command_done', self) + elif (cmd_code == CmdCode.READ_BLOCK) or (cmd_code == CmdCode.WRITE_BLOCK): + rc = parse_block(rx_data, status_len) + + if rc: + if (cmd_state == CmdState.WAIT) and (cmd_num_rx == cmd_num_tx): + cmd_state = CmdState.DONE + emit_signal('command_done', self) + else: + emit_signal('parse_failed', self) return true