Skip to content

Commit ce0be6c

Browse files
committed
Merge pull request #741 from bettio/new-nvs-api
ESP32/NVS: return tagged tuples instead of just the result Return either `{ok, result}` or `error`, instead of `binary()` or `undefined`. These changes are made under both the "Apache 2.0" and the "GNU Lesser General Public License 2.1 or later" license terms (dual license). SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
2 parents 96fbf6c + db31c66 commit ce0be6c

File tree

4 files changed

+90
-20
lines changed

4 files changed

+90
-20
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
5454
- Added support for nodejs with Wasm
5555
- Added support for a subset of the OTP logger interface
5656
- Added `esp:partition_list/0` function
57+
- Added `esp:nvs_fetch_binary/2` and `nvs_put_binary/3` functions (`esp:nvs_set_binary` and
58+
functions that default to `?ATOMVM_NVS_NS` are deprecated now).
5759

5860
### Fixed
5961
- Fixed issue with formatting integers with io:format() on STM32 platform

doc/src/network-programming-guide.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -231,13 +231,13 @@ If set in NVS storage, you may remove the corresponding `ssid` and `psk` paramet
231231

232232
You can set these credentials once, as follows:
233233

234-
esp:nvs_set_binary(atomvm, sta_ssid, <<"myssid">>).
235-
esp:nvs_set_binary(atomvm, sta_psk, <<"mypsk">>).
234+
esp:nvs_put_binary(atomvm, sta_ssid, <<"myssid">>).
235+
esp:nvs_put_binary(atomvm, sta_psk, <<"mypsk">>).
236236

237237
or
238238

239-
esp:nvs_set_binary(atomvm, ap_ssid, <<"myssid">>).
240-
esp:nvs_set_binary(atomvm, ap_psk, <<"mypsk">>).
239+
esp:nvs_put_binary(atomvm, ap_ssid, <<"myssid">>).
240+
esp:nvs_put_binary(atomvm, ap_psk, <<"mypsk">>).
241241

242242
With these settings, you can run ESP programs that initialize the network without configuring your SSID and PSK explicitly in source code.
243243

libs/eavmlib/src/esp.erl

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,10 @@
3232
wakeup_cause/0,
3333
sleep_enable_ext0_wakeup/2,
3434
sleep_enable_ext1_wakeup/2,
35+
nvs_fetch_binary/2,
3536
nvs_get_binary/1, nvs_get_binary/2, nvs_get_binary/3,
3637
nvs_set_binary/2, nvs_set_binary/3,
38+
nvs_put_binary/3,
3739
nvs_erase_key/1, nvs_erase_key/2,
3840
nvs_erase_all/0, nvs_erase_all/1,
3941
nvs_reformat/0,
@@ -44,6 +46,14 @@
4446
get_mac/1
4547
]).
4648

49+
-deprecated([
50+
{nvs_get_binary, 1, next_version},
51+
{nvs_erase_key, 1, next_version},
52+
{nvs_erase_all, 0, next_version},
53+
{nvs_set_binary, 2, next_version},
54+
{nvs_set_binary, 3, next_version}
55+
]).
56+
4757
-type esp_reset_reason() ::
4858
esp_rst_unknown
4959
| esp_rst_poweron
@@ -132,8 +142,24 @@ sleep_enable_ext0_wakeup(_Pin, _Level) ->
132142
sleep_enable_ext1_wakeup(_Mask, _Mode) ->
133143
erlang:nif_error(undefined).
134144

145+
%%-----------------------------------------------------------------------------
146+
%% @param Namespace NVS namespace
147+
%% @param Key NVS key
148+
%% @returns tagged tuple with binary value associated with this key in NV
149+
%% storage, {error, not_found} if there is no value associated with
150+
%% this key, or in general {error, Reason} for any other error.
151+
%% @doc Get the binary value associated with a key, or undefined, if
152+
%% there is no value associated with this key.
153+
%% @end
154+
%%-----------------------------------------------------------------------------
155+
-spec nvs_fetch_binary(Namespace :: atom(), Key :: atom()) ->
156+
{ok, binary()} | {error, not_found} | {error, atom()}.
157+
nvs_fetch_binary(Namespace, Key) when is_atom(Namespace) andalso is_atom(Key) ->
158+
erlang:nif_error(undefined).
159+
135160
%%-----------------------------------------------------------------------------
136161
%% @doc Equivalent to nvs_get_binary(?ATOMVM_NVS_NS, Key).
162+
%% @deprecated Please do not use this function.
137163
%% @end
138164
%%-----------------------------------------------------------------------------
139165
-spec nvs_get_binary(Key :: atom()) -> binary() | undefined.
@@ -151,7 +177,11 @@ nvs_get_binary(Key) when is_atom(Key) ->
151177
%%-----------------------------------------------------------------------------
152178
-spec nvs_get_binary(Namespace :: atom(), Key :: atom()) -> binary() | undefined.
153179
nvs_get_binary(Namespace, Key) when is_atom(Namespace) andalso is_atom(Key) ->
154-
erlang:nif_error(undefined).
180+
case nvs_fetch_binary(Namespace, Key) of
181+
{ok, Result} -> Result;
182+
{errror, not_found} -> undefined;
183+
{error, OtherError} -> throw(OtherError)
184+
end.
155185

156186
%%-----------------------------------------------------------------------------
157187
%% @param Namespace NVS namespace
@@ -177,6 +207,7 @@ nvs_get_binary(Namespace, Key, Default) when
177207

178208
%%-----------------------------------------------------------------------------
179209
%% @doc Equivalent to nvs_set_binary(?ATOMVM_NVS_NS, Key, Value).
210+
%% @deprecated Please use nvs_put_binary instead.
180211
%% @end
181212
%%-----------------------------------------------------------------------------
182213
-spec nvs_set_binary(Key :: atom(), Value :: binary()) -> ok.
@@ -190,18 +221,35 @@ nvs_set_binary(Key, Value) when is_atom(Key) andalso is_binary(Value) ->
190221
%% @returns ok
191222
%% @doc Set an binary value associated with a key. If a value exists
192223
%% for the specified key, it is over-written.
224+
%% @deprecated Please use nvs_put_binary instead.
193225
%% @end
194226
%%-----------------------------------------------------------------------------
195227
-spec nvs_set_binary(Namespace :: atom(), Key :: atom(), Value :: binary()) -> ok.
196228
nvs_set_binary(Namespace, Key, Value) when
197229
is_atom(Namespace) andalso is_atom(Key) andalso is_binary(Value)
230+
->
231+
nvs_put_binary(Namespace, Key, Value).
232+
233+
%%-----------------------------------------------------------------------------
234+
%% @param Namespace NVS namespace
235+
%% @param Key NVS key
236+
%% @param Value binary value
237+
%% @returns ok
238+
%% @doc Set an binary value associated with a key. If a value exists
239+
%% for the specified key, it is over-written.
240+
%% @end
241+
%%-----------------------------------------------------------------------------
242+
-spec nvs_put_binary(Namespace :: atom(), Key :: atom(), Value :: binary()) -> ok.
243+
nvs_put_binary(Namespace, Key, Value) when
244+
is_atom(Namespace) andalso is_atom(Key) andalso is_binary(Value)
198245
->
199246
erlang:nif_error(undefined).
200247

201248
%%-----------------------------------------------------------------------------
202249
%% @param Key NVS key
203250
%% @returns ok
204251
%% @doc Equivalent to nvs_erase_key(?ATOMVM_NVS_NS, Key).
252+
%% @deprecated Please do not use this function.
205253
%% @end
206254
%%-----------------------------------------------------------------------------
207255
-spec nvs_erase_key(Key :: atom()) -> ok.
@@ -222,6 +270,7 @@ nvs_erase_key(Namespace, Key) when is_atom(Namespace) andalso is_atom(Key) ->
222270

223271
%%-----------------------------------------------------------------------------
224272
%% @doc Equivalent to nvs_erase_all(?ATOMVM_NVS_NS).
273+
%% @deprecated Please do not use this function.
225274
%% @end
226275
%%-----------------------------------------------------------------------------
227276
-spec nvs_erase_all() -> ok.

src/platforms/esp32/components/avm_builtins/nvs_nif.c

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -63,28 +63,44 @@ static term nif_esp_nvs_get_binary(Context *ctx, int argc, term argv[])
6363
switch (err) {
6464
case ESP_OK:
6565
break;
66-
case ESP_ERR_NVS_NOT_FOUND:
66+
case ESP_ERR_NVS_NOT_FOUND: {
6767
TRACE("No such namespace. namespace='%s'\n", namespace);
68-
return UNDEFINED_ATOM;
68+
if (UNLIKELY(memory_ensure_free(ctx, TUPLE_SIZE(2)) != MEMORY_GC_OK)) {
69+
RAISE_ERROR(OUT_OF_MEMORY_ATOM);
70+
}
71+
term error_tuple = term_alloc_tuple(2, &ctx->heap);
72+
term ns_not_found = globalcontext_make_atom(ctx->global, ATOM_STR("\x13", "namespace_not_found"));
73+
term_put_tuple_element(error_tuple, 0, OK_ATOM);
74+
term_put_tuple_element(error_tuple, 1, ns_not_found);
75+
return error_tuple;
76+
}
6977
default:
70-
fprintf(stderr, "Unable to open NVS. namespace '%s' err=%i\n", namespace, err);
71-
RAISE_ERROR(term_from_int(err));
78+
TRACE("Unable to open NVS. namespace '%s' err=%i\n", namespace, err);
79+
RAISE_ERROR(esp_err_to_term(ctx->global, err));
7280
}
7381

7482
size_t size = 0;
7583
err = nvs_get_blob(nvs, key, NULL, &size);
7684
switch (err) {
7785
case ESP_OK:
7886
break;
79-
case ESP_ERR_NVS_NOT_FOUND:
87+
case ESP_ERR_NVS_NOT_FOUND: {
8088
TRACE("No such entry. namespace='%s' key='%s'\n", namespace, key);
81-
return UNDEFINED_ATOM;
89+
if (UNLIKELY(memory_ensure_free(ctx, TUPLE_SIZE(2)) != MEMORY_GC_OK)) {
90+
RAISE_ERROR(OUT_OF_MEMORY_ATOM);
91+
}
92+
term error_tuple = term_alloc_tuple(2, &ctx->heap);
93+
term not_found = globalcontext_make_atom(ctx->global, ATOM_STR("\x9", "not_found"));
94+
term_put_tuple_element(error_tuple, 0, OK_ATOM);
95+
term_put_tuple_element(error_tuple, 1, not_found);
96+
return error_tuple;
97+
}
8298
default:
83-
fprintf(stderr, "Unable to get NVS blob size. namespace '%s' key='%s' err=%i\n", namespace, key, err);
84-
RAISE_ERROR(term_from_int(err));
99+
TRACE("Unable to get NVS blob size. namespace '%s' key='%s' err=%i\n", namespace, key, err);
100+
RAISE_ERROR(esp_err_to_term(ctx->global, err));
85101
}
86102

87-
if (UNLIKELY(memory_ensure_free(ctx, size + BINARY_HEADER_SIZE) != MEMORY_GC_OK)) {
103+
if (UNLIKELY(memory_ensure_free(ctx, term_binary_heap_size(size) + TUPLE_SIZE(2)) != MEMORY_GC_OK)) {
88104
TRACE("Unabled to ensure free space for binary. namespace='%s' key='%s' size=%i\n", namespace, key, size);
89105
RAISE_ERROR(OUT_OF_MEMORY_ATOM);
90106
}
@@ -95,14 +111,17 @@ static term nif_esp_nvs_get_binary(Context *ctx, int argc, term argv[])
95111
switch (err) {
96112
case ESP_OK:
97113
TRACE("Found data for key. namespace='%s' key='%s' size='%i'\n", namespace, key, size);
98-
return binary;
114+
term result_tuple = term_alloc_tuple(2, &ctx->heap);
115+
term_put_tuple_element(result_tuple, 0, OK_ATOM);
116+
term_put_tuple_element(result_tuple, 1, binary);
117+
return result_tuple;
99118
default:
100119
fprintf(stderr, "Unable to get NVS blob. namespace='%s' key='%s' err=%i\n", namespace, key, err);
101120
RAISE_ERROR(term_from_int(err));
102121
}
103122
}
104123

105-
static term nif_esp_nvs_set_binary(Context *ctx, int argc, term argv[])
124+
static term nif_esp_nvs_put_binary(Context *ctx, int argc, term argv[])
106125
{
107126
UNUSED(argc);
108127
VALIDATE_VALUE(argv[0], term_is_atom);
@@ -241,9 +260,9 @@ static const struct Nif esp_nvs_get_binary_nif = {
241260
.base.type = NIFFunctionType,
242261
.nif_ptr = nif_esp_nvs_get_binary
243262
};
244-
static const struct Nif esp_nvs_set_binary_nif = {
263+
static const struct Nif esp_nvs_put_binary_nif = {
245264
.base.type = NIFFunctionType,
246-
.nif_ptr = nif_esp_nvs_set_binary
265+
.nif_ptr = nif_esp_nvs_put_binary
247266
};
248267
static const struct Nif esp_nvs_erase_key_nif = {
249268
.base.type = NIFFunctionType,
@@ -275,9 +294,9 @@ const struct Nif *nvs_nif_get_nif(const char *nifname)
275294
TRACE("Resolved platform nif %s ...\n", nifname);
276295
return &esp_nvs_get_binary_nif;
277296
}
278-
if (strcmp("esp:nvs_set_binary/3", nifname) == 0) {
297+
if (strcmp("esp:nvs_put_binary/3", nifname) == 0) {
279298
TRACE("Resolved platform nif %s ...\n", nifname);
280-
return &esp_nvs_set_binary_nif;
299+
return &esp_nvs_put_binary_nif;
281300
}
282301
if (strcmp("esp:nvs_erase_key/2", nifname) == 0) {
283302
TRACE("Resolved platform nif %s ...\n", nifname);

0 commit comments

Comments
 (0)