1818#include <memory/memory_shared.h>
1919#include <stdio.h>
2020#include <string.h>
21+ #include <sys/stat.h>
22+ #include <stdlib.h>
23+
24+
25+ #define FAKE_MEMORY_ENV_VAR "FAKE_MEMORY_FILEPATH"
26+ #define SHARED_SUFFIX "shared"
27+ #define APP_SUFFIX "app"
28+ #define EEPROM_SUFFIX "eeprom"
2129
2230static uint8_t _memory_shared_data [FLASH_SHARED_DATA_LEN ] = {0 };
2331static uint8_t _memory_app_data [FLASH_APPDATA_LEN ] = {0 };
2432static uint8_t _memory_smarteeprom [SMARTEEPROM_RESERVED_FLASH_PAGES * FLASH_PAGE_SIZE ] = {0 };
2533
34+ static void _init_file_if_needed (
35+ const char * base_path ,
36+ const char * suffix ,
37+ const uint8_t * data ,
38+ size_t data_size )
39+ {
40+ char path [512 ];
41+ if (snprintf (path , sizeof (path ), "%s_%s" , base_path , suffix ) >= sizeof (path )) {
42+ fprintf (stderr , "file path %s_%s too long\n" , base_path , suffix );
43+ exit (EXIT_FAILURE );
44+ }
45+
46+ struct stat st ;
47+ if (stat (path , & st ) == 0 ) {
48+ return ; // The file already exists, do nothing.
49+ }
50+
51+ FILE * f = fopen (path , "wb" );
52+ if (f ) {
53+ fwrite (data , 1 , data_size , f );
54+ fclose (f );
55+ } else {
56+ fprintf (stderr , "error: could not create fake memory file %s\n" , path );
57+ exit (EXIT_FAILURE );
58+ }
59+ }
60+
2661void fake_memory_factoryreset (void )
2762{
2863 memset (_memory_shared_data , 0xff , sizeof (_memory_shared_data ));
2964 memset (_memory_app_data , 0xff , sizeof (_memory_app_data ));
3065 memset (_memory_smarteeprom , 0xff , sizeof (_memory_smarteeprom ));
66+
67+ const char * base_path = getenv (FAKE_MEMORY_ENV_VAR );
68+ if (base_path ) {
69+ _init_file_if_needed (base_path , SHARED_SUFFIX , _memory_shared_data , sizeof (_memory_shared_data ));
70+ _init_file_if_needed (base_path , APP_SUFFIX , _memory_app_data , sizeof (_memory_app_data ));
71+ _init_file_if_needed (base_path , EEPROM_SUFFIX , _memory_smarteeprom , sizeof (_memory_smarteeprom ));
72+ }
3173}
74+
3275#define ALLOWED_HASH \
3376 "\x1e\x4a\xa8\x36\x4e\x93\x5c\x07\x85\xe4\xf8\x91\x20\x83\x07\xd8\x32\xf7\x88\x17\x2e\x4b\xf6" \
3477 "\x16\x21\xde\x6d\xf9\xec\x3c\x21\x5f"
@@ -63,8 +106,78 @@ static uint8_t* _get_memory(uint32_t base)
63106 }
64107}
65108
109+ static void _write_file_chunk (const char * suffix , uint32_t offset , const uint8_t * chunk , size_t len )
110+ {
111+ char path [512 ];
112+ const char * base_path = getenv (FAKE_MEMORY_ENV_VAR );
113+ if (!base_path ) {
114+ return ;
115+ }
116+ if (snprintf (path , sizeof (path ), "%s_%s" , base_path , suffix ) >= sizeof (path )) {
117+ fprintf (stderr , "file path %s_%s too long\n" , base_path , suffix );
118+ exit (EXIT_FAILURE );
119+ }
120+ FILE * f = fopen (path , "r+b" );
121+ if (!f ) {
122+ fprintf (stderr , "error: fake memory file %s not found\n" , path );
123+ exit (EXIT_FAILURE );
124+ }
125+ fseek (f , offset , SEEK_SET );
126+ fwrite (chunk , 1 , len , f );
127+ fclose (f );
128+ }
129+
130+ static void _read_file_chunk (const char * suffix , uint32_t offset , uint8_t * chunk , size_t len )
131+ {
132+ char path [512 ];
133+ const char * base_path = getenv (FAKE_MEMORY_ENV_VAR );
134+ if (!base_path ) {
135+ return ;
136+ }
137+ if (snprintf (path , sizeof (path ), "%s_%s" , base_path , suffix ) >= sizeof (path )) {
138+ fprintf (stderr , "file path %s_%s too long\n" , base_path , suffix );
139+ exit (EXIT_FAILURE );
140+ }
141+ FILE * f = fopen (path , "rb" );
142+ if (!f ) {
143+ fprintf (stderr , "error: fake memory file %s not found\n" , path );
144+ exit (EXIT_FAILURE );
145+ }
146+ fseek (f , offset , SEEK_SET );
147+ fread (chunk , 1 , len , f );
148+ fclose (f );
149+ }
150+
66151bool memory_write_to_address_fake (uint32_t base , uint32_t addr , const uint8_t * chunk )
67152{
153+ const char * base_path = getenv (FAKE_MEMORY_ENV_VAR );
154+
155+ if (base_path ) {
156+ size_t len = CHUNK_SIZE ;
157+ const char * suffix = NULL ;
158+ switch (base ) {
159+ case FLASH_SHARED_DATA_START :
160+ suffix = SHARED_SUFFIX ;
161+ break ;
162+ case FLASH_APPDATA_START :
163+ suffix = APP_SUFFIX ;
164+ break ;
165+ case FLASH_SMARTEEPROM_START :
166+ suffix = EEPROM_SUFFIX ;
167+ break ;
168+ default :
169+ return false;
170+ }
171+ if (chunk == NULL ) {
172+ uint8_t empty [CHUNK_SIZE ];
173+ memset (empty , 0xff , CHUNK_SIZE );
174+ _write_file_chunk (suffix , addr , empty , len );
175+ } else {
176+ _write_file_chunk (suffix , addr , chunk , len );
177+ }
178+ return true;
179+ }
180+
68181 if (chunk == NULL ) {
69182 memset (_get_memory (base ) + addr , 0xff , (size_t )CHUNK_SIZE );
70183 } else {
@@ -80,11 +193,23 @@ bool memory_write_chunk_fake(uint32_t chunk_num, const uint8_t* chunk)
80193
81194void memory_read_chunk_fake (uint32_t chunk_num , uint8_t * chunk_out )
82195{
196+ const char * base_path = getenv (FAKE_MEMORY_ENV_VAR );
197+ if (base_path ) {
198+ _read_file_chunk (APP_SUFFIX , chunk_num * (size_t )CHUNK_SIZE , chunk_out , (size_t )CHUNK_SIZE );
199+ return ;
200+ }
201+
83202 memcpy (chunk_out , _memory_app_data + chunk_num * (size_t )CHUNK_SIZE , (size_t )CHUNK_SIZE );
84203}
85204
86205void memory_read_shared_bootdata_fake (uint8_t * chunk_out )
87206{
207+ const char * base_path = getenv (FAKE_MEMORY_ENV_VAR );
208+ if (base_path ) {
209+ _read_file_chunk (SHARED_SUFFIX , 0 , chunk_out , (size_t )FLASH_SHARED_DATA_LEN );
210+ return ;
211+ }
212+
88213 memcpy (chunk_out , _memory_shared_data , (size_t )FLASH_SHARED_DATA_LEN );
89214}
90215
0 commit comments