Microzig as pkg (#10)

* works as a package

* run zig fmt on all files
wch-ch32v003
Matt Knight 3 years ago committed by GitHub
parent 46a924234e
commit f46c2e4ea9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -35,7 +35,7 @@ pub fn ensure() void {
}
/// Returns the current cpu frequency in hertz.
pub fn get() callconv(.Inline) u32 {
pub inline fn get() u32 {
ensure();
return @field(clock_source_type, freq_decl_name);
}

@ -66,47 +66,6 @@ pub fn hang() noreturn {
}
}
/// This is the logical entry point for microzig.
/// It will invoke the main function from the root source file
/// and provides error return handling as well as a event loop if requested.
///
/// Why is this function exported?
/// This is due to the modular design of microzig to allow the "chip" dependency of microzig
/// to call into our main function here. If we would use a normal function call, we'd have a
/// circular dependency between the `microzig` and `chip` package. This function is also likely
/// to be invoked from assembly, so it's also convenient in that regard.
export fn microzig_main() noreturn {
if (!@hasDecl(root, "main"))
@compileError("The root source file must provide a public function main!");
const main = @field(root, "main");
const info: std.builtin.TypeInfo = @typeInfo(@TypeOf(main));
const invalid_main_msg = "main must be either 'pub fn main() void' or 'pub fn main() !void'.";
if (info != .Fn or info.Fn.args.len > 0)
@compileError(invalid_main_msg);
const return_type = info.Fn.return_type orelse @compileError(invalid_main_msg);
if (info.Fn.calling_convention == .Async)
@compileError("TODO: Embedded event loop not supported yet. Please try again later.");
if (@typeInfo(return_type) == .ErrorUnion) {
main() catch |err| {
// TODO:
// - Compute maximum size on the type of "err"
// - Do not emit error names when std.builtin.strip is set.
var msg: [64]u8 = undefined;
@panic(std.fmt.bufPrint(&msg, "main() returned error {s}", .{@errorName(err)}) catch @panic("main() returned error."));
};
} else {
main();
}
// main returned, just hang around here a bit
hang();
}
comptime {
_ = cpu.startup_logic;
}

@ -0,0 +1,46 @@
const std = @import("std");
const app = @import("app");
const microzig = @import("microzig");
pub usingnamespace app;
/// This is the logical entry point for microzig.
/// It will invoke the main function from the root source file
/// and provides error return handling as well as a event loop if requested.
///
/// Why is this function exported?
/// This is due to the modular design of microzig to allow the "chip" dependency of microzig
/// to call into our main function here. If we would use a normal function call, we'd have a
/// circular dependency between the `microzig` and `chip` package. This function is also likely
/// to be invoked from assembly, so it's also convenient in that regard.
export fn microzig_main() noreturn {
if (!@hasDecl(app, "main"))
@compileError("The root source file must provide a public function main!");
const main = @field(app, "main");
const info: std.builtin.TypeInfo = @typeInfo(@TypeOf(main));
const invalid_main_msg = "main must be either 'pub fn main() void' or 'pub fn main() !void'.";
if (info != .Fn or info.Fn.args.len > 0)
@compileError(invalid_main_msg);
const return_type = info.Fn.return_type orelse @compileError(invalid_main_msg);
if (info.Fn.calling_convention == .Async)
@compileError("TODO: Embedded event loop not supported yet. Please try again later.");
if (@typeInfo(return_type) == .ErrorUnion) {
main() catch |err| {
// TODO:
// - Compute maximum size on the type of "err"
// - Do not emit error names when std.builtin.strip is set.
var msg: [64]u8 = undefined;
@panic(std.fmt.bufPrint(&msg, "main() returned error {s}", .{@errorName(err)}) catch @panic("main() returned error."));
};
} else {
main();
}
// main returned, just hang around here a bit
microzig.hang();
}

@ -12,6 +12,7 @@ pub const Backing = union(enum) {
chip: Chip,
};
const Pkg = std.build.Pkg;
const root_path = root() ++ "/";
fn root() []const u8 {
return std.fs.path.dirname(@src().file) orelse unreachable;
@ -23,34 +24,12 @@ pub fn addEmbeddedExecutable(
source: []const u8,
backing: Backing,
) !*std.build.LibExeObjStep {
const Pkg = std.build.Pkg;
const microzig_base = Pkg{
.name = "microzig",
.path = .{ .path = root_path ++ "core/microzig.zig" },
};
const has_board = (backing == .board);
const chip = switch (backing) {
.chip => |c| c,
.board => |b| b.chip,
};
const has_board = (backing == .board);
const chip_package = Pkg{
.name = "chip",
.path = .{ .path = chip.path },
.dependencies = &[_]Pkg{
microzig_base,
pkgs.mmio,
Pkg{
.name = "cpu",
.path = .{ .path = chip.cpu.path },
.dependencies = &[_]Pkg{ microzig_base, pkgs.mmio },
},
},
};
const config_file_name = blk: {
const hash = hash_blk: {
var hasher = std.hash.SipHash128(1, 2).init("abcdefhijklmnopq");
@ -97,47 +76,95 @@ pub fn addEmbeddedExecutable(
try writer.print("pub const cpu_name = .@\"{}\";\n", .{std.fmt.fmtSliceEscapeUpper(chip.cpu.name)});
}
const microzig_pkg = Pkg{
.name = "microzig",
.path = .{ .path = root_path ++ "core/microzig.zig" },
};
const chip_pkg = Pkg{
.name = "chip",
.path = .{ .path = chip.path },
.dependencies = &[_]Pkg{
microzig_pkg,
pkgs.mmio,
Pkg{
.name = "cpu",
.path = .{ .path = chip.cpu.path },
.dependencies = &[_]Pkg{ microzig_pkg, pkgs.mmio },
},
},
};
const config_pkg = Pkg{
.name = "microzig-config",
.path = .{ .path = config_file_name },
};
const linkerscript = try LinkerScriptStep.create(builder, chip);
const exe = builder.addExecutable(name, source);
const exe = builder.addExecutable(name, root_path ++ "core/start.zig");
// might not be true for all machines (Pi Pico), but
// for the HAL it's true (it doesn't know the concept of threading)
exe.single_threaded = true;
exe.setTarget(chip.cpu.target);
const linkerscript = try LinkerScriptStep.create(builder, chip);
exe.setLinkerScriptPath(.{ .generated = &linkerscript.generated_file });
// TODO:
// - Generate the linker scripts from the "chip" or "board" package instead of using hardcoded ones.
// - This requires building another tool that runs on the host that compiles those files and emits the linker script.
// - src/tools/linkerscript-gen.zig is the source file for this
exe.bundle_compiler_rt = false;
switch (backing) {
.chip => {
exe.addPackage(Pkg{
.name = microzig_base.name,
.path = microzig_base.path,
.dependencies = &[_]Pkg{ config_pkg, chip_package },
.name = "app",
.path = .{ .path = source },
.dependencies = &[_]Pkg{
Pkg{
.name = microzig_pkg.name,
.path = microzig_pkg.path,
.dependencies = &[_]Pkg{ config_pkg, chip_pkg },
},
},
});
exe.addPackage(Pkg{
.name = microzig_pkg.name,
.path = microzig_pkg.path,
.dependencies = &[_]Pkg{ config_pkg, chip_pkg },
});
},
.board => |board| {
exe.addPackage(Pkg{
.name = microzig_base.name,
.path = microzig_base.path,
.name = "app",
.path = .{ .path = source },
.dependencies = &[_]Pkg{
Pkg{
.name = microzig_pkg.name,
.path = microzig_pkg.path,
.dependencies = &[_]Pkg{
config_pkg,
chip_pkg,
Pkg{
.name = "board",
.path = .{ .path = board.path },
.dependencies = &[_]Pkg{ microzig_pkg, chip_pkg, pkgs.mmio },
},
},
},
},
});
exe.addPackage(Pkg{
.name = microzig_pkg.name,
.path = microzig_pkg.path,
.dependencies = &[_]Pkg{
config_pkg,
chip_package,
chip_pkg,
Pkg{
.name = "board",
.path = .{ .path = board.path },
.dependencies = &[_]Pkg{ microzig_base, chip_package, pkgs.mmio },
.dependencies = &[_]Pkg{ microzig_pkg, chip_pkg, pkgs.mmio },
},
},
});

@ -21724,4 +21724,3 @@ pub const GPIO = extern struct {
PINCLR31: u1, // bit offset: 31 desc: Fast GPIO output value Clear bits. Bit 0 in CLRx controls pin Px[0], bit 31 in CLRx controls pin Px[31]. 0 = Controlled pin output is unchanged. 1 = Controlled pin output is set to LOW.
});
};

@ -17770,4 +17770,3 @@ pub const USB = extern struct {
padding1: u1 = 0,
});
};

@ -1,11 +1,4 @@
const std = @import("std");
const micro = @import("microzig");
const micro_linker = @import("microzig-linker");
pub const cpu = @import("cpu");
pub const registers = @import("registers.zig");
pub const memory_regions = [_]micro_linker.MemoryRegion{
micro_linker.MemoryRegion{ .offset = 0x00000000, .length = 64 * 1024, .kind = .flash },
micro_linker.MemoryRegion{ .offset = 0x10000000, .length = 20 * 1024, .kind = .ram },
};

@ -1,26 +1,26 @@
const std = @import("std");
pub fn sei() callconv(.Inline) void {
pub inline fn sei() void {
asm volatile ("sei");
}
pub fn cli() callconv(.Inline) void {
pub inline fn cli() void {
asm volatile ("cli");
}
pub fn sbi(comptime reg: u5, comptime bit: u3) callconv(.Inline) void {
pub inline fn sbi(comptime reg: u5, comptime bit: u3) void {
asm volatile ("sbi %[reg], %[bit]"
:
: [reg] "I" (reg),
[bit] "I" (bit)
[bit] "I" (bit),
);
}
pub fn cbi(comptime reg: u5, comptime bit: u3) callconv(.Inline) void {
pub inline fn cbi(comptime reg: u5, comptime bit: u3) void {
asm volatile ("cbi %[reg], %[bit]"
:
: [reg] "I" (reg),
[bit] "I" (bit)
[bit] "I" (bit),
);
}

Loading…
Cancel
Save