33
44 The sketch formats the board QSPI flash as follow:
55
6- * Partition 1 5MB: used for network certificates and OTA
7- * Partition 2 11MB: general purpose
6+ * Partition 1 1MB: used for network certificates
7+ * Partition 2 5MB: OTA
8+ * Partition 3 1MB: Provisioning KVStore
9+ * Partition 4 7MB: User data
810
911 This example code is in the public domain.
1012*/
1315#include " MBRBlockDevice.h"
1416#include " LittleFileSystem.h"
1517#include " FATFileSystem.h"
18+ #include " certificates.h"
1619
1720BlockDevice* root = BlockDevice::get_default_instance();
18- MBRBlockDevice sys_bd (root, 1 );
19- MBRBlockDevice user_bd (root, 2 );
20- FATFileSystem sys_fs (" sys" );
21+ MBRBlockDevice wifi_data (root, 1 );
22+ MBRBlockDevice ota_data (root, 2 );
23+ MBRBlockDevice kvstore_data (root, 3 );
24+ MBRBlockDevice user_data (root, 4 );
25+ FATFileSystem wifi_data_fs (" wlan" );
26+ FATFileSystem ota_data_fs (" fs" );
2127FileSystem * user_data_fs;
2228
2329bool waitResponse () {
2430 bool confirmation = false ;
31+ bool proceed = false ;
2532 while (confirmation == false ) {
2633 if (Serial.available ()) {
2734 char choice = Serial.read ();
2835 switch (choice) {
2936 case ' y' :
3037 case ' Y' :
3138 confirmation = true ;
32- return true ;
39+ proceed = true ;
3340 break ;
3441 case ' n' :
3542 case ' N' :
3643 confirmation = true ;
37- return false ;
44+ proceed = false ;
3845 break ;
3946 default :
4047 continue ;
4148 }
4249 }
4350 }
51+ return proceed;
52+ }
53+
54+ void printProgress (uint32_t offset, uint32_t size, uint32_t threshold, bool reset) {
55+ static int percent_done = 0 ;
56+ if (reset == true ) {
57+ percent_done = 0 ;
58+ Serial.println (" Flashed " + String (percent_done) + " %" );
59+ } else {
60+ uint32_t percent_done_new = offset * 100 / size;
61+ if (percent_done_new >= percent_done + threshold) {
62+ percent_done = percent_done_new;
63+ Serial.println (" Flashed " + String (percent_done) + " %" );
64+ }
65+ }
4466}
4567
4668void setup () {
@@ -49,21 +71,75 @@ void setup() {
4971 while (!Serial);
5072
5173 Serial.println (" \n WARNING! Running the sketch all the content of the QSPI flash will be erased." );
74+ Serial.println (" The following partitions will be created:" );
75+ Serial.println (" Partition 1: Network certificates 1MB" );
76+ Serial.println (" Partition 2: OTA 5MB" );
77+ Serial.println (" Partition 3: Provisioning KVStore 1MB" );
78+ Serial.println (" Partition 4: User data 7MB" ),
5279 Serial.println (" Do you want to proceed? Y/[n]" );
5380
5481 if (true == waitResponse ()) {
55- MBRBlockDevice::partition (root, 1 , 0x0B , 0 , 5 * 1024 * 1024 );
56- MBRBlockDevice::partition (root, 2 , 0x0B , 5 * 1024 * 1024 , 15 * 1024 * 1024 );
57- MBRBlockDevice::partition (root, 3 , 0x0B , 15 * 1024 * 1024 , 16 * 1024 * 1024 );
82+ if (root->init () != BD_ERROR_OK) {
83+ Serial.println (F (" Error: QSPI init failure." ));
84+ return ;
85+ }
5886
59- int err = sys_fs.reformat (&sys_bd);
60- if (err) {
61- Serial.println (" Error formatting sys partition" );
87+ Serial.println (" Do you want to perform a full erase of the QSPI flash before proceeding? Y/[n]" );
88+ Serial.println (" Note: Full flash erase can take up to one minute." );
89+ bool fullErase = waitResponse ();
90+ if (fullErase == true ) {
91+ Serial.println (" Full erase started, please wait..." );
92+ root->erase (0x0 , root->size ());
93+ Serial.println (" Full erase completed." );
94+ } else {
95+ // Erase only the first sector containing the MBR
96+ root->erase (0x0 , root->get_erase_size ());
97+ }
98+
99+ MBRBlockDevice::partition (root, 1 , 0x0B , 0 , 1 * 1024 * 1024 );
100+ MBRBlockDevice::partition (root, 2 , 0x0B , 1 * 1024 * 1024 , 6 * 1024 * 1024 );
101+ MBRBlockDevice::partition (root, 3 , 0x0B , 6 * 1024 * 1024 , 7 * 1024 * 1024 );
102+ MBRBlockDevice::partition (root, 4 , 0x0B , 7 * 1024 * 1024 , 14 * 1024 * 1024 );
103+ // free space from 15.5MB to 16 MB
104+
105+ bool reformat = true ;
106+ if (!wifi_data_fs.mount (&wifi_data)) {
107+ Serial.println (" \n Partition 1 already contains a filesystem, do you want to reformat it? Y/[n]" );
108+ wifi_data_fs.unmount ();
109+
110+ reformat = waitResponse ();
111+ }
112+
113+ if (reformat && wifi_data_fs.reformat (&wifi_data)) {
114+ Serial.println (" Error formatting WiFi partition" );
115+ return ;
116+ }
117+
118+ bool restore = true ;
119+ if (reformat || fullErase) {
120+ Serial.println (" \n Do you want to restore the WiFi firmware and certificates? Y/[n]" );
121+ restore = waitResponse ();
122+ }
123+
124+ if (reformat && restore) {
125+ flashCertificates ();
126+ }
127+
128+ reformat = true ;
129+ if (!ota_data_fs.mount (&ota_data)) {
130+ Serial.println (" \n Partition 2 already contains a filesystem, do you want to reformat it? Y/[n]" );
131+ ota_data_fs.unmount ();
132+
133+ reformat = waitResponse ();
134+ }
135+
136+ if (reformat && ota_data_fs.reformat (&ota_data)) {
137+ Serial.println (" Error formatting OTA partition" );
138+ return ;
62139 }
63140
64141 Serial.println (" \n Do you want to use LittleFS to format user data partition? Y/[n]" );
65142 Serial.println (" If No, FatFS will be used to format user partition." );
66-
67143 if (true == waitResponse ()) {
68144 Serial.println (" Formatting user partition with LittleFS." );
69145 user_data_fs = new LittleFileSystem (" user" );
@@ -72,9 +148,17 @@ void setup() {
72148 user_data_fs = new FATFileSystem (" user" );
73149 }
74150
75- err = user_data_fs->reformat (&user_bd);
76- if (err) {
151+ reformat = true ;
152+ if (!user_data_fs->mount (&user_data)) {
153+ Serial.println (" \n Partition 4 already contains a filesystem, do you want to reformat it? Y/[n]" );
154+ user_data_fs->unmount ();
155+
156+ reformat = waitResponse ();
157+ }
158+
159+ if (reformat && user_data_fs->reformat (&user_data)) {
77160 Serial.println (" Error formatting user partition" );
161+ return ;
78162 }
79163
80164 Serial.println (" \n QSPI Flash formatted!" );
@@ -83,6 +167,30 @@ void setup() {
83167 Serial.println (" It's now safe to reboot or disconnect your board." );
84168}
85169
170+ const uint32_t file_size = 421098 ;
171+ extern const unsigned char wifi_firmware_image_data[];
172+
173+ void flashCertificates () {
174+ FILE* fp = fopen (" /wlan/cacert.pem" , " wb" );
175+
176+ Serial.println (" Flashing certificates" );
177+ uint32_t chunk_size = 128 ;
178+ uint32_t byte_count = 0 ;
179+ printProgress (byte_count, cacert_pem_len, 10 , true );
180+ while (byte_count < cacert_pem_len) {
181+ if (byte_count + chunk_size > cacert_pem_len)
182+ chunk_size = cacert_pem_len - byte_count;
183+ int ret = fwrite (&cacert_pem[byte_count], chunk_size, 1 ,fp);
184+ if (ret != 1 ) {
185+ Serial.println (" Error writing certificates" );
186+ break ;
187+ }
188+ byte_count += chunk_size;
189+ printProgress (byte_count, cacert_pem_len, 10 , false );
190+ }
191+ fclose (fp);
192+ }
193+
86194void loop () {
87195
88196}
0 commit comments