diff --git a/README.md b/README.md index f2e6d47..53a9022 100644 --- a/README.md +++ b/README.md @@ -6,29 +6,17 @@ Minimalist bare metal Rust firmware for Red Pitaya. Development instructions ------------------------ -Configure Nix channels: - -```shell -nix-channel --add https://nixbld.m-labs.hk/channel/custom/artiq/fast-beta/artiq-fast -nix-channel --update -``` - -Notes: - -- Rust Pitaya does not depend on ARTIQ but uses some packages available in the ARTIQ channel. -- If you are using Nix channels the first time, you need to be aware of this bug: https://github.com/NixOS/nix/issues/3831. - Pure build with Nix and execution on a remote JTAG server: ```shell -nix-build -A rust-pitaya-jtag +nix build .#rust-pitaya-jtag ./remote_run.sh ``` Impure incremental build and execution on a remote JTAG server: ```shell -nix-shell +nix develop cd src gateware/rust-pitaya.py -g ../build/gateware # build gateware make # build firmware @@ -38,14 +26,13 @@ cd .. Notes: -- This is developed with Nixpkgs 20.09, and the ``nixbld.m-labs.hk`` binary substituter can also be used here (see the ARTIQ manual for the public key and instructions). - The impure build process is also compatible with non-Nix systems. - If the board is connected to the local machine, use the ``local_run.sh`` script. License ------- -Copyright (C) 2019-2020 M-Labs Limited. +Copyright (C) 2019-2022 M-Labs Limited. Rust Pitaya is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by diff --git a/default.nix b/default.nix deleted file mode 100644 index 37f57e4..0000000 --- a/default.nix +++ /dev/null @@ -1,87 +0,0 @@ -let - zynq-rs = (import ./zynq-rs.nix); - pkgs = import { overlays = [ (import "${zynq-rs}/nix/mozilla-overlay.nix") ]; }; - rustPlatform = (import "${zynq-rs}/nix/rust-platform.nix" { inherit pkgs; }); - cargo-xbuild = (import zynq-rs).cargo-xbuild; - redpitaya-szl = (import zynq-rs).redpitaya-szl; - mkbootimage = import "${zynq-rs}/nix/mkbootimage.nix" { inherit pkgs; }; - artiqpkgs = import { inherit pkgs; }; - vivado = import { inherit pkgs; }; -in rec { - rust-pitaya-firmware = rustPlatform.buildRustPackage { - name = "rust-pitaya-firmware"; - - src = ./src; - cargoSha256 = "173013gdlk8mljps6lar892zqgxrmxa7fkv8is3wgvgf7dnifjzs"; - - nativeBuildInputs = [ - pkgs.gnumake - (pkgs.python3.withPackages(ps: (with artiqpkgs; [ migen migen-axi misoc ]))) - cargo-xbuild - pkgs.llvmPackages_9.llvm - pkgs.llvmPackages_9.clang-unwrapped - ]; - buildPhase = '' - export XARGO_RUST_SRC="${rustPlatform.rust.rustc.src}/library" - export CARGO_HOME=$(mktemp -d cargo-home.XXX) - make - ''; - - installPhase = '' - mkdir -p $out $out/nix-support - cp ../build/firmware.bin $out/firmware.bin - cp ../build/firmware/armv7-none-eabihf/release/firmware $out/firmware.elf - echo file binary-dist $out/firmware.bin >> $out/nix-support/hydra-build-products - echo file binary-dist $out/firmware.elf >> $out/nix-support/hydra-build-products - ''; - - doCheck = false; - dontFixup = true; - }; - rust-pitaya-gateware = pkgs.runCommand "rust-pitaya-gateware" - { - nativeBuildInputs = [ - (pkgs.python3.withPackages(ps: (with artiqpkgs; [ migen migen-axi misoc ]))) - vivado - ]; - } - '' - python ${./src/gateware}/rust-pitaya.py -g build - mkdir -p $out $out/nix-support - cp build/top.bit $out - echo file binary-dist $out/top.bit >> $out/nix-support/hydra-build-products - ''; - - - rust-pitaya-jtag = pkgs.runCommand "rust-pitaya-jtag" {} - '' - mkdir $out - ln -s ${redpitaya-szl}/szl.elf $out - ln -s ${rust-pitaya-firmware}/firmware.bin $out - ln -s ${rust-pitaya-gateware}/top.bit $out - ''; - rust-pitaya-sd = pkgs.runCommand "rust-pitaya-sd" - { - buildInputs = [ mkbootimage ]; - } - '' - # Do not use "long" paths in boot.bif, because embedded developers - # can't write software (mkbootimage will segfault). - bifdir=`mktemp -d` - cd $bifdir - ln -s ${redpitaya-szl}/szl.elf szl.elf - ln -s ${rust-pitaya-firmware}/firmware.elf firmware.elf - ln -s ${rust-pitaya-gateware}/top.bit top.bit - cat > boot.bif << EOF - the_ROM_image: - { - [bootloader]szl.elf - top.bit - firmware.elf - } - EOF - mkdir $out $out/nix-support - mkbootimage boot.bif $out/boot.bin - echo file binary-dist $out/boot.bin >> $out/nix-support/hydra-build-products - ''; -} diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..976bb59 --- /dev/null +++ b/flake.lock @@ -0,0 +1,241 @@ +{ + "nodes": { + "artiq": { + "inputs": { + "artiq-comtools": "artiq-comtools", + "mozilla-overlay": "mozilla-overlay", + "nixpkgs": "nixpkgs", + "sipyco": "sipyco", + "src-migen": "src-migen", + "src-misoc": "src-misoc", + "src-pythonparser": "src-pythonparser" + }, + "locked": { + "lastModified": 1661404661, + "narHash": "sha256-j3l/plOlK2Hcd4XIC32PDfKvqUY8Apr9sBeczyJ/L8A=", + "ref": "master", + "rev": "b705862ecd014b0c3b69051c1c822f13ce8aeea2", + "revCount": 8144, + "type": "git", + "url": "https://github.com/m-labs/artiq.git" + }, + "original": { + "type": "git", + "url": "https://github.com/m-labs/artiq.git" + } + }, + "artiq-comtools": { + "inputs": { + "nixpkgs": [ + "artiq-zynq", + "artiq", + "nixpkgs" + ], + "sipyco": [ + "artiq-zynq", + "artiq", + "sipyco" + ] + }, + "locked": { + "lastModified": 1654007592, + "narHash": "sha256-vaDFhE1ItjqtIcinC/6RAJGbj44pxxMUEeQUa3FtgEE=", + "owner": "m-labs", + "repo": "artiq-comtools", + "rev": "cb73281154656ee8f74db1866859e31bf42755cd", + "type": "github" + }, + "original": { + "owner": "m-labs", + "repo": "artiq-comtools", + "type": "github" + } + }, + "artiq-zynq": { + "inputs": { + "artiq": "artiq", + "mozilla-overlay": "mozilla-overlay_2", + "zynq-rs": "zynq-rs" + }, + "locked": { + "lastModified": 1661774127, + "narHash": "sha256-OTJKLZBoJtisDcpjckMsq2PgtgrkwSm5VV51kOPS8yI=", + "ref": "master", + "rev": "38f4d6cd2e7a0c2122bff674e04d4c251fc76b3b", + "revCount": 576, + "type": "git", + "url": "https://git.m-labs.hk/m-labs/artiq-zynq" + }, + "original": { + "type": "git", + "url": "https://git.m-labs.hk/m-labs/artiq-zynq" + } + }, + "mozilla-overlay": { + "flake": false, + "locked": { + "lastModified": 1657214286, + "narHash": "sha256-rO/4oymKXU09wG2bcTt4uthPCp1XsBZjxuCJo3yVXNs=", + "owner": "mozilla", + "repo": "nixpkgs-mozilla", + "rev": "0508a66e28a5792fdfb126bbf4dec1029c2509e0", + "type": "github" + }, + "original": { + "owner": "mozilla", + "repo": "nixpkgs-mozilla", + "type": "github" + } + }, + "mozilla-overlay_2": { + "flake": false, + "locked": { + "lastModified": 1657214286, + "narHash": "sha256-rO/4oymKXU09wG2bcTt4uthPCp1XsBZjxuCJo3yVXNs=", + "owner": "mozilla", + "repo": "nixpkgs-mozilla", + "rev": "0508a66e28a5792fdfb126bbf4dec1029c2509e0", + "type": "github" + }, + "original": { + "owner": "mozilla", + "repo": "nixpkgs-mozilla", + "type": "github" + } + }, + "mozilla-overlay_3": { + "flake": false, + "locked": { + "lastModified": 1650459918, + "narHash": "sha256-sroCK+QJTmoXtcRkwZyKOP9iAYOPID2Bwdxn4GkG16w=", + "owner": "mozilla", + "repo": "nixpkgs-mozilla", + "rev": "e1f7540fc0a8b989fb8cf701dc4fd7fc76bcf168", + "type": "github" + }, + "original": { + "owner": "mozilla", + "repo": "nixpkgs-mozilla", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1657123678, + "narHash": "sha256-cowVkScfUPlbBXUp08MeVk/wgm9E1zp1uC+9no2hZYw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "316b762afdb9e142a803f29c49a88b4a47db80ee", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-22.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "artiq-zynq": "artiq-zynq" + } + }, + "sipyco": { + "inputs": { + "nixpkgs": [ + "artiq-zynq", + "artiq", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1654830914, + "narHash": "sha256-tratXcWu6Dgzd0Qd9V6EMjuNlE9qDN1pKFhP+Gt0b64=", + "owner": "m-labs", + "repo": "sipyco", + "rev": "58b0935f7ae47659abee5b5792fa594153328d6f", + "type": "github" + }, + "original": { + "owner": "m-labs", + "repo": "sipyco", + "type": "github" + } + }, + "src-migen": { + "flake": false, + "locked": { + "lastModified": 1656649178, + "narHash": "sha256-A91sZRrprEuPOtIUVxm6wX5djac9wnNZQ4+cU1nvJPc=", + "owner": "m-labs", + "repo": "migen", + "rev": "0fb91737090fe45fd764ea3f71257a4c53c7a4ae", + "type": "github" + }, + "original": { + "owner": "m-labs", + "repo": "migen", + "type": "github" + } + }, + "src-misoc": { + "flake": false, + "locked": { + "lastModified": 1649324486, + "narHash": "sha256-Mw/fQS3lHFvCm7L1k63joRkz5uyijQfywcOq+X2+o2s=", + "ref": "master", + "rev": "f1dc58d2b8c222ba41c25cee4301626625f46e43", + "revCount": 2420, + "submodules": true, + "type": "git", + "url": "https://github.com/m-labs/misoc.git" + }, + "original": { + "submodules": true, + "type": "git", + "url": "https://github.com/m-labs/misoc.git" + } + }, + "src-pythonparser": { + "flake": false, + "locked": { + "lastModified": 1628745371, + "narHash": "sha256-p6TgeeaK4NEmbhimEXp31W8hVRo4DgWmcCoqZ+UdN60=", + "owner": "m-labs", + "repo": "pythonparser", + "rev": "5413ee5c9f8760e95c6acd5d6e88dabb831ad201", + "type": "github" + }, + "original": { + "owner": "m-labs", + "repo": "pythonparser", + "type": "github" + } + }, + "zynq-rs": { + "inputs": { + "mozilla-overlay": "mozilla-overlay_3", + "nixpkgs": [ + "artiq-zynq", + "artiq", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1661505762, + "narHash": "sha256-gXML1pez4LvYxuAG9AX3inKq0e7+D8SvNd/tW4OwXu4=", + "ref": "master", + "rev": "92b3f3e1dd14fb2e53868665d95bbea4270da33e", + "revCount": 621, + "type": "git", + "url": "https://git.m-labs.hk/m-labs/zynq-rs" + }, + "original": { + "type": "git", + "url": "https://git.m-labs.hk/m-labs/zynq-rs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..c8e5e07 --- /dev/null +++ b/flake.nix @@ -0,0 +1,118 @@ +{ + description = "Minimalist bare metal Rust firmware for Red Pitaya"; + + inputs.artiq-zynq.url = git+https://git.m-labs.hk/m-labs/artiq-zynq; + + outputs = { self, artiq-zynq }: + let + pkgs = import artiq-zynq.inputs.artiq.inputs.nixpkgs { system = "x86_64-linux"; overlays = [ (import artiq-zynq.inputs.mozilla-overlay) ]; }; + zynqpkgs = artiq-zynq.inputs.zynq-rs.packages.x86_64-linux; + artiqpkgs = artiq-zynq.inputs.artiq.packages.x86_64-linux; + artiqzynqpkgs = artiq-zynq.packages.x86_64-linux; + rustPlatform = artiq-zynq.inputs.zynq-rs.rustPlatform; + in { + packages.x86_64-linux = rec { + rust-pitaya-firmware = rustPlatform.buildRustPackage { + name = "rust-pitaya-firmware"; + + src = ./src; + cargoLock = { + lockFile = src/Cargo.lock; + outputHashes = { + "libasync-0.0.0" = "sha256-gXML1pez4LvYxuAG9AX3inKq0e7+D8SvNd/tW4OwXu4="; + }; + }; + + nativeBuildInputs = [ + pkgs.gnumake + (pkgs.python3.withPackages(ps: [ artiqpkgs.migen artiqzynqpkgs.migen-axi artiqpkgs.misoc ])) + pkgs.cargo-xbuild + pkgs.llvmPackages_9.llvm + pkgs.llvmPackages_9.clang-unwrapped + ]; + buildPhase = '' + XARGO_RUST_SRC="${rustPlatform.rust.rustc}/lib/rustlib/src/rust/library"; + export CARGO_HOME=$(mktemp -d cargo-home.XXX) + make + ''; + + installPhase = '' + mkdir -p $out $out/nix-support + cp ../build/firmware.bin $out/firmware.bin + cp ../build/firmware/armv7-none-eabihf/release/firmware $out/firmware.elf + echo file binary-dist $out/firmware.bin >> $out/nix-support/hydra-build-products + echo file binary-dist $out/firmware.elf >> $out/nix-support/hydra-build-products + ''; + + doCheck = false; + dontFixup = true; + }; + rust-pitaya-gateware = pkgs.runCommand "rust-pitaya-gateware" + { + nativeBuildInputs = [ + (pkgs.python3.withPackages(ps: [ artiqpkgs.migen artiqzynqpkgs.migen-axi artiqpkgs.misoc ])) + artiqpkgs.vivado + ]; + } + '' + python ${./src/gateware}/rust-pitaya.py -g build + mkdir -p $out $out/nix-support + cp build/top.bit $out + echo file binary-dist $out/top.bit >> $out/nix-support/hydra-build-products + ''; + rust-pitaya-jtag = pkgs.runCommand "rust-pitaya-jtag" {} + '' + mkdir $out + ln -s ${zynqpkgs.szl}/szl-redpitaya.elf $out + ln -s ${rust-pitaya-firmware}/firmware.bin $out + ln -s ${rust-pitaya-gateware}/top.bit $out + ''; + rust-pitaya-sd = pkgs.runCommand "rust-pitaya-sd" + { + buildInputs = [ zynqpkgs.mkbootimage ]; + } + '' + # Do not use "long" paths in boot.bif, because embedded developers + # can't write software (mkbootimage will segfault). + bifdir=`mktemp -d` + cd $bifdir + ln -s ${zynqpkgs.szl}/szl-redpitaya.elf szl.elf + ln -s ${rust-pitaya-firmware}/firmware.elf firmware.elf + ln -s ${rust-pitaya-gateware}/top.bit top.bit + cat > boot.bif << EOF + the_ROM_image: + { + [bootloader]szl.elf + top.bit + firmware.elf + } + EOF + mkdir $out $out/nix-support + mkbootimage boot.bif $out/boot.bin + echo file binary-dist $out/boot.bin >> $out/nix-support/hydra-build-products + ''; + }; + devShell.x86_64-linux = pkgs.mkShell { + name = "rust-pitaya-dev-shell"; + buildInputs = with pkgs; [ + pkgs.gnumake + rustPlatform.rust.rustc + rustPlatform.rust.cargo + pkgs.llvmPackages_9.llvm + pkgs.llvmPackages_9.clang-unwrapped + pkgs.cacert + cargo-xbuild + + pkgs.openocd + pkgs.openssh pkgs.rsync + (pkgs.python3.withPackages(ps: [ artiqpkgs.migen artiqzynqpkgs.migen-axi artiqpkgs.misoc artiqzynqpkgs.artiq-netboot ])) + artiqpkgs.vivado + + zynqpkgs.mkbootimage + ]; + XARGO_RUST_SRC = "${rustPlatform.rust.rustc}/lib/rustlib/src/rust/library"; + OPENOCD_ZYNQ = "${artiq-zynq.inputs.zynq-rs}/openocd"; + SZL = "${zynqpkgs.szl}"; + }; + }; +} diff --git a/local_run.sh b/local_run.sh index e836f34..1188764 100755 --- a/local_run.sh +++ b/local_run.sh @@ -33,7 +33,7 @@ load_bitstream_cmd="" build_dir=`pwd`/build result_dir=`pwd`/result cd $OPENOCD_ZYNQ -openocd -f redpitaya.cfg -c "load_image $SZL; resume 0; exit" +openocd -f redpitaya.cfg -c "load_image $SZL/szl-redpitaya.elf; resume 0; exit" sleep 5 if [ $impure -eq 1 ]; then if [ $load_bitstream -eq 1 ]; then diff --git a/remote_run.sh b/remote_run.sh index 3cfcff5..9de351c 100755 --- a/remote_run.sh +++ b/remote_run.sh @@ -46,7 +46,7 @@ echo "Creating $target_folder..." ssh $sshopts $target_host "mkdir -p $target_folder" echo "Copying files..." rsync -e "ssh $sshopts" -Lc $OPENOCD_ZYNQ/* $target_host:$target_folder -rsync -e "ssh $sshopts" -Lc $SZL $target_host:$target_folder +rsync -e "ssh $sshopts" -Lc $SZL/szl-redpitaya.elf $target_host:$target_folder if [ $impure -eq 1 ]; then if [ $load_bitstream -eq 1 ]; then load_bitstream_cmd="-g build/gateware/top.bit" @@ -59,6 +59,6 @@ else firmware="$pure_dir/firmware.bin" fi echo "Programming board..." -ssh $sshopts $target_host "cd $target_folder; openocd -f redpitaya.cfg -c'load_image szl.elf; resume 0; exit'" +ssh $sshopts $target_host "cd $target_folder; openocd -f redpitaya.cfg -c'load_image szl-redpitaya.elf; resume 0; exit'" sleep 5 artiq_netboot $load_bitstream_cmd -f $firmware -b $board_host diff --git a/shell.nix b/shell.nix deleted file mode 100644 index 5ce31c9..0000000 --- a/shell.nix +++ /dev/null @@ -1,33 +0,0 @@ -let - zynq-rs = (import ./zynq-rs.nix); - pkgs = import { overlays = [ (import "${zynq-rs}/nix/mozilla-overlay.nix") ]; }; - rustPlatform = (import "${zynq-rs}/nix/rust-platform.nix" { inherit pkgs; }); - cargo-xbuild = (import zynq-rs).cargo-xbuild; - artiq-fast = ; - artiqpkgs = import "${artiq-fast}/default.nix" { inherit pkgs; }; - vivado = import "${artiq-fast}/vivado.nix" { inherit pkgs; }; - redpitaya-szl = (import zynq-rs).redpitaya-szl; -in - pkgs.stdenv.mkDerivation { - name = "rust-pitaya-env"; - buildInputs = [ - pkgs.gnumake - rustPlatform.rust.rustc - rustPlatform.rust.cargo - pkgs.llvmPackages_9.llvm - pkgs.cacert - cargo-xbuild - - pkgs.openocd - pkgs.openssh pkgs.rsync - - (pkgs.python3.withPackages(ps: (with artiqpkgs; [ migen migen-axi misoc artiq-netboot ]))) - vivado - - (import "${zynq-rs}/nix/mkbootimage.nix" { inherit pkgs; }) - ]; - - XARGO_RUST_SRC = "${rustPlatform.rust.rustc.src}/library"; - OPENOCD_ZYNQ = "${zynq-rs}/openocd"; - SZL = "${redpitaya-szl}/szl.elf"; - }