Files
templates/c/flash-storage/Tests/test_flash_storage.c

28 lines
4.0 KiB
C

#include "ds18b20.h"
#include "flash_storage.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
#define BASE0 0x10000000U
#define BANK (128U*1024U)
typedef struct { uint8_t bytes[2U*BANK];uint32_t tick;int fail_after;int calls; } mock_flash_t;
static flash_storage_status_t mread(void*c,uint32_t a,void*d,size_t n){mock_flash_t*m=c;if(a<BASE0||n>sizeof(m->bytes)-(a-BASE0))return FLASH_STORAGE_E_BOUNDS;memcpy(d,m->bytes+a-BASE0,n);return FLASH_STORAGE_OK;}
static flash_storage_status_t mprogram(void*c,uint32_t a,const void*d,size_t n){mock_flash_t*m=c;size_t i;if(m->fail_after>=0&&m->calls++>=m->fail_after)return FLASH_STORAGE_E_IO;if(a<BASE0||n>sizeof(m->bytes)-(a-BASE0))return FLASH_STORAGE_E_BOUNDS;for(i=0;i<n;++i)m->bytes[a-BASE0+i]&=((const uint8_t*)d)[i];return FLASH_STORAGE_OK;}
static flash_storage_status_t merase(void*c,uint32_t a,size_t n){mock_flash_t*m=c;if(a<BASE0||n>sizeof(m->bytes)-(a-BASE0))return FLASH_STORAGE_E_BOUNDS;memset(m->bytes+a-BASE0,0xFF,n);return FLASH_STORAGE_OK;}
static uint32_t mtick(void*c){return ((mock_flash_t*)c)->tick;}
static const flash_storage_ops_t fops={mread,mprogram,merase,mtick};
static const flash_storage_layout_t flayout={{BASE0,BASE0+BANK},BANK,4U,BANK,0U,10U};
typedef struct { uint8_t level;uint32_t tick; } mock_wire_t;
static void wl(void*c){((mock_wire_t*)c)->level=0;}static void wr(void*c){((mock_wire_t*)c)->level=1;}static uint8_t wi(void*c){return ((mock_wire_t*)c)->level;}static void wd(void*c,uint32_t u){((mock_wire_t*)c)->tick+=u/1000U;}static uint32_t wt(void*c){return ((mock_wire_t*)c)->tick;}static const ds18b20_onewire_ops_t wops={wl,wr,wi,wd,wt,0,0};
static void test_ds(void){uint8_t good[8]={0x28,1,2,3,4,5,6,0};uint8_t sp[9]={0x91,0x01,0x4b,0x46,0x7f,0xff,0x0c,0x10,0};uint8_t r1[2][8],r2[3][8];ds18b20_t a,b;mock_wire_t wa={1,0},wb={1,0};float t;good[7]=ds18b20_crc8(good,7);sp[8]=ds18b20_crc8(sp,8);assert(ds18b20_validate_rom(good)==DS18B20_OK);good[7]^=1;assert(ds18b20_validate_rom(good)==DS18B20_E_CRC);assert(ds18b20_decode_temperature(sp,&t)==DS18B20_OK&&t>25.0f&&t<25.1f);sp[8]^=1;assert(ds18b20_decode_temperature(sp,&t)==DS18B20_E_CRC);assert(ds18b20_init(&a,&wops,&wa,r1,2)==DS18B20_OK);assert(ds18b20_init(&b,&wops,&wb,r2,3)==DS18B20_OK);assert(a.platform_context!=b.platform_context&&a.roms!=b.roms);}
static void test_flash(void){mock_flash_t m;flash_storage_t s,recovered;flash_storage_info_t info;uint8_t one[512],two[512],out[512];size_t n;memset(&m,0,sizeof(m));memset(m.bytes,0xFF,sizeof(m.bytes));m.fail_after=-1;memset(one,0x11,sizeof(one));memset(two,0x22,sizeof(two));assert(flash_storage_init(&s,&fops,&m,&flayout)==0);assert(flash_storage_write(&s,one,sizeof(one))==0);m.fail_after=m.calls;assert(flash_storage_write(&s,two,sizeof(two))==FLASH_STORAGE_E_IO);m.fail_after=-1;assert(flash_storage_init(&recovered,&fops,&m,&flayout)==0);assert(flash_storage_read_latest(&recovered,out,sizeof(out),&n,0)==0&&n==512&&!memcmp(out,one,512));assert(flash_storage_get_info(&recovered,&info)==0);assert(info.reserved_bytes*100U>=info.allocated_bytes*10U);
/* Заполняем до перехода банка; последовательность и данные обязаны пережить wrap. */
for(unsigned i=0;i<220U;++i){two[0]=(uint8_t)i;assert(flash_storage_write(&recovered,two,512)==0);}assert(recovered.latest_address>=BASE0+BANK);assert(flash_storage_init(&s,&fops,&m,&flayout)==0);assert(flash_storage_read_latest(&s,out,512,&n,0)==0&&out[0]==(uint8_t)219U);}
static void test_instances(void){mock_flash_t a,b;eeprom_store_t ea,eb;uint8_t x=7,y=9,z=0;memset(&a,0,sizeof(a));memset(&b,0,sizeof(b));memset(a.bytes,0xFF,sizeof(a.bytes));memset(b.bytes,0xFF,sizeof(b.bytes));a.fail_after=b.fail_after=-1;assert(eeprom_store_init(&ea,&fops,&a,&flayout)==0);assert(eeprom_store_init(&eb,&fops,&b,&flayout)==0);assert(eeprom_store_write(&ea,10,&x,1)==0);assert(eeprom_store_write(&eb,10,&y,1)==0);assert(eeprom_store_read(&ea,10,&z,1)==0&&z==7);assert(eeprom_store_read(&eb,10,&z,1)==0&&z==9);}
int main(void){test_ds();test_flash();test_instances();puts("portable library tests: OK");return 0;}