Files
ds18b20-MODBUS/john103C8T6/EEPROM_Emul/src/flash_ring.c

124 lines
3.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "flash_ring.h"
extern int last_page_addr;
BufferState_t buffer_init(void) {
BufferState_t state = {0};
// Ищем последнюю записанную запись
for (int i = 0; i < RECORDS_PER_PAGE; i++) {
uint32_t record_addr = LAST_PAGE_ADDR + (i * RECORD_SIZE);
FlashRecord_t* record = (FlashRecord_t*)record_addr;
// Проверяем валидность записи (не 0xFFFFFFFF)
if (record->timestamp != 0xFFFFFFFF) {
state.write_index = i + 1;
state.initialized = 1;
} else {
break;
}
}
// Если буфер заполнен, начинаем с начала
if (state.write_index >= RECORDS_PER_PAGE) {
state.write_index = 0;
}
return state;
}
HAL_StatusTypeDef buffer_write_record(FlashRecord_t* record, BufferState_t* state) {
HAL_StatusTypeDef status;
// Если нужно стереть страницу (начало нового цикла)
if (state->write_index == 0 && state->initialized) {
status = erase_flash_page();
if (status != HAL_OK) return status;
}
// Записываем данные
uint32_t record_addr = last_page_addr + (state->write_index * RECORD_SIZE);
status = write_flash_record(record_addr, record);
if (status != HAL_OK) return status;
// Обновляем индекс
state->write_index++;
if (state->write_index >= RECORDS_PER_PAGE) {
state->write_index = 0;
}
state->initialized = 1;
return HAL_OK;
}
HAL_StatusTypeDef erase_flash_page(void) {
HAL_FLASH_Unlock();
FLASH_EraseInitTypeDef EraseInit = {
.TypeErase = FLASH_TYPEERASE_PAGES,
.PageAddress = LAST_PAGE_ADDR,
.NbPages = 1
};
uint32_t page_error;
HAL_StatusTypeDef status = HAL_FLASHEx_Erase(&EraseInit, &page_error);
HAL_FLASH_Lock();
return status;
}
// Запись одной записи
HAL_StatusTypeDef write_flash_record(uint32_t address, FlashRecord_t* record) {
HAL_FLASH_Unlock();
HAL_StatusTypeDef status = HAL_OK;
// Записываем данные по 4 байта (слово)
uint32_t* data_ptr = (uint32_t*)record;
uint32_t words_to_write = (RECORD_SIZE + 3) / 4; // округление вверх
for (uint32_t i = 0; i < words_to_write; i++) {
status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,
address + (i * 4),
data_ptr[i]);
if (status != HAL_OK) break;
}
HAL_FLASH_Lock();
return status;
}
// Чтение записи по индексу
FlashRecord_t* buffer_read_record(uint32_t index) {
if (index >= RECORDS_PER_PAGE) return NULL;
uint32_t record_addr = LAST_PAGE_ADDR + (index * RECORD_SIZE);
FlashRecord_t* record = (FlashRecord_t*)record_addr;
// Проверяем что запись не пустая
if (record->timestamp == 0xFFFFFFFF) {
return NULL;
}
return record;
}
// Получение всех записей в порядке от старых к новым
void buffer_get_all_records(FlashRecord_t* records[], uint32_t* count) {
*count = 0;
BufferState_t state = buffer_init();
if (!state.initialized) return;
// Начинаем с текущего write_index (самые старые данные)
for (int i = 0; i < RECORDS_PER_PAGE; i++) {
uint32_t idx = (state.write_index + i) % RECORDS_PER_PAGE;
FlashRecord_t* record = buffer_read_record(idx);
if (record) {
records[(*count)++] = record;
}
}
}