Возможна загрузка прошивки, но не переходит в неё

This commit is contained in:
lulko 2025-03-19 18:56:00 +03:00
parent 1de6c1bda1
commit 4b543e78ce
3 changed files with 160 additions and 102 deletions

View file

@ -2,94 +2,119 @@ import can
import time
from intelhex import IntelHex
from crc import Calculator, Crc16
# Конфигурация CAN
# Конфигурация
CAN_CHANNEL = 'socketcan'
CAN_INTERFACE = 'can0'
CAN_BITRATE = 1000000
# Параметры из заголовочного файла
BOOT_CAN_ID = 0x721
DATA_CAN_ID = 0x730
BOOT_CAN_END = 0x722
ACK_CAN_ID = 0x723
BOOT_CAN_ID = 0x71
DATA_CAN_ID = 0x73
BOOT_CAN_END = 0x72
ACK_CAN_ID = 0x75
# Конфигурация CRC16
CRC16_POLYNOMIAL = 0x8005 # Стандартный полином CRC-16-IBM
CRC16_INIT = 0xFFFF
#конфиг для crc16 ibm
def debug_print(msg):
print(f"[DEBUG] {msg}")
def send_firmware(hex_file):
bus = can.interface.Bus(channel='can0',
bustype='socketcan')
# Чтение и преобразование HEX-файла
ih = IntelHex(hex_file)
binary_data = ih.tobinarray()
fw_size = len(binary_data)
# Расчет CRC16
# calculator = Calculator(Crc16.CCITT, optimize=True)
fw_crc = 0x6933
# Отправка команды START
start_data = bytearray([0x01])
start_data += fw_size.to_bytes(4, 'little')
start_data += fw_crc.to_bytes(2, 'little') # 2 байта для CRC16
start_msg = can.Message(
arbitration_id=BOOT_CAN_ID,
data=start_data,
is_extended_id=False
)
bus.send(start_msg)
# Ожидание подтверждения
ack = wait_for_ack(bus)
if not ack or ack.data[0] != 0x01:
print("Ошибка инициализации!")
bus.shutdown()
return
# Отправка данных
packet_size = 8
for i in range(0, len(binary_data), packet_size):
chunk = binary_data[i:i+packet_size]
chunk += b'\x00' * (8 - len(chunk))
try:
debug_print("Инициализация CAN...")
bus = can.interface.Bus(
channel=CAN_INTERFACE,
bustype=CAN_CHANNEL,
bitrate=CAN_BITRATE
)
data_msg = can.Message(
arbitration_id=DATA_CAN_ID,
data=chunk,
debug_print("Чтение HEX-файла...")
ih = IntelHex(hex_file)
binary_data = ih.tobinstr() # Исправлено на tobinstr()
fw_size = len(binary_data)
debug_print(f"Размер прошивки: {fw_size} байт")
# Расчет CRC
debug_print("Расчёт CRC...")
calculator = Calculator(Crc16.IBM)
fw_crc = calculator.checksum(binary_data)
debug_print(f"CRC: 0x{fw_crc:04X}")
# Отправка START
start_data = bytearray([0x01])
start_data += fw_size.to_bytes(4, 'little')
start_data += fw_crc.to_bytes(2, 'little')
debug_print(f"START: {list(start_data)}")
start_msg = can.Message(
arbitration_id=BOOT_CAN_ID,
data=bytes(start_data),
is_extended_id=False
)
bus.send(data_msg)
try:
bus.send(start_msg)
except can.CanError as e:
debug_print(f"Ошибка отправки START: {str(e)}")
return
# Ожидание ACK
debug_print("Ожидание ACK...")
ack = wait_for_ack(bus)
if not ack or ack.data[0] != 0x02:
print("Ошибка передачи данных!")
break
if not ack:
debug_print("Таймаут ACK START")
return
debug_print(f"Получен ACK: {list(ack.data)}")
# Отправка данных
packet_size = 8
for i in range(0, len(binary_data), packet_size):
chunk = binary_data[i:i+packet_size]
# Дополнение до 8 байт
if len(chunk) < 8:
chunk += b'\xFF' * (8 - len(chunk))
progress = (i + len(chunk)) / fw_size * 100
print(f"\rПрогресс: {progress:.1f}%", end='')
debug_print(f"Пакет {i//8}: {list(chunk)}")
data_msg = can.Message(
arbitration_id=DATA_CAN_ID,
data=chunk,
is_extended_id=False
)
try:
bus.send(data_msg)
except can.CanError as e:
debug_print(f"Ошибка отправки данных: {str(e)}")
return
# Завершение передачи
finish_msg = can.Message(
arbitration_id=BOOT_CAN_END,
data=[0xAA],
is_extended_id=False
)
bus.send(finish_msg)
ack = wait_for_ack(bus, timeout=5)
if ack and ack.data[0] == 0xAA:
print("\nПрошивка успешно загружена!")
else:
print("\nОшибка верификации!")
ack = wait_for_ack(bus)
if not ack:
debug_print("Таймаут ACK DATA")
return
bus.shutdown()
# Финал
debug_print("Отправка FINISH...")
finish_msg = can.Message(
arbitration_id=BOOT_CAN_END,
data=bytes([0xAA]),
is_extended_id=False
)
bus.send(finish_msg)
ack = wait_for_ack(bus, timeout=5)
if ack == 0xAA:
debug_print("Прошивка подтверждена!")
else:
debug_print("Ошибка верификации!")
except Exception as e:
debug_print(f"Критическая ошибка: {str(e)}")
finally:
bus.shutdown()
def wait_for_ack(bus, timeout=1.0):
start_time = time.time()
while time.time() - start_time < timeout:
msg = bus.recv(timeout=0.1)
msg = bus.recv(timeout=0) # Неблокирующий режим
if msg and msg.arbitration_id == ACK_CAN_ID:
return msg
return None
@ -97,5 +122,7 @@ def wait_for_ack(bus, timeout=1.0):
if __name__ == "__main__":
import sys
if len(sys.argv) != 2:
print("Использование: python can_flasher.py firmware.hex")
print("Использование: sudo python3 can_flasher.py firmware.hex")
sys.exit(1)
send_firmware(sys.argv[1])