From cdf1db1c4197f76cf2dd876e3c8a27c807acb7fd Mon Sep 17 00:00:00 2001 From: Mumtahin Farabi Date: Tue, 12 May 2026 00:23:26 -0400 Subject: feat(firmware): scaffold setup Signed-off-by: Mumtahin Farabi --- firmware/CMakeLists.txt | 1 + firmware/Kconfig | 1 + firmware/boards/walter_esp32s3_procpu.conf | 15 ++++++ firmware/boards/walter_esp32s3_procpu.overlay | 19 +++++++ firmware/prj.conf | 10 ++++ firmware/src/main.c | 21 ++++++++ firmware/tests/CMakeLists.txt | 12 +++++ firmware/tests/kernel.c | 42 ++++++++++++++++ firmware/tests/prj.conf | 10 ++++ firmware/tests/shell.c | 71 +++++++++++++++++++++++++++ firmware/tests/testcase.yaml | 19 +++++++ firmware/west.yml | 21 ++++++++ 12 files changed, 242 insertions(+) create mode 100644 firmware/CMakeLists.txt create mode 100644 firmware/Kconfig create mode 100644 firmware/boards/walter_esp32s3_procpu.conf create mode 100644 firmware/boards/walter_esp32s3_procpu.overlay create mode 100644 firmware/prj.conf create mode 100644 firmware/src/main.c create mode 100644 firmware/tests/CMakeLists.txt create mode 100644 firmware/tests/kernel.c create mode 100644 firmware/tests/prj.conf create mode 100644 firmware/tests/shell.c create mode 100644 firmware/tests/testcase.yaml create mode 100644 firmware/west.yml (limited to 'firmware') diff --git a/firmware/CMakeLists.txt b/firmware/CMakeLists.txt new file mode 100644 index 0000000..88c4c02 --- /dev/null +++ b/firmware/CMakeLists.txt @@ -0,0 +1 @@ +target_sources(app PRIVATE src/main.c) diff --git a/firmware/Kconfig b/firmware/Kconfig new file mode 100644 index 0000000..161325b --- /dev/null +++ b/firmware/Kconfig @@ -0,0 +1 @@ +source "$(ZEPHYR_BASE)/Kconfig" diff --git a/firmware/boards/walter_esp32s3_procpu.conf b/firmware/boards/walter_esp32s3_procpu.conf new file mode 100644 index 0000000..2208466 --- /dev/null +++ b/firmware/boards/walter_esp32s3_procpu.conf @@ -0,0 +1,15 @@ +# Walter-specific Kconfig overrides — only applied when building for +# walter/esp32s3/procpu (auto-discovered by Zephyr's build system). + +# Required for the v3_3_regulator node in walter_esp32s3_procpu.overlay. +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED=y + +# Cellular networking and TLS go here as we add them. Examples: +# CONFIG_NETWORKING=y +# CONFIG_NET_NATIVE=y +# CONFIG_NET_L2_PPP=y +# CONFIG_MODEM=y +# CONFIG_MODEM_CELLULAR=y +# CONFIG_MBEDTLS_ENABLE_HEAP=y +# CONFIG_MBEDTLS_HEAP_SIZE=10240 diff --git a/firmware/boards/walter_esp32s3_procpu.overlay b/firmware/boards/walter_esp32s3_procpu.overlay new file mode 100644 index 0000000..e500c05 --- /dev/null +++ b/firmware/boards/walter_esp32s3_procpu.overlay @@ -0,0 +1,19 @@ +/* + * Walter-specific application-level DT additions. + * + * Walter has a MOSFET on GPIO0 (active-low) that gates the on-board 3.3V + * output rail. The rail is OFF at reset; any external sensor wired to V3.3 + * is unpowered until something asserts this GPIO. Modeled as a regulator-fixed + * with regulator-boot-on so Zephyr's regulator framework enables it during + * kernel init, before driver init runs. + */ + +/ { + v3_3_regulator: v3_3-regulator { + compatible = "regulator-fixed"; + regulator-name = "walter-3v3-output"; + enable-gpios = <&gpio0 0 GPIO_ACTIVE_LOW>; + regulator-boot-on; + regulator-always-on; + }; +}; diff --git a/firmware/prj.conf b/firmware/prj.conf new file mode 100644 index 0000000..85d70de --- /dev/null +++ b/firmware/prj.conf @@ -0,0 +1,10 @@ +CONFIG_LOG=y +CONFIG_LOG_CMDS=y + +CONFIG_SHELL=y +CONFIG_SHELL_BACKEND_SERIAL=y +CONFIG_KERNEL_SHELL=y +CONFIG_DEVICE_SHELL=y +CONFIG_HWINFO=y +CONFIG_HWINFO_SHELL=y +CONFIG_GPIO_SHELL=y diff --git a/firmware/src/main.c b/firmware/src/main.c new file mode 100644 index 0000000..3566e33 --- /dev/null +++ b/firmware/src/main.c @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2026 Apidae Systems + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +LOG_MODULE_REGISTER(main, LOG_LEVEL_INF); + +int main(void) +{ + LOG_INF("Walter is alive"); + + while (1) { + k_sleep(K_SECONDS(1)); + } + + return 0; +} diff --git a/firmware/tests/CMakeLists.txt b/firmware/tests/CMakeLists.txt new file mode 100644 index 0000000..474f3b1 --- /dev/null +++ b/firmware/tests/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(tests) + +if(TEST_SUITE_KERNEL) + target_sources(app PRIVATE kernel.c) +endif() + +if(TEST_SUITE_SHELL) + target_sources(app PRIVATE shell.c) +endif() diff --git a/firmware/tests/kernel.c b/firmware/tests/kernel.c new file mode 100644 index 0000000..c9f84b6 --- /dev/null +++ b/firmware/tests/kernel.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2026 Apidae Systems + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +LOG_MODULE_REGISTER(kernel, LOG_LEVEL_INF); + +ZTEST_SUITE(kernel, NULL, NULL, NULL, NULL, NULL); + +ZTEST(kernel, test_uptime_advances) +{ + int64_t t0 = k_uptime_get(); + + k_sleep(K_MSEC(50)); + + int64_t t1 = k_uptime_get(); + + zassert_true(t1 > t0, + "uptime did not advance: t0=%lld t1=%lld", t0, t1); + zassert_true((t1 - t0) >= 40, + "delta %lld ms is implausibly short", (t1 - t0)); +} + +ZTEST(kernel, test_log_subsystem_alive) +{ + LOG_INF("kernel test ran at uptime=%lld ms", k_uptime_get()); +} + +ZTEST(kernel, test_constants_make_sense) +{ + zassert_true(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC > 0, + "SYS_CLOCK_HW_CYCLES_PER_SEC=%d", + CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC); + zassert_true(CONFIG_SYS_CLOCK_TICKS_PER_SEC > 0, + "SYS_CLOCK_TICKS_PER_SEC=%d", + CONFIG_SYS_CLOCK_TICKS_PER_SEC); +} diff --git a/firmware/tests/prj.conf b/firmware/tests/prj.conf new file mode 100644 index 0000000..9d81903 --- /dev/null +++ b/firmware/tests/prj.conf @@ -0,0 +1,10 @@ +CONFIG_ZTEST=y +CONFIG_TEST=y +CONFIG_LOG=y +CONFIG_LOG_MODE_IMMEDIATE=y +CONFIG_MAIN_STACK_SIZE=4096 + +CONFIG_SHELL=y +CONFIG_SHELL_BACKEND_DUMMY=y +CONFIG_SHELL_BACKEND_SERIAL=n +CONFIG_KERNEL_SHELL=y diff --git a/firmware/tests/shell.c b/firmware/tests/shell.c new file mode 100644 index 0000000..5b52a53 --- /dev/null +++ b/firmware/tests/shell.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2026 Apidae Systems + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +static atomic_t hello_invocations = ATOMIC_INIT(0); + +static int cmd_hello(const struct shell *sh, size_t argc, char **argv) +{ + atomic_inc(&hello_invocations); + shell_print(sh, "hello from %s", argc > 1 ? argv[1] : "test"); + return 0; +} + +SHELL_CMD_REGISTER(hello, NULL, "test-only command — increments a counter", cmd_hello); + +ZTEST_SUITE(shell, NULL, NULL, NULL, NULL, NULL); + +ZTEST(shell, test_dummy_backend_is_ready) +{ + const struct shell *sh = shell_backend_dummy_get_ptr(); + + zassert_not_null(sh, "dummy shell backend pointer is NULL"); +} + +ZTEST(shell, test_executes_builtin_help) +{ + const struct shell *sh = shell_backend_dummy_get_ptr(); + int rc = shell_execute_cmd(sh, "help"); + + zassert_ok(rc, "shell_execute_cmd(\"help\") failed: %d", rc); +} + +ZTEST(shell, test_executes_kernel_uptime) +{ + const struct shell *sh = shell_backend_dummy_get_ptr(); + int rc = shell_execute_cmd(sh, "kernel uptime"); + + zassert_ok(rc, "shell_execute_cmd(\"kernel uptime\") failed: %d", rc); +} + +ZTEST(shell, test_executes_custom_command_with_side_effect) +{ + const struct shell *sh = shell_backend_dummy_get_ptr(); + atomic_val_t before = atomic_get(&hello_invocations); + + int rc = shell_execute_cmd(sh, "hello world"); + + zassert_ok(rc, "shell_execute_cmd(\"hello world\") failed: %d", rc); + + atomic_val_t after = atomic_get(&hello_invocations); + zassert_equal(after, before + 1, + "custom command did not run: before=%ld after=%ld", + (long)before, (long)after); +} + +ZTEST(shell, test_unknown_command_does_not_crash) +{ + const struct shell *sh = shell_backend_dummy_get_ptr(); + int rc = shell_execute_cmd(sh, "definitely_not_a_real_command_xyz"); + + zassert_not_equal(rc, 0, + "unknown command should return non-zero, got %d", rc); +} diff --git a/firmware/tests/testcase.yaml b/firmware/tests/testcase.yaml new file mode 100644 index 0000000..8ba79d0 --- /dev/null +++ b/firmware/tests/testcase.yaml @@ -0,0 +1,19 @@ +common: + harness: ztest + integration_platforms: + - walter/esp32s3/procpu + platform_allow: + - walter/esp32s3/procpu + timeout: 30 + tags: + - boot + +tests: + boot.kernel: + extra_args: TEST_SUITE_KERNEL=y + tags: + - kernel + boot.shell: + extra_args: TEST_SUITE_SHELL=y + tags: + - shell diff --git a/firmware/west.yml b/firmware/west.yml new file mode 100644 index 0000000..f174236 --- /dev/null +++ b/firmware/west.yml @@ -0,0 +1,21 @@ +manifest: + self: + path: firmware + + remotes: + - name: zephyrproject + url-base: https://github.com/zephyrproject-rtos + + projects: + - name: zephyr + remote: zephyrproject + revision: f1ff557f96f74a6d82d8b290bc4488ee5f93c483 # main~2: before HAL CS timing regression + import: + path-prefix: firmware + name-allowlist: + - hal_espressif + - hal_xtensa + - cmsis + - picolibc + - mcuboot + - mbedtls -- cgit v1.3