AtomVM icon indicating copy to clipboard operation
AtomVM copied to clipboard

Zephyr Support

Open bettio opened this issue 2 years ago • 12 comments

Let's discuss how to support Zephyr and what should be supported.

bettio avatar Sep 08 '23 12:09 bettio

As a reference it might be interesting supporting a nRF52 device, or a NXP one like Teensy.

bettio avatar Sep 08 '23 12:09 bettio

Hi, Zephyr has support for a lot of boards, including the following:

  • Teensy 4 (https://docs.zephyrproject.org/latest/boards/arm/teensy4/doc/index.html)
  • nRF52 DK (https://docs.zephyrproject.org/2.7.0/boards/arm/nrf52dk_nrf52832/doc/index.html)

adolfogc avatar Sep 08 '23 16:09 adolfogc

The port of AtomVM to Zephyr, I think could be structured as a module (https://docs.zephyrproject.org/latest/develop/modules.html), by adding libAtomVM as a library and some platform files specific to the Zephyr-port.

An example for adding libAtomVM as a library:

zephyr_library_named(libAtomVM)

if(CONFIG_ATOMVM)

function(gperf_generate input output)
    add_custom_command(
        OUTPUT ${output}
        COMMAND gperf -t ${input} > ${output}
        DEPENDS ${input}
        COMMENT "Hashing ${input}"
    )
endfunction()

set(ATOMVM_DIR ${CMAKE_CURRENT_SOURCE_DIR}/..)

gperf_generate($(ATOMVM_DIR)/src/libAtomVM/bifs.gperf bifs_hash.h)
gperf_generate($(ATOMVM_DIR)/src/libAtomVM/nifs.gperf nifs_hash.h)

zephyr_include_directories(
    ${CMAKE_CURRENT_BINARY_DIR}
    $(ATOMVM_DIR)/src/libAtomVM
    $(ATOMVM_DIR)/zephyr
)

zephyr_library_sources(
    ${CMAKE_CURRENT_BINARY_DIR}/bifs_hash.h
    ${CMAKE_CURRENT_BINARY_DIR}/nifs_hash.h
    $(ATOMVM_DIR)/src/libAtomVM/atom.c
    $(ATOMVM_DIR)/src/libAtomVM/atomshashtable.c
    $(ATOMVM_DIR)/src/libAtomVM/avmpack.c
    $(ATOMVM_DIR)/src/libAtomVM/bif.c
    $(ATOMVM_DIR)/src/libAtomVM/bitstring.c
    $(ATOMVM_DIR)/src/libAtomVM/context.c
    $(ATOMVM_DIR)/src/libAtomVM/debug.c
    $(ATOMVM_DIR)/src/libAtomVM/defaultatoms.c
    $(ATOMVM_DIR)/src/libAtomVM/dictionary.c
    $(ATOMVM_DIR)/src/libAtomVM/externalterm.c
    $(ATOMVM_DIR)/src/libAtomVM/globalcontext.c
    $(ATOMVM_DIR)/src/libAtomVM/iff.c
    $(ATOMVM_DIR)/src/libAtomVM/interop.c
    $(ATOMVM_DIR)/src/libAtomVM/mailbox.c
    $(ATOMVM_DIR)/src/libAtomVM/memory.c
    $(ATOMVM_DIR)/src/libAtomVM/module.c
    $(ATOMVM_DIR)/src/libAtomVM/nifs.c
    $(ATOMVM_DIR)/src/libAtomVM/port.c
    $(ATOMVM_DIR)/src/libAtomVM/posix_nifs.c
    $(ATOMVM_DIR)/src/libAtomVM/refc_binary.c
    $(ATOMVM_DIR)/src/libAtomVM/resources.c
    $(ATOMVM_DIR)/src/libAtomVM/scheduler.c
    $(ATOMVM_DIR)/src/libAtomVM/stacktrace.c
    $(ATOMVM_DIR)/src/libAtomVM/term.c
    $(ATOMVM_DIR)/src/libAtomVM/timer_list.c
    $(ATOMVM_DIR)/src/libAtomVM/valueshashtable.c
)

zephyr_library_compile_definitions(ATOMVM_VERSION=${ATOMVM_BASE_VERSION})

if (CONFIG_ATOMVM_ADVANCED_TRACING)
    zephyr_library_compile_definitions(ENABLE_ADVANCED_TRACE)
endif()

if (CONFIG_ATOMVM_DISABLE_SMP)
    zephyr_library_compile_definitions(AVM_NO_SMP)
else()
    include(CheckIncludeFile)
    CHECK_INCLUDE_FILE(stdatomic.h STDATOMIC_INCLUDE)
    if(HAVE_PLATFORM_SMP_H)
        zephyr_library_compile_definitions(HAVE_PLATFORM_SMP_H)
    endif()
    include(CheckCSourceCompiles)
    check_c_source_compiles("
        #include <stdatomic.h>
        int main() {
            _Static_assert(ATOMIC_POINTER_LOCK_FREE == 2, \"Expected ATOMIC_POINTER_LOCK_FREE to be equal to 2\");
        }
    " ATOMIC_POINTER_LOCK_FREE_IS_TWO)
    if (NOT ATOMIC_POINTER_LOCK_FREE_IS_TWO AND NOT HAVE_PLATFORM_SMP_H)
        if (NOT STDATOMIC_INCLUDE)
            message(FATAL_ERROR "stdatomic.h cannot be found, you need to disable SMP on this platform or provide platform_smp.h and define HAVE_PLATFORM_SMP_H")
        else()
            message(FATAL_ERROR "Platform doesn't support atomic pointers, you need to disable SMP or provide platform_smp.h and define HAVE_PLATFORM_SMP_H")
        endif()
    endif()
endif()

if (CONFIG_ATOMVM_USE_32BIT_FLOAT)
    zephyr_library_compile_definitions(AVM_USE_SINGLE_PRECISION)
endif()

if (CONFIG_ATOMVM_VERBOSE_ABORT)
    zephyr_library_compile_definitions(AVM_VERBOSE_ABORT)
endif()

if (CONFIG_ATOMVM_CREATE_STACKTRACES)
    zephyr_library_compile_definitions(AVM_CREATE_STACKTRACES)
endif()

### PENDING 
include(DefineIfExists)
# HAVE_OPEN & HAVE_CLOSE are used in globalcontext.h
# define_if_function_exists(libAtomVM open "fcntl.h" PUBLIC HAVE_OPEN)
# define_if_function_exists(libAtomVM close "unistd.h" PUBLIC HAVE_CLOSE)
# define_if_function_exists(libAtomVM mkfifo "sys/stat.h" PRIVATE HAVE_MKFIFO)
# define_if_function_exists(libAtomVM unlink "unistd.h" PRIVATE HAVE_UNLINK)
# define_if_symbol_exists(libAtomVM O_CLOEXEC "fcntl.h" PRIVATE HAVE_O_CLOEXEC)
# define_if_symbol_exists(libAtomVM O_DIRECTORY "fcntl.h" PRIVATE HAVE_O_DIRECTORY)
# define_if_symbol_exists(libAtomVM O_DSYNC "fcntl.h" PRIVATE HAVE_O_DSYNC)
# define_if_symbol_exists(libAtomVM O_EXEC "fcntl.h" PRIVATE HAVE_O_EXEC)
# define_if_symbol_exists(libAtomVM O_NOFOLLOW "fcntl.h" PRIVATE HAVE_O_NOFOLLOW)
# define_if_symbol_exists(libAtomVM O_RSYNC "fcntl.h" PRIVATE HAVE_O_RSYNC)
# define_if_symbol_exists(libAtomVM O_SEARCH "fcntl.h" PRIVATE HAVE_O_SEARCH)
# define_if_symbol_exists(libAtomVM O_TTY_INIT "fcntl.h" PRIVATE HAVE_O_TTY_INIT)
### PENDING

zephyr_library_compile_features(c_std_11)

endif()

adolfogc avatar Sep 08 '23 16:09 adolfogc

A good example of how another project structured their Zephyr port is QPCPP:

  • https://github.com/QuantumLeaps/qpcpp
  • https://github.com/QuantumLeaps/qpcpp-zephyr-app

adolfogc avatar Sep 08 '23 16:09 adolfogc

Zephyr supports 450+ bosrds. So if we get atom vm on zephyr we will get all the board support for free.

mkschreder avatar Sep 18 '23 15:09 mkschreder

@adolfogc I think it's an excellent start. For the file functions you can enable fs. Zephyr supports several filesystems including ext2fs. This should be enough to load some beam code and run it :)

mkschreder avatar Sep 18 '23 19:09 mkschreder

Hi @mkschreder, thanks for the information! I will try to take a look again, sometime in the near future

adolfogc avatar Sep 23 '23 01:09 adolfogc

Several recent bugs in our stm32 port based on libopencm3, and the general lack of maintenance and documentation supporting the project, coupled with the fact that libopncm3 builds are under a GPL-3 license instead of Apache-2 like the rest of our ports has me investigating re-basing out stm32 support on Zephyr. This would be advantageous for several reasons like expanding our supported devices, as well as make maintaining and developing the port much easier using the provided APIs, as well as much more extensive documentation, an active community of users and developers for support, and many included on-board and 3rd party peripheral drivers and networking support, which will make adding these features to the VM much easier.

UncleGrumpy avatar Nov 16 '23 03:11 UncleGrumpy

I have opened a draft PR #958 that builds and loads a packed avm file. Currently none of the output from the BEAM application is being displayed on the console, but logging working, so printf does go to the console. Also no none of the attempted methods set C11 standard. The compiler is still issuing c99 warnings.

Any feedback or advice is greatly appreciated.

UncleGrumpy avatar Nov 22 '23 05:11 UncleGrumpy

Hi @UncleGrumpy, nice work! I will try to test it using my Heltec Wireless Stick V3 (ESP32-S3) in December.

adolfogc avatar Nov 22 '23 06:11 adolfogc

Hi @UncleGrumpy, nice work! I will try to test it using my Heltec Wireless Stick V3 (ESP32-S3) in December.

Just in case you weren't aware, that device is already supported by the esp32 port, which has features and drivers available that will likely take a while longer to make it into this port.

UncleGrumpy avatar Nov 22 '23 07:11 UncleGrumpy

Hi, thank you. Yes, I was aware of that, but I want to experiment with CAN bus and other peripherals, and will try to base it on Zephyr.

adolfogc avatar Nov 22 '23 17:11 adolfogc