in core/logging/logging_flash.c [346:469]
int logging_flash_init_state (const struct logging_flash *logging)
{
int curr_sector_num;
uint8_t *pos;
uint8_t *end;
uint32_t entry_id = 0;
uint32_t prev_entry_id = 0;
uint32_t flash_addr;
int found_next = 0;
int status;
if ((logging == NULL) || (logging->state == NULL) || (logging->flash == NULL)) {
return LOGGING_INVALID_ARGUMENT;
}
if (FLASH_BLOCK_BASE (logging->base_addr) != logging->base_addr) {
return LOGGING_STORAGE_NOT_ALIGNED;
}
memset (logging->state, 0, sizeof (struct logging_flash_state));
flash_addr = logging->base_addr;
end = logging->state->entry_buffer + sizeof (logging->state->entry_buffer);
for (curr_sector_num = 0; curr_sector_num < LOGGING_FLASH_SECTORS; ++curr_sector_num) {
status = spi_flash_read (logging->flash,
logging->base_addr + (FLASH_SECTOR_SIZE * curr_sector_num),
logging->state->entry_buffer, sizeof (logging->state->entry_buffer));
if (status != 0) {
return status;
}
pos = logging->state->entry_buffer;
while ((end - pos) >= (int) sizeof (struct logging_entry_header)) {
struct logging_entry_header *header = (struct logging_entry_header*) pos;
if (!LOGGING_IS_ENTRY_START (header->log_magic) ||
(LOGGING_HEADER_FORMAT (header->log_magic) == 0xA)) {
if (found_next == 0) {
if (FLASH_SECTOR_OFFSET (flash_addr) == 0) {
found_next = 1;
}
else {
bool blank = true;
while (pos != end) {
if (*pos != 0xff) {
blank = false;
break;
}
pos++;
}
if (!blank) {
flash_addr = FLASH_SECTOR_BASE (flash_addr) + FLASH_SECTOR_SIZE;
}
else {
found_next = 1;
}
}
}
break;
}
else {
int length = header->length & ~LOGGING_FLASH_TERMINATOR;
if ((length > (end - pos)) ||
(length < (int) sizeof (struct logging_entry_header))) {
if (found_next == 0) {
flash_addr = FLASH_SECTOR_BASE (flash_addr) + FLASH_SECTOR_SIZE;
}
break;
}
if (header->length & LOGGING_FLASH_TERMINATOR) {
if (found_next == 0) {
flash_addr = FLASH_SECTOR_BASE (flash_addr) + FLASH_SECTOR_SIZE;
}
break;
}
if (found_next < 2) {
entry_id = header->entry_id + 1;
if (prev_entry_id > entry_id) {
entry_id = prev_entry_id;
logging->state->log_start = curr_sector_num;
found_next = 2;
}
else if (found_next == 0) {
flash_addr += length;
prev_entry_id = entry_id;
}
}
logging->state->flash_used[curr_sector_num] += length;
pos += length;
}
}
if ((FLASH_SECTOR_SIZE - FLASH_SECTOR_OFFSET (flash_addr)) <
sizeof (struct logging_entry_header)) {
flash_addr = FLASH_SECTOR_BASE (flash_addr) + FLASH_SECTOR_SIZE;
}
}
if (flash_addr >= (logging->base_addr + LOGGING_FLASH_AREA_LEN)) {
flash_addr = logging->base_addr;
}
status = platform_mutex_init (&logging->state->lock);
if (status != 0) {
return status;
}
logging->state->next_addr = flash_addr;
logging->state->next_entry_id = entry_id;
logging->state->next_write = logging->state->entry_buffer;
logging->state->write_remain =
sizeof (logging->state->entry_buffer) - FLASH_SECTOR_OFFSET (flash_addr);
return 0;
}