-
Notifications
You must be signed in to change notification settings - Fork 164
FreeRTOS microzig module #871
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,109 @@ | ||
| const std = @import("std"); | ||
| const microzig = @import("microzig"); | ||
|
|
||
| const freertos = @import("freertos"); | ||
| const freertos_os = freertos.OS; | ||
|
|
||
| const rp2xxx = microzig.hal; | ||
| const time = rp2xxx.time; | ||
| const gpio = rp2xxx.gpio; | ||
|
|
||
| const uart = rp2xxx.uart.instance.num(0); | ||
| const uart_tx_pin = gpio.num(0); | ||
|
|
||
| pub const microzig_options = microzig.Options{ | ||
| .log_level = .debug, | ||
| .logFn = rp2xxx.uart.log, | ||
| .cpu = .{ | ||
| .ram_vector_table = true, | ||
| }, | ||
| }; | ||
|
|
||
| pub fn main() !void { | ||
| uart_tx_pin.set_function(.uart); | ||
|
|
||
| uart.apply(.{ | ||
| .clock_config = rp2xxx.clock_config, | ||
| }); | ||
|
|
||
| rp2xxx.uart.init_logger(uart); | ||
|
|
||
| // Give it large stack because printing is demanding | ||
| _ = freertos_os.xTaskCreate(hello_task, "hello_task", freertos_os.MINIMAL_STACK_SIZE * 8, null, freertos_os.MAX_PRIORITIES - 1, null); | ||
|
|
||
| freertos_os.vTaskStartScheduler(); | ||
| } | ||
|
|
||
| pub fn hello_task(_: ?*anyopaque) callconv(.c) void { | ||
| var i: u32 = 0; | ||
| while (true) : (i += 1) { | ||
| std.log.info("Hello from FreeRTOS task {}", .{i}); | ||
| freertos_os.vTaskDelay(500); | ||
| } | ||
| } | ||
|
|
||
| /// | ||
| /// Some ugly glue code to implement required functions from FreeRTOS and Pico SDK | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why not tuck this into freertos root.zig?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is debatable and in future can change. This code require some access to hal and some parts can be duplicated/implemented with what wi have in microzig right now and some other part probably no, especially those that require accessing some shared resource that have to be done by one API (microzig API). I will put comment about that in this place. |
||
| /// - This can be improved later | ||
| /// - Multicore not supported yet - multicore_reset_core1 have to be implemented | ||
| /// | ||
| export fn panic_unsupported() callconv(.c) noreturn { | ||
| @panic("not supported"); | ||
| } | ||
|
|
||
| export fn irq_set_priority(num: c_uint, priority: u8) callconv(.c) void { | ||
| const p: *volatile u32 = @ptrFromInt(@intFromPtr(µzig.chip.peripherals.PPB.NVIC_IPR0) + (num >> 2)); | ||
| const shift: u5 = @intCast(8 * (@as(u32, @intCast(num)) & 3)); | ||
| const mask: u32 = @as(u32, 0xff) << shift; | ||
| p.* = (p.* & ~mask) | (@as(u32, priority) << shift); | ||
| } | ||
|
|
||
| export fn irq_set_enabled(_: c_uint, enabled: bool) callconv(.c) void { | ||
| if (enabled) { | ||
| microzig.cpu.interrupt.enable(@enumFromInt(0)); | ||
| } else { | ||
| microzig.cpu.interrupt.disable(@enumFromInt(0)); | ||
| } | ||
| } | ||
|
|
||
| export fn irq_set_exclusive_handler(_: u8) callconv(.c) void { | ||
| panic_unsupported(); | ||
| } | ||
|
|
||
| export fn multicore_launch_core1(entry: *const fn () callconv(.c) void) callconv(.c) void { | ||
| microzig.hal.multicore.launch_core1(@ptrCast(entry)); | ||
| } | ||
|
|
||
| export fn multicore_reset_core1() callconv(.c) void { | ||
| // TODO: please implement this in microzig.hal.multicore and call it here | ||
| } | ||
|
|
||
| export fn clock_get_hz(_: u32) callconv(.c) u32 { | ||
| std.log.info("clock_get_hz called", .{}); | ||
| // FIXME: this seems to return null | ||
| // return microzig.hal.clock_config.sys_freq.?; | ||
| return 125_000_000; | ||
| } | ||
|
|
||
| export fn spin_lock_claim(_: c_uint) callconv(.c) void {} | ||
|
|
||
| export fn next_striped_spin_lock_num() callconv(.c) c_uint { | ||
| return 16; | ||
| } | ||
|
|
||
| export fn exception_set_exclusive_handler(num: c_uint, handler: *const fn () callconv(.c) void) callconv(.c) void { | ||
| const cs = microzig.interrupt.enter_critical_section(); | ||
| defer cs.leave(); | ||
|
|
||
| // TODO: can this code be simplified? | ||
| if (num == 11) { | ||
| microzig.cpu.ram_vector_table.SVCall = .{ .c = handler }; | ||
| } else if (num == 14) { | ||
| microzig.cpu.ram_vector_table.PendSV = .{ .naked = @ptrCast(handler) }; | ||
| } else if (num == 15) { | ||
| microzig.cpu.ram_vector_table.SysTick = .{ .c = handler }; | ||
| } | ||
|
|
||
| // used in PicoSDK - do we need this? | ||
| asm volatile ("DMB" ::: .{ .memory = true }); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,99 @@ | ||
| const std = @import("std"); | ||
|
|
||
| const FreeRTOSPort = enum { | ||
Grazfather marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| RP2040, | ||
| RP2350_ARM, | ||
| RP2350_RISCV, | ||
| }; | ||
|
|
||
| pub fn build(b: *std.Build) void { | ||
| const target = b.standardTargetOptions(.{}); | ||
| const optimize = b.standardOptimizeOption(.{}); | ||
|
|
||
| // Configurable options | ||
| const port_name = b.option( | ||
| FreeRTOSPort, | ||
| "port_name", | ||
| "FreeRTOS port to use", | ||
| ) orelse .RP2040; | ||
|
|
||
| if (port_name != .RP2040) { | ||
| @panic("Right now only RP2040 port is supported"); | ||
| } | ||
|
|
||
| const foundationlibc_dep = b.dependency("foundationlibc", .{ | ||
| .target = target, | ||
| .optimize = optimize, | ||
| .single_threaded = true, | ||
| }); | ||
|
|
||
| const freertos_lib = b.addModule("freertos_lib", .{ | ||
| .target = target, | ||
| .optimize = optimize, | ||
| }); | ||
|
|
||
| // Link libc | ||
| freertos_lib.linkLibrary(foundationlibc_dep.artifact("foundation")); | ||
|
|
||
| const freertos_kernel_dep = b.dependency("freertos_kernel", .{}); | ||
|
|
||
| // Add FreeRTOS kernel source files | ||
| freertos_lib.addCSourceFiles(.{ | ||
| .root = freertos_kernel_dep.path("."), | ||
| .files = &files, | ||
| .flags = &flags, | ||
| }); | ||
|
|
||
| // FreeRTOS include paths | ||
| freertos_lib.addIncludePath(b.path("config")); | ||
| freertos_lib.addIncludePath(freertos_kernel_dep.path("include")); | ||
|
|
||
| // Add FreeRTOS port source files | ||
| freertos_lib.addCSourceFiles(.{ | ||
| .root = freertos_kernel_dep.path("./portable/ThirdParty/GCC/RP2040/"), | ||
| .files = &files_port, | ||
| .flags = &flags, | ||
| }); | ||
|
|
||
| // FreeRTOS port include paths | ||
| freertos_lib.addIncludePath(freertos_kernel_dep.path("./portable/ThirdParty/GCC/RP2040/include/")); | ||
|
|
||
| // Pico SDK include paths | ||
| freertos_lib.addIncludePath(b.path("picosdk/include_common/")); | ||
| freertos_lib.addIncludePath(b.path("picosdk/include_rp2040/")); | ||
|
|
||
| // TODO: USE addConfigHeader instead? | ||
| freertos_lib.addCMacro("configSMP_SPINLOCK_0", "PICO_SPINLOCK_ID_OS1"); | ||
| freertos_lib.addCMacro("configSMP_SPINLOCK_1", "PICO_SPINLOCK_ID_OS2"); | ||
|
|
||
| freertos_lib.addCMacro("LIB_PICO_MULTICORE", "0"); | ||
|
|
||
| // Had problems when this was enabled. | ||
| // Microzig but also Pico SDK? dont set VTOR to 0x10000100 for RP2040 at boot even when ram_vector_table is set to false | ||
| freertos_lib.addCMacro("PICO_NO_RAM_VECTOR_TABLE", "0"); | ||
|
|
||
| const mod = b.addModule("freertos", .{ .root_source_file = b.path("src/root.zig"), .target = target, .optimize = optimize }); | ||
| mod.addImport("freertos_lib", freertos_lib); | ||
|
|
||
| for (freertos_lib.c_macros.items) |m| { | ||
| mod.c_macros.append(b.allocator, m) catch @panic("out of memory"); | ||
| } | ||
| for (freertos_lib.include_dirs.items) |dir| { | ||
| mod.include_dirs.append(b.allocator, dir) catch @panic("out of memory"); | ||
| } | ||
| } | ||
|
|
||
| const flags = [_][]const u8{ "-std=c11", "-fno-sanitize=undefined", "-Wno-pointer-to-int-cast" }; | ||
| const files = [_][]const u8{ | ||
| "croutine.c", | ||
| "event_groups.c", | ||
| "list.c", | ||
| "queue.c", | ||
| "stream_buffer.c", | ||
| "tasks.c", | ||
| "timers.c", | ||
| "portable/MemMang/heap_1.c", | ||
| }; | ||
| const files_port = [_][]const u8{ | ||
| "port.c", | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| .{ | ||
| .name = .zig_rtos, | ||
| .version = "0.0.0", | ||
| .fingerprint = 0x5089c38a1e0691c8, // Changing this has security and trust implications. | ||
| .minimum_zig_version = "0.16.0-dev.2193+fc517bd01", | ||
| .dependencies = .{ | ||
| .freertos_kernel = .{ | ||
| .url = "git+https://github.com/FreeRTOS/FreeRTOS-Kernel.git#52822473466cfa5cdd2146d02dae5f924b8552e4", | ||
| .hash = "N-V-__8AAMb4CQGTaQBhmyNrZe5AydR8ZY3met6pGoXDe1MC", | ||
| }, | ||
| .freertos_kernel_community = .{ | ||
| .url = "git+https://github.com/FreeRTOS/FreeRTOS-Kernel-Community-Supported-Ports.git#9ab3b5fb235838b3fc03d4f1cdcfab22007413d2", | ||
| .hash = "N-V-__8AAPdlHQB-Q5duFJp5D3hmNoJsOsWXr84CsPai1Pk9", | ||
| }, | ||
| .foundationlibc = .{ | ||
| .path = "../foundation-libc/", | ||
| }, | ||
| }, | ||
| .paths = .{ "build.zig", "build.zig.zon", "src", "picosdk", "config" }, | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where did you pull this from? I think it would be nice to be able to have a hash on this.
Did you have to make any modifications?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this is new module created be me and sits next to lwip or fundation-libc. This module pulls freertos source code as dependency and provide glue code to produce zig wrapper around it.