Skip to content
File

Blob: firmware/platform/metrics.c

c78 lines
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 
18struct radio_metrics {
19 temperature_sensor_handle_t temperature;
20 uint32_t memory[6];
21};
22 
23radio_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 
38int32_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 
68void 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}