-
Notifications
You must be signed in to change notification settings - Fork 1
/
flake.nix
152 lines (133 loc) · 4.55 KB
/
flake.nix
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
{
description = "Running Rust code for ESP32C3 on a QEMU emulator";
inputs = {
qemu-espressif.url = "github:SFrijters/nix-qemu-espressif";
flake-utils.url = "github:numtide/flake-utils";
nixpkgs.follows = "qemu-espressif/nixpkgs";
rust-overlay = {
url = "github:oxalica/rust-overlay";
inputs.nixpkgs.follows = "qemu-espressif/nixpkgs";
};
};
outputs =
{
nixpkgs,
flake-utils,
qemu-espressif,
rust-overlay,
...
}:
# Maybe other systems work as well, but they have not been tested
flake-utils.lib.eachSystem
[
"x86_64-linux"
"aarch64-linux"
"x86_64-darwin"
"aarch64-darwin"
]
(
system:
let
inherit (nixpkgs) lib;
pkgs = import nixpkgs {
inherit system;
overlays = [ (import rust-overlay) ];
};
pkgsCross = import nixpkgs {
inherit system;
crossSystem = {
# https://github.com/NixOS/nixpkgs/issues/281527#issuecomment-2180971963
inherit system;
rust.rustcTarget = "riscv32imc-unknown-none-elf";
};
};
toolchain = (pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml);
rustPlatform = pkgsCross.makeRustPlatform {
rustc = toolchain;
cargo = toolchain;
};
qemu-esp32c3 = qemu-espressif.packages.${system}.qemu-esp32c3;
elf-binary = pkgs.callPackage ./blinky { inherit rustPlatform; };
inherit (elf-binary.meta) name;
emulate-script = pkgs.writeShellApplication {
name = "emulate-${name}";
runtimeInputs = [
pkgs.espflash
pkgs.esptool
pkgs.gnugrep
pkgs.netcat
qemu-esp32c3
];
text = ''
# Some sanity checks
file -b "${elf-binary}/bin/${name}" | grep "ELF 32-bit LSB executable.*UCB RISC-V.*soft-float ABI.*statically linked"
# Create an image for qemu
espflash save-image --chip esp32c3 --merge ${elf-binary}/bin/${name} ${name}.bin
# Get stats
esptool.py image_info --version 2 ${name}.bin
# Start qemu in the background, open a tcp port to interact with it
qemu-system-riscv32 -nographic -monitor tcp:127.0.0.1:44444,server,nowait -icount 3 -machine esp32c3 -drive file=${name}.bin,if=mtd,format=raw -serial file:qemu-${name}.log &
# Wait a bit
sleep 3s
# Kill qemu nicely by sending 'q' (quit) over tcp
echo q | nc -N 127.0.0.1 44444
cat qemu-${name}.log
# Sanity check
grep "ESP-ROM:esp32c3-api1-20210207" qemu-${name}.log
# Did we get the expected output?
grep "Hello world" qemu-${name}.log
'';
};
flash-script = pkgs.writeShellApplication {
name = "flash-${name}";
runtimeInputs = [ pkgs.espflash ];
text = ''
espflash flash --monitor ${elf-binary}/bin/${name}
'';
};
in
{
packages = {
inherit elf-binary flash-script emulate-script;
default = emulate-script;
};
checks.default = pkgs.runCommand "qemu-check-${name}" { } ''
${lib.getExe emulate-script}
mkdir "$out"
cp qemu-${name}.log "$out"
'';
devShells.default = pkgs.mkShell {
name = "${name}-dev";
packages = [
pkgs.espflash
pkgs.esptool
pkgs.gnugrep
pkgs.netcat
qemu-esp32c3
toolchain
];
shellHook = ''
echo "==> Using toolchain version ${toolchain.version}"
echo " Using cargo version $(cargo --version)"
echo " Using rustc version $(rustc --version)"
echo " Using espflash version $(espflash --version)"
'';
};
apps = {
default = {
type = "app";
program = "${lib.getExe emulate-script}";
};
emulate = {
type = "app";
program = "${lib.getExe emulate-script}";
};
flash = {
type = "app";
program = "${lib.getExe flash-script}";
};
};
formatter = pkgs.nixfmt-rfc-style;
}
);
}