atomvm / AtomVM

Tiny Erlang VM
https://www.atomvm.net
Apache License 2.0
1.45k stars 98 forks source link

Zephyr Support #802

Open bettio opened 12 months ago

bettio commented 12 months ago

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

bettio commented 12 months ago

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

adolfogc commented 12 months ago

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

adolfogc commented 12 months ago

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 commented 12 months ago

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

mkschreder commented 11 months ago

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

mkschreder commented 11 months ago

@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 :)

adolfogc commented 11 months ago

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

UncleGrumpy commented 9 months ago

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 commented 9 months ago

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.

adolfogc commented 9 months ago

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

UncleGrumpy commented 9 months ago

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.

adolfogc commented 9 months ago

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.