Added CRC check for CAN data and FLASH data

This commit is contained in:
lulko 2025-04-15 16:13:08 +03:00
parent a2fc185c1e
commit f1ae83dcf1
4 changed files with 56 additions and 24 deletions

View file

@ -1,8 +1,8 @@
#ifndef FLASH_H_
#define FLASH_H_
#include "stm32f446xx.h"
#include <stdio.h>
#include <stdlib.h>
/* for addr in FLASH */
@ -66,7 +66,7 @@ void write_param(uint8_t param_id, uint8_t val);
FLASH_RECORD* load_params();
void compact_page();
void flash_read(uint32_t addr,FLASH_RECORD* ptr);
bool validate_crc(FLASH_RECORD* crc,uint32_t length);
uint16_t validate_crc16(uint8_t *data,uint32_t length);
void flash_write(uint32_t addr, FLASH_RECORD* record);
#endif /* FLASH_H_ */

View file

@ -116,22 +116,23 @@ uint8_t flash_read_word(uint32_t address){
}
// Wait if flash
bool validate_crc(FLASH_RECORD* ptr, uint32_t length) {
uint16_t crc = 0xFFFF; // Начальное значение
uint16_t crc_value = ptr->crc;
uint8_t* data = reinterpret_cast<uint8_t*>(&crc_value);
uint16_t validate_crc16(uint8_t *data, uint32_t length) {
uint16_t crc = 0xFFFF; // Начальное значение для MODBUS
while (length--) {
crc ^= *data++; // Обрабатываем LSB первым
crc ^= *data++; // XOR с очередным байтом данных
for (uint8_t i = 0; i < 8; i++) {
if (crc & 0x0001) { // Проверяем младший бит
if (crc & 0x0001) {
crc = (crc >> 1) ^ 0xA001; // Полином 0x8005 (reverse)
} else {
crc >>= 1;
}
}
}
return crc == 0? true : false;
return crc; // Возвращаем вычисленный CRC
}
/* read struct from FLASH */
void flash_read(uint32_t addr,FLASH_RECORD* ptr){
uint8_t* flash_ptr = (uint8_t*)addr;
@ -145,14 +146,19 @@ void compact_page(){
for(int i = (uint32_t)SECTOR_6;i < (uint32_t)SECTOR_7;i += FLASH_RECORD_SIZE) {
FLASH_RECORD rec;
flash_read(i,&rec);
uint16_t calculated_crc = validate_crc16((uint8_t*)&rec, sizeof(FLASH_RECORD) - 2); //Вычисляем CRC без последних двух байтов.STRUCT - 2BYTE__CRC
if (validate_crc(&rec,2)){
if (calculated_crc == rec.crc && rec.data_id < PARAM_COUNT) {
// Если CRC совпадает и ID параметра валидный, сохраняем последнее значение
latest[rec.data_id] = rec;
}
else
//Если не совпадает продолжить читать флэш
continue;
}
erase_sector(6);
write_ptr = SECTOR_6; // Сброс на начало
for (int i = 0; i < PARAM_COUNT; i++) {
if (latest[i].data_id != 0xFF) {
// Выравнивание перед каждой записью
@ -165,12 +171,14 @@ void compact_page(){
}
}
void write_param(uint8_t param_id, uint8_t val) {
FLASH_RECORD param_flash = {param_id, val, 6933};
void write_param(uint8_t param_id, uint8_t val) {
FLASH_RECORD param_flash = {param_id, val};
__disable_irq(); // Запрещаем прерывания на время всей операции
// Проверка выравнивания ДО проверки границ сектора
param_flash.crc = validate_crc16((uint8_t*)&param_flash,sizeof(param_flash) - 2);//Нахождение CRC для данных, хранящихся во флэш памяти
// Проверка выравнивания ДО проверки границ сектора кратного 4
if (write_ptr % 4 != 0) {
write_ptr += (4 - (write_ptr % 4));
}
@ -178,14 +186,13 @@ void write_param(uint8_t param_id, uint8_t val) {
// Проверка переполнения с учётом выравнивания
if (write_ptr + FLASH_RECORD_SIZE >= SECTOR_6_END) {
compact_page(); // После compact_page write_ptr обновляется
// Повторно выравниваем после компактификации. То есть сколько не хватает для кратности
// Повторно выравниваем после функции. То есть сколько не хватает для кратности
if (write_ptr % 4 != 0) {
write_ptr += (4 - (write_ptr % 4));
}
}
flash_write(write_ptr, &param_flash);
write_ptr += FLASH_RECORD_SIZE;
flash_write(write_ptr, &param_flash); //внутри функции итак автоматические инкрементируется указатель write_ptr на размер структуры
__enable_irq(); // Разрешаем прерывания
}
@ -196,8 +203,10 @@ FLASH_RECORD* load_params(){
FLASH_RECORD res;
for(uint32_t addr = SECTOR_6;addr < SECTOR_6_END;addr +=FLASH_RECORD_SIZE) {
flash_read(addr,&res);
if (!validate_crc(&res,2))
break;
/* провекра CRC */
uint16_t calculated_crc = validate_crc16((uint8_t*)&res, sizeof(FLASH_RECORD) - 2); //Вычисляем CRC без последних двух байтов.STRUCT - 2BYTE__CRC
if (calculated_crc != res.crc || res.data_id >= PARAM_COUNT)
continue;
else{
latest[res.data_id] = res;
}

View file

@ -157,8 +157,8 @@ void send_id() {
CAN_TX_msg.id = flash_rec->value;
CAN_TX_msg.buf[0] = 'I';
memcpy(&CAN_TX_msg.buf[1], &(flash_rec->value), sizeof(uint8_t));
memcpy(&CAN_TX_msg.buf[6], (uint8_t*)&crc_h, sizeof(uint8_t));
memcpy(&CAN_TX_msg.buf[7], (uint8_t*)&crc_l, sizeof(uint8_t));
// memcpy(&CAN_TX_msg.buf[6], (uint8_t*)&crc_h, sizeof(uint8_t));
// memcpy(&CAN_TX_msg.buf[7], (uint8_t*)&crc_l, sizeof(uint8_t));
Can.write(CAN_TX_msg);
}
@ -191,8 +191,31 @@ void send_data() {
void listen_can(const CAN_message_t &msg) {
msg_id = msg.id;
/* Проверка CRC с фрейма данных */
// Extract CRC from message
crc_h = msg.buf[6];
crc_l = msg.buf[7];
// Combine high and low bytes to form the received CRC
uint16_t received_crc = (crc_h << 8) | crc_l;
// Create a temporary buffer for CRC calculation
uint8_t crc_data[6]; // First 6 bytes of message data
// Copy message ID and data for CRC calculation
memcpy(crc_data, (uint32_t*)&msg_id, sizeof(msg_id));
memcpy(crc_data + sizeof(msg_id), msg.buf, 2); // First 2 bytes of data
// Calculate CRC
uint16_t calculated_crc = validate_crc16(crc_data, sizeof(crc_data));
// Verify CRC matches
if (calculated_crc != received_crc) {
// CRC mismatch, ignore message
return;
}
/* 0x691
69 - адрес устройства
1 - что делать дальше с данными */

View file

@ -17,7 +17,7 @@ def calculate_crc16_modbus(data: bytes) -> int:
if crc & 0x0001:
crc = (crc >> 1) ^ 0xA001
else:
crc >>= 1
crc >>= 2
return crc
def send_can_message(bus, can_id, data):