Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ PebbleOS is the operating system running on Pebble smartwatches.
## Code style

- clang-format for C code
- ruff for Python code

## Firmware development

Expand Down
80 changes: 80 additions & 0 deletions include/pbl/services/common/analytics/analytics.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/* SPDX-FileCopyrightText: 2026 Core Devices LLC */
/* SPDX-License-Identifier: Apache-2.0 */

// OS
PBL_ANALYTICS_METRIC_DEFINE_UNSIGNED(memory_pct_max)
PBL_ANALYTICS_METRIC_DEFINE_UNSIGNED(stack_free_kernel_main_bytes)
PBL_ANALYTICS_METRIC_DEFINE_UNSIGNED(stack_free_kernel_background_bytes)
PBL_ANALYTICS_METRIC_DEFINE_UNSIGNED(stack_free_newtimers_bytes)
PBL_ANALYTICS_METRIC_DEFINE_SIGNED(utc_offset_s)

// Battery & Power
PBL_ANALYTICS_METRIC_DEFINE_UNSIGNED(battery_soc_pct)
PBL_ANALYTICS_METRIC_DEFINE_UNSIGNED(battery_soc_pct_drop)
PBL_ANALYTICS_METRIC_DEFINE_SCALED_UNSIGNED(battery_voltage, 1000)
PBL_ANALYTICS_METRIC_DEFINE_SCALED_SIGNED(battery_voltage_delta, 1000)
PBL_ANALYTICS_METRIC_DEFINE_TIMER(battery_charge_time_ms)
PBL_ANALYTICS_METRIC_DEFINE_TIMER(battery_discharge_duration_ms)

// Hardware I/O
PBL_ANALYTICS_METRIC_DEFINE_TIMER(backlight_on_time_ms)
PBL_ANALYTICS_METRIC_DEFINE_UNSIGNED(backlight_avg_intensity_pct)
PBL_ANALYTICS_METRIC_DEFINE_TIMER(vibrator_on_time_ms)
PBL_ANALYTICS_METRIC_DEFINE_UNSIGNED(vibrator_avg_strength_pct)
PBL_ANALYTICS_METRIC_DEFINE_TIMER(hrm_on_time_ms)
PBL_ANALYTICS_METRIC_DEFINE_UNSIGNED(button_pressed_count)

// CPU usage
PBL_ANALYTICS_METRIC_DEFINE_SCALED_UNSIGNED(cpu_running_pct, 100)
PBL_ANALYTICS_METRIC_DEFINE_SCALED_UNSIGNED(cpu_sleep0_pct, 100)
PBL_ANALYTICS_METRIC_DEFINE_SCALED_UNSIGNED(cpu_sleep1_pct, 100)
PBL_ANALYTICS_METRIC_DEFINE_SCALED_UNSIGNED(cpu_sleep2_pct, 100)

// Accelerometer
PBL_ANALYTICS_METRIC_DEFINE_UNSIGNED(accel_sample_count)
PBL_ANALYTICS_METRIC_DEFINE_UNSIGNED(accel_shake_count)
PBL_ANALYTICS_METRIC_DEFINE_UNSIGNED(accel_double_tap_count)
PBL_ANALYTICS_METRIC_DEFINE_UNSIGNED(accel_peek_count)

// Notifications, phone calls, etc.
PBL_ANALYTICS_METRIC_DEFINE_UNSIGNED(notification_received_count)
PBL_ANALYTICS_METRIC_DEFINE_UNSIGNED(notification_received_dnd_count)
PBL_ANALYTICS_METRIC_DEFINE_UNSIGNED(phone_call_incoming_count)
PBL_ANALYTICS_METRIC_DEFINE_TIMER(phone_call_time_ms)

// Modes
PBL_ANALYTICS_METRIC_DEFINE_TIMER(low_power_time_ms)
PBL_ANALYTICS_METRIC_DEFINE_TIMER(stationary_time_ms)

// Watchface
PBL_ANALYTICS_METRIC_DEFINE_TIMER(watchface_time_ms)
PBL_ANALYTICS_METRIC_DEFINE_STRING(watchface_name, 32)
PBL_ANALYTICS_METRIC_DEFINE_STRING(watchface_uuid, 39)

// File system
PBL_ANALYTICS_METRIC_DEFINE_UNSIGNED(pfs_space_free_kb)

// NOR Flash
PBL_ANALYTICS_METRIC_DEFINE_UNSIGNED(flash_spi_write_bytes)
PBL_ANALYTICS_METRIC_DEFINE_UNSIGNED(flash_spi_erase_bytes)

// BLE
PBL_ANALYTICS_METRIC_DEFINE_TIMER(ble_adv_short_intvl_time_ms)
PBL_ANALYTICS_METRIC_DEFINE_TIMER(ble_adv_long_intvl_time_ms)
PBL_ANALYTICS_METRIC_DEFINE_TIMER(ble_conn_itvl_min_time_ms)
PBL_ANALYTICS_METRIC_DEFINE_TIMER(ble_conn_itvl_mid_time_ms)
PBL_ANALYTICS_METRIC_DEFINE_TIMER(ble_conn_itvl_max_time_ms)

// Settings
PBL_ANALYTICS_METRIC_DEFINE_UNSIGNED(settings_health_tracking_enabled)
PBL_ANALYTICS_METRIC_DEFINE_UNSIGNED(settings_health_hrm_enabled)
PBL_ANALYTICS_METRIC_DEFINE_UNSIGNED(settings_health_hrm_measurement_interval)
PBL_ANALYTICS_METRIC_DEFINE_UNSIGNED(settings_health_hrm_activity_tracking_enabled)

// Application
PBL_ANALYTICS_METRIC_DEFINE_UNSIGNED(app_message_sent_count)
PBL_ANALYTICS_METRIC_DEFINE_UNSIGNED(app_message_received_count)

// Connectivity
PBL_ANALYTICS_METRIC_DEFINE_TIMER(connectivity_connected_time_ms)
PBL_ANALYTICS_METRIC_DEFINE_TIMER(connectivity_expected_time_ms)
63 changes: 48 additions & 15 deletions include/pbl/services/common/analytics/analytics.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,61 @@

#pragma once

#if defined(ANALYTICS_IMPL_MEMFAULT)
#include "memfault/analytics_impl.h"
#else
#include "null/analytics_impl.h"
#endif
#include <stdint.h>

static inline void analytics_init(void) {
analytics_impl_init();
}
#define PBL_ANALYTICS_KEY(key_name) PBL_ANALYTICS_KEY__##key_name

void analytics_external_update(void);
enum pbl_analytics_key {
#define PBL_ANALYTICS_METRIC_DEFINE_UNSIGNED(key) \
PBL_ANALYTICS_KEY(key),
#define PBL_ANALYTICS_METRIC_DEFINE_SIGNED(key) \
PBL_ANALYTICS_KEY(key),
#define PBL_ANALYTICS_METRIC_DEFINE_SCALED_UNSIGNED(key, scale) \
PBL_ANALYTICS_KEY(key),
#define PBL_ANALYTICS_METRIC_DEFINE_SCALED_SIGNED(key, scale) \
PBL_ANALYTICS_KEY(key),
#define PBL_ANALYTICS_METRIC_DEFINE_TIMER(key) \
PBL_ANALYTICS_KEY(key),
#define PBL_ANALYTICS_METRIC_DEFINE_STRING(key, len) \
PBL_ANALYTICS_KEY(key),
#include "analytics.def"
#undef PBL_ANALYTICS_METRIC_DEFINE_UNSIGNED
#undef PBL_ANALYTICS_METRIC_DEFINE_SIGNED
#undef PBL_ANALYTICS_METRIC_DEFINE_SCALED_UNSIGNED
#undef PBL_ANALYTICS_METRIC_DEFINE_SCALED_SIGNED
#undef PBL_ANALYTICS_METRIC_DEFINE_TIMER
#undef PBL_ANALYTICS_METRIC_DEFINE_STRING
PBL_ANALYTICS_KEY_COUNT,
};

void pbl_analytics_init(void);

void pbl_analytics_set_signed(enum pbl_analytics_key key, int32_t signed_value);

void pbl_analytics_set_unsigned(enum pbl_analytics_key key, uint32_t unsigned_value);

void pbl_analytics_set_string(enum pbl_analytics_key key, const char *value);

void pbl_analytics_timer_start(enum pbl_analytics_key key);

void pbl_analytics_timer_stop(enum pbl_analytics_key key);

void pbl_analytics_add(enum pbl_analytics_key key, int32_t amount);

#define PBL_ANALYTICS_SET_SIGNED(key_name, signed_value) \
PBL_ANALYTICS_IMPL_SET_SIGNED(key_name, signed_value)
pbl_analytics_set_signed(PBL_ANALYTICS_KEY(key_name), signed_value)

#define PBL_ANALYTICS_SET_UNSIGNED(key_name, unsigned_value) \
PBL_ANALYTICS_IMPL_SET_UNSIGNED(key_name, unsigned_value)
pbl_analytics_set_unsigned(PBL_ANALYTICS_KEY(key_name), unsigned_value)

#define PBL_ANALYTICS_SET_STRING(key_name, value) PBL_ANALYTICS_IMPL_SET_STRING(key_name, value)
#define PBL_ANALYTICS_SET_STRING(key_name, value) \
pbl_analytics_set_string(PBL_ANALYTICS_KEY(key_name), value)

#define PBL_ANALYTICS_TIMER_START(key_name) PBL_ANALYTICS_IMPL_TIMER_START(key_name)
#define PBL_ANALYTICS_TIMER_START(key_name) \
pbl_analytics_timer_start(PBL_ANALYTICS_KEY(key_name))

#define PBL_ANALYTICS_TIMER_STOP(key_name) PBL_ANALYTICS_IMPL_TIMER_STOP(key_name)
#define PBL_ANALYTICS_TIMER_STOP(key_name) \
pbl_analytics_timer_stop(PBL_ANALYTICS_KEY(key_name))

#define PBL_ANALYTICS_ADD(key_name, amount) PBL_ANALYTICS_IMPL_ADD(key_name, amount)
#define PBL_ANALYTICS_ADD(key_name, amount) \
pbl_analytics_add(PBL_ANALYTICS_KEY(key_name), amount)
17 changes: 17 additions & 0 deletions include/pbl/services/common/analytics/backend.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/* SPDX-FileCopyrightText: 2026 Core Devices LLC */
/* SPDX-License-Identifier: Apache-2.0 */

#pragma once

#include "analytics.h"

#include <stdint.h>

struct pbl_analytics_backend_ops {
void (*set_signed)(enum pbl_analytics_key key, int32_t signed_value);
void (*set_unsigned)(enum pbl_analytics_key key, uint32_t unsigned_value);
void (*set_string)(enum pbl_analytics_key key, const char *value);
void (*timer_start)(enum pbl_analytics_key key);
void (*timer_stop)(enum pbl_analytics_key key);
void (*add)(enum pbl_analytics_key key, int32_t amount);
};
20 changes: 0 additions & 20 deletions include/pbl/services/common/analytics/memfault/analytics_impl.h

This file was deleted.

16 changes: 0 additions & 16 deletions include/pbl/services/common/analytics/null/analytics_impl.h

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,8 @@ typedef enum {
DlsSystemTagActivityAccelSamples = 82,
DlsSystemTagActivitySession = 84,
DlsSystemTagProtobufLogSession = 85,
#ifdef MEMFAULT
DlsSystemTagMemfaultChunksSession = 86,
#endif
DlsSystemTagAnalyticsNativeHeartbeat = 87,
} DlsSystemTag;

//! Init the data logging service. Called by the system at boot time.
Expand Down
10 changes: 10 additions & 0 deletions src/fw/console/prompt_commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,11 @@ extern void command_mflt_metrics_dump(void);
extern void command_mflt_device_info(void);
#endif

#ifdef ANALYTICS_NATIVE
extern void command_analytics_native_metrics_dump(void);
extern void command_analytics_native_heartbeat(void);
#endif

extern void command_console_disable_rx(const char *seconds_str);

#if MICRO_FAMILY_SF32LB52
Expand Down Expand Up @@ -654,6 +659,11 @@ static const Command s_prompt_commands[] = {
{ "mflt metrics_dump", command_mflt_metrics_dump, 0 },
{ "mflt device_info", command_mflt_device_info, 0 },
#endif // MEMFAULT

#if ANALYTICS_NATIVE
{ "analytics native metrics_dump", command_analytics_native_metrics_dump, 0 },
Comment thread
gmarull marked this conversation as resolved.
{ "analytics native heartbeat", command_analytics_native_heartbeat, 0 },
#endif
};

#define NUM_PROMPT_COMMANDS ARRAY_LENGTH(s_prompt_commands)
2 changes: 1 addition & 1 deletion src/fw/freertos_application.c
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ void dump_current_runtime_stats(void) {
prompt_send_response(buf);
}

void analytics_external_collect_cpu_stats(void) {
void pbl_analytics_external_collect_cpu_stats(void) {
uint32_t stop_ticks = s_analytics_stop_ticks;
uint32_t sleep_ticks = s_analytics_sleep_ticks;

Expand Down
2 changes: 1 addition & 1 deletion src/fw/kernel/kernel_heap.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ void kernel_heap_init(void) {
});
}

void analytics_external_collect_kernel_heap_stats(void) {
void pbl_analytics_external_collect_kernel_heap_stats(void) {
uint32_t headroom = heap_get_minimum_headroom(&s_kernel_heap);
size_t total_size = heap_size(&s_kernel_heap);
uint32_t headroom_pct = (total_size > 0) ? (headroom * 100) / total_size : 0;
Expand Down
2 changes: 1 addition & 1 deletion src/fw/kernel/pebble_tasks.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ void pebble_task_suspend(PebbleTask task) {
vTaskSuspend(g_task_handles[task]);
}

void analytics_external_collect_stack_free(void) {
void pbl_analytics_external_collect_stack_free(void) {
PBL_ANALYTICS_SET_UNSIGNED(stack_free_kernel_main_bytes, prv_task_get_stack_free(PebbleTask_KernelMain));
PBL_ANALYTICS_SET_UNSIGNED(stack_free_kernel_background_bytes, prv_task_get_stack_free(PebbleTask_KernelBackground));
PBL_ANALYTICS_SET_UNSIGNED(stack_free_newtimers_bytes, prv_task_get_stack_free(PebbleTask_NewTimers));
Expand Down
2 changes: 1 addition & 1 deletion src/fw/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ static NOINLINE void prv_main_task_init(void) {
task_watchdog_init();
task_watchdog_pause(30);

analytics_init();
pbl_analytics_init();
register_system_timers();
system_task_timer_init();

Expand Down
Loading
Loading