33 uint8_t emergency_stop;
35 uint32_t timestamp_ms;
37 uint32_t sequence_number;
43 uint32_t process_a_seq;
44 uint32_t process_b_seq;
45 volatile uint8_t ready_a;
46 volatile uint8_t ready_b;
47 volatile uint8_t process_a_healthy;
48 volatile uint8_t process_b_healthy;
49 uint32_t timestamp_ms;
52__attribute__((aligned(64)))
65 { .train_id = 101, .position = 500 },
66 { .train_id = 102, .position = 2500 },
67 { .train_id = 103, .position = 7500 },
70#define TRAIN_COUNT (sizeof(trains) / sizeof(trains[0]))
76static uint32_t crc32_checksum(
const uint8_t *data, uint32_t len)
78 uint32_t crc = 0xffffffff;
79 for (uint32_t i = 0; i < len; i++) {
80 uint8_t
byte = data[i];
81 crc = (crc >> 8) ^ (uint32_t)(crc ^ byte);
83 return crc ^ 0xffffffff;
90static train_command_t compute_train_command(uint32_t train_id, uint32_t position)
96 .timestamp_ms = (uint32_t)(time(NULL) * 1000) & 0xffffffff,
100 if (position < 1000) {
101 cmd.signal_state = 2;
102 cmd.speed_limit = 80;
103 }
else if (position < 5000) {
104 cmd.signal_state = 1;
105 cmd.speed_limit = 40;
106 }
else if (position < 9000) {
107 cmd.signal_state = 0;
110 cmd.emergency_stop = 1;
111 cmd.signal_state = 0;
115 uint8_t *cmd_bytes = (uint8_t *)&cmd;
116 cmd.checksum = crc32_checksum(cmd_bytes,
117 sizeof(cmd) -
sizeof(cmd.checksum));
126int main(
int argc,
char *argv[])
131 uint32_t cycle_count = 0;
132 uint32_t process_a_seq = 0;
134 fprintf(stderr,
"[EAST:A] Process A (Standby Channel A) starting\n");
135 fprintf(stderr,
"[EAST:A] Synchronizing with WEST (role: STANDBY)\n");
142 for (uint32_t i = 0; i < TRAIN_COUNT; i++) {
143 trains[i].position += (i + 1) * 3;
144 if (trains[i].position > 10000) {
145 trains[i].position = 10000;
150 for (uint32_t i = 0; i < TRAIN_COUNT; i++) {
155 cmd.sequence_number = process_a_seq;
157 shared_mem.cmd_a = cmd;
158 shared_mem.process_a_seq = process_a_seq;
159 __sync_synchronize();
160 shared_mem.ready_a = 1;
162 if (cycle_count % 10 == 0) {
164 "[EAST:A] Cycle %u (STANDBY): train=%u, pos=%u, sig=%u, speed=%u\n",
165 cycle_count, cmd.train_id, cmd.position,
166 cmd.signal_state, cmd.speed_limit);
170 shared_mem.process_a_healthy = 1;