1 /* 2 * Copyright (c) 2023 Juan Manuel Cruz <jcruz@fi.uba.ar> <jcruz@frba.utn.edu.ar>. 3 * Copyright (c) 2026 Martin Javier Klöckner <mklockner@fi.uba.ar> 4 * 5 * See file `LICENSE` for full details 6 */ 7 8 #include "main.h" 9 10 #include "logger.h" 11 #include "dwt.h" 12 13 #include "board.h" 14 #include "task_system.h" 15 #include "task_actuator.h" 16 #include "task_sensor.h" 17 18 #define G_APP_CNT_INI 0ul 19 #define G_APP_TICK_CNT_INI 0ul 20 #define G_APP_WCET_INI 0ul 21 22 #define TASK_X_WCET_INI 0ul 23 #define TASK_X_DELAY_MIN 0ul 24 25 typedef struct { 26 void (*task_init)(void *); 27 void (*task_update)(void *); 28 void *parameters; 29 } task_cfg_t; 30 31 typedef struct { 32 uint32_t WCET; // Task worst-case execution time (microseconds) 33 } task_dta_t; 34 35 const task_cfg_t task_cfg_list[] = { 36 {task_sensor_init, task_sensor_update, NULL}, 37 {task_system_init, task_system_update, NULL}, 38 {task_actuator_init, task_actuator_update, NULL} 39 }; 40 41 #define TASK_QTY (sizeof(task_cfg_list)/sizeof(task_cfg_t)) 42 43 uint32_t g_app_cnt; 44 uint32_t g_app_runtime_us; 45 uint32_t g_app_WCET_us; // Worst case execution time historically 46 47 volatile uint32_t g_app_tick_cnt; 48 49 task_dta_t task_dta_list[TASK_QTY]; 50 51 void app_init(void) 52 { 53 LOGGER_INFO("Initializing `app`..."); 54 55 g_app_WCET_us = G_APP_WCET_INI; 56 57 cycle_counter_init(); 58 59 for (uint32_t index = 0; TASK_QTY > index; index++) 60 { 61 (*task_cfg_list[index].task_init)(task_cfg_list[index].parameters); 62 task_dta_list[index].WCET = TASK_X_WCET_INI; 63 } 64 65 __asm("CPSID i"); 66 g_app_tick_cnt = G_APP_TICK_CNT_INI; 67 g_task_sensor_tick_cnt = G_APP_TICK_CNT_INI; 68 g_task_system_tick_cnt = G_APP_TICK_CNT_INI; 69 g_task_actuator_tick_cnt = G_APP_TICK_CNT_INI; 70 __asm("CPSIE i"); 71 72 LOGGER_INFO("Done initializing `app`"); 73 } 74 75 void app_update(void) 76 { 77 uint32_t index; 78 bool b_time_update_required = false; 79 uint32_t cycle_counter_time_us; 80 81 __asm("CPSID i"); 82 if (G_APP_TICK_CNT_INI < g_app_tick_cnt) 83 { 84 g_app_tick_cnt--; 85 b_time_update_required = true; 86 } 87 __asm("CPSIE i"); 88 89 /* Check if it's time to run tasks */ 90 while (b_time_update_required) 91 { 92 /* Update App Counter */ 93 g_app_cnt++; 94 g_app_runtime_us = 0; 95 96 /* Go through the task arrays */ 97 for (index = 0; TASK_QTY > index; index++) 98 { 99 cycle_counter_reset(); 100 101 /* Run task_x_update */ 102 (*task_cfg_list[index].task_update)(task_cfg_list[index].parameters); 103 104 cycle_counter_time_us = cycle_counter_get_time_us(); 105 106 /* Update variables */ 107 g_app_runtime_us += cycle_counter_time_us; 108 109 if (g_app_WCET_us < g_app_runtime_us) { 110 g_app_WCET_us = g_app_runtime_us; 111 LOGGER_INFO("app worst execution time (WCET): %lu us", g_app_WCET_us); 112 } 113 114 if (task_dta_list[index].WCET < cycle_counter_time_us) 115 { 116 task_dta_list[index].WCET = cycle_counter_time_us; 117 } 118 } 119 120 __asm("CPSID i"); 121 if (G_APP_TICK_CNT_INI < g_app_tick_cnt) 122 { 123 g_app_tick_cnt--; 124 b_time_update_required = true; 125 } 126 else 127 { 128 b_time_update_required = false; 129 } 130 __asm("CPSIE i"); 131 } 132 } 133 134 void HAL_SYSTICK_Callback(void) 135 { 136 /* Update Tick Counters */ 137 g_app_tick_cnt++; 138 g_task_sensor_tick_cnt++; 139 g_task_system_tick_cnt++; 140 g_task_actuator_tick_cnt++; 141 }
