diff options
Diffstat (limited to 'build.zig')
| -rw-r--r-- | build.zig | 48 |
1 files changed, 48 insertions, 0 deletions
@@ -180,6 +180,14 @@ pub fn build(b: *std.Build) void { .{ .name = "hal", .module = hal_mod }, .{ .name = "mmio", .module = mmio_mod }, .{ .name = "regs", .module = regs_mod }, + // The wire protocol `examples/uartperf.zig` answers, imported rather than copied so + // the firmware and the host tool cannot disagree about a frame. It is deliberately + // free of any OS dependency for exactly this reason: one file, two targets. + .{ .name = "perfproto", .module = b.createModule(.{ + .root_source_file = b.path("tools/perfproto.zig"), + .target = target, + .optimize = optimize, + }) }, }, }), }); @@ -397,6 +405,32 @@ pub fn build(b: *std.Build) void { run_con.step.dependOn(&flash.step); b.step("interact", "flash the image, then attach a terminal").dependOn(&run_con.step); + // The measuring instrument. Its own binary for the same reason the console is: it drives the + // port for tens of seconds and must not have the build runner repainting a progress tree into + // the middle of a timed transfer. It shares `tools/perfproto.zig` with the firmware responder, + // so a frame the host writes and a frame the board parses cannot drift apart. + const bench_proto = b.createModule(.{ + .root_source_file = b.path("tools/perfproto.zig"), + .target = b.graph.host, + .optimize = .ReleaseSafe, + }); + const bench_exe = b.addExecutable(.{ + .name = "p4-bench", + .root_module = b.createModule(.{ + .root_source_file = b.path("tools/bench_main.zig"), + .target = b.graph.host, + .optimize = .ReleaseSafe, + .imports = &.{.{ .name = "perfproto", .module = bench_proto }}, + }), + }); + const bench_install = b.addInstallArtifact(bench_exe, .{}); + const bench = b.addRunArtifact(bench_exe); + bench.addArgs(&.{ "--port", port_path }); + bench.stdio = .inherit; + bench.step.dependOn(&bench_install.step); + b.step("bench", "measure the serial link: verified throughput each way, and latency") + .dependOn(&bench.step); + const reset = ResetStep.create(b, port_path); b.step("reset", "reset the board and let the flashed application run").dependOn(&reset.step); @@ -456,6 +490,20 @@ pub fn build(b: *std.Build) void { }); test_step.dependOn(&b.addRunArtifact(console_tests).step); + // The measurement protocol. These are the tests that keep a throughput number honest: that a + // frame round-trips, that a short read is "incomplete" rather than "invalid", that a lost byte + // mid-stream changes the CRC, and that the pattern generator does not repeat on a 256-byte + // boundary - a plain counter would hash identically after losing exactly 256 bytes and the + // instrument would report a clean run over corrupt data. + const proto_tests = b.addTest(.{ + .root_module = b.createModule(.{ + .root_source_file = b.path("tools/perfproto.zig"), + .target = b.graph.host, + .optimize = .Debug, + }), + }); + test_step.dependOn(&b.addRunArtifact(proto_tests).step); + // The radio path's host-testable parts. A wrong checksum, a wrong snprintf, or a scheduler that // loses a task is far cheaper to find here than on a board whose only output is a serial line. // |
