24
24
* THE SOFTWARE.
25
25
*/
26
26
27
+ #include <string.h>
28
+
27
29
#include "common-hal/nvm/ByteArray.h"
30
+ #include "bindings/espidf/__init__.h"
28
31
29
32
#include "py/runtime.h"
33
+ #include "py/gc.h"
30
34
#include "nvs_flash.h"
31
35
32
36
uint32_t common_hal_nvm_bytearray_get_length (nvm_bytearray_obj_t * self ) {
@@ -50,48 +54,94 @@ static void get_nvs_handle(nvs_handle_t *nvs_handle) {
50
54
}
51
55
}
52
56
57
+ // Get a copy of the nvm data, or an array initialized to all 0 bytes if it is not present
58
+ static esp_err_t get_bytes (nvs_handle_t handle , uint8_t * * buf_out ) {
59
+ size_t size ;
60
+ void * buf ;
61
+ esp_err_t result = nvs_get_blob (handle , "data" , NULL , & size );
62
+ if (result == ESP_ERR_NVS_NOT_FOUND ) {
63
+ size = CIRCUITPY_INTERNAL_NVM_SIZE ;
64
+ } else if (result != ESP_OK ) {
65
+ * buf_out = NULL ;
66
+ return result ;
67
+ }
68
+ buf = gc_alloc (size , 0 , false); // this SHOULD be the same as
69
+ if (result == ESP_OK ) {
70
+ result = nvs_get_blob (handle , "data" , buf , & size );
71
+ } else {
72
+ result = ESP_OK ;
73
+ }
74
+ * buf_out = buf ;
75
+ return result ;
76
+ }
77
+
53
78
bool common_hal_nvm_bytearray_set_bytes (nvm_bytearray_obj_t * self ,
54
79
uint32_t start_index , uint8_t * values , uint32_t len ) {
55
- char index [9 ];
56
80
57
81
// start nvs
58
82
nvs_handle_t handle ;
59
83
get_nvs_handle (& handle );
60
84
61
- // stage flash changes
62
- for (uint32_t i = 0 ; i < len ; i ++ ) {
63
- sprintf (index , "%i" , start_index + i );
64
- if (nvs_set_u8 (handle , (const char * )index , values [i ]) != ESP_OK ) {
65
- return false;
66
- }
85
+ // get from flash
86
+ uint8_t * buf = NULL ;
87
+ esp_err_t result = get_bytes (handle , & buf );
88
+ if (result != ESP_OK ) {
89
+ gc_free (buf );
90
+ nvs_close (handle );
91
+ raise_esp_error (result );
92
+ }
93
+
94
+ // erase old data, including 6.3.x incompatible data
95
+ result = nvs_erase_all (handle );
96
+ if (result != ESP_OK ) {
97
+ gc_free (buf );
98
+ nvs_close (handle );
99
+ raise_esp_error (result );
100
+ }
101
+
102
+ // make our modification
103
+ memcpy (buf + start_index , values , len );
104
+
105
+ result = nvs_set_blob (handle , "data" , buf , CIRCUITPY_INTERNAL_NVM_SIZE );
106
+ if (result != ESP_OK ) {
107
+ gc_free (buf );
108
+ nvs_close (handle );
109
+ raise_esp_error (result );
67
110
}
68
111
69
- // commit flash changes
70
- if (nvs_commit (handle ) != ESP_OK ) {
71
- return false;
112
+ result = nvs_commit (handle );
113
+ if (result != ESP_OK ) {
114
+ gc_free (buf );
115
+ nvs_close (handle );
116
+ raise_esp_error (result );
72
117
}
73
118
74
119
// close nvs
120
+ gc_free (buf );
75
121
nvs_close (handle );
76
122
return true;
77
123
}
78
124
79
125
void common_hal_nvm_bytearray_get_bytes (nvm_bytearray_obj_t * self ,
80
126
uint32_t start_index , uint32_t len , uint8_t * values ) {
81
- char index [9 ];
82
127
83
128
// start nvs
84
129
nvs_handle_t handle ;
85
130
get_nvs_handle (& handle );
86
131
87
132
// get from flash
88
- for (uint32_t i = 0 ; i < len ; i ++ ) {
89
- sprintf (index , "%i" , start_index + i );
90
- if (nvs_get_u8 (handle , (const char * )index , & values [i ]) != ESP_OK ) {
91
- mp_raise_RuntimeError (translate ("NVS Error" ));
92
- }
133
+ uint8_t * buf ;
134
+ esp_err_t result = get_bytes (handle , & buf );
135
+ if (result != ESP_OK ) {
136
+ gc_free (buf );
137
+ nvs_close (handle );
138
+ raise_esp_error (result );
93
139
}
94
140
141
+ // copy the subset of data requested
142
+ memcpy (values , buf + start_index , len );
143
+
95
144
// close nvs
145
+ gc_free (buf );
96
146
nvs_close (handle );
97
147
}
0 commit comments