firmware-nucleo/App/Src/app.c (6851B)
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 // TODO: *_interface libraries should already include *_attribute headers 9 10 #include "main.h" 11 12 #include "logger.h" 13 #include "dwt.h" 14 15 #include "app.h" 16 #include "task_system.h" 17 #include "task_buttons.h" 18 #include "task_buzzer.h" 19 #include "task_leds.h" 20 #include "task_menu.h" 21 #include "task_temp_ctrl.h" 22 #include "task_temp_sensor.h" 23 #include "task_remote.h" 24 25 #define G_APP_CNT_INI 0ul 26 #define G_APP_TICK_CNT_INI 0ul 27 #define G_APP_WCET_INI 0ul 28 #define G_APP_WCET_MEAN_SAMPLES 1000 // 1 second update rate 29 30 #define TASK_X_WCET_INI 0ul 31 #define TASK_X_WCET_SAMPLE_TIME_MS 10000ul 32 #define TASK_X_TICK_INI 0ul 33 #define TASK_X_DELAY_MIN 0ul 34 35 typedef struct { 36 void (*task_init)(void *); 37 void (*task_update)(void *); 38 void *parameters; 39 } task_cfg_t; 40 41 typedef struct { 42 uint32_t WCET; // Task worst-case execution time in microseconds 43 uint32_t WCET_interval; // WCET in last `TASK_X_WCET_SAMPLE_TIME_MS` ms 44 } task_dta_t; 45 46 shared_data_type shared_data; 47 uint32_t g_app_runtime_us; 48 uint32_t g_app_runtime_us_mean; // Mean of g_app_runtime_us in 49 // G_APP_WCET_MEAN_SAMPLES 50 uint32_t g_app_runtime_us_mean_aux; 51 uint32_t g_app_runtime_us_mean_cnt; 52 uint32_t g_app_WCET_us; // Worst case execution time historically 53 uint32_t g_app_WCET_sample_us; // Worst case execution time in sample time 54 volatile uint32_t g_app_tick_cnt; 55 56 const task_cfg_t task_cfg_list[] = { 57 {task_system_init, task_system_update, &shared_data}, 58 {task_buttons_init, task_buttons_update, NULL}, 59 {task_buzzer_init, task_buzzer_update, NULL}, 60 {task_leds_init, task_leds_update, NULL}, 61 {task_menu_init, task_menu_update, &shared_data}, 62 {task_temp_ctrl_init, task_temp_ctrl_update, &shared_data}, 63 {task_temp_sensor_init, task_temp_sensor_update, &shared_data}, 64 {task_remote_init, task_remote_update, &shared_data}, 65 }; 66 67 #define TASK_QTY (sizeof(task_cfg_list)/sizeof(task_cfg_t)) 68 69 task_dta_t task_dta_list[TASK_QTY] = {0}; 70 71 void app_init(void) 72 { 73 LOGGER_INFO("Initializing `app`..."); 74 75 cycle_counter_init(); 76 77 shared_data_type *p_shared_data = &shared_data; 78 79 p_shared_data->temp_set_point = 0; 80 p_shared_data->temp_sensor = -20; 81 p_shared_data->temp_ctrl_pwm_dc = 0; 82 p_shared_data->temp_ctrl_enabled = false; 83 p_shared_data->timer = NULL; 84 85 for (uint32_t index = 0; TASK_QTY > index; index++) 86 { 87 (*task_cfg_list[index].task_init)(task_cfg_list[index].parameters); 88 task_dta_list[index].WCET = TASK_X_WCET_INI; 89 } 90 91 __asm("CPSID i"); 92 g_app_tick_cnt = G_APP_TICK_CNT_INI; 93 g_task_system_tick_cnt = G_APP_TICK_CNT_INI; 94 g_task_buttons_tick_cnt = G_APP_TICK_CNT_INI; 95 g_task_leds_tick_cnt = G_APP_TICK_CNT_INI; 96 g_task_menu_tick_cnt = G_APP_TICK_CNT_INI; 97 g_task_temp_ctrl_tick_cnt = G_APP_TICK_CNT_INI; 98 g_task_temp_sensor_tick_cnt = G_APP_TICK_CNT_INI; 99 g_task_remote_tick_cnt = G_APP_TICK_CNT_INI; 100 __asm("CPSIE i"); 101 102 LOGGER_INFO("Done initializing `app`"); 103 g_app_WCET_us = G_APP_WCET_INI; 104 g_app_runtime_us_mean = g_app_runtime_us_mean_aux = G_APP_WCET_INI; 105 g_app_runtime_us_mean_cnt = 0; 106 } 107 108 void app_update(void) 109 { 110 uint32_t index; 111 bool b_time_update_required = false; 112 uint32_t cycle_counter_time_us; 113 114 __asm("CPSID i"); 115 if (G_APP_TICK_CNT_INI < g_app_tick_cnt) 116 { 117 g_app_tick_cnt--; 118 b_time_update_required = true; 119 } 120 __asm("CPSIE i"); 121 122 while (b_time_update_required) 123 { 124 g_app_runtime_us = 0; 125 126 for (index = 0; TASK_QTY > index; index++) 127 { 128 cycle_counter_reset(); 129 130 if (0 == g_app_WCET_sample_us) 131 { 132 g_app_WCET_sample_us = TASK_X_WCET_SAMPLE_TIME_MS; 133 task_dta_list[index].WCET_interval = 0; 134 } 135 else 136 { 137 g_app_WCET_sample_us--; 138 } 139 140 (*task_cfg_list[index].task_update)(task_cfg_list[index].parameters); 141 142 cycle_counter_time_us = cycle_counter_get_time_us(); 143 g_app_runtime_us += cycle_counter_time_us; 144 145 if (g_app_WCET_us < g_app_runtime_us) { 146 g_app_WCET_us = g_app_runtime_us; 147 LOGGER_INFO("App worst execution time (WCET): %lu us", g_app_WCET_us); 148 } 149 150 if (task_dta_list[index].WCET < cycle_counter_time_us) 151 { 152 task_dta_list[index].WCET = cycle_counter_time_us; 153 } 154 155 if (task_dta_list[index].WCET_interval< cycle_counter_time_us) 156 { 157 task_dta_list[index].WCET_interval = cycle_counter_time_us; 158 } 159 } 160 161 if (G_APP_WCET_MEAN_SAMPLES == g_app_runtime_us_mean_cnt) 162 { 163 g_app_runtime_us_mean_cnt = 0; 164 g_app_runtime_us_mean = g_app_runtime_us_mean_aux / G_APP_WCET_MEAN_SAMPLES; 165 g_app_runtime_us_mean_aux = G_APP_WCET_INI; 166 } 167 else 168 { 169 g_app_runtime_us_mean_cnt++; 170 g_app_runtime_us_mean_aux += g_app_runtime_us; 171 } 172 173 __asm("CPSID i"); 174 if (G_APP_TICK_CNT_INI < g_app_tick_cnt) 175 { 176 g_app_tick_cnt--; 177 b_time_update_required = true; 178 } 179 else 180 { 181 b_time_update_required = false; 182 } 183 __asm("CPSIE i"); 184 } 185 } 186 187 // Callbacks definition 188 189 // This is called every ms 190 void HAL_SYSTICK_Callback(void) 191 { 192 g_app_tick_cnt++; 193 194 g_task_system_tick_cnt++; 195 g_task_buttons_tick_cnt++; 196 g_task_buzzer_tick_cnt++; 197 g_task_leds_tick_cnt++; 198 g_task_menu_tick_cnt++; 199 g_task_temp_ctrl_tick_cnt++; 200 g_task_temp_sensor_tick_cnt++; 201 g_task_remote_tick_cnt++; 202 } 203 204 void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) 205 { 206 if (huart->Instance == USART1) 207 { 208 b_ds18b20_dma_tx_done = true; 209 } 210 } 211 212 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) 213 { 214 if (huart->Instance == USART1) 215 { 216 b_ds18b20_dma_rx_done = true; 217 } 218 if (huart->Instance == USART3) 219 { 220 task_remote_queue_enqueue(&task_remote_rx_queue, task_remote_uart_rx_byte); 221 HAL_UART_Receive_IT(&huart3, &task_remote_uart_rx_byte, 1); 222 } 223 } 224 225 void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t size) 226 { 227 if (huart->Instance == USART1) 228 { 229 b_ds18b20_dma_rx_done = true; 230 } 231 } 232 233 void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) 234 { 235 if(huart->Instance == USART1) 236 { 237 ; 238 } 239 }
