Added the zig_main project to software for zig based implementation of code for robot

This commit is contained in:
2026-05-05 20:14:04 +12:00
parent 7d752f2534
commit f21f909a71
83 changed files with 13631 additions and 0 deletions

View File

@@ -0,0 +1,233 @@
// Zig wrappers for ESP-IDF's POSIX pthread implementation (backed by FreeRTOS).
//
// Symbols come from idf-sys.zig (generated by `zig translate-c include/stubs.h`
// with ESP_IDF_COMP_PTHREAD_ENABLED defined, which pulls in pthread.h and
// esp_pthread.h).
//
// Error handling:
// POSIX pthread_* functions return 0 on success, errno on failure → `check()`.
// ESP-IDF esp_pthread_* functions return esp_err_t → `errors.espCheckError()`.
const sys = @import("sys");
const errors = @import("error");
// ---------------------------------------------------------------------------
// Error helper for POSIX-style return codes
// ---------------------------------------------------------------------------
pub const Error = error{PthreadError};
fn check(rc: c_int) Error!void {
if (rc != 0) return error.PthreadError;
}
// ---------------------------------------------------------------------------
// Type aliases (from idf-sys)
// ---------------------------------------------------------------------------
pub const Thread_t = sys.pthread_t;
pub const Attr_t = sys.pthread_attr_t;
pub const Mutex_t = sys.pthread_mutex_t;
pub const MutexAttr_t = sys.pthread_mutexattr_t;
pub const Cond_t = sys.pthread_cond_t;
pub const CondAttr_t = sys.pthread_condattr_t;
pub const Key_t = sys.pthread_key_t;
pub const Once_t = sys.pthread_once_t;
pub const SchedParam = sys.sched_param;
pub const Timespec = sys.timespec;
/// ESP-IDF-specific pthread configuration (stack size, priority, core pinning, etc.).
pub const EspCfg = sys.esp_pthread_cfg_t;
// ---------------------------------------------------------------------------
// Thread — lifecycle & identity
// ---------------------------------------------------------------------------
pub const Thread = struct {
/// Create a thread with optional attributes. Returns the thread ID.
pub fn create(
attr: ?*const Attr_t,
start_fn: *const fn (?*anyopaque) callconv(.c) ?*anyopaque,
arg: ?*anyopaque,
) !Thread_t {
var tid: Thread_t = undefined;
try check(sys.pthread_create(&tid, attr, start_fn, arg));
return tid;
}
/// Wait for a thread to terminate; returns its exit value.
pub fn join(tid: Thread_t) !?*anyopaque {
var value: ?*anyopaque = null;
try check(sys.pthread_join(tid, &value));
return value;
}
/// Detach a thread so its resources are freed automatically on exit.
pub fn detach(tid: Thread_t) !void {
try check(sys.pthread_detach(tid));
}
/// Terminate the calling thread with `retval`.
pub fn exit(retval: ?*anyopaque) noreturn {
sys.pthread_exit(retval);
unreachable;
}
/// Return the thread ID of the calling thread.
pub fn self() Thread_t {
return sys.pthread_self();
}
/// Return `true` if two thread IDs refer to the same thread.
pub fn equal(t1: Thread_t, t2: Thread_t) bool {
return sys.pthread_equal(t1, t2) != 0;
}
/// Yield the processor to another ready thread.
pub fn yield() void {
sys.pthread_yield();
}
};
// ---------------------------------------------------------------------------
// Thread attributes
// ---------------------------------------------------------------------------
pub const Attr = struct {
pub fn init(attr: *Attr_t) !void {
try check(sys.pthread_attr_init(attr));
}
pub fn deinit(attr: *Attr_t) !void {
try check(sys.pthread_attr_destroy(attr));
}
pub fn setStackSize(attr: *Attr_t, size: usize) !void {
try check(sys.pthread_attr_setstacksize(attr, size));
}
pub fn getStackSize(attr: *const Attr_t) !usize {
var sz: usize = 0;
try check(sys.pthread_attr_getstacksize(attr, &sz));
return sz;
}
pub fn setDetachState(attr: *Attr_t, state: c_int) !void {
try check(sys.pthread_attr_setdetachstate(attr, state));
}
pub fn getDetachState(attr: *const Attr_t) !c_int {
var s: c_int = 0;
try check(sys.pthread_attr_getdetachstate(attr, &s));
return s;
}
pub fn setSchedParam(attr: *Attr_t, param: *const SchedParam) !void {
try check(sys.pthread_attr_setschedparam(attr, param));
}
pub fn getSchedParam(attr: *const Attr_t) !SchedParam {
var p: SchedParam = .{};
try check(sys.pthread_attr_getschedparam(attr, &p));
return p;
}
};
// ---------------------------------------------------------------------------
// Mutex
// ---------------------------------------------------------------------------
pub const Mutex = struct {
pub fn init(mutex: *Mutex_t, attr: ?*const MutexAttr_t) !void {
try check(sys.pthread_mutex_init(mutex, attr));
}
pub fn deinit(mutex: *Mutex_t) !void {
try check(sys.pthread_mutex_destroy(mutex));
}
pub fn lock(mutex: *Mutex_t) !void {
try check(sys.pthread_mutex_lock(mutex));
}
pub fn tryLock(mutex: *Mutex_t) !void {
try check(sys.pthread_mutex_trylock(mutex));
}
pub fn unlock(mutex: *Mutex_t) !void {
try check(sys.pthread_mutex_unlock(mutex));
}
pub fn timedLock(mutex: *Mutex_t, timeout: *const Timespec) !void {
try check(sys.pthread_mutex_timedlock(mutex, timeout));
}
};
// ---------------------------------------------------------------------------
// Condition variable
// ---------------------------------------------------------------------------
pub const Cond = struct {
pub fn init(cond: *Cond_t, attr: ?*const CondAttr_t) !void {
try check(sys.pthread_cond_init(cond, attr));
}
pub fn deinit(cond: *Cond_t) !void {
try check(sys.pthread_cond_destroy(cond));
}
pub fn wait(cond: *Cond_t, mutex: *Mutex_t) !void {
try check(sys.pthread_cond_wait(cond, mutex));
}
pub fn timedWait(cond: *Cond_t, mutex: *Mutex_t, abstime: *const Timespec) !void {
try check(sys.pthread_cond_timedwait(cond, mutex, abstime));
}
pub fn signal(cond: *Cond_t) !void {
try check(sys.pthread_cond_signal(cond));
}
pub fn broadcast(cond: *Cond_t) !void {
try check(sys.pthread_cond_broadcast(cond));
}
};
// ---------------------------------------------------------------------------
// Thread-local storage (TLS) keys
// ---------------------------------------------------------------------------
pub const Key = struct {
pub fn create(destructor: ?*const fn (?*anyopaque) callconv(.c) void) !Key_t {
var key: Key_t = undefined;
try check(sys.pthread_key_create(&key, destructor));
return key;
}
pub fn delete(key: Key_t) !void {
try check(sys.pthread_key_delete(key));
}
pub fn setSpecific(key: Key_t, value: ?*const anyopaque) !void {
try check(sys.pthread_setspecific(key, value));
}
pub fn getSpecific(key: Key_t) ?*anyopaque {
return sys.pthread_getspecific(key);
}
};
// ---------------------------------------------------------------------------
// Once-only initialisation
// ---------------------------------------------------------------------------
pub fn once(once_ctrl: *Once_t, init_fn: *const fn () callconv(.c) void) !void {
try check(sys.pthread_once(once_ctrl, init_fn));
}
// ---------------------------------------------------------------------------
// ESP-IDF pthread extensions (esp_pthread.h)
// ---------------------------------------------------------------------------
pub const EspThread = struct {
/// Return a default ESP pthread configuration populated from menuconfig values.
pub fn getDefaultConfig() EspCfg {
return sys.esp_pthread_get_default_config();
}
/// Set per-thread creation parameters for the next `pthread_create()` call.
/// Overrides stack size, priority, core affinity, and thread name.
pub fn setConfig(cfg: *const EspCfg) !void {
try errors.espCheckError(sys.esp_pthread_set_cfg(cfg));
}
/// Retrieve the currently active ESP pthread configuration.
pub fn getConfig(cfg: *EspCfg) !void {
try errors.espCheckError(sys.esp_pthread_get_cfg(cfg));
}
/// Initialise the ESP pthread library (called internally by ESP-IDF startup).
pub fn init() !void {
try errors.espCheckError(sys.esp_pthread_init());
}
};