a slightly different question from an earlier post, now that i’ve learned a few more things…
consider the following code, which i’ve already compiled for my bare-metal MCU and have inspect the generated .asm
file:
const std = @import("std");
fn REG(adr: u32) *volatile u32 {
const reg: *volatile u32 = @ptrFromInt(adr);
return reg;
}
fn done() void {
var dummy: u32 = 0xCAFE;
const vp: *volatile u32 = &dummy;
while (vp.* != 0) {}
}
const Counter = struct {
_val: u8 = 0,
fn inc(self: *Counter) void {
comptime self._val += 1;
}
fn get(self: *Counter) u8 {
return self._val;
}
};
fn mkCounter() Counter {
comptime var c: Counter = .{};
return c;
}
export fn main() void {
comptime var ctr = mkCounter();
comptime {
ctr.inc();
ctr.inc();
std.debug.assert(ctr.get() == 2);
}
REG(12345678).* = ctr.get();
done();
}
as you can see, i’ve created a Counter
instance which i’ve manipulated at comptime
using the (comptime
-only) inc
method… i then call get
when writing the counter’s value to some (phony) memory-mapped address…
[[ as an aside, i can in fact write the _val
field at runtime (by design in zig); disciplined use of the Counter
methods preserves the semantics i’m looking for ]]
what i want to do, however, is effectively have my comptime var ctr
exist at container-level – where in fact zig prevents such declarations…
as an example, i’d like MyMod.zig
to expose a single Counter
instance to any of its clients; these clients can then call the inc
method as often as they wish at comptime
… at runtime, however, any client (as well as MyMod
itself) can read the finally tally through the get
method…
thoughts on how to realize this in zig ???