File
Blob: firmware/platform/metrics.c
| 1 | #include <limits.h> |
| 2 | #include <math.h> |
| 3 | #include <stdlib.h> |
| 4 | #include <string.h> |
| 5 | #include "radio_bridge.h" |
| 6 | #include "driver/temperature_sensor.h" |
| 7 | #include "esp_heap_caps.h" |
| 8 | #include "esp_timer.h" |
| 9 | #include "esp_wifi.h" |
| 10 | #include "freertos/FreeRTOS.h" |
| 11 | #include "freertos/idf_additions.h" |
| 12 | |
| 13 | #if !configGENERATE_RUN_TIME_STATS |
| 14 | #error "Reapply sdkconfig.defaults to enable the metrics runtime counters" |
| 15 | #endif |
| 16 | _Static_assert(sizeof(configRUN_TIME_COUNTER_TYPE) == 8, "Metrics require U64 runtime counters"); |
| 17 | |
| 18 | struct radio_metrics { |
| 19 | temperature_sensor_handle_t temperature; |
| 20 | uint32_t memory[6]; |
| 21 | }; |
| 22 | |
| 23 | radio_metrics *radio_metrics_open(void) |
| 24 | { |
| 25 | radio_metrics *m = calloc(1, sizeof(*m)); |
| 26 | if (!m) |
| 27 | return NULL; |
| 28 | temperature_sensor_config_t config = TEMPERATURE_SENSOR_CONFIG_DEFAULT(-10, 80); |
| 29 | if (temperature_sensor_install(&config, &m->temperature) != ESP_OK) |
| 30 | m->temperature = NULL; |
| 31 | if (m->temperature && temperature_sensor_enable(m->temperature) != ESP_OK) { |
| 32 | temperature_sensor_uninstall(m->temperature); |
| 33 | m->temperature = NULL; |
| 34 | } |
| 35 | return m; |
| 36 | } |
| 37 | |
| 38 | int32_t radio_metrics_sample(radio_metrics *m, uint64_t clocks[3], uint32_t memory[6], |
| 39 | int32_t sensors[2], int32_t detailed) |
| 40 | { |
| 41 | if (!m || !clocks || !memory || !sensors) |
| 42 | return ESP_ERR_INVALID_ARG; |
| 43 | clocks[0] = esp_timer_get_time(); |
| 44 | clocks[1] = ulTaskGetIdleRunTimeCounterForCore(0); |
| 45 | clocks[2] = ulTaskGetIdleRunTimeCounterForCore(1); |
| 46 | const uint32_t caps[2] = {MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT, |
| 47 | MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT}; |
| 48 | for (int pool = 0; pool < 2; pool++) { |
| 49 | m->memory[pool * 3] = heap_caps_get_free_size(caps[pool]); |
| 50 | if (detailed) { |
| 51 | m->memory[pool * 3 + 1] = heap_caps_get_minimum_free_size(caps[pool]); |
| 52 | m->memory[pool * 3 + 2] = heap_caps_get_largest_free_block(caps[pool]); |
| 53 | } |
| 54 | } |
| 55 | memcpy(memory, m->memory, sizeof(m->memory)); |
| 56 | sensors[0] = sensors[1] = INT32_MIN; |
| 57 | float celsius; |
| 58 | if (m->temperature && temperature_sensor_get_celsius(m->temperature, &celsius) == ESP_OK && |
| 59 | isfinite(celsius) && celsius >= -10 && celsius <= 80) { |
| 60 | sensors[0] = (int32_t)lroundf(celsius * 1000); |
| 61 | } |
| 62 | wifi_ap_record_t ap; |
| 63 | if (esp_wifi_sta_get_ap_info(&ap) == ESP_OK) |
| 64 | sensors[1] = ap.rssi; |
| 65 | return ESP_OK; |
| 66 | } |
| 67 | |
| 68 | void radio_metrics_free(radio_metrics *m) |
| 69 | { |
| 70 | if (!m) |
| 71 | return; |
| 72 | if (m->temperature) { |
| 73 | temperature_sensor_disable(m->temperature); |
| 74 | temperature_sensor_uninstall(m->temperature); |
| 75 | } |
| 76 | free(m); |
| 77 | } |