mirror of
https://github.com/esphome/esphome.git
synced 2025-11-18 15:55:46 +00:00
[bthome] Use StaticVector with compile-time sizes
Switch from FixedVector (runtime-sized, heap allocated) to StaticVector (compile-time sized, stack allocated) for better memory efficiency: **Changes:** - Replace FixedVector with StaticVector in bthome.h - Use cg.add_define to set sizes at compile time before creating component - Remove runtime init() calls (StaticVector doesn't need them) - Add default defines to esphome/core/defines.h for static analysis **Benefits:** - All memory allocated on stack at compile time - Zero runtime allocation overhead - Better for embedded systems with limited heap - StaticVector allocates all N slots upfront (no dynamic growth) **Defines added:** - BTHOME_MAX_MEASUREMENTS: Max number of sensor measurements - BTHOME_MAX_BINARY_MEASUREMENTS: Max number of binary sensor measurements - BTHOME_MAX_ADV_PACKETS: Max advertisement packets for cycling Sizes are calculated from YAML config and set via cg.add_define before component instantiation, ensuring compile-time type safety.
This commit is contained in:
@@ -172,6 +172,16 @@ FINAL_VALIDATE_SCHEMA = esp32_ble.validate_variant
|
|||||||
|
|
||||||
|
|
||||||
async def to_code(config):
|
async def to_code(config):
|
||||||
|
# Calculate sizes for StaticVector compile-time allocation
|
||||||
|
num_sensors = max(1, len(config.get(CONF_SENSORS, [])))
|
||||||
|
num_binary_sensors = max(1, len(config.get(CONF_BINARY_SENSORS, [])))
|
||||||
|
max_packets = max(1, num_sensors + num_binary_sensors)
|
||||||
|
|
||||||
|
# Add defines for compile-time sizes (must be before new_Pvariable)
|
||||||
|
cg.add_define("BTHOME_MAX_MEASUREMENTS", num_sensors)
|
||||||
|
cg.add_define("BTHOME_MAX_BINARY_MEASUREMENTS", num_binary_sensors)
|
||||||
|
cg.add_define("BTHOME_MAX_ADV_PACKETS", max_packets)
|
||||||
|
|
||||||
var = cg.new_Pvariable(config[CONF_ID])
|
var = cg.new_Pvariable(config[CONF_ID])
|
||||||
|
|
||||||
parent = await cg.get_variable(config[esp32_ble.CONF_BLE_ID])
|
parent = await cg.get_variable(config[esp32_ble.CONF_BLE_ID])
|
||||||
@@ -182,17 +192,6 @@ async def to_code(config):
|
|||||||
cg.add(var.set_max_interval(config[CONF_MAX_INTERVAL]))
|
cg.add(var.set_max_interval(config[CONF_MAX_INTERVAL]))
|
||||||
cg.add(var.set_tx_power(config[CONF_TX_POWER]))
|
cg.add(var.set_tx_power(config[CONF_TX_POWER]))
|
||||||
|
|
||||||
# Initialize FixedVectors with proper sizes
|
|
||||||
num_sensors = len(config.get(CONF_SENSORS, []))
|
|
||||||
num_binary_sensors = len(config.get(CONF_BINARY_SENSORS, []))
|
|
||||||
max_packets = max(1, num_sensors + num_binary_sensors)
|
|
||||||
|
|
||||||
# Initialize the measurements and binary_measurements FixedVectors
|
|
||||||
cg.add(cg.RawExpression(f"{var}->measurements_.init({num_sensors})"))
|
|
||||||
cg.add(cg.RawExpression(f"{var}->binary_measurements_.init({num_binary_sensors})"))
|
|
||||||
cg.add(cg.RawExpression(f"{var}->adv_packets_.init({max_packets})"))
|
|
||||||
cg.add(cg.RawExpression(f"{var}->adv_packet_sizes_.init({max_packets})"))
|
|
||||||
|
|
||||||
if CONF_ENCRYPTION_KEY in config:
|
if CONF_ENCRYPTION_KEY in config:
|
||||||
key = config[CONF_ENCRYPTION_KEY]
|
key = config[CONF_ENCRYPTION_KEY]
|
||||||
key_bytes = [cg.RawExpression(f"0x{key[i:i+2]}") for i in range(0, len(key), 2)]
|
key_bytes = [cg.RawExpression(f"0x{key[i:i+2]}") for i in range(0, len(key), 2)]
|
||||||
|
|||||||
@@ -57,8 +57,8 @@ class BTHome : public Component, public GAPEventHandler, public Parented<ESP32BL
|
|||||||
bool encrypt_payload_(const uint8_t *plaintext, size_t plaintext_len, uint8_t *ciphertext, size_t *ciphertext_len);
|
bool encrypt_payload_(const uint8_t *plaintext, size_t plaintext_len, uint8_t *ciphertext, size_t *ciphertext_len);
|
||||||
void trigger_immediate_advertising_(uint8_t measurement_index, bool is_binary);
|
void trigger_immediate_advertising_(uint8_t measurement_index, bool is_binary);
|
||||||
|
|
||||||
FixedVector<SensorMeasurement> measurements_;
|
StaticVector<SensorMeasurement, BTHOME_MAX_MEASUREMENTS> measurements_;
|
||||||
FixedVector<BinarySensorMeasurement> binary_measurements_;
|
StaticVector<BinarySensorMeasurement, BTHOME_MAX_BINARY_MEASUREMENTS> binary_measurements_;
|
||||||
|
|
||||||
uint16_t min_interval_{};
|
uint16_t min_interval_{};
|
||||||
uint16_t max_interval_{};
|
uint16_t max_interval_{};
|
||||||
@@ -72,8 +72,8 @@ class BTHome : public Component, public GAPEventHandler, public Parented<ESP32BL
|
|||||||
uint32_t counter_{0};
|
uint32_t counter_{0};
|
||||||
|
|
||||||
// Advertisement cycling support
|
// Advertisement cycling support
|
||||||
FixedVector<std::unique_ptr<uint8_t[]>> adv_packets_; // Multiple advertisement packets
|
StaticVector<std::unique_ptr<uint8_t[]>, BTHOME_MAX_ADV_PACKETS> adv_packets_; // Multiple advertisement packets
|
||||||
FixedVector<uint16_t> adv_packet_sizes_; // Size of each packet
|
StaticVector<uint16_t, BTHOME_MAX_ADV_PACKETS> adv_packet_sizes_; // Size of each packet
|
||||||
uint8_t current_packet_index_{0};
|
uint8_t current_packet_index_{0};
|
||||||
bool data_changed_{true};
|
bool data_changed_{true};
|
||||||
bool immediate_advertising_pending_{false};
|
bool immediate_advertising_pending_{false};
|
||||||
|
|||||||
@@ -176,6 +176,9 @@
|
|||||||
#define USE_ESP32_BLE_SERVER
|
#define USE_ESP32_BLE_SERVER
|
||||||
#define USE_ESP32_BLE_UUID
|
#define USE_ESP32_BLE_UUID
|
||||||
#define USE_ESP32_BLE_ADVERTISING
|
#define USE_ESP32_BLE_ADVERTISING
|
||||||
|
#define BTHOME_MAX_MEASUREMENTS 8
|
||||||
|
#define BTHOME_MAX_BINARY_MEASUREMENTS 8
|
||||||
|
#define BTHOME_MAX_ADV_PACKETS 16
|
||||||
#define USE_ESP32_BLE_SERVER_SET_VALUE_ACTION
|
#define USE_ESP32_BLE_SERVER_SET_VALUE_ACTION
|
||||||
#define USE_ESP32_BLE_SERVER_DESCRIPTOR_SET_VALUE_ACTION
|
#define USE_ESP32_BLE_SERVER_DESCRIPTOR_SET_VALUE_ACTION
|
||||||
#define USE_ESP32_BLE_SERVER_NOTIFY_ACTION
|
#define USE_ESP32_BLE_SERVER_NOTIFY_ACTION
|
||||||
|
|||||||
Reference in New Issue
Block a user