mirror of
https://github.com/esphome/esphome.git
synced 2026-08-22 22:26:21 +00:00
[bk72xx_ble] Codegen-sized StaticVector for scan listeners (#18055)
This commit is contained in:
@@ -24,6 +24,7 @@ from esphome.components import libretiny
|
|||||||
from esphome.components.libretiny.const import FAMILY_BK7231N, FAMILY_BK7238
|
from esphome.components.libretiny.const import FAMILY_BK7231N, FAMILY_BK7238
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.const import CONF_ENABLE_ON_BOOT, CONF_ID
|
from esphome.const import CONF_ENABLE_ON_BOOT, CONF_ID
|
||||||
|
from esphome.core import CORE, CoroPriority, coroutine_with_priority
|
||||||
from esphome.types import ConfigType
|
from esphome.types import ConfigType
|
||||||
|
|
||||||
DEPENDENCIES = ["bk72xx"]
|
DEPENDENCIES = ["bk72xx"]
|
||||||
@@ -45,6 +46,23 @@ CONFIG_SCHEMA = cv.Schema(
|
|||||||
).extend(cv.COMPONENT_SCHEMA)
|
).extend(cv.COMPONENT_SCHEMA)
|
||||||
|
|
||||||
|
|
||||||
|
KEY_SCAN_LISTENER_COUNT = "bk72xx_ble_scan_listener_count"
|
||||||
|
|
||||||
|
|
||||||
|
def request_scan_listener_slot() -> None:
|
||||||
|
"""Called from a consumer's codegen once per registered scan listener; sizes
|
||||||
|
the controller's StaticVector listener storage (heap-free, mirrors the
|
||||||
|
tracker's ble_device_base listener storage)."""
|
||||||
|
CORE.data[KEY_SCAN_LISTENER_COUNT] = CORE.data.get(KEY_SCAN_LISTENER_COUNT, 0) + 1
|
||||||
|
|
||||||
|
|
||||||
|
@coroutine_with_priority(CoroPriority.FINAL)
|
||||||
|
async def _add_listener_count() -> None:
|
||||||
|
# FINAL: every consumer's to_code has requested its slot by now.
|
||||||
|
if count := CORE.data.get(KEY_SCAN_LISTENER_COUNT, 0):
|
||||||
|
cg.add_define("BK72XX_BLE_SCAN_LISTENER_COUNT", count)
|
||||||
|
|
||||||
|
|
||||||
async def to_code(config: ConfigType) -> None:
|
async def to_code(config: ConfigType) -> None:
|
||||||
var = cg.new_Pvariable(config[CONF_ID])
|
var = cg.new_Pvariable(config[CONF_ID])
|
||||||
await cg.register_component(var, config)
|
await cg.register_component(var, config)
|
||||||
@@ -92,3 +110,5 @@ async def to_code(config: ConfigType) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
cg.add_define("USE_BK72XX_BLE")
|
cg.add_define("USE_BK72XX_BLE")
|
||||||
|
|
||||||
|
CORE.add_job(_add_listener_count)
|
||||||
|
|||||||
@@ -179,8 +179,10 @@ void BK72xxBLE::loop() {
|
|||||||
if (report == nullptr)
|
if (report == nullptr)
|
||||||
return;
|
return;
|
||||||
do {
|
do {
|
||||||
|
#ifdef BK72XX_BLE_SCAN_LISTENER_COUNT
|
||||||
for (auto *listener : this->scan_listeners_)
|
for (auto *listener : this->scan_listeners_)
|
||||||
listener->on_scan_report(*report);
|
listener->on_scan_report(*report);
|
||||||
|
#endif
|
||||||
this->report_pool_.release(report);
|
this->report_pool_.release(report);
|
||||||
} while ((report = this->report_queue_.pop()) != nullptr);
|
} while ((report = this->report_queue_.pop()) != nullptr);
|
||||||
|
|
||||||
|
|||||||
@@ -6,10 +6,10 @@
|
|||||||
|
|
||||||
#include "esphome/core/component.h"
|
#include "esphome/core/component.h"
|
||||||
#include "esphome/core/event_pool.h"
|
#include "esphome/core/event_pool.h"
|
||||||
|
#include "esphome/core/helpers.h"
|
||||||
#include "esphome/core/lock_free_queue.h"
|
#include "esphome/core/lock_free_queue.h"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace esphome::bk72xx_ble {
|
namespace esphome::bk72xx_ble {
|
||||||
|
|
||||||
@@ -62,8 +62,12 @@ class BK72xxBLE final : public Component {
|
|||||||
/// Controller BLE address, least-significant octet first (BLE convention).
|
/// Controller BLE address, least-significant octet first (BLE convention).
|
||||||
void get_mac_lsb_first(uint8_t out[6]) const;
|
void get_mac_lsb_first(uint8_t out[6]) const;
|
||||||
|
|
||||||
|
#ifdef BK72XX_BLE_SCAN_LISTENER_COUNT
|
||||||
/// Register a consumer for scan reports (delivered on the main task via loop()).
|
/// Register a consumer for scan reports (delivered on the main task via loop()).
|
||||||
|
/// Storage is codegen-sized: the consumer's codegen requests a slot via
|
||||||
|
/// request_scan_listener_slot(), which emits BK72XX_BLE_SCAN_LISTENER_COUNT.
|
||||||
void register_scan_listener(BLEScanListener *listener) { this->scan_listeners_.push_back(listener); }
|
void register_scan_listener(BLEScanListener *listener) { this->scan_listeners_.push_back(listener); }
|
||||||
|
#endif
|
||||||
|
|
||||||
/// Start the controller scan. Interval/window are in BLE units (0.625 ms).
|
/// Start the controller scan. Interval/window are in BLE units (0.625 ms).
|
||||||
/// Enables the stack first if needed. Returns false on controller failure.
|
/// Enables the stack first if needed. Returns false on controller failure.
|
||||||
@@ -78,7 +82,11 @@ class BK72xxBLE final : public Component {
|
|||||||
protected:
|
protected:
|
||||||
void resolve_mac_();
|
void resolve_mac_();
|
||||||
|
|
||||||
std::vector<BLEScanListener *> scan_listeners_;
|
#ifdef BK72XX_BLE_SCAN_LISTENER_COUNT
|
||||||
|
// Codegen-sized: no heap allocation, no std::vector template instantiation —
|
||||||
|
// the same StaticVector pattern as the tracker's ble_device_base listeners.
|
||||||
|
StaticVector<BLEScanListener *, BK72XX_BLE_SCAN_LISTENER_COUNT> scan_listeners_;
|
||||||
|
#endif
|
||||||
// Report ring: the BDK notice callback (BLE task) allocates a report from the
|
// Report ring: the BDK notice callback (BLE task) allocates a report from the
|
||||||
// pool, fills it and pushes the pointer; loop() pops, dispatches and releases.
|
// pool, fills it and pushes the pointer; loop() pops, dispatches and releases.
|
||||||
// Lock-free SPSC, zero allocation at steady state — the esp32_ble pattern.
|
// Lock-free SPSC, zero allocation at steady state — the esp32_ble pattern.
|
||||||
|
|||||||
@@ -69,6 +69,9 @@ async def to_code(config: ConfigType) -> None:
|
|||||||
|
|
||||||
parent = await cg.get_variable(config[CONF_BK72XX_BLE_ID])
|
parent = await cg.get_variable(config[CONF_BK72XX_BLE_ID])
|
||||||
cg.add(var.set_parent(parent))
|
cg.add(var.set_parent(parent))
|
||||||
|
# The tracker registers itself as a controller scan listener in setup();
|
||||||
|
# request the codegen-sized StaticVector slot for it.
|
||||||
|
bk72xx_ble.request_scan_listener_slot()
|
||||||
|
|
||||||
# Get notified when an OTA update starts, to pause scanning (esp32_ble_tracker parity)
|
# Get notified when an OTA update starts, to pause scanning (esp32_ble_tracker parity)
|
||||||
ota.request_ota_state_listeners()
|
ota.request_ota_state_listeners()
|
||||||
|
|||||||
@@ -454,6 +454,7 @@
|
|||||||
|
|
||||||
#ifdef USE_LIBRETINY
|
#ifdef USE_LIBRETINY
|
||||||
#define USE_BK72XX_BLE
|
#define USE_BK72XX_BLE
|
||||||
|
#define BK72XX_BLE_SCAN_LISTENER_COUNT 1
|
||||||
#define USE_LN882H_BLE
|
#define USE_LN882H_BLE
|
||||||
#define LN882H_BLE_SCAN_LISTENER_COUNT 1
|
#define LN882H_BLE_SCAN_LISTENER_COUNT 1
|
||||||
#define USE_CAPTIVE_PORTAL
|
#define USE_CAPTIVE_PORTAL
|
||||||
|
|||||||
Reference in New Issue
Block a user