* // 1. Create two underlying IPC channels (one per CPU)
* sapi_buffer_t channel_a_buf, channel_b_buf;
* sapi_buffer_init(&channel_a_buf, storage_a, capacity_a);
* sapi_buffer_init(&channel_b_buf, storage_b, capacity_b);
*
* // 2. Create vital channel that wraps both with 2oo2 voting
* sapi_buffer_t channels[2] = {channel_a_buf, channel_b_buf};
* sapi_channel_config_t config = {
* .name = "dual_redundant_signal",
* .strategy = SAPI_VOTING_2OO2,
* .channels = channels,
* .num_channels = 2,
* .on_disagreement = handle_cpu_fault,
* .timeout_ms = 100
* };
*
* sapi_channel_t vital_ch;
* sapi_vital_channel_create(&vital_ch, &config);
*
* // 3. Send command to both CPUs
* signal_command_t cmd = {.signal_id = 5, .state = SIGNAL_RED};
* sapi_status_t status = sapi_vital_send(vital_ch, &cmd, sizeof(cmd), 100);
*
* if (status != SAPI_STATUS_OK) {
* sapi_log_error("Send failed: %d", status);
* sapi_safestate_enter(SAPI_SAFESTATE_LEVEL_SAFE);
* }
*
* // 4. Receive reply from both CPUs (voting ensures agreement)
* signal_reply_t reply;
* status = sapi_vital_receive(vital_ch, &reply, sizeof(reply), 100);
*
* if (status == SAPI_STATUS_OK) {
* // Both CPUs agreed - safe to use reply
* printf("Signal update confirmed by both CPUs\n");
* } else {
* // CPUs disagreed - likely a CPU fault
* sapi_log_error("CPU disagreement detected!");
* sapi_safestate_enter(SAPI_SAFESTATE_LEVEL_SAFE);
* }
*
* // 5. Check health
* sapi_channel_health_t health;
* sapi_vital_get_health(vital_ch, &health);
* printf("Messages: %u sent, %u received, %u disagreements\n",
* health.messages_sent, health.messages_received, health.disagreements);
*