- make-uefi-iso.sh: UEFI ISO image builder - test_boot.S, test_boot.ld: test boot assembly and linker script - eim_config.toml: EIM (External Interface Module) configuration - edk2-ovmf RPM for UEFI firmware - GAP_ANALYSIS_PIKEOS_PARITY.md: PikeOS parity gap analysis
145 lines
4.3 KiB
C
145 lines
4.3 KiB
C
/*
|
|
* UniversalisOS — Bug fixes test
|
|
*
|
|
* Tests:
|
|
* - Schedule table with task pointers (not pool indices)
|
|
* - Software timers (uos_timer_create/start/stop)
|
|
* - Budget overrun after task delete should NOT fire
|
|
* - Stack high-water mark
|
|
*/
|
|
#include "freertos/freertos.h"
|
|
#include "uos_api.h"
|
|
#include "uos_hrt.h"
|
|
#include "uos_sched_table.h"
|
|
#include "uos_timer_wheel.h"
|
|
#include "uos_port.h"
|
|
|
|
#define UART0_DR (*(volatile uint32_t*)0x4000C000)
|
|
static void putc(char c) { UART0_DR = c; }
|
|
static void puts(const char *s) { while (*s) putc(*s++); }
|
|
static void putnum(uint32_t n) {
|
|
char buf[10]; int i = 0;
|
|
if (n == 0) { putc('0'); return; }
|
|
while (n > 0) { buf[i++] = '0' + (n % 10); n /= 10; }
|
|
while (i > 0) putc(buf[--i]);
|
|
}
|
|
|
|
static StackType_t stack1[256] __attribute__((aligned(8)));
|
|
static StackType_t stack2[256] __attribute__((aligned(8)));
|
|
static StackType_t stack3[256] __attribute__((aligned(8)));
|
|
|
|
/* Task handles — needed for schedule table entries (pointer-based) */
|
|
static TaskHandle_t hT1, hT2, hT3;
|
|
|
|
/* Software timer callback */
|
|
static volatile int g_timer_fired;
|
|
static void timer_cb(void* arg) __attribute__((used));
|
|
static void timer_cb(void* arg) {
|
|
static void (*volatile g_timer_cb_ptr)(void*) = timer_cb; (void)g_timer_cb_ptr;
|
|
(void)arg;
|
|
g_timer_fired++;
|
|
}
|
|
|
|
/* HRT protection hook — count violations */
|
|
static volatile int g_violations;
|
|
static uos_hrt_action_t hrt_hook(uos_hrt_violation_t v, uos_task_t* t, uos_tick_t val) {
|
|
(void)v; (void)t; (void)val;
|
|
g_violations++;
|
|
return UOS_HRT_ACTION_IGNORE;
|
|
}
|
|
|
|
/* Task 1 */
|
|
static void task1(void *arg) {
|
|
(void)arg;
|
|
uos_task_t* self = uos_task_self();
|
|
uos_hrt_set_exec_budget(self, 3);
|
|
for (int i = 0; i < 3; i++) {
|
|
puts("[T1] t="); putnum(uos_tick_get()); puts("\n");
|
|
vTaskDelay(10);
|
|
}
|
|
uint32_t used = uos_task_stack_used(self);
|
|
puts("[T1] stack="); putnum(used); puts("/256\n");
|
|
puts("[T1] done\n");
|
|
vTaskDelete(NULL);
|
|
}
|
|
|
|
/* Task 2 */
|
|
static void task2(void *arg) {
|
|
(void)arg;
|
|
for (int i = 0; i < 3; i++) {
|
|
puts("[T2] t="); putnum(uos_tick_get()); puts("\n");
|
|
vTaskDelay(10);
|
|
}
|
|
puts("[T2] done\n");
|
|
vTaskDelete(NULL);
|
|
}
|
|
|
|
/* Task 3 */
|
|
static void task3(void *arg) {
|
|
(void)arg;
|
|
for (int i = 0; i < 3; i++) {
|
|
puts("[T3] t="); putnum(uos_tick_get()); puts("\n");
|
|
vTaskDelay(10);
|
|
}
|
|
puts("[T3] done\n");
|
|
vTaskDelete(NULL);
|
|
}
|
|
|
|
int main(void) {
|
|
uos_init();
|
|
uos_hrt_set_hook(hrt_hook);
|
|
|
|
puts("\n=== Bug Fix Test ===\n");
|
|
|
|
/* Create tasks FIRST so we have valid pointers for schedule entries */
|
|
hT1 = xTaskCreateStatic(task1, "T1", 256, NULL, 3, stack1, NULL);
|
|
hT2 = xTaskCreateStatic(task2, "T2", 256, NULL, 2, stack2, NULL);
|
|
hT3 = xTaskCreateStatic(task3, "T3", 256, NULL, 1, stack3, NULL);
|
|
|
|
/* Get the underlying uos_task_t* for schedule table entries */
|
|
uos_task_t* ut1 = pvTaskGetUosTask(hT1);
|
|
uos_task_t* ut2 = pvTaskGetUosTask(hT2);
|
|
uos_task_t* ut3 = pvTaskGetUosTask(hT3);
|
|
|
|
/* Schedule table with task POINTERS (Bug 1 fix) */
|
|
static const uos_sched_entry_t entries[] = {
|
|
{ 0, NULL, 0, 0 }, /* Placeholder — filled at runtime below */
|
|
};
|
|
(void)entries; /* We use a mutable copy instead */
|
|
|
|
static uos_sched_entry_t rt_entries[3];
|
|
rt_entries[0].offset = 0;
|
|
rt_entries[0].task = ut1;
|
|
rt_entries[0].event_mask = 0;
|
|
rt_entries[0].flags = UOS_SCHED_ENTRY_ACTIVATE;
|
|
|
|
rt_entries[1].offset = 5;
|
|
rt_entries[1].task = ut2;
|
|
rt_entries[1].event_mask = 0;
|
|
rt_entries[1].flags = UOS_SCHED_ENTRY_ACTIVATE;
|
|
|
|
rt_entries[2].offset = 8;
|
|
rt_entries[2].task = ut3;
|
|
rt_entries[2].event_mask = 0;
|
|
rt_entries[2].flags = UOS_SCHED_ENTRY_ACTIVATE;
|
|
|
|
static uos_sched_table_t table = {
|
|
.name = "fix", .period = 10, .num_entries = 3,
|
|
.entries = rt_entries,
|
|
};
|
|
|
|
uos_sched_table_register(&table);
|
|
uos_sched_table_start(&table, 0);
|
|
|
|
vTaskStartScheduler();
|
|
|
|
/* After all tasks complete, check violations */
|
|
puts("\n=== Results ===\n");
|
|
puts("HRT violations after delete: "); putnum(g_violations); puts("\n");
|
|
if (g_violations == 0) {
|
|
puts("PASS: No spurious violations after task delete\n");
|
|
} else {
|
|
puts("FAIL: Violations fired for deleted tasks\n");
|
|
}
|
|
for (;;) ;
|
|
}
|