Skip to content

Commit e0c409c

Browse files
committed
Merge branch 'master' into feature/smp
Merge fixes and RTC slow memory support.
2 parents 682b185 + d35a000 commit e0c409c

File tree

11 files changed

+254
-3
lines changed

11 files changed

+254
-3
lines changed

.github/workflows/esp32-build.yaml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,5 +46,14 @@ jobs:
4646
. $IDF_PATH/export.sh
4747
idf.py reconfigure
4848
idf.py build
49-
# Print component size info
49+
idf.py size
50+
- name: Print component size info with idf.py
51+
# size-components doesn't work with a .noinit section on 4.2.x branch.
52+
# The bug was fixed on later versions and didn't occur on 4.0.x & 3.x
53+
# https://github.com/espressif/esp-idf/issues/8428
54+
if: matrix.build-system == 'idf' && matrix.idf-version != '4.2.3'
55+
shell: bash
56+
working-directory: ./src/platforms/esp32/
57+
run: |
58+
. $IDF_PATH/export.sh
5059
idf.py size-components

libs/eavmlib/src/esp.erl

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
nvs_erase_key/1, nvs_erase_key/2,
3838
nvs_erase_all/0, nvs_erase_all/1,
3939
nvs_reformat/0,
40+
rtc_slow_get_binary/0,
41+
rtc_slow_set_binary/1,
4042
freq_hz/0
4143
]).
4244

@@ -225,6 +227,28 @@ nvs_erase_all(Namespace) when is_atom(Namespace) ->
225227
nvs_reformat() ->
226228
throw(nif_error).
227229

230+
%%-----------------------------------------------------------------------------
231+
%% @returns the currently stored binary in RTC slow memory.
232+
%% @doc Get the binary currently stored in RTC slow memory. Must not be
233+
%% called unless the binary was stored with rtc_slow_set_binary/1.
234+
%% A limited checksum is ran and this function may throw badarg if
235+
%% the checksum is not valid.
236+
%% @end
237+
%%-----------------------------------------------------------------------------
238+
-spec rtc_slow_get_binary() -> binary().
239+
rtc_slow_get_binary() ->
240+
throw(nif_error).
241+
242+
%%-----------------------------------------------------------------------------
243+
%% @returns ok
244+
%% @doc Store a binary to RTC slow memory. This memory is not erased on
245+
%% software reset and deep sleeps.
246+
%% @end
247+
%%-----------------------------------------------------------------------------
248+
-spec rtc_slow_set_binary(Bin :: binary()) -> ok.
249+
rtc_slow_set_binary(Bin) when is_binary(Bin) ->
250+
throw(nif_error).
251+
228252
%%-----------------------------------------------------------------------------
229253
%% @returns Clock frequency (in hz)
230254
%% @doc Return the clock frequency on the chip

src/libAtomVM/opcodesswitch.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ typedef union
126126
break; \
127127
\
128128
case 1: \
129-
dest_term = term_from_int4(((first_byte & 0xE0) << 3) | code_chunk[(base_index) + (off) + 1]); \
129+
dest_term = term_from_int(((first_byte & 0xE0) << 3) | code_chunk[(base_index) + (off) + 1]); \
130130
off += 2; \
131131
break; \
132132
\
@@ -430,7 +430,7 @@ typedef union
430430
break; \
431431
\
432432
case 1: \
433-
dest_term = term_from_int4(((first_byte & 0xE0) << 3) | code_chunk[(base_index) + (off) + 1]); \
433+
dest_term = term_from_int(((first_byte & 0xE0) << 3) | code_chunk[(base_index) + (off) + 1]); \
434434
off += 2; \
435435
break; \
436436
\

src/platforms/esp32/components/avm_builtins/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ set(AVM_BUILTIN_COMPONENT_SRCS
2424
"ledc_nif.c"
2525
"network_driver.c"
2626
"nvs_nif.c"
27+
"rtc_slow_nif.c"
2728
"socket_driver.c"
2829
"spi_driver.c"
2930
"uart_driver.c"

src/platforms/esp32/components/avm_builtins/Kconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,16 @@ config AVM_ENABLE_NVS_NIFS
3232
bool "Enable NVS NIFs"
3333
default y
3434

35+
config AVM_ENABLE_RTC_SLOW_NIFS
36+
bool "Enable RTC SLOW NIFs"
37+
default y
38+
39+
config AVM_RTC_SLOW_MAX_SIZE
40+
int "RTC SLOW maximum binary size"
41+
# By default, use the maximum size for esp-idf < 4.4
42+
# In newer version, available size is 8170
43+
default 4086
44+
3545
config AVM_ENABLE_GPIO_PORT_DRIVER
3646
bool "Enable GPIO port driver"
3747
default y
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/*
2+
* This file is part of AtomVM.
3+
*
4+
* Copyright 2023 Paul Guyot <[email protected]>
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*
18+
* SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
19+
*/
20+
21+
#include <sdkconfig.h>
22+
#ifdef CONFIG_AVM_ENABLE_RTC_SLOW_NIFS
23+
24+
#include <atom.h>
25+
#include <defaultatoms.h>
26+
#include <interop.h>
27+
#include <memory.h>
28+
#include <nifs.h>
29+
#include <stdlib.h>
30+
#include <term.h>
31+
32+
#include <rom/crc.h>
33+
34+
#include "esp32_sys.h"
35+
36+
//#define ENABLE_TRACE
37+
#include "trace.h"
38+
39+
#ifndef CONFIG_AVM_RTC_SLOW_MAX_SIZE
40+
#define CONFIG_AVM_RTC_SLOW_MAX_SIZE 4086
41+
#endif
42+
43+
// Ensure checksum is incorrect when memory is zeroed.
44+
#define RTC_SLOW_CRC32_MAGIC 0x55555555
45+
46+
RTC_NOINIT_ATTR uint32_t rtc_slow_data_checksum;
47+
RTC_NOINIT_ATTR uint16_t rtc_slow_data_size;
48+
RTC_NOINIT_ATTR uint8_t rtc_slow_data[CONFIG_AVM_RTC_SLOW_MAX_SIZE];
49+
50+
static void rtc_slow_nif_init(GlobalContext *global);
51+
static const struct Nif *rtc_slow_nif_get_nif(const char *nifname);
52+
53+
static term nif_esp_rtc_slow_get_binary(Context *ctx, int argc, term argv[])
54+
{
55+
UNUSED(argc);
56+
UNUSED(argv);
57+
if (rtc_slow_data_size > sizeof(rtc_slow_data)) {
58+
RAISE_ERROR(BADARG_ATOM);
59+
}
60+
uint32_t checksum = crc32_le(RTC_SLOW_CRC32_MAGIC, rtc_slow_data, rtc_slow_data_size);
61+
if (checksum != rtc_slow_data_checksum) {
62+
RAISE_ERROR(BADARG_ATOM);
63+
}
64+
if (UNLIKELY(memory_ensure_free(ctx, term_binary_data_size_in_terms(rtc_slow_data_size) + BINARY_HEADER_SIZE) != MEMORY_GC_OK)) {
65+
RAISE_ERROR(OUT_OF_MEMORY_ATOM);
66+
}
67+
68+
return term_from_literal_binary(rtc_slow_data, rtc_slow_data_size, ctx);
69+
}
70+
71+
static term nif_esp_rtc_slow_set_binary(Context *ctx, int argc, term argv[])
72+
{
73+
UNUSED(argc);
74+
VALIDATE_VALUE(argv[0], term_is_binary);
75+
term binary = argv[0];
76+
size_t size = term_binary_size(binary);
77+
if (size > sizeof(rtc_slow_data)) {
78+
RAISE_ERROR(BADARG_ATOM);
79+
}
80+
const uint8_t *data = (const uint8_t *) term_binary_data(binary);
81+
rtc_slow_data_checksum = crc32_le(RTC_SLOW_CRC32_MAGIC, data, size);
82+
rtc_slow_data_size = size;
83+
memcpy(rtc_slow_data, data, size);
84+
85+
return OK_ATOM;
86+
}
87+
88+
static const struct Nif esp_rtc_slow_get_binary_nif = {
89+
.base.type = NIFFunctionType,
90+
.nif_ptr = nif_esp_rtc_slow_get_binary
91+
};
92+
static const struct Nif esp_rtc_slow_set_binary_nif = {
93+
.base.type = NIFFunctionType,
94+
.nif_ptr = nif_esp_rtc_slow_set_binary
95+
};
96+
97+
void rtc_slow_nif_init(GlobalContext *gloabl)
98+
{
99+
// no-op
100+
}
101+
102+
const struct Nif *rtc_slow_nif_get_nif(const char *nifname)
103+
{
104+
if (strcmp("esp:rtc_slow_get_binary/0", nifname) == 0) {
105+
TRACE("Resolved platform nif %s ...\n", nifname);
106+
return &esp_rtc_slow_get_binary_nif;
107+
}
108+
if (strcmp("esp:rtc_slow_set_binary/1", nifname) == 0) {
109+
TRACE("Resolved platform nif %s ...\n", nifname);
110+
return &esp_rtc_slow_set_binary_nif;
111+
}
112+
return NULL;
113+
}
114+
115+
REGISTER_NIF_COLLECTION(rtc_slow, rtc_slow_nif_init, rtc_slow_nif_get_nif)
116+
117+
#endif

src/platforms/esp32/test/main/test_erl_sources/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ function(compile_erlang module_name)
3737
endfunction()
3838

3939
compile_erlang(test_md5)
40+
compile_erlang(test_rtc_slow)
4041
compile_erlang(test_socket)
4142
compile_erlang(test_time_and_processes)
4243
compile_erlang(test_tz)
@@ -46,12 +47,14 @@ add_custom_command(
4647
COMMAND HostAtomVM-prefix/src/HostAtomVM-build/tools/packbeam/PackBEAM -i esp32_test_modules.avm
4748
HostAtomVM-prefix/src/HostAtomVM-build/libs/atomvmlib.avm
4849
test_md5.beam
50+
test_rtc_slow.beam
4951
test_socket.beam
5052
test_time_and_processes.beam
5153
test_tz.beam
5254
DEPENDS
5355
HostAtomVM
5456
"${CMAKE_CURRENT_BINARY_DIR}/test_md5.beam"
57+
"${CMAKE_CURRENT_BINARY_DIR}/test_rtc_slow.beam"
5558
"${CMAKE_CURRENT_BINARY_DIR}/test_socket.beam"
5659
"${CMAKE_CURRENT_BINARY_DIR}/test_time_and_processes.beam"
5760
"${CMAKE_CURRENT_BINARY_DIR}/test_tz.beam"
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
%
2+
% This file is part of AtomVM.
3+
%
4+
% Copyright 2023 Paul Guyot <[email protected]>
5+
%
6+
% Licensed under the Apache License, Version 2.0 (the "License");
7+
% you may not use this file except in compliance with the License.
8+
% You may obtain a copy of the License at
9+
%
10+
% http://www.apache.org/licenses/LICENSE-2.0
11+
%
12+
% Unless required by applicable law or agreed to in writing, software
13+
% distributed under the License is distributed on an "AS IS" BASIS,
14+
% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
% See the License for the specific language governing permissions and
16+
% limitations under the License.
17+
%
18+
% SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
19+
%
20+
21+
-module(test_rtc_slow).
22+
-export([start/0]).
23+
24+
-define(CONFIG_AVM_RTC_SLOW_MAX_SIZE, 1024).
25+
26+
% Simply ensure rtc_slow nifs can be called
27+
start() ->
28+
% During qemu tests, RTC Slow memory is initialized to 0.
29+
% So the checksum is always wrong.
30+
ok =
31+
try
32+
esp:rtc_slow_get_binary()
33+
catch
34+
error:badarg -> ok
35+
end,
36+
ok = esp:rtc_slow_set_binary(<<>>),
37+
<<>> = esp:rtc_slow_get_binary(),
38+
ok = esp:rtc_slow_set_binary(<<42>>),
39+
<<42>> = esp:rtc_slow_get_binary(),
40+
LargeBin16K = build_bin(16 * 1024),
41+
ok =
42+
try
43+
esp:rtc_slow_set_binary(LargeBin16K),
44+
should_fail
45+
catch
46+
error:badarg -> ok
47+
end,
48+
<<42>> = esp:rtc_slow_get_binary(),
49+
LargeBinMax = build_bin(?CONFIG_AVM_RTC_SLOW_MAX_SIZE),
50+
ok = esp:rtc_slow_set_binary(LargeBinMax),
51+
LargeBinMaxPlusOne = build_bin(?CONFIG_AVM_RTC_SLOW_MAX_SIZE + 1),
52+
ok =
53+
try
54+
esp:rtc_slow_set_binary(LargeBinMaxPlusOne),
55+
should_fail
56+
catch
57+
error:badarg -> ok
58+
end,
59+
LargeBinMax = esp:rtc_slow_get_binary(),
60+
% Make sure get/set is semantically correct, even with binaries that do not fit the heap
61+
esp:rtc_slow_set_binary(<<42:1024>>),
62+
X = esp:rtc_slow_get_binary(),
63+
true = id(X) =:= <<42:1024>>,
64+
esp:rtc_slow_set_binary(<<43:1024>>),
65+
Y = esp:rtc_slow_get_binary(),
66+
true = id(Y) =:= <<43:1024>>,
67+
true = id(X) =:= <<42:1024>>,
68+
0.
69+
70+
build_bin(Len) ->
71+
<<42:(Len * 8)>>.
72+
73+
id(X) -> X.

src/platforms/esp32/test/main/test_main.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,12 @@ TEST_CASE("test_socket", "[test_run]")
216216
eth_stop(eth_netif);
217217
}
218218

219+
TEST_CASE("test_rtc_slow", "[test_run]")
220+
{
221+
term ret_value = avm_test_case("test_rtc_slow.beam");
222+
TEST_ASSERT(term_to_int(ret_value) == 0);
223+
}
224+
219225
void app_main(void)
220226
{
221227
UNITY_BEGIN();

src/platforms/esp32/test/sdkconfig.defaults

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ CONFIG_PARTITION_TABLE_CUSTOM=y
22
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
33
CONFIG_ESP_INT_WDT_TIMEOUT_MS=10000
44
CONFIG_ETH_USE_OPENETH=y
5+
CONFIG_AVM_RTC_SLOW_MAX_SIZE=1024

0 commit comments

Comments
 (0)