-
Notifications
You must be signed in to change notification settings - Fork 242
/
Flash_get_put.ino
147 lines (118 loc) · 4.79 KB
/
Flash_get_put.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/***********************************************************************|
| Urboot read/write interface library |
| |
| Flash_get_put.ino |
| |
| A library for interfacing with Urboot's flash write functionality |
| Developed in 2023 by Stefan Rueger and MCUdude |
| https://github.com/stefanrueger/ |
| https://github.com/MCUdude/ |
| |
| In this example we write a float and a struct to flash page 0, and we |
| set a flag on flash page 1 to indicate there is content to be read |
| afterwards. After a reset we read back the flash content and prints |
| them to the serial monitor. |
| |
| A RAM buffer (ram_buffer) is required for this library to work. It |
| acts as a memory pool you can read from and write to, and recommended |
| size for this buffer is one flash page, 256/128/64 bytes depending on |
| what chip you're using. ram_buffer[] and flash[] is the exact same |
| array, flash[] is just pointing to ram_buffer[]. |
|***********************************************************************/
#include <Flash.h>
struct MyStruct
{
float field1;
uint8_t field2;
char name[10];
};
// RAM buffer needed by the Flash library. Use flash[] to access the buffer.
uint8_t ram_buffer[SPM_PAGESIZE];
// Allocate two flash pages for storing data. Use PROGMEM1 to allocate space above 64kiB
#define NUMBER_OF_PAGES 2
const uint8_t flash_space[SPM_PAGESIZE * NUMBER_OF_PAGES] __attribute__((aligned(SPM_PAGESIZE))) PROGMEM = {};
// Flash constructor
Flash flash(flash_space, sizeof(flash_space), ram_buffer, sizeof(ram_buffer));
void write_data()
{
uint8_t buffer_address = 0;
float f = 123.456f;
// First, make sure there are no content in out buffer
flash.clear_buffer();
// One simple call, with the address first and the object second
flash.put(buffer_address, f);
Serial.println(F("Written float data type!"));
// Data to store
MyStruct customVar =
{
3.14f,
65,
"MCUdude"
};
// Move address to the next byte after float 'f'
buffer_address += sizeof(float);
flash.put(buffer_address, customVar);
// Write buffer to the first allocated flash page (page 0)
flash.write_page(0);
// Now let's set a flag on another flash page to indicate that the flash memory contains content
// Here we're treating the object as an array
flash.clear_buffer();
flash[5] = 'X';
flash.write_page(1);
Serial.println(F("Written custom data type!\nReset your board to view the contents!\n"));
}
void read_data()
{
Serial.println(F("Read float from flash: "));
// Fetch first flash page
flash.fetch_page(0);
float f = 0.00f; // Variable to store data read from flash
uint8_t buffer_address = 0; // Buffer address to start from
// Get the float data from flash at position 'buffer_address'
flash.get(buffer_address, f);
Serial.print(F("The value of f is now: "));
Serial.println(f, 3);
buffer_address += sizeof(float); // Move address to the next byte after float 'f'
MyStruct customVar; // Variable to store custom object read from flash.
flash.get(buffer_address, customVar);
Serial.println(F("Read custom object from flash: "));
Serial.println(customVar.field1);
Serial.println(customVar.field2);
Serial.println(customVar.name);
}
void setup()
{
delay(2000);
Serial.begin(9600);
if(!flash.check_writable())
{
Serial.println(F("Incompatible or no Urboot compatible bootloader present! Please burn correct bootloader"));
while(1);
}
// If the allocated flash space is above 64kiB, a 16-bit pointer won't be enough anymore.
// As a workaround, you can set the address to the allocated space like this, and the
// library will handle the rest. You'll also have to allocate your flash space in
// PROGMEM1 rather than PROGMEM.
//flash.set_far_address(pgm_get_far_address(flash_space));
// Fetch flash page 1, where we may have a flag
flash.fetch_page(1);
// Check if our flag is present
if(flash[5] == 'X')
{
Serial.println(F("Content found!"));
read_data();
}
else
{
Serial.print(F("Flash page size for this chip: "));
Serial.print(SPM_PAGESIZE);
Serial.print(F(" bytes\nTotal assigned flash space: "));
Serial.print(NUMBER_OF_PAGES * SPM_PAGESIZE);
Serial.println(F(" bytes"));
Serial.println(F("No content found! Writing new content..."));
write_data();
}
}
void loop()
{
}