Skip to content

Commit 2025e40

Browse files
committed
ESP32/NVS: add fetch that returns tagged tuples instead of just the result
New fetch function returns either `{ok, result}` or `error`, instead of `binary()` or `undefined`. Signed-off-by: Davide Bettio <[email protected]>
1 parent 849fcd6 commit 2025e40

File tree

2 files changed

+50
-11
lines changed

2 files changed

+50
-11
lines changed

libs/eavmlib/src/esp.erl

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
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,
3738
nvs_erase_key/1, nvs_erase_key/2,
@@ -132,6 +133,21 @@ sleep_enable_ext0_wakeup(_Pin, _Level) ->
132133
sleep_enable_ext1_wakeup(_Mask, _Mode) ->
133134
erlang:nif_error(undefined).
134135

136+
%%-----------------------------------------------------------------------------
137+
%% @param Namespace NVS namespace
138+
%% @param Key NVS key
139+
%% @returns tagged tuple with binary value associated with this key in NV
140+
%% storage, {error, not_found} if there is no value associated with
141+
%% this key, or in general {error, Reason} for any other error.
142+
%% @doc Get the binary value associated with a key, or undefined, if
143+
%% there is no value associated with this key.
144+
%% @end
145+
%%-----------------------------------------------------------------------------
146+
-spec nvs_fetch_binary(Namespace :: atom(), Key :: atom()) ->
147+
{ok, binary()} | {error, not_found} | {error, atom()}.
148+
nvs_fetch_binary(Namespace, Key) when is_atom(Namespace) andalso is_atom(Key) ->
149+
erlang:nif_error(undefined).
150+
135151
%%-----------------------------------------------------------------------------
136152
%% @doc Equivalent to nvs_get_binary(?ATOMVM_NVS_NS, Key).
137153
%% @end
@@ -151,7 +167,11 @@ nvs_get_binary(Key) when is_atom(Key) ->
151167
%%-----------------------------------------------------------------------------
152168
-spec nvs_get_binary(Namespace :: atom(), Key :: atom()) -> binary() | undefined.
153169
nvs_get_binary(Namespace, Key) when is_atom(Namespace) andalso is_atom(Key) ->
154-
erlang:nif_error(undefined).
170+
case nvs_fetch_binary(Namespace, Key) of
171+
{ok, Result} -> Result;
172+
{errror, not_found} -> undefined;
173+
{error, OtherError} -> throw(OtherError)
174+
end.
155175

156176
%%-----------------------------------------------------------------------------
157177
%% @param Namespace NVS namespace

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

Lines changed: 29 additions & 10 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, term_binary_heap_size(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,7 +111,10 @@ 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));

0 commit comments

Comments
 (0)