Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port to Zephyr OS #958

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions README.ZEPHYR.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<!--
Copyright 2023 Winford (Uncle Grumpy) <[email protected]>

SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
-->

# AtomVM for Zephyr
This is an experimental port that will hopefully replace the current stm32 `libopencm3` based port, and should support many more boards.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stm32 -> STM32

Not all boards supported by Zephyr are capable of running AtomVM. The most likely excluding factor will be lack of flash storage space to accommodate both the VM and user BEAM applications. We will likely need a customized device tree to only define the boards that AtomVM can support. Currently a build can be attempted for any board supported by the Zephyr SDK and the user will need to determining if the final build can fit onto the device and still have space left for a user application partition (on stm32 devices this is typically a 128K block size).

## Prerequisites

* `west` Make sure to follow its [installation procedure](https://docs.zephyrproject.org/latest/develop/getting_started/index.html#get-zephyr-and-install-python-dependencies)
* `Zephyr SDK` [installation procedure](https://docs.zephyrproject.org/latest/develop/getting_started/index.html#install-the-zephyr-sdk)
* `cmake`
* `ninja`
* An appropriate flashing tool and software for your device, such as [st-flash](https://github.com/texane/stlink) for flashing STM32 devices with a [st-link v2](https://www.st.com/en/development-tools/st-link-v2.html) or [st-link v3](https://www.st.com/en/development-tools/stlink-v3set.html) device.
* A serial console program, such as `minicom` or `screen`, so that you can view console output from your AtomVM application.

## Building
Before building for the first time you need to have set up `west` and `Zephyr SDK`, following the [Zephyr Project Getting Started instructions](https://docs.zephyrproject.org/latest/develop/getting_started/index.html). After setup is complete from inside the AtomVM/src/platforms/zephyr directory use `west` to build for your board with the `-b` switch:

$ west build -b nucleo_f429zi -p=auto .

The `-p=auto` option instructs `west` to perform a pristine build if changes have been made, which is a recommended practice.

## Listing `west` target devices
A complete list of boards supported by

$ west boards

## Flashing

$ west flash

## Debugging
To start a live gdb session on the device use:

$ west attach
5 changes: 5 additions & 0 deletions src/platforms/zephyr/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Copyright 2023 Winford (Uncle Grumpy) <[email protected]>
#
# SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later

build/
130 changes: 130 additions & 0 deletions src/platforms/zephyr/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
#
# This file is part of AtomVM.
#
# Copyright 2023 Winford (Uncle Grumpy) <[email protected]>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
#

cmake_minimum_required (VERSION 3.20)
set(CMAKE_C_STANDARD_REQUIRED YES)
set(CMAKE_CXX_STANDARD_REQUIRED YES)

# Enforce to disable any compiler-specific extensions
set(CMAKE_C_EXTENSIONS NO)
set(CMAKE_CXX_EXTENSIONS NO)
set(C_STANDARD_REQUIRED YES)
set_property(GLOBAL PROPERTY C_STANDARD_REQUIRED TRUE)
set_property(GLOBAL PROPERTY CSTD iso9899:2011)
set_property(GLOBAL PROPERTY C_STANDARD iso9899:2011)

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(AtomVM LANGUAGES C)

if (NOT BOARD)
message(FATAL_ERROR "No BOARD specified for device config generator")
endif ()

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../CMakeModules")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})

# Options that make sense for this platform
option(AVM_USE_32BIT_FLOAT "Use 32 bit floats." ON)
option(AVM_VERBOSE_ABORT "Print module and line number on VM abort" OFF)
option(AVM_CREATE_STACKTRACES "Create stacktraces" ON)
option(AVM_NEWLIB_NANO "Use 'nano' newlib. Saves 46kB, no `long long` support" OFF)
option(AVM_LOG_DISABLE "Disable log output" OFF)
option(AVM_ENABLE_LOG_COLOR "Use color log output" OFF)
option(AVM_ENABLE_LOG_LINES "Include source and line info for all enbled levels" OFF)
option(AVM_CONFIG_REBOOT_ON_NOT_OK "Reboot when application exits with non 'ok' return" OFF)
option(AVM_DISABLE_GPIO_NIFS "Disable GPIO nifs (input and output)" OFF)
option(AVM_DISABLE_GPIO_PORT_DRIVER "Disable GPIO 'port' driver (input, output, and interrupts)" OFF)

set(AVM_DISABLE_SMP ON FORCE)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the case of the Zephyr port, could testing for the CONFIG_SMP variable work? That variable is set in the Kconfig and made available in CMake.

See:

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. I was realizing today that making KConfig options to set these options would be preferable to passing extra -D options to west.

Copy link

@adolfogc adolfogc Nov 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think of structuring it as a Zephyr module, where the CMakeLists.txt could be something like:

cmake_minimum_required (VERSION 3.20)

if(Zephyr_FOUND)
    set(AVM_PORT_ZEPHYR ON)
endif()

# Options that make sense for this platform
cmake_dependent_option(AVM_USE_32BIT_FLOAT "Use 32 bit floats." ON "NOT CONFIG_64BIT" OFF)
option(AVM_VERBOSE_ABORT "Print module and line number on VM abort" OFF)
option(AVM_CREATE_STACKTRACES "Create stacktraces" ON)
cmake_dependent_option(AVM_NEWLIB_NANO "Use 'nano' newlib. Saves 46kB, no `long long` support" ON "CONFIG_HAS_NEWLIB_LIBC_NANO" OFF)
option(AVM_LOG_DISABLE "Disable log output" OFF)
option(AVM_ENABLE_LOG_COLOR "Use color log output" OFF)
option(AVM_ENABLE_LOG_LINES "Include source and line info for all enbled levels" OFF)
option(AVM_CONFIG_REBOOT_ON_NOT_OK "Reboot when application exits with non 'ok' return" OFF)
option(AVM_DISABLE_GPIO_NIFS "Disable GPIO nifs (input and output)" OFF)
option(AVM_DISABLE_GPIO_PORT_DRIVER "Disable GPIO 'port' driver (input, output, and interrupts)" OFF)

include_directories(src/libAtomVM)  # libAtomVM
include_directories(src/platforms/zephyr)  # AtomVM (Zephyr port)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The module would set the minimal Kconfig options for AtomVM:

menuconfig AVM
    bool "AVM"
    default n
    help
        Enables the AtomVM Module
    depends on FPU
    select APP_LINK_WITH_POSIX_SUBSYS
    select FORTIFY_SOURCE_RUN_TIME
    select POSIX_API
    select POSIX_CLOCK
    select POSIX_SIGNAL
    select REBOOT
    select REQUIRES_FLOAT_PRINTF
    select RUNTIME_ERROR_CHECKS
    select STACK_USAGE

if AVM

module = AVM
module-str = AtomVM

endif

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of implementing main, the port could provide an implementation called avm_main which the Zephyr application could call from its own main implementation.

set(CONFIG_ATOMVM_DISABLE_SMP ON FORCE)
zephyr_library_compile_definitions(AVM_NO_SMP)
zephyr_library_compile_definitions(CONFIG_AVM_NO_SMP)
add_compile_definitions(AVM_NO_SMP)

set(HAVE_CLOCK_SETTIME ON FORCE)

if (AVM_NEWLIB_NANO)
set(LINKER_FLAGS "${LINKER_FLAGS} -specs=nano.specs")
set(AVM_LOG_DISABLE ON FORCE)
endif()

if (AVM_CONFIG_REBOOT_ON_NOT_OK)
add_compile_definitions(CONFIG_REBOOT_ON_NOT_OK)
endif()

# Configure logging
if (AVM_LOG_DISABLE)
add_compile_definitions(AVM_LOG_DISABLE)
elseif (AVM_LOG_LEVEL_MAX)
set(AVM_LOG_LEVEL_MAX ${AVM_LOG_LEVEL_MAX} CACHE STRING "AtomVM max log level")
else()
set(AVM_LOG_LEVEL_MAX LOG_INFO CACHE STRING "AtomVM max log level")
endif()
if (AVM_LOG_LEVEL_MAX)
set_property(CACHE AVM_LOG_LEVEL_MAX PROPERTY STRINGS LOG_NONE LOG_ERROR LOG_WARN LOG_INFO LOG_DEBUG)
add_compile_definitions(AVM_LOG_LEVEL_MAX=${AVM_LOG_LEVEL_MAX})
endif()
if (AVM_ENABLE_LOG_COLOR)
add_compile_definitions(ENABLE_LOG_COLOR)
endif()
if (AVM_ENABLE_LOG_LINES)
add_compile_definitions(ENABLE_LOG_LINE_INFO)
endif()

# Configure Drivers
if (AVM_DISABLE_GPIO_NIFS)
add_compile_definitions(AVM_DISABLE_GPIO_NIFS)
endif()
if (AVM_DISABLE_GPIO_PORT_DRIVER)
add_compile_definitions(AVM_DISABLE_GPIO_PORT_DRIVER)
endif()

## Include additional compilation flags
#include(cmake/compile-flags.cmake)

set(
PLATFORM_LIB_SUFFIX
${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}
)

# Specify output executable
target_sources(app PRIVATE src/main.c)
target_include_directories(app PRIVATE
${CMAKE_CURRENT_BINARY_DIR}/libAtomVM
${CMAKE_BINARY_DIR}/zephyr/include/generated)

add_subdirectory(src/lib)

target_link_libraries(app PRIVATE libAtomVM${PLATFORM_LIB_SUFFIX})

set_property(TARGET app PROPERTY C_STANDARD 11)

if(CMAKE_COMPILER_IS_GNUCC)
target_compile_options(app PUBLIC -Wall -Wextra -ggdb)
endif()

add_subdirectory(src/libAtomVM libAtomVM)
target_link_libraries(app PUBLIC libAtomVM)

message("----------------------------------------")
message(STATUS "Board : ${BOARD}")
message("--------Device Configuration Info-------")
message(STATUS "Clock Hz : ${CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC}")
message(STATUS "Flash Size : ${CONFIG_FLASH_SIZE}K")
5 changes: 5 additions & 0 deletions src/platforms/zephyr/VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
VERSION_MAJOR = 0
VERSION_MINOR = 6
PATCHLEVEL = 0
VERSION_TWEAK = 2
EXTRAVERSION = alpha
3 changes: 3 additions & 0 deletions src/platforms/zephyr/VERSION.license
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
SPDX-FileCopyrightText: 2023 Winford (Uncle Grumpy) <[email protected]>

SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
39 changes: 39 additions & 0 deletions src/platforms/zephyr/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#
# This file is part of AtomVM.
#
# Copyright 2023 Winford (Uncle Grumpy) <[email protected]>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
#

CONFIG_KERNEL_BIN_NAME="AtomVM"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this makes sense

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That changes the name of the final binary to AtomVM.elf rather than kernel.elf, it's purely cosmetic.

CONFIG_STDOUT_CONSOLE=y
CONFIG_CONSOLE_SUBSYS=y
CONFIG_SYS_HEAP_AUTO=y
CONFIG_GPIO=y
CONFIG_PINCTRL_DYNAMIC=y
CONFIG_POSIX_CLOCK=y
CONFIG_REQUIRES_FLOAT_PRINTF=y
CONFIG_FPU=y
CONFIG_RTC=y
CONFIG_RESET=y
CONFIG_REBOOT=y
CONFIG_STACK_USAGE=y
CONFIG_RUNTIME_ERROR_CHECKS=y
CONFIG_OUTPUT_PRINT_MEMORY_USAGE=y
CONFIG_DYNAMIC_INTERRUPTS=y
CONFIG_FORTIFY_SOURCE_RUN_TIME=y

CONFIG_DEBUG_OPTIMIZATIONS=y
48 changes: 48 additions & 0 deletions src/platforms/zephyr/src/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#
# This file is part of AtomVM.
#
# Copyright 2022 Paul Guyot <[email protected]>
# Copyright 2023 Winford <[email protected]>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
#

cmake_minimum_required (VERSION 3.20.5)

set(
PLATFORM_LIB_SUFFIX
${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}
)
project (libAtomVM${PLATFORM_LIB_SUFFIX})
zephyr_library_named(libAtomVM${PLATFORM_LIB_SUFFIX})

zephyr_include_directories(
${CMAKE_CURRENT_BINARY_DIR}
../../../../libAtomVM
${CMAKE_BINARY_DIR}/zephyr/include/generated/
)

zephyr_library_sources(
platform_nifs.c
sys.c
)

if(CMAKE_COMPILER_IS_GNUCC)
target_compile_options(libAtomVM${PLATFORM_LIB_SUFFIX} PUBLIC -Wall -pedantic -Wextra -ggdb)
endif()
set_property(TARGET libAtomVM${PLATFORM_LIB_SUFFIX} PROPERTY C_STANDARD 11)

target_link_libraries(app PUBLIC libAtomVM${PLATFORM_LIB_SUFFIX})
target_link_options(libAtomVM${PLATFORM_LIB_SUFFIX} PUBLIC ${LINK_OPTIONS} -Wl,--whole-archive ${CMAKE_CURRENT_BINARY_DIR}/liblibAtomVM${PLATFORM_LIB_SUFFIX}.a -Wl,--no-whole-archive)
33 changes: 33 additions & 0 deletions src/platforms/zephyr/src/lib/avm_devcfg.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/* This file is part of AtomVM.
*
* Copyright 2023 Winford (Uncle Grumpy) <[email protected]>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
*/

#ifndef _AVM_DEVCFG_H_
#define _AVM_DEVCFG_H_

#include <autoconf.h>

#if (CONFIG_FLASH_SIZE == 512)
#define AVM_APP_ADDRESS ((CONFIG_FLASH_BASE_ADDRESS) + 0x60000U)
#else
#define AVM_APP_ADDRESS ((CONFIG_FLASH_BASE_ADDRESS) + 0x80000U)
Copy link
Collaborator

@bettio bettio Dec 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where are 0x60000U and 0x80000U coming from?

#endif

#define CFG_FLASH_END ((uint32_t) ((CONFIG_FLASH_BASE_ADDRESS) + ((CONFIG_FLASH_SIZE) *1024)))

#endif /* _AVM_DEVCFG_H_ */
Loading
Loading