Safe API Framework 0.1.0 build 384e6ae
Layered API framework for safety-related applications (ERTMS RBC reference targeting CENELEC EN 50128 SIL 4)
Loading...
Searching...
No Matches
process_c.c
Go to the documentation of this file.
1
9
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13#include <stdint.h>
14#include <unistd.h>
15#include <time.h>
16
17typedef struct {
18 uint32_t train_id;
19 uint32_t position;
20 uint8_t signal_state;
21 uint8_t emergency_stop;
22 uint16_t speed_limit;
23 uint32_t timestamp_ms;
24 uint32_t checksum;
25 uint32_t sequence_number;
27
28typedef struct {
29 train_command_t cmd_a;
30 train_command_t cmd_b;
31 uint32_t process_a_seq;
32 uint32_t process_b_seq;
33 volatile uint8_t ready_a;
34 volatile uint8_t ready_b;
35 volatile uint8_t process_a_healthy;
36 volatile uint8_t process_b_healthy;
37 uint32_t timestamp_ms;
39
40__attribute__((aligned(64)))
41extern shared_state_t shared_mem;
42
43typedef struct {
44 train_command_t voted_command;
45 uint8_t vote_result;
46 uint32_t voter_sequence;
47 char log_message[256];
48} voted_result_t;
49
50__attribute__((aligned(64)))
51static voted_result_t voted_result = {0};
52
53typedef struct {
54 uint32_t total_results;
55 uint32_t matches;
56 uint32_t mismatches;
57 uint32_t timeouts;
58 uint32_t process_a_errors;
59 uint32_t process_b_errors;
61
62static service_stats_t stats = {0};
63
64int main(int argc, char *argv[])
65{
66 (void)argc;
67 (void)argv;
68
69 uint32_t cycle_count = 0;
70 uint32_t last_voter_seq = 0;
71
72 printf("\n");
73 printf("╔════════════════════════════════════════════════════════════╗\n");
74 printf("║ EAST Site - Process C (Standby Service Channel) ║\n");
75 printf("║ Ready to display results if promoted to ONLINE ║\n");
76 printf("╚════════════════════════════════════════════════════════════╝\n");
77 printf("\n");
78
79 while (1) {
80 cycle_count++;
81
82 uint8_t process_a_healthy = shared_mem.process_a_healthy;
83 uint8_t process_b_healthy = shared_mem.process_b_healthy;
84
85 if (!process_a_healthy) {
86 stats.process_a_errors++;
87 printf("[EAST:C] ⚠️ Process A is NOT RESPONDING (STANDBY)\n");
88 }
89
90 if (!process_b_healthy) {
91 stats.process_b_errors++;
92 printf("[EAST:C] ⚠️ Process B is NOT RESPONDING (STANDBY)\n");
93 }
94
95 if (voted_result.voter_sequence != last_voter_seq) {
96 stats.total_results++;
97 last_voter_seq = voted_result.voter_sequence;
98
99 switch (voted_result.vote_result) {
100 case 0:
101 stats.matches++;
102 break;
103 case 1:
104 stats.mismatches++;
105 break;
106 case 2:
107 stats.timeouts++;
108 break;
109 }
110
111 printf("[EAST:C] Cycle %u (STANDBY mirrored): ", cycle_count);
112 printf("%s\n", voted_result.log_message);
113 }
114
115 if ((cycle_count % 20) == 0) {
116 printf("\n");
117 printf("┌────── EAST:C Statistics ──────┐\n");
118 printf("│ Role: STANDBY (ready to failover)\n");
119 printf("│ Total results mirrored: %u\n", stats.total_results);
120 printf("│ Matches: %u (%.0f%%)\n", stats.matches,
121 stats.total_results > 0 ?
122 (100.0 * stats.matches / stats.total_results) : 0.0);
123 printf("│ Mismatches: %u\n", stats.mismatches);
124 printf("│ A healthy: %s, B healthy: %s\n",
125 process_a_healthy ? "YES" : "NO ",
126 process_b_healthy ? "YES" : "NO ");
127 printf("└───────────────────────────────┘\n");
128 printf("\n");
129 }
130
131 usleep(50000);
132 }
133
134 return EXIT_SUCCESS;
135}