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;
53__attribute__((aligned(64)))
66 { .train_id = 101, .position = 500 },
67 { .train_id = 102, .position = 2500 },
68 { .train_id = 103, .position = 7500 },
71#define TRAIN_COUNT (sizeof(trains) / sizeof(trains[0]))
77static uint32_t crc32_checksum(
const uint8_t *data, uint32_t len)
79 uint32_t crc = 0xffffffff;
80 for (uint32_t i = 0; i < len; i++) {
81 uint8_t
byte = data[i];
82 crc = (crc >> 8) ^ (uint32_t)(crc ^ byte);
84 return crc ^ 0xffffffff;
91static train_command_t compute_train_command(uint32_t train_id, uint32_t position)
97 .timestamp_ms = (uint32_t)(time(NULL) * 1000) & 0xffffffff,
102 if (position < 1000) {
103 cmd.signal_state = 2;
104 cmd.speed_limit = 80;
105 }
else if (position < 5000) {
106 cmd.signal_state = 1;
107 cmd.speed_limit = 40;
108 }
else if (position < 9000) {
109 cmd.signal_state = 0;
112 cmd.emergency_stop = 1;
113 cmd.signal_state = 0;
118 uint8_t *cmd_bytes = (uint8_t *)&cmd;
119 cmd.checksum = crc32_checksum(cmd_bytes,
120 sizeof(cmd) -
sizeof(cmd.checksum));
129int main(
int argc,
char *argv[])
134 uint32_t cycle_count = 0;
135 uint32_t process_a_seq = 0;
137 fprintf(stderr,
"[WEST:A] Process A (Vital Channel A) starting\n");
138 fprintf(stderr,
"[WEST:A] Computing train commands every 25ms\n");
145 for (uint32_t i = 0; i < TRAIN_COUNT; i++) {
146 trains[i].position += (i + 1) * 3;
147 if (trains[i].position > 10000) {
148 trains[i].position = 10000;
153 for (uint32_t i = 0; i < TRAIN_COUNT; i++) {
158 cmd.sequence_number = process_a_seq;
161 shared_mem.cmd_a = cmd;
162 shared_mem.process_a_seq = process_a_seq;
163 __sync_synchronize();
164 shared_mem.ready_a = 1;
166 if (cycle_count % 10 == 0) {
168 "[WEST:A] Cycle %u: train=%u, pos=%u, sig=%u, speed=%u\n",
169 cycle_count, cmd.train_id, cmd.position,
170 cmd.signal_state, cmd.speed_limit);
175 shared_mem.process_a_healthy = 1;