instantiate vector table in start.zig (#22)

wch-ch32v003
Matt Knight 3 years ago committed by GitHub
parent 8a5ee67588
commit 13f0a1e347
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -4,6 +4,57 @@ const microzig = @import("microzig");
pub usingnamespace app;
fn isValidField(field_name: []const u8) bool {
return !std.mem.startsWith(u8, field_name, "reserved") and
!std.mem.eql(u8, field_name, "initial_stack_pointer") and
!std.mem.eql(u8, field_name, "reset");
}
const VectorTable = microzig.chip.VectorTable;
export const vector_table: VectorTable linksection("microzig_flash_start") = blk: {
var tmp: microzig.chip.VectorTable = .{};
if (@hasDecl(app, "interrupts")) {
if (@typeInfo(app.interrupts) != .Struct)
@compileLog("root.interrupts must be a struct");
inline for (@typeInfo(app.interrupts).Struct.decls) |decl| {
const calling_convention = @typeInfo(@TypeOf(@field(app.interrupts, decl.name))).Fn.calling_convention;
const handler = @field(app.interrupts, decl.name);
if (!@hasField(VectorTable, decl.name)) {
var msg: []const u8 = "There is no such interrupt as '" ++ decl.name ++ "'. Declarations in 'interrupts' must be one of:\n";
inline for (std.meta.fields(VectorTable)) |field| {
if (isValidField(field.name)) {
msg = msg ++ " " ++ field.name ++ "\n";
}
}
@compileError(msg);
}
if (!isValidField(decl.name))
@compileError("You are not allowed to specify '" ++ decl.name ++ "' in the vector table, for your sins you must now pay a $5 fine to the ZSF: https://github.com/sponsors/ziglang");
@field(tmp, decl.name) = switch (calling_convention) {
.C => .{ .C = handler },
.Naked => .{ .Naked = handler },
// for unspecified calling convention we are going to generate small wrapper
.Unspecified => .{
.C = struct {
fn wrapper() callconv(.C) void {
if (calling_convention == .Unspecified) // TODO: workaround for some weird stage1 bug
@call(.{ .modifier = .always_inline }, handler, .{});
}
}.wrapper,
},
else => @compileError("unsupported calling convention for function " ++ decl.name),
};
}
}
break :blk tmp;
};
/// 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.

@ -3,7 +3,7 @@ const micro = @import("microzig");
pub const cpu = @import("cpu");
pub const registers = @import("registers.zig");
pub const VectorTable = registers.VectorTable;
pub const PinTarget = enum(u2) {
func00 = 0b00,
func01 = 0b01,

@ -21798,55 +21798,3 @@ pub const VectorTable = extern struct {
USBActivity: InterruptVector = makeUnhandledHandler("USBActivity"),
CANActivity: InterruptVector = makeUnhandledHandler("CANActivity"),
};
fn isValidField(field_name: []const u8) bool {
return !std.mem.startsWith(u8, field_name, "reserved") and
!std.mem.eql(u8, field_name, "initial_stack_pointer") and
!std.mem.eql(u8, field_name, "reset");
}
export const vectors: VectorTable linksection("microzig_flash_start") = blk: {
var temp: VectorTable = .{};
if (@hasDecl(root, "vector_table")) {
const vector_table = root.vector_table;
if (@typeInfo(vector_table) != .Struct)
@compileLog("root.vector_table must be a struct");
inline for (@typeInfo(vector_table).Struct.decls) |decl| {
const calling_convention = @typeInfo(@TypeOf(@field(vector_table, decl.name))).Fn.calling_convention;
const handler = @field(vector_table, decl.name);
if (!@hasField(VectorTable, decl.name)) {
var msg: []const u8 = "There is no such interrupt as '" ++ decl.name ++ "', declarations in 'root.vector_table' must be one of:\n";
inline for (std.meta.fields(VectorTable)) |field| {
if (isValidField(field.name)) {
msg = msg ++ " " ++ field.name ++ "\n";
}
}
@compileError(msg);
}
if (!isValidField(decl.name))
@compileError("You are not allowed to specify '" ++ decl.name ++ "' in the vector table, for your sins you must now pay a $5 fine to the ZSF: https://github.com/sponsors/ziglang");
@field(temp, decl.name) = switch (calling_convention) {
.C => .{ .C = handler },
.Naked => .{ .Naked = handler },
// for unspecified calling convention we are going to generate small wrapper
.Unspecified => .{
.C = struct {
fn wrapper() callconv(.C) void {
if (calling_convention == .Unspecified) // TODO: workaround for some weird stage1 bug
@call(.{ .modifier = .always_inline }, handler, .{});
}
}.wrapper,
},
else => @compileError("unsupported calling convention for function " ++ decl.name),
};
}
}
break :blk temp;
};

@ -1,2 +1,3 @@
pub const cpu = @import("cpu");
pub const registers = @import("registers.zig");
pub const VectorTable = registers.VectorTable;

@ -1,4 +1,3 @@
const std = @import("std");
pub const cpu = @import("cpu");
pub const registers = @import("registers.zig");
pub const VectorTable = registers.VectorTable;

@ -3,6 +3,7 @@ const micro = @import("microzig");
pub const cpu = @import("cpu");
pub const registers = @import("registers.zig");
pub const VectorTable = registers.VectorTable;
pub fn parsePin(comptime spec: []const u8) type {
const invalid_format_msg = "The given pin '" ++ spec ++ "' has an invalid format. Pins must follow the format \"P{Port}{Pin}\" scheme.";

@ -5,7 +5,8 @@ const micro = @import("microzig");
// right now.
pub const panic = micro.panic;
pub const vector_table = struct {
pub const interrupts = struct {
pub fn SysTick() void {
@panic("hit systick!");
}

Loading…
Cancel
Save