Skip to content

Commit

Permalink
update doc
Browse files Browse the repository at this point in the history
  • Loading branch information
RecursiveError committed Feb 20, 2025
1 parent 51e26f0 commit 733ba7b
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 4 deletions.
4 changes: 4 additions & 0 deletions core/src/core/experimental.zig
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,8 @@ pub const i2c = @import("experimental/i2c.zig");
pub const Pin = @import("experimental/pin.zig").Pin;
pub const spi = @import("experimental/spi.zig");
pub const uart = @import("experimental/uart.zig");

///semihosting requires a valid host session, either via a simulator or via a debug probe, otherwise the code will always result in a halt.
///This implementation only supports Arm-M.
///More info: https://github.com/ARM-software/abi-aa/blob/main/semihosting/semihosting.rst
pub const ARM_semihosting = @import("experimental/semihosting.zig");
38 changes: 35 additions & 3 deletions core/src/core/experimental/semihosting.zig
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ pub const Debug = struct {
subcode: usize,
};

pub const MemInfo = extern struct {
heap_base: *anyopaque,
heap_limit: *anyopaque,
stack_base: *anyopaque,
stack_limit: *anyopaque,
};

//WriteC and Write0 write direct to the Debug terminal, no context need
const Writer = std.io.Writer(void, anyerror, writerfn);

Expand Down Expand Up @@ -66,11 +73,12 @@ pub const Debug = struct {
dbg_w.print(fmt, args) catch return;
}

//get C errno value
///get C errno value
pub fn get_errno() usize {
resume @as(usize, @bitCast(sys_errno()));
}
///get ARGV from the command line.

///get data from the command line.
/// NOTE: The semihosting implementation might impose limits on the maximum length of the string that can be transferred.
/// However, the implementation must be able to support a command-line length of at least 80 bytes.
pub fn get_cmd_args(buffer: []u8) anyerror![]const u8 {
Expand All @@ -82,6 +90,7 @@ pub const Debug = struct {
return if (ret == 0) cmd.buffer[0..cmd.len] else error.Fail;
}

//currently the semihost specification defines only 2 extensions, where both belong to the same extension byte.
pub fn check_extensions(feature_byte: usize, feature_bit: u3) bool {
const MAGIC: [4]u8 = .{ 0x53, 0x48, 0x46, 0x42 };
var magic_buffer: [4]u8 = undefined;
Expand Down Expand Up @@ -121,17 +130,29 @@ pub const Debug = struct {
return try fs.open(":tt", .@"A+");
}

pub fn system_memory() MemInfo {
var mem: MemInfo = undefined;
sys_heapinfo(&mem);
return mem;
}

///Signals an exception to the debugger
/// NOTE: Not all semihosting client implementations will necessarily trap every corresponding event.
/// NOTE: It is possible for the debugger to request that the application continues by performing an RDI_Execute request or equivalent.
pub fn panic(reason: PanicCodes, subcode: usize) void {
const data = PanicData{
.reason = @intFromEnum(reason) + 0x20000,
.subcode = subcode,
};
//check for EXIT_EXT

//check for EXIT_EXT
//when the exit extension is not implemented on 32bit targets
//sys_exit does not receive "exit code"
if (check_extensions(0, 0)) {
_ = sys_exit_ext(&data);
} else {
//ARM-A/M 32bit only
//on 32bit targets sys_exit receives data by value and not by reference
_ = sys_exit(@ptrFromInt(data.reason));
}
}
Expand Down Expand Up @@ -330,6 +351,7 @@ pub const Syscalls = enum(usize) {
WRITE0 = 0x04,
SYS_WRITE = 0x05,
SYS_READ = 0x06,
SYS_ISERROR = 0x08,
SYS_ISTTY = 0x09,
SYS_SEEK = 0x0A,
SYS_FLEN = 0x0C,
Expand All @@ -339,6 +361,7 @@ pub const Syscalls = enum(usize) {
SYS_TIME = 0x11,
SYS_ERRNO = 0x13,
SYS_GET_CMD_LINE = 0x15,
SYS_HEAPINFO = 0x16,
SYS_EXIT = 0x18,
SYS_EXIT_EXTENDED = 0x20,
SYS_ELAPSED = 0x30,
Expand Down Expand Up @@ -401,6 +424,11 @@ pub inline fn sys_rename(file: [*]const fs.Path) isize {
return call(.SYS_RENAME, file);
}

//only useful when using syscalls directly
pub inline fn sys_iserror(ret_code: *const isize) bool {
return call(.SYS_ISERROR, ret_code) != 0;
}

pub inline fn sys_istty(file: *const fs.File) isize {
return call(.SYS_ISTTY, file);
}
Expand All @@ -421,6 +449,10 @@ pub inline fn sys_cmd_line(args: *Debug.Argv) isize {
return call(.SYS_GET_CMD_LINE, args);
}

pub inline fn sys_heapinfo(args: *Debug.MemInfo) void {
_ = call(.SYS_HEAPINFO, args);
}

pub inline fn sys_exit(args: *const Debug.PanicData) isize {
return call(.SYS_EXIT, args);
}
Expand Down
2 changes: 1 addition & 1 deletion examples/stmicro/stm32/build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ pub fn build(b: *std.Build) void {
const available_examples = [_]Example{
.{ .target = stm32.chips.STM32F103C8, .name = "STM32F103C8", .file = "src/blinky.zig" },
.{ .target = stm32.boards.stm32f3discovery, .name = "stm32f3discovery", .file = "src/blinky.zig" },
.{ .target = stm32.chips.STM32F100RB, .name = "STM32F1_semihost", .file = "src/semihosting.zig" }, //set a valid qemu target for test semihosting
// TODO: stm32.pins.GlobalConfiguration is not available on those targets
// .{ .target = stm32.chips.stm32f303vc, .name = "stm32f303vc", .file = "src/blinky.zig" },
// .{ .target = stm32.chips.stm32f407vg, .name = "stm32f407vg", .file = "src/blinky.zig" },
// .{ .target = stm32.chips.stm32f429zit6u, .name = "stm32f429zit6u", .file = "src/blinky.zig" },
// .{ .target = stm32.boards.stm32f4discovery, .name = "stm32f4discovery", .file = "src/blinky.zig" },
// .{ .target = stm32.boards.stm3240geval, .name = "stm3240geval", .file = "src/blinky.zig" },
// .{ .target = stm32.boards.stm32f429idiscovery, .name = "stm32f429idiscovery", .file = "src/blinky.zig" },
.{ .target = stm32.chips.STM32F100RB, .name = "STM32F1_semihost", .file = "src/semihosting.zig" }, //QEMU target: stm32vldiscovery
};

for (available_examples) |example| {
Expand Down

0 comments on commit 733ba7b

Please sign in to comment.