#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <stdarg.h>
// Warning type definitions
#define WARNING_NONE 0
#define WARNING1 1
#define WARNING2 2
#define WARNING3 3
// Display timing constants
#define T_DIS_MIN 4 // Minimum display time
#define T_DIS_CYCLE 6 // Cycle display time
// Display state enumeration
typedef enum {
DISPLAY_MIN_TIME, // Minimum display time phase
DISPLAY_CYCLE // Cycle display phase
} DisplayState;
// Log levels
typedef enum {
LOG_DEBUG,
LOG_INFO,
LOG_WARNING,
LOG_ERROR
} LogLevel;
// System state variables
static uint8_t current_warning = WARNING_NONE;
static DisplayState display_state = DISPLAY_MIN_TIME;
static uint16_t timer = 0;
// Warning flags
static bool flag_warning1 = false;
static bool flag_warning2 = false;
static bool flag_warning3 = false;
// Warning state (min time completion)
static bool warning1_min_done = false;
static bool warning2_min_done = false;
static bool warning3_min_done = false;
// Edge detection for new warnings
static bool last_flag1 = false;
static bool last_flag2 = false;
static bool last_flag3 = false;
// Warning duration counters
static int warning1_duration = 0;
static int warning2_duration = 0;
static int warning3_duration = 0;
// Log file pointer
static FILE *log_file = NULL;
// Function prototypes
void reset_system(void);
void set_warning_flags(bool w1, bool w2, bool w3);
void print_current_state(void);
uint8_t get_highest_priority_warning(void);
uint8_t get_next_cycle_warning(uint8_t current);
void warning_display_handler(void);
bool all_warnings_min_time_done(void);
bool has_new_warning(void);
void generate_random_warnings(int time_step, float probability);
void print_warning_flags(void);
void log_message(LogLevel level, const char *format, ...);
void close_log_file(void);
void open_log_file(const char *filename);
void clear_log_file(const char *filename);
void random_warning_test(void);
void scenario_simulation_test(void);
void scenario_execution(int test_choice);
void print_main_menu(void);
void handle_user_choice(int choice, bool *continue_testing);
// Open log file
void open_log_file(const char *filename) {
if (log_file != NULL) {
fclose(log_file);
log_file = NULL;
}
log_file = fopen(filename, "w");
if (log_file == NULL) {
log_file = fopen(filename, "a+");
if (log_file == NULL) {
printf("Error: Failed to create log file %s\n", filename);
exit(1);
}
}
time_t now = time(NULL);
struct tm *t = localtime(&now);
char time_str[20];
strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", t);
fprintf(log_file, "===== Warning System Log - Start Time: %s =====\n\n", time_str);
fflush(log_file);
printf("[%s] [INFO] Log file opened: %s (cleared)\n", time_str, filename);
}
// Clear log file
void clear_log_file(const char *filename) {
FILE *temp = fopen(filename, "w");
if (temp != NULL) {
fclose(temp);
printf("Log file cleared: %s\n", filename);
} else {
temp = fopen(filename, "a+");
if (temp != NULL) {
fclose(temp);
printf("Created new log file: %s\n", filename);
} else {
printf("Warning: Unable to access log file %s\n", filename);
}
}
}
// Close log file
void close_log_file(void) {
if (log_file != NULL) {
log_message(LOG_INFO, "Closing log file");
fclose(log_file);
log_file = NULL;
}
}
// Log message function
void log_message(LogLevel level, const char *format, ...) {
time_t now = time(NULL);
struct tm *t = localtime(&now);
char time_str[20];
strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", t);
const char *level_str = "";
switch (level) {
case LOG_DEBUG: level_str = "DEBUG"; break;
case LOG_INFO: level_str = "INFO"; break;
case LOG_WARNING: level_str = "WARNING"; break;
case LOG_ERROR: level_str = "ERROR"; break;
}
char message[256];
va_list args;
va_start(args, format);
vsnprintf(message, sizeof(message), format, args);
va_end(args);
printf("[%s] [%s] %s\n", time_str, level_str, message);
if (log_file != NULL) {
fprintf(log_file, "[%s] [%s] %s\n", time_str, level_str, message);
fflush(log_file);
}
}
// Reset system state
void reset_system(void) {
current_warning = WARNING_NONE;
display_state = DISPLAY_MIN_TIME;
timer = 0;
flag_warning1 = false;
flag_warning2 = false;
flag_warning3 = false;
last_flag1 = false;
last_flag2 = false;
last_flag3 = false;
warning1_min_done = false;
warning2_min_done = false;
warning3_min_done = false;
warning1_duration = 0;
warning2_duration = 0;
warning3_duration = 0;
log_message(LOG_INFO, "System reset");
}
// Set warning flags
void set_warning_flags(bool w1, bool w2, bool w3) {
if (w1 != flag_warning1) {
log_message(LOG_INFO, "Warning1: %s", w1 ? "ACTIVE" : "INACTIVE");
}
if (w2 != flag_warning2) {
log_message(LOG_INFO, "Warning2: %s", w2 ? "ACTIVE" : "INACTIVE");
}
if (w3 != flag_warning3) {
log_message(LOG_INFO, "Warning3: %s", w3 ? "ACTIVE" : "INACTIVE");
}
last_flag1 = flag_warning1;
last_flag2 = flag_warning2;
last_flag3 = flag_warning3;
flag_warning1 = w1;
flag_warning2 = w2;
flag_warning3 = w3;
if (!w1) warning1_min_done = false;
if (!w2) warning2_min_done = false;
if (!w3) warning3_min_done = false;
}
// Print current warning flags
void print_warning_flags(void) {
char flags[128];
snprintf(flags, sizeof(flags), "Flags: W1=%d (Rem:%d), W2=%d (Rem:%d), W3=%d (Rem:%d)",
flag_warning1, warning1_duration,
flag_warning2, warning2_duration,
flag_warning3, warning3_duration);
log_message(LOG_DEBUG, "%s", flags);
}
// Check for new warnings
bool has_new_warning(void) {
if (!last_flag1 && flag_warning1) return true;
if (!last_flag2 && flag_warning2) return true;
if (!last_flag3 && flag_warning3) return true;
return false;
}
// Print current system state
void print_current_state(void) {
if (current_warning == WARNING_NONE) {
log_message(LOG_DEBUG, "State: No warning displayed");
return;
}
const char* state_str = (display_state == DISPLAY_MIN_TIME) ? "Min Time" : "Cycle Display";
char state_msg[128];
snprintf(state_msg, sizeof(state_msg), "State: Warning %d, Timer: %d, Phase: %s",
current_warning, timer, state_str);
log_message(LOG_DEBUG, "%s", state_msg);
}
// Get highest priority warning
uint8_t get_highest_priority_warning(void) {
if (flag_warning1) return WARNING1;
if (flag_warning2) return WARNING2;
if (flag_warning3) return WARNING3;
return WARNING_NONE;
}
// Get next warning in cycle
uint8_t get_next_cycle_warning(uint8_t current) {
if (!flag_warning2 && !flag_warning3 && flag_warning1) return WARNING1;
if (!flag_warning1 && !flag_warning3 && flag_warning2) return WARNING2;
if (!flag_warning1 && !flag_warning2 && flag_warning3) return WARNING3;
if (current == WARNING1) {
if (flag_warning2) return WARNING2;
if (flag_warning3) return WARNING3;
return WARNING1;
}
if (current == WARNING2) {
if (flag_warning3) return WARNING3;
if (flag_warning1) return WARNING1;
return WARNING2;
}
if (current == WARNING3) {
if (flag_warning1) return WARNING1;
if (flag_warning2) return WARNING2;
return WARNING3;
}
return get_highest_priority_warning();
}
// Check if all warnings have completed min time
bool all_warnings_min_time_done(void) {
if (flag_warning1 && !warning1_min_done) return false;
if (flag_warning2 && !warning2_min_done) return false;
if (flag_warning3 && !warning3_min_done) return false;
return true;
}
// Warning display state machine
void warning_display_handler(void) {
// Check for new warnings during cycle phase
if (display_state == DISPLAY_CYCLE && has_new_warning()) {
uint8_t highest_unfinished = WARNING_NONE;
if (flag_warning1 && !warning1_min_done) {
highest_unfinished = WARNING1;
} else if (flag_warning2 && !warning2_min_done) {
highest_unfinished = WARNING2;
} else if (flag_warning3 && !warning3_min_done) {
highest_unfinished = WARNING3;
}
if (highest_unfinished != WARNING_NONE) {
current_warning = highest_unfinished;
display_state = DISPLAY_MIN_TIME;
timer = 0;
log_message(LOG_INFO, "Cycle interrupted, switching to warning %d min time", current_warning);
return;
}
}
// State 1: No warning displayed
if (current_warning == WARNING_NONE) {
uint8_t highest = get_highest_priority_warning();
if (highest != WARNING_NONE) {
current_warning = highest;
timer = 1;
display_state = DISPLAY_MIN_TIME;
log_message(LOG_INFO, "Switching to warning %d (initial)", current_warning);
}
return;
}
// Check if current warning still exists
bool current_warning_exists = false;
switch (current_warning) {
case WARNING1: current_warning_exists = flag_warning1; break;
case WARNING2: current_warning_exists = flag_warning2; break;
case WARNING3: current_warning_exists = flag_warning3; break;
}
// Handle warning disappearance
if (!current_warning_exists) {
log_message(LOG_INFO, "Warning %d disappeared", current_warning);
uint8_t next = get_highest_priority_warning();
if (next != WARNING_NONE) {
current_warning = next;
timer = 0;
display_state = DISPLAY_MIN_TIME;
log_message(LOG_INFO, "Switching to warning %d", current_warning);
} else {
current_warning = WARNING_NONE;
timer = 0;
display_state = DISPLAY_MIN_TIME;
log_message(LOG_INFO, "No warnings to display");
}
return;
}
// State 2: Minimum display time phase
if (display_state == DISPLAY_MIN_TIME) {
timer++;
log_message(LOG_DEBUG, "Warning %d: Min time %d/%d", current_warning, timer, T_DIS_MIN);
if (timer >= T_DIS_MIN) {
switch (current_warning) {
case WARNING1:
warning1_min_done = true;
log_message(LOG_INFO, "Warning 1 min time completed");
break;
case WARNING2:
warning2_min_done = true;
log_message(LOG_INFO, "Warning 2 min time completed");
break;
case WARNING3:
warning3_min_done = true;
log_message(LOG_INFO, "Warning 3 min time completed");
break;
}
if (all_warnings_min_time_done()) {
current_warning = get_highest_priority_warning();
display_state = DISPLAY_CYCLE;
timer = 0;
log_message(LOG_INFO, "All min times completed, starting cycle with warning %d", current_warning);
} else {
uint8_t next = WARNING_NONE;
if (flag_warning1 && !warning1_min_done) {
next = WARNING1;
} else if (flag_warning2 && !warning2_min_done) {
next = WARNING2;
} else if (flag_warning3 && !warning3_min_done) {
next = WARNING3;
}
if (next != WARNING_NONE) {
current_warning = next;
timer = 0;
display_state = DISPLAY_MIN_TIME;
log_message(LOG_INFO, "Switching to warning %d", current_warning);
} else {
current_warning = get_highest_priority_warning();
display_state = DISPLAY_CYCLE;
timer = 0;
log_message(LOG_ERROR, "No unfinished warnings, starting cycle");
}
}
}
return;
}
// State 3: Cycle display phase
if (display_state == DISPLAY_CYCLE) {
timer++;
log_message(LOG_DEBUG, "Warning %d: Cycle %d/%d", current_warning, timer, T_DIS_CYCLE);
if (timer >= T_DIS_CYCLE) {
uint8_t next_warning = get_next_cycle_warning(current_warning);
if (next_warning != current_warning) {
log_message(LOG_INFO, "Warning %d cycle ended, switching to warning %d", current_warning, next_warning);
current_warning = next_warning;
timer = 0;
} else {
log_message(LOG_INFO, "Warning %d cycle ended, continuing", current_warning);
timer = 0;
}
}
}
}
// Generate random warnings
void generate_random_warnings(int time_step, float probability) {
bool w1 = flag_warning1;
bool w2 = flag_warning2;
bool w3 = flag_warning3;
if (warning1_duration > 0) {
warning1_duration--;
w1 = true;
} else {
w1 = (rand() % 100) < (probability * 100);
if (w1 && !flag_warning1) {
warning1_duration = T_DIS_MIN + 1;
log_message(LOG_INFO, "New warning 1, duration: %d", warning1_duration + 1);
}
}
if (warning2_duration > 0) {
warning2_duration--;
w2 = true;
} else {
w2 = (rand() % 100) < (probability * 100);
if (w2 && !flag_warning2) {
warning2_duration = T_DIS_MIN + 1;
log_message(LOG_INFO, "New warning 2, duration: %d", warning2_duration + 1);
}
}
if (warning3_duration > 0) {
warning3_duration--;
w3 = true;
} else {
w3 = (rand() % 100) < (probability * 100);
if (w3 && !flag_warning3) {
warning3_duration = T_DIS_MIN + 1;
log_message(LOG_INFO, "New warning 3, duration: %d", warning3_duration + 1);
}
}
set_warning_flags(w1, w2, w3);
}
void print_main_menu(void) {
printf("\n===== Warning Display System Test Menu =====\n");
printf("1. Random Warning Generation Test\n");
printf("2. Scenario Simulation Tests\n");
printf("0. Exit Program\n");
printf("Select test mode: ");
}
void handle_user_choice(int choice, bool *continue_testing) {
switch (choice) {
case 1:
random_warning_test();
break;
case 2:
scenario_simulation_test();
break;
case 0:
*continue_testing = false;
printf("Exiting program...\n");
break;
default:
printf("Invalid selection, please try again!\n");
break;
}
}
void random_warning_test(void) {
int time_steps = 0;
float probability = 0.0f;
printf("\n=== Random Warning Generation Test ===\n");
printf("Enter test time steps: ");
scanf("%d", &time_steps);
printf("Enter warning probability (0.0-1.0): ");
scanf("%f", &probability);
if (probability < 0 || probability > 1) {
printf("Error: Probability must be between 0 and 1!\n");
return;
}
log_message(LOG_INFO, "===== Random Warning Test Started =====");
log_message(LOG_INFO, "Parameters: Time steps=%d, Probability=%.2f", time_steps, probability);
srand(time(NULL)); // Initialize random seed
reset_system();
for (int time_step = 0; time_step < time_steps; time_step++) {
if (time_step % 10 == 0) {
log_message(LOG_INFO, "[Status Summary] Time step: %d", time_step);
}
generate_random_warnings(time_step, probability);
warning_display_handler();
}
log_message(LOG_INFO, "===== Random Warning Test Completed =====");
}
void scenario_simulation_test(void) {
int test_choice = 0;
printf("\n=== Scenario Simulation Tests ===\n");
printf("1. Single Warning Full Cycle\n");
printf("2. Multi-Warning Priority Display\n");
printf("3. New Warning During Min Time\n");
printf("4. New Warning During Cycle\n");
printf("5. Warning Disappearance\n");
printf("6. Multi-Warning Disappearance\n");
printf("0. Return to Main Menu\n");
printf("Select test scenario: ");
scanf("%d", &test_choice);
log_message(LOG_INFO, "===== Scenario Test Started =====");
scenario_execution(test_choice);
log_message(LOG_INFO, "===== Scenario Test Completed =====");
}
void scenario_execution(int test_choice) {
switch (test_choice) {
case 1:
log_message(LOG_INFO, "Scenario 1: Single Warning Full Cycle");
reset_system();
set_warning_flags(true, false, false);
for (int i = 0; i < T_DIS_MIN + T_DIS_CYCLE + 2; i++) {
warning_display_handler();
}
break;
case 2:
log_message(LOG_INFO, "Scenario 2: Multi-Warning Priority Display");
reset_system();
set_warning_flags(true, true, true);
for (int i = 0; i < (T_DIS_MIN + T_DIS_CYCLE) * 3 + 2; i++) {
warning_display_handler();
}
break;
case 3:
log_message(LOG_INFO, "Scenario 3: New Warning During Min Time");
reset_system();
set_warning_flags(true, false, false);
for (int i = 0; i < 2; i++) {
warning_display_handler();
}
set_warning_flags(true, true, true);
for (int i = 0; i < T_DIS_MIN * 2 + T_DIS_CYCLE * 3 + 2; i++) {
warning_display_handler();
}
break;
case 4:
log_message(LOG_INFO, "Scenario 4: New Warning During Cycle");
reset_system();
set_warning_flags(true, false, false);
for (int i = 0; i < T_DIS_MIN + 2; i++) {
warning_display_handler();
}
set_warning_flags(true, true, false);
for (int i = 0; i < T_DIS_MIN + T_DIS_CYCLE + 2; i++) {
warning_display_handler();
}
break;
case 5:
log_message(LOG_INFO, "Scenario 5: Warning Disappearance");
reset_system();
set_warning_flags(true, true, true);
for (int i = 0; i < T_DIS_MIN; i++) {
warning_display_handler();
}
set_warning_flags(false, true, true);
for (int i = 0; i < T_DIS_MIN + T_DIS_CYCLE + 2; i++) {
warning_display_handler();
}
break;
case 6:
log_message(LOG_INFO, "Scenario 6: Multi-Warning Disappearance");
reset_system();
set_warning_flags(true, true, true);
for (int i = 0; i < T_DIS_MIN; i++) {
warning_display_handler();
}
set_warning_flags(false, false, false);
for (int i = 0; i < 3; i++) {
warning_display_handler();
}
break;
default:
printf("Invalid scenario selection, returning to main menu.\n");
break;
}
}
int main() {
const char *log_filename = "warning_system.log";
int choice = 0;
bool continue_testing = true;
while (continue_testing) {
// 打印主菜单
print_main_menu();
scanf("%d", &choice);
// 清空并打开日志文件
clear_log_file(log_filename);
open_log_file(log_filename);
// 根据用户输入选择对应功能
handle_user_choice(choice, &continue_testing);
// 关闭日志文件
close_log_file();
// 如果未退出,询问是否继续
if (continue_testing && choice != 0) {
char continue_choice;
printf("\nContinue testing? (y/n): ");
scanf(" %c", &continue_choice);
if (continue_choice == 'n' || continue_choice == 'N') {
continue_testing = false;
printf("Thank you for using the system!\n");
}
}
}
return 0;
}
代码是否可以简化
最新发布