Добавлена адресация к бутлоадеру

This commit is contained in:
lulko 2025-03-22 13:56:28 +03:00
parent a1bcbdb33b
commit cf1c6eb05c
4 changed files with 50 additions and 21 deletions

View file

@ -130,6 +130,7 @@ FLASH_RECORD load_params(){
flash_read(addr,&res); flash_read(addr,&res);
if (!validate_crc(&res)) if (!validate_crc(&res))
break; break;
/* нашли адрес */
else if(res.data_id == addr_id) { else if(res.data_id == addr_id) {
latest = res; latest = res;
} }

View file

@ -23,10 +23,10 @@ enum {
#define FLAG_BOOT 0x08060000 // Адрес хранения флага для обновления прошивки #define FLAG_BOOT 0x08060000 // Адрес хранения флага для обновления прошивки
#define UPDATE_FLAG 0xDEADBEEF // Уникальное 32-битное значение #define UPDATE_FLAG 0xDEADBEEF // Уникальное 32-битное значение
#define APP_ADDRESS 0x08008000 // Адрес основной прошивки #define APP_ADDRESS 0x08008000 // Адрес основной прошивки
#define BOOT_CAN_ID 0x71 // CAN ID бутлоадера #define BOOT_CAN_ID 0x01 // CAN ID бутлоадера
#define BOOT_CAN_END 0x72 // CAN ID завершения передачи #define BOOT_CAN_END 0x02 // CAN ID завершения передачи
#define DATA_CAN_ID 0x73 // CAN ID данных #define DATA_CAN_ID 0x03 // CAN ID данных
#define ACK_CAN_ID 0x75 // CAN ID подтверждения #define ACK_CAN_ID 0x05 // CAN ID подтверждения
#define MAX_FW_SIZE 0x3FFF // Макс. размер прошивки (256KB) #define MAX_FW_SIZE 0x3FFF // Макс. размер прошивки (256KB)

View file

@ -12,6 +12,11 @@ volatile uint32_t fw_crc = 0;
volatile uint32_t jump; volatile uint32_t jump;
static FLASH_RECORD flash_record = {0}; static FLASH_RECORD flash_record = {0};
static uint32_t ptr_flash; 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 jump_to_app();
void process_can_message(const CAN_message_t &msg); void process_can_message(const CAN_message_t &msg);
@ -32,8 +37,8 @@ void setup() {
// SendTimer->attachInterrupt(process_can_message); // SendTimer->attachInterrupt(process_can_message);
SendTimer->resume(); SendTimer->resume();
// Разрешить все ID (маска 0x00000000) // Разрешить все ID (маска 0x00000000)
Can.setFilter(0, 0, STD); Can.setFilter(0, 0, STD);
// Настройка GPIO // Настройка GPIO
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN; RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN;
GPIOC->MODER |= GPIO_MODER_MODE10_0 | GPIO_MODER_MODE11_0; GPIOC->MODER |= GPIO_MODER_MODE10_0 | GPIO_MODER_MODE11_0;
@ -54,12 +59,15 @@ void setup() {
if(*(volatile uint32_t*)(FLAG_BOOT) == UPDATE_FLAG) { if(*(volatile uint32_t*)(FLAG_BOOT) == UPDATE_FLAG) {
fw_update = true; 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(); erase_flash_pages();
} else { } else {
jump_to_app(); jump_to_app();
} }
} }
void loop() { void loop() {
@ -75,7 +83,15 @@ void loop() {
void process_can_message(const CAN_message_t &msg) { 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: case BOOT_CAN_ID:
if(msg.buf[0] == 0x01) { // Старт передачи if(msg.buf[0] == 0x01) { // Старт передачи
fw_size = *(uint32_t*)&msg.buf[1]; //размер прошивки тип 4 байта 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: // Завершение передачи case BOOT_CAN_END: // Завершение передачи
if(verify_firmware()) { if(verify_firmware()) {
erase_sector(7); // Сброс флага
send_ack(0xAA); send_ack(0xAA);
erase_sector(7); // Сброс флага
NVIC_SystemReset(); NVIC_SystemReset();
} else { } else {
send_ack(0x55); send_ack(0x55);
@ -106,8 +122,7 @@ void process_can_message(const CAN_message_t &msg) {
break; break;
} }
} }
}
void jump_to_app() { void jump_to_app() {
__disable_irq(); __disable_irq();
@ -177,4 +192,3 @@ void send_ack(uint8_t status) {
ack.buf[0] = status; ack.buf[0] = status;
Can.write(ack); Can.write(ack);
} }

View file

@ -1,4 +1,5 @@
import can import can
import sys
import time import time
from intelhex import IntelHex from intelhex import IntelHex
from crc import Calculator, Crc16 from crc import Calculator, Crc16
@ -6,10 +7,12 @@ from crc import Calculator, Crc16
CAN_CHANNEL = 'socketcan' CAN_CHANNEL = 'socketcan'
CAN_INTERFACE = 'can0' CAN_INTERFACE = 'can0'
CAN_BITRATE = 1000000 CAN_BITRATE = 1000000
BOOT_CAN_ID = 0x71 #ch =int(input("Введите id устройства:"))
DATA_CAN_ID = 0x73 ch = int(sys.argv[2])
BOOT_CAN_END = 0x72 BOOT_CAN_ID = (ch * 16) + 1
ACK_CAN_ID = 0x75 DATA_CAN_ID = (ch * 16) + 3
BOOT_CAN_END = (ch * 16) + 2
ACK_CAN_ID = 0x05
#конфиг для crc16 ibm #конфиг для crc16 ibm
@ -18,6 +21,17 @@ ACK_CAN_ID = 0x75
def debug_print(msg): def debug_print(msg):
print(f"[DEBUG] {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): def send_firmware(hex_file):
try: try:
debug_print("Инициализация CAN...") debug_print("Инициализация CAN...")
@ -36,7 +50,7 @@ def send_firmware(hex_file):
# Расчет CRC # Расчет CRC
debug_print("Расчёт CRC...") debug_print("Расчёт CRC...")
calculator = Calculator(Crc16.IBM) 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}") debug_print(f"CRC: 0x{fw_crc:04X}")
# Отправка START # Отправка START
@ -100,8 +114,8 @@ def send_firmware(hex_file):
) )
bus.send(finish_msg) bus.send(finish_msg)
ack = wait_for_ack(bus, timeout=5) ack = wait_for_ack(bus, timeout=3)
if ack == 0xAA: if ack and ack.data[0] == 0xAA:
debug_print("Прошивка подтверждена!") debug_print("Прошивка подтверждена!")
else: else:
debug_print("Ошибка верификации!") debug_print("Ошибка верификации!")
@ -121,7 +135,7 @@ def wait_for_ack(bus, timeout=1.0):
if __name__ == "__main__": if __name__ == "__main__":
import sys import sys
if len(sys.argv) != 2: if len(sys.argv) != 3:
print("Использование: sudo python3 can_flasher.py firmware.hex") print("Использование: sudo python3 can_flasher.py firmware.hex")
sys.exit(1) sys.exit(1)