добавил второй проект для C8T6
This commit is contained in:
123
john103C8T6/EEPROM_Emul/src/flash_ring.c
Normal file
123
john103C8T6/EEPROM_Emul/src/flash_ring.c
Normal file
@@ -0,0 +1,123 @@
|
||||
#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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user