Initial LinuxCNC WebAssembly workspace snapshot

This commit is contained in:
2026-08-20 18:21:15 +08:00
commit 5dd614c335
92 changed files with 200203 additions and 0 deletions

166
wasm-core/src/sim_hal.c Normal file
View File

@@ -0,0 +1,166 @@
#include "sim_hal.h"
#include <stddef.h>
#include <string.h>
typedef struct {
uint32_t used;
char name[SIM_HAL_NAME_CAPACITY];
sim_hal_value value;
} pin_entry;
typedef struct {
uint32_t used;
char name[SIM_HAL_NAME_CAPACITY];
uint32_t period;
} thread_entry;
typedef struct {
uint32_t used;
char name[SIM_HAL_NAME_CAPACITY];
uint32_t thread;
uint32_t calls;
uint32_t fail;
} function_entry;
typedef struct {
uint32_t tick;
pin_entry pins[SIM_HAL_PIN_CAPACITY];
thread_entry threads[SIM_HAL_THREAD_CAPACITY];
function_entry functions[SIM_HAL_FUNCTION_CAPACITY];
} hal_state;
static hal_state state;
static int valid_name(const char *name) {
return name != NULL && name[0] != '\0' && strlen(name) < SIM_HAL_NAME_CAPACITY;
}
static int find_pin(const char *name) {
uint32_t index;
for (index = 0; index < SIM_HAL_PIN_CAPACITY; ++index) {
if (state.pins[index].used && strcmp(state.pins[index].name, name) == 0) return (int)index;
}
return -1;
}
static int find_thread(const char *name) {
uint32_t index;
for (index = 0; index < SIM_HAL_THREAD_CAPACITY; ++index) {
if (state.threads[index].used && strcmp(state.threads[index].name, name) == 0) return (int)index;
}
return -1;
}
static int find_function(const char *name) {
uint32_t index;
for (index = 0; index < SIM_HAL_FUNCTION_CAPACITY; ++index) {
if (state.functions[index].used && strcmp(state.functions[index].name, name) == 0) return (int)index;
}
return -1;
}
void sim_hal_reset(void) {
memset(&state, 0, sizeof(state));
}
int32_t sim_hal_register_pin(const char *name, uint32_t type) {
uint32_t index;
if (!valid_name(name) || type < SIM_HAL_BIT || type > SIM_HAL_FLOAT) return SIM_HAL_ERR_ARGUMENT;
if (find_pin(name) >= 0) return SIM_HAL_ERR_DUPLICATE;
for (index = 0; index < SIM_HAL_PIN_CAPACITY; ++index) {
if (!state.pins[index].used) {
state.pins[index].used = 1;
strcpy(state.pins[index].name, name);
state.pins[index].value.type = type;
return SIM_HAL_OK;
}
}
return SIM_HAL_ERR_FULL;
}
int32_t sim_hal_set_pin(const char *name, sim_hal_value value) {
int index = find_pin(name);
if (index < 0) return SIM_HAL_ERR_NOT_FOUND;
if (value.type != state.pins[index].value.type) return SIM_HAL_ERR_TYPE;
if (value.type == SIM_HAL_BIT && value.value.bit > 1U) return SIM_HAL_ERR_RANGE;
state.pins[index].value = value;
return SIM_HAL_OK;
}
int32_t sim_hal_get_pin(const char *name, sim_hal_value *out) {
int index = find_pin(name);
if (index < 0 || out == NULL) return index < 0 ? SIM_HAL_ERR_NOT_FOUND : SIM_HAL_ERR_ARGUMENT;
*out = state.pins[index].value;
return SIM_HAL_OK;
}
int32_t sim_hal_connect(const char *source, const char *target) {
int source_index = find_pin(source);
int target_index = find_pin(target);
if (source_index < 0 || target_index < 0) return SIM_HAL_ERR_NOT_FOUND;
if (state.pins[source_index].value.type != state.pins[target_index].value.type) return SIM_HAL_ERR_CONNECTION;
state.pins[target_index].value = state.pins[source_index].value;
return SIM_HAL_OK;
}
int32_t sim_hal_register_thread(const char *name, uint32_t period_ticks) {
uint32_t index;
if (!valid_name(name) || period_ticks == 0U || period_ticks > 1000000U) return SIM_HAL_ERR_RANGE;
if (find_thread(name) >= 0) return SIM_HAL_ERR_DUPLICATE;
for (index = 0; index < SIM_HAL_THREAD_CAPACITY; ++index) {
if (!state.threads[index].used) {
state.threads[index].used = 1;
strcpy(state.threads[index].name, name);
state.threads[index].period = period_ticks;
return SIM_HAL_OK;
}
}
return SIM_HAL_ERR_FULL;
}
int32_t sim_hal_register_function(const char *thread, const char *name) {
uint32_t index;
int thread_index = find_thread(thread);
if (thread_index < 0) return SIM_HAL_ERR_NOT_FOUND;
if (!valid_name(name)) return SIM_HAL_ERR_ARGUMENT;
if (find_function(name) >= 0) return SIM_HAL_ERR_DUPLICATE;
for (index = 0; index < SIM_HAL_FUNCTION_CAPACITY; ++index) {
if (!state.functions[index].used) {
state.functions[index].used = 1;
strcpy(state.functions[index].name, name);
state.functions[index].thread = (uint32_t)thread_index;
return SIM_HAL_OK;
}
}
return SIM_HAL_ERR_FULL;
}
int32_t sim_hal_set_function_failure(const char *name, uint32_t fail) {
int index = find_function(name);
if (index < 0) return SIM_HAL_ERR_NOT_FOUND;
state.functions[index].fail = fail ? 1U : 0U;
return SIM_HAL_OK;
}
int32_t sim_hal_step(uint32_t ticks) {
uint32_t target = state.tick + ticks;
uint32_t tick;
uint32_t function_index;
for (tick = state.tick + 1U; tick <= target; ++tick) {
for (function_index = 0; function_index < SIM_HAL_FUNCTION_CAPACITY; ++function_index) {
function_entry *function = &state.functions[function_index];
if (!function->used || tick % state.threads[function->thread].period != 0U) continue;
if (function->fail) return SIM_HAL_ERR_FUNCTION;
function->calls += 1U;
}
}
state.tick = target;
return SIM_HAL_OK;
}
uint32_t sim_hal_tick(void) { return state.tick; }
uint32_t sim_hal_function_calls(const char *name) { int index = find_function(name); return index < 0 ? 0U : state.functions[index].calls; }
uint32_t sim_hal_pin_count(void) { uint32_t i, count = 0; for (i = 0; i < SIM_HAL_PIN_CAPACITY; ++i) count += state.pins[i].used; return count; }
uint32_t sim_hal_thread_count(void) { uint32_t i, count = 0; for (i = 0; i < SIM_HAL_THREAD_CAPACITY; ++i) count += state.threads[i].used; return count; }
uint32_t sim_hal_function_count(void) { uint32_t i, count = 0; for (i = 0; i < SIM_HAL_FUNCTION_CAPACITY; ++i) count += state.functions[i].used; return count; }