/* 隔离单测: 传感数据三档上报调度 (与 iot_mqtt_publish_sensor Step2/3 同构) * 立即档: car_state 沿 → 直通门控 * 快速档: |variation|>10 → 300ms * 空闲档: interval (测试用 60s) */ #include #include #include #define THRESH 10 #define FAST_MS 300 #define IDLE_MS 60000 /* interval=60s */ #define NCOIL 4 typedef struct { int32_t variation; uint8_t car_state; } Coil; static uint8_t last_car[NCOIL]; static uint32_t last_pub; /* 返回 1=本轮发布 */ static int publish_step(uint32_t now, Coil *coils, int n) { uint8_t fast_mode = 0, car_edge = 0; int i; for (i = 0; i < n; i++) { if (last_car[i] != coils[i].car_state) { car_edge = 1; break; } int32_t v = coils[i].variation, av = (v>=0)?v:-v; if (av > THRESH) fast_mode = 1; } uint32_t itv = (fast_mode || car_edge) ? FAST_MS : IDLE_MS; if (!car_edge && last_pub != 0 && (now - last_pub) < itv) return 0; last_pub = now; for (i = 0; i < n; i++) last_car[i] = coils[i].car_state; /* 门控后刷新快照 */ return 1; } static int fails = 0; #define CHECK(c,m) do{ if(!(c)){ printf("FAIL: %s\n", m); fails++; } }while(0) int main(void) { Coil coils[NCOIL]; memset(coils, 0, sizeof(coils)); memset(last_car, 0, sizeof(last_car)); last_pub = 0; /* T1: 首发 (last_pub=0 直发) */ CHECK(publish_step(1000, coils, NCOIL) == 1, "T1 首发"); /* T2: 空闲档 — 平稳时 60s 内不发, 到点才发 */ CHECK(publish_step(1500, coils, NCOIL) == 0, "T2 空闲0.5s不发"); CHECK(publish_step(31000, coils, NCOIL) == 0, "T2 空闲30s不发"); CHECK(publish_step(61000, coils, NCOIL) == 1, "T2 空闲60s到点发"); /* T3: 立即档 — 进车沿, 距上次发布仅 50ms 也立即发 (旧版要等300ms) */ coils[1].car_state = 1; /* ch2 进车 */ CHECK(publish_step(61050, coils, NCOIL) == 1, "T3 进车沿距上次50ms仍立即发"); /* T4: 同一个沿不重复触发 — 快照已同步, 下一轮回到常规档 */ coils[1].variation = 53; /* 有车, variation高 → 快速档 */ CHECK(publish_step(61100, coils, NCOIL) == 0, "T4 沿已消费, 50ms后不再直通"); CHECK(publish_step(61350, coils, NCOIL) == 1, "T4 快速档300ms到点发"); /* T5: 快速档仍受 300ms 门控 (variation大但无沿) */ CHECK(publish_step(61500, coils, NCOIL) == 0, "T5 快速档150ms不发"); CHECK(publish_step(61650, coils, NCOIL) == 1, "T5 快速档300ms发"); /* T6: 出车沿同样立即 — 距上次仅 20ms */ coils[1].car_state = 0; coils[1].variation = 0; CHECK(publish_step(61670, coils, NCOIL) == 1, "T6 出车沿20ms立即发"); /* T7: 出车后平稳 → 回落空闲档 */ CHECK(publish_step(61970, coils, NCOIL) == 0, "T7 平稳300ms不发(已是空闲档)"); CHECK(publish_step(121670, coils, NCOIL) == 1, "T7 空闲60s到点发"); /* T8: 多通道同帧翻转 → 一次立即发布覆盖全部 (单包含4通道) */ coils[0].car_state = 1; coils[2].car_state = 1; CHECK(publish_step(121700, coils, NCOIL) == 1, "T8 双通道沿立即发"); CHECK(publish_step(121750, coils, NCOIL) == 0, "T8 快照已同步不重发"); printf(fails ? "\n== %d FAIL ==\n" : "\n== ALL PASS ==\n", fails); return fails; }