Files
ninlight-w600/test/fake_flash.c
T
Michael Sauer 91721ac47d feat: Flash-HAL-Interface und Settings-Store mit A/B-Slots
Implementiert:
- Flash HAL (nl_flash_read/write/erase_sector) Interfaces
- Flash Layout mit A/B-Settings Slots und weiteren Regions
- Test-Fake für Flash mit Fehlerinjection (Stromausfall-Simulation)
- Settings-Store mit CRC32 Recovery und Slot-Alternierung
- Vollständige Test-Suite mit Corruption/Power-Loss-Tests
2026-09-11 13:24:52 +02:00

61 lines
1.5 KiB
C

#include "fake_flash.h"
#include <string.h>
uint8_t fake_flash_mem[FAKE_FLASH_SIZE];
unsigned fake_flash_erases[FAKE_FLASH_SECTORS];
unsigned fake_flash_dirty_writes;
static long s_fail_after = -1;
void fake_flash_reset(void)
{
memset(fake_flash_mem, 0xFF, sizeof fake_flash_mem);
memset(fake_flash_erases, 0, sizeof fake_flash_erases);
fake_flash_dirty_writes = 0;
s_fail_after = -1;
}
void fake_flash_fail_after(long bytes)
{
s_fail_after = bytes;
}
int nl_flash_read(uint32_t addr, void *buf, uint32_t len)
{
if (addr + len > FAKE_FLASH_SIZE)
return -1;
memcpy(buf, &fake_flash_mem[addr], len);
return 0;
}
int nl_flash_write(uint32_t addr, const void *buf, uint32_t len)
{
const uint8_t *p = (const uint8_t *)buf;
if (addr + len > FAKE_FLASH_SIZE)
return -1;
for (uint32_t i = 0; i < len; i++) {
if (s_fail_after == 0)
return -1;
if (s_fail_after > 0)
s_fail_after--;
if (fake_flash_mem[addr + i] != 0xFF)
fake_flash_dirty_writes++;
fake_flash_mem[addr + i] &= p[i]; /* NOR: bits only go from 1 to 0 */
}
return 0;
}
int nl_flash_erase_sector(uint32_t addr)
{
if (addr % NL_FLASH_SECTOR_SIZE || addr >= FAKE_FLASH_SIZE || s_fail_after == 0)
return -1;
memset(&fake_flash_mem[addr], 0xFF, NL_FLASH_SECTOR_SIZE);
fake_flash_erases[addr / NL_FLASH_SECTOR_SIZE]++;
return 0;
}
uint32_t nl_flash_region_base(void)
{
return 0;
}