Added CRC check for CAN data and FLASH data
This commit is contained in:
parent
a2fc185c1e
commit
f1ae83dcf1
4 changed files with 56 additions and 24 deletions
|
@ -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_ */
|
||||
|
|
|
@ -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);
|
||||
|
||||
if (validate_crc(&rec,2)){
|
||||
uint16_t calculated_crc = validate_crc16((uint8_t*)&rec, sizeof(FLASH_RECORD) - 2); //Вычисляем CRC без последних двух байтов.STRUCT - 2BYTE__CRC
|
||||
|
||||
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};
|
||||
|
||||
FLASH_RECORD param_flash = {param_id, val};
|
||||
__disable_irq(); // Запрещаем прерывания на время всей операции
|
||||
|
||||
param_flash.crc = validate_crc16((uint8_t*)¶m_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, ¶m_flash);
|
||||
write_ptr += FLASH_RECORD_SIZE;
|
||||
flash_write(write_ptr, ¶m_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;
|
||||
}
|
||||
|
|
27
src/main.cpp
27
src/main.cpp
|
@ -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 - что делать дальше с данными */
|
||||
|
|
|
@ -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):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue