diff --git a/CMakeLists.txt b/CMakeLists.txt index f38fbee..75be2dc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,13 +8,23 @@ if (NOT DEFINED LF_MAIN) endif() if (NOT DEFINED LOG_LEVEL) - set(LOG_LEVEL "LF_LOG_LEVEL_WARN") + set(LOG_LEVEL "LF_LOG_LEVEL_DEBUG") endif() pico_sdk_init() -set(LF_MAIN_TARGET ${LF_MAIN}) -add_executable(${LF_MAIN_TARGET}) +if (NOT DEFINED FEDERATE) + include(${CMAKE_CURRENT_SOURCE_DIR}/src-gen/${LF_MAIN}/CMakeLists.txt) +else() + include(${CMAKE_CURRENT_SOURCE_DIR}/src-gen/${LF_MAIN}/${FEDERATE}/Include.cmake) +endif() + +add_subdirectory($ENV{REACTOR_UC_PATH} ${CMAKE_CURRENT_BINARY_DIR}/reactor-uc) +target_compile_definitions(reactor-uc PUBLIC LF_LOG_LEVEL_ALL=${LOG_LEVEL}) +target_compile_definitions(reactor-uc PUBLIC LF_LOG_LEVEL_PLATFORM=LF_LOG_LEVEL_WARN) +target_compile_definitions(reactor-uc PUBLIC LF_COLORIZE_LOGS=0) +target_compile_definitions(reactor-uc PUBLIC NETWORK_CHANNEL_UART) +target_compile_definitions(reactor-uc PUBLIC PLATFORM_PICO) include($ENV{REACTOR_UC_PATH}/cmake/lfc.cmake) @@ -24,4 +34,4 @@ lf_build_generated_code(${LF_MAIN_TARGET} ${CMAKE_CURRENT_SOURCE_DIR}/src-gen/${ target_link_libraries(${LF_MAIN_TARGET} PUBLIC pico_stdlib pico_sync) pico_enable_stdio_usb(${LF_MAIN_TARGET} 1) -pico_enable_stdio_uart(${LF_MAIN_TARGET} 1) \ No newline at end of file +pico_enable_stdio_uart(${LF_MAIN_TARGET} 1) diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..7e1ccce --- /dev/null +++ b/flake.lock @@ -0,0 +1,60 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "id": "flake-utils", + "type": "indirect" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1739446958, + "narHash": "sha256-+/bYK3DbPxMIvSL4zArkMX0LQvS7rzBKXnDXLfKyRVc=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "2ff53fe64443980e139eaa286017f53f88336dd0", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..5420e5d --- /dev/null +++ b/flake.nix @@ -0,0 +1,16 @@ +{ + description = "nix flake for building reactor-uc projects for the pico platform"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; + }; + + outputs = { nixpkgs, flake-utils }: + flake-utils.lib.eachDefaultSystem + (system: + let pkgs = nixpkgs.legacyPackages.${system}; in + { + devShells.default = import ./shell.nix { inherit pkgs; }; + } + ); +} diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..d6691ac --- /dev/null +++ b/shell.nix @@ -0,0 +1,110 @@ +{ pkgs }: +let + arm-pkgs = pkgs.pkgsCross.armhf-embedded; + buildPackages = arm-pkgs.buildPackages; + newlib-nano = arm-pkgs.stdenv.mkDerivation (finalAttrs: { + pname = "newlib"; + version = "4.3.0.20230120"; + + src = pkgs.fetchurl { + url = "ftp://sourceware.org/pub/newlib/newlib-${finalAttrs.version}.tar.gz"; + sha256 = "sha256-g6Yqma9Z4465sMWO0JLuJNcA//Q6IsA+QzlVET7zUVA="; + }; + + patches = [ + # https://bugs.gentoo.org/723756 + (pkgs.fetchpatch { + name = "newlib-3.3.0-no-nano-cxx.patch"; + url = "https://gitweb.gentoo.org/repo/gentoo.git/plain/sys-libs/newlib/files/newlib-3.3.0-no-nano-cxx.patch?id=9ee5a1cd6f8da6d084b93b3dbd2e8022a147cfbf"; + sha256 = "sha256-S3mf7vwrzSMWZIGE+d61UDH+/SK/ao1hTPee1sElgco="; + }) + ]; + + depsBuildBuild = [ + buildPackages.stdenv.cc + pkgs.texinfo + ]; + + preConfigure = + '' + export CC=cc + substituteInPlace configure --replace 'noconfigdirs target-newlib target-libgloss' 'noconfigdirs' + substituteInPlace configure --replace 'cross_only="target-libgloss target-newlib' 'cross_only="' + ''; + + configurePlatforms = [ + "build" + "target" + ]; + + configureFlags = + [ + "--with-newlib" + "--host=${arm-pkgs.targetPlatform.config}" + "--disable-newlib-fseek-optimization" + "--disable-newlib-fvwrite-in-streamio" + "--disable-newlib-supplied-syscalls" + "--disable-newlib-unbuf-stream-opt" + "--disable-newlib-wide-orient" + "--disable-nls" + "--enable-lite-exit" + "--enable-newlib-global-atexit" + "--enable-newlib-nano-formatted-io" + "--enable-newlib-nano-malloc" + "--enable-newlib-reent-check-verify" + "--enable-newlib-reent-small" + "--enable-newlib-retargetable-locking" + ]; + enableParallelBuilding = true; + dontDisableStatic = true; + + postInstall = '' + mkdir -p $out${finalAttrs.passthru.incdir}/newlib-nano + cp $out${finalAttrs.passthru.incdir}/newlib.h $out${finalAttrs.passthru.incdir}/newlib-nano/ + + ( + cd $out${finalAttrs.passthru.libdir} + + for f in librdimon.a libc.a libg.a; do + # Some libraries are only available for specific architectures. + # For example, librdimon.a is only available on ARM. + echo $f + echo "==========================================================" + [ -f "$f" ] && cp "$f" "''${f%%\.a}_nano.a" + done + ) + '' + + ''[ "$(find $out -type f | wc -l)" -gt 0 ] || (echo '$out is empty' 1>&2 && exit 1)''; + + passthru = { + incdir = "/${arm-pkgs.targetPlatform.config}/include"; + libdir = "/${arm-pkgs.targetPlatform.config}/lib"; + }; + + meta = with pkgs.lib; { + description = "C library intended for use on embedded systems"; + homepage = "https://sourceware.org/newlib/"; + license = licenses.gpl2Plus; + }; + }); + +in +pkgs.mkShell { + buildInputs = with pkgs; [ + pkg-config + gnumake + openocd + picotool + python312Packages.pyserial + buildPackages.gcc-arm-embedded + buildPackages.binutils + buildPackages.libcCross + newlib-nano + ]; + + shellHook = '' + export REACTOR_UC_PATH=../reactor-uc + export OBJDUMP=${buildPackages.gcc-arm-embedded}/arm-none-eabi/bin/objdump + export OBJCOPY=${buildPackages.gcc-arm-embedded}/arm-none-eabi/bin/objcopy + ''; +} diff --git a/src/TestFed.lf b/src/TestFed.lf new file mode 100644 index 0000000..78bcec4 --- /dev/null +++ b/src/TestFed.lf @@ -0,0 +1,46 @@ +target uC + +import Led from "./lib/Led.lf" + +reactor Src(id: int = 0) { + state count: int = id; + + output out: int + led = new Led() + + timer t(1sec, 1sec); + + reaction(t) -> out, led.tog {= + self->count++; + lf_set(out, self->count); + lf_set(led.tog, true); + =} +} + +reactor Dst { + led = new Led() + + input in: int + timer t(1sec, 1sec); + + reaction(t) -> led.tog {= + lf_set(led.tog, true); + printf("TOGGLE\n"); + =} + + reaction(in) -> led.tog{= + lf_set(led.tog, true); + =} +} + +federated reactor { + @interface_uart(name="uart0", uart_device=1, baud_rate=57600, data_bits=8, parity="UART_PARITY_EVEN", stop_bits=1, async=false) + fed1 = new Src(id=42) + + @interface_uart(name="uart0", uart_device=1, baud_rate=57600, data_bits=8, parity="UART_PARITY_EVEN", stop_bits=1, async=false) + fed2 = new Dst() + + @link(left="uart0", right="uart0") + fed1.out -> fed2.in +} +