1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-08-02 03:48:58 +00:00

refactor(core): introduce suspend module

[no changelog]
This commit is contained in:
cepetr 2025-06-18 13:42:34 +02:00 committed by cepetr
parent b35c7b40ba
commit 564743ef7e
22 changed files with 177 additions and 181 deletions

View File

@ -17,15 +17,15 @@ FEATURES_WANTED = [
"display",
"dma2d",
"input",
"iwdg",
"optiga",
"power_manager",
"power_save",
"rgb_led",
"rtc",
"secure_domain",
"suspend",
"tropic",
"usb",
"iwdg",
]
if TREZOR_MODEL in ('T3W1', ):

View File

@ -58,6 +58,7 @@ FEATURES_WANTED = [
"rgb_led",
"sd_card",
"secmon_layout",
"suspend",
"tropic",
"usb",
]

View File

@ -40,14 +40,15 @@ FEATURES_WANTED = [
"input",
"optiga",
"power_manager",
"power_save",
"rgb_led",
"rtc",
"sd_card",
"secmon_layout",
"smp",
"suspend",
"tropic",
"usb",
"smp",
]
if DISABLE_OPTIGA:

View File

@ -24,15 +24,15 @@ FEATURES_WANTED = [
"nfc",
"optiga",
"power_manager",
"power_save",
"rgb_led",
"rtc",
"sbu",
"sd_card",
"secure_domain",
"smp",
"suspend",
"tropic",
"usb",
"smp",
]
CCFLAGS_MOD = ''

View File

@ -33,9 +33,9 @@ FEATURE_FLAGS = {
FEATURES_WANTED = [
"consumption_mask",
"optiga",
"power_save",
"secmon_layout",
"secure_domain",
"suspend",
"tropic",
]

View File

@ -27,8 +27,8 @@
#include "../button_poll.h"
#ifdef USE_POWER_MANAGER
#include <sys/power_manager.h>
#ifdef USE_SUSPEND
#include <sys/suspend.h>
#endif
#ifdef KERNEL_MODE
@ -165,9 +165,9 @@ void BTN_EXTI_INTERRUPT_HANDLER(void) {
// Clear the EXTI line pending bit
__HAL_GPIO_EXTI_CLEAR_FLAG(BTN_EXTI_INTERRUPT_PIN);
#ifdef USE_POWER_MANAGER
#ifdef USE_SUSPEND
// Inform the powerctl module about button press
pm_wakeup_flags_set(PM_WAKEUP_FLAG_BUTTON);
wakeup_flags_set(WAKEUP_FLAG_BUTTON);
#endif
mpu_restore(mpu_mode);

View File

@ -25,11 +25,14 @@
#include <io/nrf.h>
#include <sys/irq.h>
#include <sys/mpu.h>
#include <sys/power_manager.h>
#include <sys/systick.h>
#include <sys/systimer.h>
#include <util/tsqueue.h>
#ifdef USE_SUSPEND
#include <sys/suspend.h>
#endif
#include "../crc8.h"
#include "../nrf_internal.h"
@ -305,10 +308,10 @@ void NRF_EXTI_INTERRUPT_HANDLER(void) {
nrf_driver_t *drv = &g_nrf_driver;
#ifdef USE_POWER_MANAGER
#ifdef USE_SUSPEND
if (drv->wakeup) {
// Inform the power manager module about nrf/ble wakeup
pm_wakeup_flags_set(PM_WAKEUP_FLAG_BLE);
wakeup_flags_set(WAKEUP_FLAG_BLE);
drv->wakeup = false;
}
#endif

View File

@ -21,16 +21,6 @@
#include <trezor_types.h>
/* Power manager wakeup flags */
typedef enum {
PM_WAKEUP_FLAG_BUTTON = 0x1 << 0, // Button pressed
PM_WAKEUP_FLAG_WPC = 0x1 << 1, // Wireless power charging event
PM_WAKEUP_FLAG_BLE = 0x1 << 2, // Bluetooth connection event
PM_WAKEUP_FLAG_NFC = 0x1 << 3, // NFC event
PM_WAKEUP_FLAG_USB = 0x1 << 4, // USB event
PM_WAKEUP_FLAG_RTC = 0x1 << 5, // RTC wake-up timer
} pm_wakeup_flags_t;
/* power manager status codes */
typedef enum {
PM_OK = 0,
@ -209,23 +199,3 @@ pm_status_t pm_set_soc_limit(uint8_t limit);
* @return pm_status_t Status code indicating success or failure
*/
pm_status_t pm_store_data_to_backup_ram();
/**
* @brief Set wakeup flags
* @param flags Wakeup flags to set
* @return pm_status_t Status code indicating success or failure
*/
pm_status_t pm_wakeup_flags_set(pm_wakeup_flags_t flags);
/**
* @brief Reset wakeup flags
* @return pm_status_t Status code indicating success or failure
*/
pm_status_t pm_wakeup_flags_reset(void);
/**
* @brief Get wakeup flags
* @param flags Pointer to store the current wakeup flags
* @return pm_status_t Status code indicating success or failure
*/
pm_status_t pm_wakeup_flags_get(pm_wakeup_flags_t* flags);

View File

@ -18,12 +18,14 @@
*/
#ifdef KERNEL_MODE
#include <trezor_rtl.h>
#include <sys/backup_ram.h>
#include <sys/irq.h>
#include <sys/pmic.h>
#include <sys/suspend.h>
#include <sys/systick.h>
#include <sys/systimer.h>
#include <trezor_rtl.h>
#ifdef USE_RTC
#include <sys/rtc.h>
@ -233,7 +235,7 @@ pm_status_t pm_suspend(void) {
// rtc_wakeup_timer_start(10);
#endif
pm_wakeup_flags_t wakeup_flags = pm_control_suspend();
wakeup_flags_t wakeup_flags = system_suspend();
// TODO: Handle wake-up flags
UNUSED(wakeup_flags);
@ -466,44 +468,6 @@ static bool pm_load_recovery_data(pm_recovery_data_t* recovery) {
return true;
}
pm_status_t pm_wakeup_flags_set(pm_wakeup_flags_t flags) {
pm_driver_t* drv = &g_pm;
if (!drv->initialized) {
return PM_NOT_INITIALIZED;
}
irq_key_t irq_key = irq_lock();
drv->wakeup_flags |= flags;
irq_unlock(irq_key);
return PM_OK;
}
pm_status_t pm_wakeup_flags_reset(void) {
pm_driver_t* drv = &g_pm;
if (!drv->initialized) {
return PM_NOT_INITIALIZED;
}
irq_key_t irq_key = irq_lock();
drv->wakeup_flags = 0;
irq_unlock(irq_key);
return PM_OK;
}
pm_status_t pm_wakeup_flags_get(pm_wakeup_flags_t* flags) {
pm_driver_t* drv = &g_pm;
if (!drv->initialized) {
return PM_NOT_INITIALIZED;
}
irq_key_t irq_key = irq_lock();
*flags = drv->wakeup_flags;
irq_unlock(irq_key);
return PM_OK;
}
pm_status_t pm_set_soc_limit(uint8_t limit) {
pm_driver_t* drv = &g_pm;

View File

@ -99,9 +99,6 @@ typedef struct {
systimer_t* monitoring_timer;
systimer_t* shutdown_timer;
// Wakeup flags
volatile pm_wakeup_flags_t wakeup_flags;
} pm_driver_t;
// State handler function definition
@ -133,10 +130,3 @@ void pm_charging_controller(pm_driver_t* drv);
// Battery initial state of charge guess function. This function use the sampled
// battery data to guess the initial state of charge in case its unknown.
void pm_battery_initial_soc_guess(void);
// Power manager control function which reboots the device into hibernate mode.
pm_status_t pm_control_hibernate(void);
// Power manager control function which puts device into suspend mode.
// Returns the wakeup flags that caused the device to wake up.
pm_wakeup_flags_t pm_control_suspend(void);

View File

@ -134,7 +134,7 @@ static pm_power_status_t pm_handle_state_hibernate(pm_driver_t* drv) {
drv->request_hibernate = false;
// Put PMIC into ship mode (ultra-low power)
pm_control_hibernate();
pmic_enter_shipmode();
return PM_STATE_HIBERNATE;
}

View File

@ -41,8 +41,8 @@
#include <sec/optiga.h>
#endif
#ifdef USE_POWER_SAVE
#include <sys/power_save.h>
#ifdef USE_SUSPEND
#include <sys/suspend_io.h>
#endif
#ifdef LOCKABLE_BOOTLOADER
@ -115,19 +115,19 @@ __attribute((no_stack_protector)) void smcall_handler(uint32_t *args,
reboot_with_rsod__verified(pminfo);
} break;
#ifdef USE_POWER_SAVE
case SMCALL_POWER_SAVE_SUSPEND_CPU: {
power_save_suspend_cpu();
#ifdef USE_SUSPEND
case SMCALL_SUSPEND_CPU: {
suspend_cpu();
} break;
case SMCALL_POWER_SAVE_SUSPEND_SECURE_IO: {
power_save_suspend_secure_io();
case SMCALL_SUSPEND_SECURE_DRIVERS: {
suspend_secure_drivers();
} break;
case SMCALL_POWER_SAVE_RESUME_SECURE_IO: {
power_save_resume_secure_io();
case SMCALL_RESUME_SECURE_DRIVERS: {
resume_secure_drivers();
} break;
#endif // USE_POWER_SAVE
#endif // USE_SUSPEND
case SMCALL_UNIT_PROPERTIES_GET: {
unit_properties_t *props = (unit_properties_t *)args[0];

View File

@ -42,9 +42,9 @@ typedef enum {
SMCALL_REBOOT_TO_OFF,
SMCALL_REBOOT_WITH_RSOD,
SMCALL_POWER_SAVE_SUSPEND_CPU,
SMCALL_POWER_SAVE_SUSPEND_SECURE_IO,
SMCALL_POWER_SAVE_RESUME_SECURE_IO,
SMCALL_SUSPEND_CPU,
SMCALL_SUSPEND_SECURE_DRIVERS,
SMCALL_RESUME_SECURE_DRIVERS,
SMCALL_GET_BOARD_NAME,
SMCALL_GET_BOARDLOADER_VERSION,

View File

@ -107,23 +107,21 @@ void reboot_with_rsod(const systask_postmortem_t *pminfo) {
// power_manager_secure.h
// =============================================================================
#ifdef USE_POWER_SAVE
#ifdef USE_SUSPEND
#include <sys/power_save.h>
#include <sys/suspend_io.h>
void power_save_suspend_cpu(void) {
smcall_invoke0(SMCALL_POWER_SAVE_SUSPEND_CPU);
void suspend_cpu(void) { smcall_invoke0(SMCALL_SUSPEND_CPU); }
void suspend_secure_drivers(void) {
smcall_invoke0(SMCALL_SUSPEND_SECURE_DRIVERS);
}
void power_save_suspend_secure_io(void) {
smcall_invoke0(SMCALL_POWER_SAVE_SUSPEND_SECURE_IO);
void resume_secure_drivers(void) {
smcall_invoke0(SMCALL_RESUME_SECURE_DRIVERS);
}
void power_save_resume_secure_io(void) {
smcall_invoke0(SMCALL_POWER_SAVE_RESUME_SECURE_IO);
}
#endif // USE_POWER_SAVE
#endif // USE_SUSPEND
// =============================================================================
// unit_properties.h

View File

@ -0,0 +1,55 @@
/*
* This file is part of the Trezor project, https://trezor.io/
*
* Copyright (c) SatoshiLabs
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <trezor_types.h>
/** Set of wake-up flags */
typedef uint16_t wakeup_flags_t;
#define WAKEUP_FLAG_BUTTON (1 << 0) /** Button pressed */
#define WAKEUP_FLAG_POWER (1 << 1) /** Power up */
#define WAKEUP_FLAG_BLE (1 << 2) /** Bluetooth connection event */
#define WAKEUP_FLAG_NFC (1 << 3) /** NFC event */
#define WAKEUP_FLAG_RTC (1 << 4) /** RTC wake-up timer */
/**
* @brief Puts device into suspend mode (actually STOP2 mode on STM32U5)
*
* @return Return flags indicating the reason for wakeup
*/
wakeup_flags_t system_suspend(void);
/**
* @brief Set wakeup flags
* @param flags Wakeup flags to set
*/
void wakeup_flags_set(wakeup_flags_t flags);
/**
* @brief Reset wakeup flags
*/
void wakeup_flags_reset(void);
/**
* @brief Get wakeup flags
* @param flags Pointer to store the current wakeup flags
*/
void wakeup_flags_get(wakeup_flags_t* flags);

View File

@ -29,7 +29,7 @@
* This function blocks until an interrupt wakes the CPU.
* Upon wake-up, it restores the system clock so the CPU can run at full speed.
*/
void power_save_suspend_cpu(void);
void suspend_cpu(void);
/**
* @brief State of the drivers before entering a low-power mode
@ -55,7 +55,7 @@ typedef struct {
* @param wakeup_params Pointer to a structure that will be filled with
* the state of the drivers before entering low-power mode.
*/
void power_save_suspend_io(power_save_wakeup_params_t *wakeup_params);
void suspend_drivers(power_save_wakeup_params_t *wakeup_params);
/**
* @brief Resumes I/O drivers.
@ -67,7 +67,7 @@ void power_save_suspend_io(power_save_wakeup_params_t *wakeup_params);
* @param wakeup_params Pointer to a structure that contains the state of the
* drivers before entering low-power mode.
*/
void power_save_resume_io(const power_save_wakeup_params_t *wakeup_params);
void resume_drivers(const power_save_wakeup_params_t *wakeup_params);
/**
* @brief Suspends secure peripherals.
@ -75,7 +75,7 @@ void power_save_resume_io(const power_save_wakeup_params_t *wakeup_params);
* This function is called before the device enters a low-power state.
* It suspends secure peripherals to reduce power consumption.
*/
void power_save_suspend_secure_io(void);
void suspend_secure_drivers(void);
/**
* @brief Resumes secure peripherals.
@ -84,4 +84,4 @@ void power_save_suspend_secure_io(void);
* It resumes secure peripherals that were suspended before entering
* the low-power state.
*/
void power_save_resume_secure_io(void);
void resume_secure_drivers(void);

View File

@ -16,55 +16,63 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef KERNEL_MODE
#if defined(KERNEL_MODE) && !defined(SECMON)
#include <trezor_bsp.h>
#include <trezor_rtl.h>
#include <sys/pmic.h>
#include <sys/power_save.h>
#include <sys/irq.h>
#include <sys/suspend.h>
#include <sys/suspend_io.h>
#include "power_manager_internal.h"
static wakeup_flags_t g_wakeup_flags = 0;
static void pm_background_tasks_suspend(void);
static bool pm_background_tasks_suspended(void);
static void pm_background_tasks_resume(void);
static void background_tasks_suspend(void);
static bool background_tasks_suspended(void);
static void background_tasks_resume(void);
pm_status_t pm_control_hibernate() {
if (!pmic_enter_shipmode()) {
return PM_ERROR;
}
// Wait for the device to power off
// systick_delay_ms(50);
return PM_ERROR;
void wakeup_flags_set(wakeup_flags_t flags) {
irq_key_t irq_key = irq_lock();
g_wakeup_flags |= flags;
irq_unlock(irq_key);
}
pm_wakeup_flags_t pm_control_suspend(void) {
void wakeup_flags_reset(void) {
irq_key_t irq_key = irq_lock();
g_wakeup_flags = 0;
irq_unlock(irq_key);
}
void wakeup_flags_get(wakeup_flags_t* flags) {
irq_key_t irq_key = irq_lock();
*flags = g_wakeup_flags;
irq_unlock(irq_key);
}
wakeup_flags_t system_suspend(void) {
// Clear all wakeup flags. From this point, any wakeup event that
// sets a wakeup flag causes this function to return.
pm_wakeup_flags_reset();
wakeup_flags_reset();
power_save_wakeup_params_t wakeup_params = {0};
// Deinitialize all drivers that are not required in low-power mode
// (e.g., USB, display, touch, haptic, etc.).
power_save_suspend_io(&wakeup_params);
suspend_drivers(&wakeup_params);
// In the following loop, the system will attempt to enter low-power mode.
// Low-power mode may be exited for various reasons, but the loop will
// terminate only if a wakeup flag is set, indicating that user interaction
// is required or the user needs to be notified.
pm_wakeup_flags_t wakeup_flags = 0;
pm_wakeup_flags_get(&wakeup_flags);
wakeup_flags_t wakeup_flags = 0;
wakeup_flags_get(&wakeup_flags);
while (wakeup_flags == 0) {
// Notify state machines running in the interrupt context about the
// impending low-power mode. They should complete any pending operations
// and avoid starting new ones.
pm_background_tasks_suspend();
background_tasks_suspend();
// Wait until all state machines are idle and the system is ready to enter
// low-power mode. This loop also exits if any wakeup flag is set
@ -75,33 +83,33 @@ pm_wakeup_flags_t pm_control_suspend(void) {
// TODO: Implement a 5-second timeout to trigger a fatal error.
// Check for wakeup flags again
pm_wakeup_flags_get(&wakeup_flags);
wakeup_flags_get(&wakeup_flags);
} while (!pm_background_tasks_suspended() && (wakeup_flags == 0));
} while (!background_tasks_suspended() && (wakeup_flags == 0));
if (wakeup_flags == 0) {
// Enter low-power mode
power_save_suspend_cpu();
suspend_cpu();
// At this point, all pending interrupts are processed.
// Some of them may set wakeup flags.
pm_wakeup_flags_get(&wakeup_flags);
wakeup_flags_get(&wakeup_flags);
}
// Resume state machines running in the interrupt context
pm_background_tasks_resume();
background_tasks_resume();
}
// Reinitialize all drivers that were stopped earlier
power_save_resume_io(&wakeup_params);
resume_drivers(&wakeup_params);
return wakeup_flags;
}
static void pm_background_tasks_suspend(void) {}
static void background_tasks_suspend(void) {}
static bool pm_background_tasks_suspended(void) { return true; }
static bool background_tasks_suspended(void) { return true; }
static void pm_background_tasks_resume(void) {}
static void background_tasks_resume(void) {}
#endif // KERNEL_MODE
#endif // defined(KERNEL_MODE) && !defined(SECMON)

View File

@ -22,7 +22,7 @@
#include <trezor_rtl.h>
#include <sys/irq.h>
#include <sys/power_save.h>
#include <sys/suspend_io.h>
#include <sys/systick.h>
#ifdef USE_BLE
@ -64,7 +64,7 @@
#endif
#ifdef SECURE_MODE
void power_save_suspend_cpu(void) {
void suspend_cpu(void) {
// Disable interrupts by setting PRIMASK to 1.
//
// The system can wake up, but interrupts will not be processed until
@ -89,7 +89,7 @@ void power_save_suspend_cpu(void) {
irq_unlock(irq_key);
}
void power_save_suspend_secure_io() {
void suspend_secure_drivers() {
#ifdef USE_STORAGE_HWKEY
secure_aes_deinit();
#endif
@ -101,7 +101,7 @@ void power_save_suspend_secure_io() {
#endif
}
void power_save_resume_secure_io() {
void resume_secure_drivers() {
#ifdef USE_STORAGE_HWKEY
secure_aes_init();
#endif
@ -119,8 +119,8 @@ void power_save_resume_secure_io() {
#endif // SECURE_MODE
void power_save_suspend_io(power_save_wakeup_params_t *wakeup_params) {
power_save_suspend_secure_io();
void suspend_drivers(power_save_wakeup_params_t *wakeup_params) {
suspend_secure_drivers();
#ifdef USE_USB
usb_stop();
@ -143,7 +143,7 @@ void power_save_suspend_io(power_save_wakeup_params_t *wakeup_params) {
#endif
}
void power_save_resume_io(const power_save_wakeup_params_t *wakeup_params) {
void resume_drivers(const power_save_wakeup_params_t *wakeup_params) {
#ifdef USE_DISPLAY
// Reinitialize all drivers that were stopped earlier
display_init(DISPLAY_RESET_CONTENT);
@ -164,7 +164,7 @@ void power_save_resume_io(const power_save_wakeup_params_t *wakeup_params) {
#ifdef USE_BLE
ble_resume(&wakeup_params->ble);
#endif
power_save_resume_secure_io();
resume_secure_drivers();
}
#endif // KERNEL_MODE

View File

@ -24,8 +24,8 @@
#include <sys/irq.h>
#include <sys/mpu.h>
#include <sys/power_manager.h>
#include <sys/rtc.h>
#include <sys/suspend.h>
// RTC driver structure
typedef struct {
@ -102,7 +102,7 @@ void RTC_IRQHandler(void) {
// Deactivate the wakeup timer to prevent re-triggering
HAL_RTCEx_DeactivateWakeUpTimer(&g_rtc_driver.hrtc);
// Signal the wakeup event to the power manager
pm_wakeup_flags_set(PM_WAKEUP_FLAG_RTC);
wakeup_flags_set(WAKEUP_FLAG_RTC);
}
mpu_restore(mpu_mode);

View File

@ -268,17 +268,19 @@ def configure(
defines += ["USE_PMIC"]
features_available.append("pmic")
if "power_save" in features_wanted:
sources += ["embed/sys/power_save/stm32u5/power_save.c"]
paths += ["embed/sys/power_save/inc"]
defines += [("USE_POWER_SAVE", "1")]
if "suspend" in features_wanted:
sources += [
"embed/sys/suspend/stm32u5/suspend.c",
"embed/sys/suspend/stm32u5/suspend_io.c",
]
paths += ["embed/sys/suspend/inc"]
defines += [("USE_SUSPEND", "1")]
if "power_manager" in features_wanted:
sources += [
"embed/sys/power_manager/stm32u5/power_manager.c",
"embed/sys/power_manager/stm32u5/power_monitoring.c",
"embed/sys/power_manager/stm32u5/power_states.c",
"embed/sys/power_manager/stm32u5/power_control.c",
"embed/sys/power_manager/fuel_gauge/fuel_gauge.c",
"embed/sys/power_manager/fuel_gauge/battery_model.c",
"embed/sys/power_manager/stwlc38/stwlc38.c",

View File

@ -274,17 +274,19 @@ def configure(
defines += ["USE_PMIC"]
features_available.append("pmic")
if "power_save" in features_wanted:
sources += ["embed/sys/power_save/stm32u5/power_save.c"]
paths += ["embed/sys/power_save/inc"]
defines += [("USE_POWER_SAVE", "1")]
if "suspend" in features_wanted:
sources += [
"embed/sys/suspend/stm32u5/suspend.c",
"embed/sys/suspend/stm32u5/suspend_io.c",
]
paths += ["embed/sys/suspend/inc"]
defines += [("USE_SUSPEND", "1")]
if "power_manager" in features_wanted:
sources += [
"embed/sys/power_manager/stm32u5/power_manager.c",
"embed/sys/power_manager/stm32u5/power_monitoring.c",
"embed/sys/power_manager/stm32u5/power_states.c",
"embed/sys/power_manager/stm32u5/power_control.c",
"embed/sys/power_manager/fuel_gauge/fuel_gauge.c",
"embed/sys/power_manager/fuel_gauge/battery_model.c",
"embed/sys/power_manager/stwlc38/stwlc38.c",

View File

@ -273,17 +273,19 @@ def configure(
defines += ["USE_PMIC"]
features_available.append("pmic")
if "power_save" in features_wanted:
sources += ["embed/sys/power_save/stm32u5/power_save.c"]
paths += ["embed/sys/power_save/inc"]
defines += [("USE_POWER_SAVE", "1")]
if "suspend" in features_wanted:
sources += [
"embed/sys/suspend/stm32u5/suspend.c",
"embed/sys/suspend/stm32u5/suspend_io.c",
]
paths += ["embed/sys/suspend/inc"]
defines += [("USE_SUSPEND", "1")]
if "power_manager" in features_wanted:
sources += [
"embed/sys/power_manager/stm32u5/power_manager.c",
"embed/sys/power_manager/stm32u5/power_monitoring.c",
"embed/sys/power_manager/stm32u5/power_states.c",
"embed/sys/power_manager/stm32u5/power_control.c",
"embed/sys/power_manager/fuel_gauge/fuel_gauge.c",
"embed/sys/power_manager/fuel_gauge/battery_model.c",
"embed/sys/power_manager/stwlc38/stwlc38.c",