test_bug6_timer_variable_collision.c
1 /******************************************************************************* 2 * test_bug6_timer_variable_collision.c 3 * 4 * Bug #6 (FIXED): In main.cpp, the temperature block now writes to 5 * `last_check1` instead of `last_check`, so both timers run independently. 6 * 7 * Post-fix behavior: 8 * - Lock check fires every ~5s using `last_check`. 9 * - Temperature check fires every ~5s using `last_check1`. 10 * - Neither timer corrupts the other. 11 ******************************************************************************/ 12 #include "stm32_hal_mock.h" 13 #include <assert.h> 14 #include <stdio.h> 15 16 /* Counters to track how many times each block fires */ 17 static int lock_check_fired = 0; 18 static int temp_check_fired = 0; 19 20 /* 21 * Simulates one iteration of the main loop timer blocks. 22 * Uses the FIXED code pattern from main.cpp. 23 */ 24 static void main_loop_iteration(uint32_t *last_check_p, uint32_t *last_check1_p) 25 { 26 /* ---- Lock check block ---- */ 27 if (HAL_GetTick() - *last_check_p > 5000) { 28 lock_check_fired++; 29 *last_check_p = HAL_GetTick(); 30 } 31 32 /* ---- Temperature check block (FIXED: writes to last_check1) ---- */ 33 if (HAL_GetTick() - *last_check1_p > 5000) { 34 temp_check_fired++; 35 *last_check1_p = HAL_GetTick(); /* FIXED: was *last_check_p */ 36 } 37 } 38 39 int main(void) 40 { 41 uint32_t last_check = 0; 42 uint32_t last_check1 = 0; 43 44 printf("=== Bug #6 (FIXED): Timer variable collision ===\n"); 45 46 /* ---- t=0: nothing fires ---- */ 47 spy_reset(); 48 mock_set_tick(0); 49 lock_check_fired = 0; 50 temp_check_fired = 0; 51 52 main_loop_iteration(&last_check, &last_check1); 53 printf(" t=0ms: lock_fired=%d temp_fired=%d\n", lock_check_fired, temp_check_fired); 54 assert(lock_check_fired == 0); 55 assert(temp_check_fired == 0); 56 printf(" PASS: Neither fires at t=0\n"); 57 58 /* ---- t=5001: both fire ---- */ 59 mock_set_tick(5001); 60 main_loop_iteration(&last_check, &last_check1); 61 printf(" t=5001ms: lock_fired=%d temp_fired=%d\n", lock_check_fired, temp_check_fired); 62 assert(lock_check_fired == 1); 63 assert(temp_check_fired == 1); 64 printf(" PASS: Both fire at t=5001\n"); 65 66 /* Both variables should be updated independently */ 67 printf(" After first fire: last_check=%u last_check1=%u\n", last_check, last_check1); 68 assert(last_check == 5001); 69 assert(last_check1 == 5001); 70 printf(" PASS: Both timers updated independently\n"); 71 72 /* ---- t=5002: neither fires (only 1ms elapsed) ---- */ 73 mock_set_tick(5002); 74 main_loop_iteration(&last_check, &last_check1); 75 printf(" t=5002ms: lock_fired=%d temp_fired=%d\n", lock_check_fired, temp_check_fired); 76 assert(lock_check_fired == 1); 77 assert(temp_check_fired == 1); 78 printf(" PASS: Neither fires at t=5002 (correct — temp no longer runs continuously)\n"); 79 80 /* ---- t=10002: both fire again ---- */ 81 mock_set_tick(10002); 82 main_loop_iteration(&last_check, &last_check1); 83 printf(" t=10002ms: lock_fired=%d temp_fired=%d\n", lock_check_fired, temp_check_fired); 84 assert(lock_check_fired == 2); 85 assert(temp_check_fired == 2); 86 printf(" PASS: Both fire at t=10002 (second cycle, independent)\n"); 87 88 /* Verify both timers updated correctly */ 89 assert(last_check == 10002); 90 assert(last_check1 == 10002); 91 printf(" PASS: Both timers at 10002, no cross-contamination\n"); 92 93 /* ---- t=15003: third cycle ---- */ 94 mock_set_tick(15003); 95 main_loop_iteration(&last_check, &last_check1); 96 assert(lock_check_fired == 3); 97 assert(temp_check_fired == 3); 98 printf(" PASS: Third cycle fires correctly at t=15003\n"); 99 100 printf("=== Bug #6 (FIXED): ALL TESTS PASSED ===\n\n"); 101 return 0; 102 }