#include "tasks.h" #include #include #include #include "ina226.h" /* 优先级的绝对值本身不重要,**相对顺序**才是 §10.3 定的东西。 留出空档(6/4/4/3/1)是为了以后插一个任务时不用整体重排 —— 重排的那次 一定会有人只改一半。 */ #define PRIO_SAFETY 6 #define PRIO_THERMAL 4 #define PRIO_ACTUATOR 4 #define PRIO_LINK 3 #define PRIO_LOG 1 static const task_desc_t s_tasks[TASK_COUNT] = { [TASK_SAFETY] = { "t_safety", 20, PRIO_SAFETY, 4096 }, [TASK_THERMAL] = { "t_thermal", 1000, PRIO_THERMAL, 3072 }, /* 执行器要跑三个状态机 + 超时兜底,栈给足;link 要收发帧与 JSON,最费。 */ [TASK_ACTUATOR] = { "t_actuator", 0, PRIO_ACTUATOR, 4096 }, [TASK_LINK] = { "t_link", 0, PRIO_LINK, 6144 }, [TASK_LOG] = { "t_log", 0, PRIO_LOG, 3072 }, }; const task_desc_t *task_desc(task_id_t id) { assert(id >= 0 && id < TASK_COUNT); return &s_tasks[id]; } bool task_table_ok(void) { for (int i = 0; i < TASK_COUNT; i++) { const task_desc_t *a = &s_tasks[i]; if (a->name == NULL || a->name[0] == '\0' || a->stack_bytes < 2048) { return false; } for (int j = i + 1; j < TASK_COUNT; j++) { if (strcmp(a->name, s_tasks[j].name) == 0) { return false; } } } /* 周期:§10.3 那一列,逐格钉死。 */ if (s_tasks[TASK_SAFETY].period_ms != 20 || s_tasks[TASK_THERMAL].period_ms != 1000) { return false; } if (s_tasks[TASK_ACTUATOR].period_ms != 0 || s_tasks[TASK_LINK].period_ms != 0 || s_tasks[TASK_LOG].period_ms != 0) { return false; } /* 优先级:t_safety 唯一最高、t_log 唯一最低。 */ for (int i = 0; i < TASK_COUNT; i++) { if (i != TASK_SAFETY && s_tasks[i].prio >= s_tasks[TASK_SAFETY].prio) { return false; } if (i != TASK_LOG && s_tasks[i].prio <= s_tasks[TASK_LOG].prio) { return false; } } if (s_tasks[TASK_THERMAL].prio != s_tasks[TASK_ACTUATOR].prio) { return false; /* §10.3 里两个都是「中」 */ } if (s_tasks[TASK_LINK].prio >= s_tasks[TASK_THERMAL].prio) { return false; } /* 巡检周期要长于 INA226 的一帧转换时间(见 tasks.h 的最后一条)。 */ if (s_tasks[TASK_SAFETY].period_ms * 1000u <= (uint32_t)INA226_CONV_US) { return false; } return true; }