Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 23 additions & 12 deletions core/src/core/experimental/semihosting.zig
Original file line number Diff line number Diff line change
Expand Up @@ -58,29 +58,40 @@ pub const Debug = struct {
len: usize,
};

fn drain(_: *std.Io.Writer, data: []const []const u8, splat: usize) std.Io.Writer.Error!usize {
_ = splat;
// TODO: implement splat
fn drain(io_w: *std.Io.Writer, data: []const []const u8, splat: usize) std.Io.Writer.Error!usize {
const buf = io_w.buffered();

var ret: usize = 0;
for (data) |d| {
if (buf.len > 0) {
ret += try writerfn({}, buf);
_ = io_w.consumeAll();
}
for (data[0 .. data.len - 1]) |d| {
ret += try writerfn({}, d);
}
for (0..splat) |_| {
const to_splat = data[data.len - 1];
ret += try writerfn({}, to_splat);
}

return ret;
}

//this is ssssssslow but WriteC is even more slow and Write0 requires '\0' sentinel
fn writerfn(_: void, data: []const u8) std.Io.Writer.Error!usize {
var len = data.len;
const len = data.len;
if (len == 0) return 0;

if (len != 1) {
const tmp_c = data[len - 1]; //check if last char is a sentinel
if (tmp_c != 0) {
len -= 1; //last char is gonna be change to '\0'
// Temporarily change last char to null byte
var tmp_data: []u8 = @constCast(data);
tmp_data[len] = 0;
tmp_data[len - 1] = 0;
write0(@ptrCast(tmp_data.ptr));
tmp_data[len] = tmp_c;
tmp_data[len - 1] = tmp_c;
// Write the last character separately
write_byte(tmp_c);
return len;
}
write0(@ptrCast(data.ptr));
Expand Down Expand Up @@ -121,18 +132,18 @@ pub const Debug = struct {
const MAGIC: [4]u8 = .{ 0x53, 0x48, 0x46, 0x42 };
var magic_buffer: [4]u8 = undefined;

//try open extension file
// Try opening the extension file
const ext_file = fs.open(":semihosting-features", .R) catch return false;

//check the size
// Check the size
const byte_size = ext_file.size() catch return false;
if (byte_size < (MAGIC.len + feature_byte + 1)) return false;

var read_buf: [256]u8 = undefined;
var file_reader = ext_file.reader(&read_buf);
_ = file_reader.interface.readSliceShort(&magic_buffer) catch return false;

//check the magic number
// Check the magic number
for (magic_buffer, MAGIC) |number, magic| {
if (number != magic) return false;
}
Expand Down Expand Up @@ -459,7 +470,7 @@ fn call(number: Syscalls, param: *const anyopaque) isize {
return asm volatile (
\\mov r0, %[num]
\\mov r1, %[p]
\\BKPT #0xAB
\\bkpt #0xAB
\\mov %[ret], r0
: [ret] "=r" (-> isize),
: [num] "r" (number),
Expand Down
1 change: 1 addition & 0 deletions examples/nordic/nrf5x/build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ pub fn build(b: *std.Build) void {
.{ .target = nrf52840_mdk, .name = "nrf52840_mdk_i2c_hall_effect", .file = "src/i2c_hall_effect.zig" },
.{ .target = nrf52840_mdk, .name = "nrf52840_mdk_i2c_temp", .file = "src/i2c_temp.zig" },
.{ .target = nrf52840_mdk, .name = "nrf52840_mdk_rtt_log", .file = "src/rtt_log.zig" },
.{ .target = nrf52840_mdk, .name = "nrf52840_mdk_semihosting", .file = "src/semihosting.zig" },
.{ .target = nrf52840_mdk, .name = "nrf52840_mdk_spi_master", .file = "src/spi_master.zig" },

.{ .target = pca10040, .name = "pca10040_blinky", .file = "src/blinky.zig" },
Expand Down
61 changes: 61 additions & 0 deletions examples/nordic/nrf5x/src/semihosting.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
const std = @import("std");
const microzig = @import("microzig");
const board = microzig.board;
const nrf = microzig.hal;

const semihosting = microzig.core.experimental.ARM_semihosting;

pub fn main() void {
board.init();
const path = "";
const file_name = path ++ "foo.txt";
const new_name = path ++ "bar.txt";
var some_buf: [80]u8 = undefined;

// Debug features
semihosting.Debug.print("Hello World\n", .{});

const args = semihosting.Debug.get_cmd_args(&some_buf) catch return;
semihosting.Debug.print("receive args: {s}\n", .{args});

semihosting.Debug.print("feature support: STDOUT FILE: {any}, EXIT CODE {any}\n", .{
semihosting.Debug.check_extensions(0, 1),
semihosting.Debug.check_extensions(0, 0),
});

const stdout = semihosting.Debug.stdout() catch return;
stdout.print("hello STDOUT!!!!\n", .{});

// Time features
const clock = semihosting.Time.absolute();
const host_time = semihosting.Time.system_time();

// fs features
const file = semihosting.fs.open(file_name, .@"W+") catch {
semihosting.Debug.print("fail to open {s}!", .{file_name});
return;
};

file.print("[{any}:{d}] | Hello File {s} id {d}", .{
clock,
host_time,
file_name,
@intFromEnum(file),
});

const f_size = file.size() catch return;

semihosting.Debug.print("now file has size {d}\n", .{f_size});
file.close() catch {
semihosting.Debug.print("fail to close {s}!", .{file_name});
return;
};

semihosting.fs.rename(file_name, new_name) catch {
semihosting.Debug.print("fail to rename {s} to {s}", .{ file_name, new_name });
};

semihosting.Debug.exit(0);

while (true) {}
}
6 changes: 3 additions & 3 deletions examples/stmicro/stm32/src/semihosting.zig
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pub fn main() void {
const new_name = path ++ "bar.txt";
var some_buf: [80]u8 = undefined;

//debug features
// Debug features
semihosting.Debug.print("Hello World\n", .{});

const args = semihosting.Debug.get_cmd_args(&some_buf) catch return;
Expand All @@ -22,11 +22,11 @@ pub fn main() void {
const stdout = semihosting.Debug.stdout() catch return;
stdout.print("hello STDOUT!!!!\n", .{});

//time features
// Time features
const clock = semihosting.Time.absolute();
const host_time = semihosting.Time.system_time();

//fs features
// fs features
const file = semihosting.fs.open(file_name, .@"W+") catch {
semihosting.Debug.print("fail to open {s}!", .{file_name});
return;
Expand Down
Loading