diff --git a/controller/fw/embed/bootloader/flash.cpp b/controller/fw/embed/bootloader/flash.cpp index fe988a1..d67b634 100644 --- a/controller/fw/embed/bootloader/flash.cpp +++ b/controller/fw/embed/bootloader/flash.cpp @@ -130,6 +130,7 @@ FLASH_RECORD load_params(){ flash_read(addr,&res); if (!validate_crc(&res)) break; +/* нашли адрес */ else if(res.data_id == addr_id) { latest = res; } diff --git a/controller/fw/embed/bootloader/flash.h b/controller/fw/embed/bootloader/flash.h index fe9b413..0a9d699 100644 --- a/controller/fw/embed/bootloader/flash.h +++ b/controller/fw/embed/bootloader/flash.h @@ -23,10 +23,10 @@ enum { #define FLAG_BOOT 0x08060000 // Адрес хранения флага для обновления прошивки #define UPDATE_FLAG 0xDEADBEEF // Уникальное 32-битное значение #define APP_ADDRESS 0x08008000 // Адрес основной прошивки -#define BOOT_CAN_ID 0x71 // CAN ID бутлоадера -#define BOOT_CAN_END 0x72 // CAN ID завершения передачи -#define DATA_CAN_ID 0x73 // CAN ID данных -#define ACK_CAN_ID 0x75 // CAN ID подтверждения +#define BOOT_CAN_ID 0x01 // CAN ID бутлоадера +#define BOOT_CAN_END 0x02 // CAN ID завершения передачи +#define DATA_CAN_ID 0x03 // CAN ID данных +#define ACK_CAN_ID 0x05 // CAN ID подтверждения #define MAX_FW_SIZE 0x3FFF // Макс. размер прошивки (256KB) diff --git a/controller/fw/embed/bootloader/main.cpp b/controller/fw/embed/bootloader/main.cpp index 3bd17fc..a97062b 100644 --- a/controller/fw/embed/bootloader/main.cpp +++ b/controller/fw/embed/bootloader/main.cpp @@ -12,6 +12,11 @@ volatile uint32_t fw_crc = 0; volatile uint32_t jump; static FLASH_RECORD flash_record = {0}; static uint32_t ptr_flash; + +volatile uint32_t msg_id; +volatile uint16_t id_x; +volatile uint8_t msg_ch; + // Прототипы функций void jump_to_app(); void process_can_message(const CAN_message_t &msg); @@ -32,8 +37,8 @@ void setup() { // SendTimer->attachInterrupt(process_can_message); SendTimer->resume(); // Разрешить все ID (маска 0x00000000) - Can.setFilter(0, 0, STD); - + Can.setFilter(0, 0, STD); + // Настройка GPIO RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN; GPIOC->MODER |= GPIO_MODER_MODE10_0 | GPIO_MODER_MODE11_0; @@ -54,12 +59,15 @@ void setup() { if(*(volatile uint32_t*)(FLAG_BOOT) == UPDATE_FLAG) { fw_update = true; - GPIOC->ODR |= GPIO_ODR_OD10; // Индикация обновления + for(int i = 0; i < 5;i++){ + GPIOC->ODR ^= GPIO_ODR_OD10; // Индикация обновления + HAL_Delay(100); + } erase_flash_pages(); } else { jump_to_app(); } - + } void loop() { @@ -75,7 +83,15 @@ void loop() { void process_can_message(const CAN_message_t &msg) { - switch(msg.id) { + msg_id = msg.id; + /* 0x691 + 69 - адрес устройства + 1 - что делать дальше с данными */ + + id_x = (msg_id >> 4) & 0xFFFF; //получение адреса устройства страшие 2 бита + msg_ch = msg_id & 0xF; // получения id, чтобы выбрать, что делать + if(id_x == flash_record.value){ + switch(msg_ch) { case BOOT_CAN_ID: if(msg.buf[0] == 0x01) { // Старт передачи fw_size = *(uint32_t*)&msg.buf[1]; //размер прошивки тип 4 байта @@ -97,8 +113,8 @@ void process_can_message(const CAN_message_t &msg) { case BOOT_CAN_END: // Завершение передачи if(verify_firmware()) { - erase_sector(7); // Сброс флага send_ack(0xAA); + erase_sector(7); // Сброс флага NVIC_SystemReset(); } else { send_ack(0x55); @@ -106,8 +122,7 @@ void process_can_message(const CAN_message_t &msg) { break; } } - - +} void jump_to_app() { __disable_irq(); @@ -177,4 +192,3 @@ void send_ack(uint8_t status) { ack.buf[0] = status; Can.write(ack); } - diff --git a/controller/fw/embed/test/python_test_boot.py b/controller/fw/embed/test/python_test_boot.py index 918095f..3f7522c 100644 --- a/controller/fw/embed/test/python_test_boot.py +++ b/controller/fw/embed/test/python_test_boot.py @@ -1,4 +1,5 @@ import can +import sys import time from intelhex import IntelHex from crc import Calculator, Crc16 @@ -6,10 +7,12 @@ from crc import Calculator, Crc16 CAN_CHANNEL = 'socketcan' CAN_INTERFACE = 'can0' CAN_BITRATE = 1000000 -BOOT_CAN_ID = 0x71 -DATA_CAN_ID = 0x73 -BOOT_CAN_END = 0x72 -ACK_CAN_ID = 0x75 +#ch =int(input("Введите id устройства:")) +ch = int(sys.argv[2]) +BOOT_CAN_ID = (ch * 16) + 1 +DATA_CAN_ID = (ch * 16) + 3 +BOOT_CAN_END = (ch * 16) + 2 +ACK_CAN_ID = 0x05 #конфиг для crc16 ibm @@ -18,6 +21,17 @@ ACK_CAN_ID = 0x75 def debug_print(msg): print(f"[DEBUG] {msg}") +def calculate_crc16_modbus(data: bytes) -> int: + crc = 0xFFFF + for byte in data: + crc ^= byte + for _ in range(8): + if crc & 0x0001: + crc = (crc >> 1) ^ 0xA001 + else: + crc >>= 1 + return crc + def send_firmware(hex_file): try: debug_print("Инициализация CAN...") @@ -36,7 +50,7 @@ def send_firmware(hex_file): # Расчет CRC debug_print("Расчёт CRC...") calculator = Calculator(Crc16.IBM) - fw_crc = calculator.checksum(binary_data) + fw_crc = calculate_crc16_modbus(binary_data) debug_print(f"CRC: 0x{fw_crc:04X}") # Отправка START @@ -100,8 +114,8 @@ def send_firmware(hex_file): ) bus.send(finish_msg) - ack = wait_for_ack(bus, timeout=5) - if ack == 0xAA: + ack = wait_for_ack(bus, timeout=3) + if ack and ack.data[0] == 0xAA: debug_print("Прошивка подтверждена!") else: debug_print("Ошибка верификации!") @@ -121,7 +135,7 @@ def wait_for_ack(bus, timeout=1.0): if __name__ == "__main__": import sys - if len(sys.argv) != 2: + if len(sys.argv) != 3: print("Использование: sudo python3 can_flasher.py firmware.hex") sys.exit(1)