Reputation: 131
I am trying to implement a ring buffer in C to an external flash memory. For reference the flash memory is BR24G32-3 with 4kb.
I am having difficulties when it comes to the wrap around. After writing to all addresses 0x0000 ~ 0x1000, when it comes to wrap around and writes over the oldest data, my checking causes an infinite loop.
What I see my algorithm doing:
How can I improve this algorithm? I am looking to fix the error when I finish writing to the end address 0x1000 and when I reset to 0x0000, my ring buffer is already finding WRITTEN (0x31) flag at every block of data.
Thank you in advance.
void rb_write_to_flash(ring_buffer_t *rb)
{
uint8_t base_head_address[2] = {0x01, 0x0C};
ringbuf_head_position(head_position); // Load initial state of the ring buffer
if (head_position[0] == 0xFF && head_position[1] == 0xFF)
{
NRF_LOG_INFO("HEAD == 0xFF");
head_position[0] = 0x00;
head_position[1] = 0x00;
}
// Convert head_position to a uint16_t value
uint16_t head_pos_value = ((uint16_t)head_position[0] << 8) | head_position[1];
do
{
// Check if position has been written
nrf_drv_twi_tx(&m_twi, EEPROM_ADDRESS, head_position, 2, true);
nrf_drv_twi_rx(&m_twi, EEPROM_ADDRESS, head_buffer, sizeof(head_buffer));
if (head_buffer[28] == WRITTEN)
{
NRF_LOG_INFO("HEAD ALREADY WRITTEN");
// Increment position by 0x20
head_pos_value += 0x20;
if (head_pos_value >= 0x1000) // Checking for overflow
{
NRF_LOG_INFO("WRAPPING AROUND");
head_pos_value = 0x00; // Reset if it exceeds 0xFFFF
uint8_t initial_address[2] = {0x00, 0x00};
write_record(base_head_address, initial_address, 2);
// Clear the WRITTEN flag for the first position in EEPROM
uint8_t clear_buffer[30] = {0xFF}; // Assuming 0xFF is the default/empty state
write_record(initial_address, clear_buffer, sizeof(clear_buffer));
}
NRF_LOG_INFO("HEAD POSITION: 0x%04x", head_pos_value);
// Convert back to array
head_position[0] = (head_pos_value >> 8) & 0xFF;
head_position[1] = head_pos_value & 0xFF;
}
} while (head_buffer[28] == WRITTEN);
// Write data to the correct position
rb->buffer[0].written = WRITTEN; // Set flag as written
write_record(head_position, (uint8_t *)rb->buffer, sizeof(rb->buffer));
// Write the new head position to flash memory
write_record(base_head_address, head_position, 2);
}
Upvotes: 1
Views: 259