Задача ЯУ-07 #2. Добавлены функции parse_block и send_block
This commit is contained in:
102
scripts/yau07.gd
102
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
|
||||
|
||||
Reference in New Issue
Block a user