feat(ble/nimble): support runtime allocation for mempool

This commit is contained in:
chenjianhua
2025-11-17 15:26:09 +08:00
parent 8fd41d86c4
commit c6709f6efa
25 changed files with 427 additions and 49 deletions
+8 -2
View File
@@ -58,10 +58,14 @@ static uint16_t ble_att_svr_id;
static void *ble_att_svr_entry_mem;
static struct os_mempool ble_att_svr_entry_pool;
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
static os_membuf_t *ble_att_svr_prep_entry_mem = NULL;
#else
static os_membuf_t ble_att_svr_prep_entry_mem[
OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_ATT_SVR_MAX_PREP_ENTRIES),
sizeof (struct ble_att_prep_entry))
];
#endif
static struct os_mempool ble_att_svr_prep_entry_pool;
@@ -71,7 +75,7 @@ ble_att_svr_entry_alloc(void)
struct ble_att_svr_entry *entry;
entry = os_memblock_get(&ble_att_svr_entry_pool);
#if MYNEWT_VAL(BLE_DYNAMIC_SERVICE)
#if MYNEWT_VAL(BLE_DYNAMIC_SERVICE) && !MYNEWT_VAL(MP_RUNTIME_ALLOC)
/* if dynamic services are enabled, try to allocate from heap */
if (entry == NULL) {
entry = nimble_platform_mem_malloc(sizeof *entry);
@@ -87,7 +91,7 @@ ble_att_svr_entry_alloc(void)
static void
ble_att_svr_entry_free(struct ble_att_svr_entry *entry)
{
#if MYNEWT_VAL(BLE_DYNAMIC_SERVICE)
#if MYNEWT_VAL(BLE_DYNAMIC_SERVICE) && !MYNEWT_VAL(MP_RUNTIME_ALLOC)
if (os_memblock_from(&ble_att_svr_entry_pool, entry)) {
os_memblock_put(&ble_att_svr_entry_pool, entry);
}
@@ -3333,6 +3337,7 @@ ble_att_svr_start(void)
ble_att_svr_free_start_mem();
if (ble_hs_max_attrs > 0) {
#if !MYNEWT_VAL(MP_RUNTIME_ALLOC)
ble_att_svr_entry_mem = nimble_platform_mem_malloc(
OS_MEMPOOL_BYTES(ble_hs_max_attrs,
sizeof (struct ble_att_svr_entry)));
@@ -3340,6 +3345,7 @@ ble_att_svr_start(void)
rc = BLE_HS_ENOMEM;
goto err;
}
#endif
rc = os_mempool_init(&ble_att_svr_entry_pool, ble_hs_max_attrs,
sizeof (struct ble_att_svr_entry),
+7 -1
View File
@@ -59,12 +59,18 @@ static ble_eatt_att_rx_fn ble_eatt_att_rx_cb;
#define BLE_EATT_MEMPOOL_SIZE \
OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_EATT_CHAN_NUM) + 1, BLE_EATT_MEMBLOCK_SIZE)
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
static os_membuf_t *ble_eatt_conn_mem = NULL;
static os_membuf_t *ble_eatt_sdu_coc_mem = NULL;
#else
static os_membuf_t ble_eatt_conn_mem[
OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_EATT_CHAN_NUM),
sizeof(struct ble_eatt))
];
static struct os_mempool ble_eatt_conn_pool;
static os_membuf_t ble_eatt_sdu_coc_mem[BLE_EATT_MEMPOOL_SIZE];
#endif
static struct os_mempool ble_eatt_conn_pool;
struct os_mbuf_pool ble_eatt_sdu_os_mbuf_pool;
static struct os_mempool ble_eatt_sdu_mbuf_mempool;
+4
View File
@@ -296,9 +296,13 @@ struct ble_gap_snapshot {
};
static SLIST_HEAD(ble_gap_hook_list, ble_gap_event_listener) ble_gap_event_listener_list;
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
static os_membuf_t *ble_gap_update_entry_mem = NULL;
#else
static os_membuf_t ble_gap_update_entry_mem[
OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE),
sizeof (struct ble_gap_update_entry))];
#endif
static struct os_mempool ble_gap_update_entry_pool;
static struct ble_gap_update_entry_list ble_gap_update_entries;
+5
View File
@@ -471,10 +471,15 @@ static const struct ble_gattc_rx_exec_entry {
};
#endif
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
static os_membuf_t *ble_gattc_proc_mem = NULL;
#else
static os_membuf_t ble_gattc_proc_mem[
OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_GATT_MAX_PROCS),
sizeof (struct ble_gattc_proc))
];
#endif
static struct os_mempool ble_gattc_proc_pool;
+32 -10
View File
@@ -2123,21 +2123,32 @@ ble_gattc_cache_conn_get_svc_changed_handle(uint16_t conn_handle)
void
ble_gattc_cache_conn_free_mem(void)
{
nimble_platform_mem_free(ble_gattc_cache_conn_mem);
ble_gattc_cache_conn_mem = NULL;
if (ble_gattc_cache_conn_mem) {
nimble_platform_mem_free(ble_gattc_cache_conn_mem);
ble_gattc_cache_conn_mem = NULL;
}
nimble_platform_mem_free(ble_gattc_cache_conn_svc_mem);
ble_gattc_cache_conn_svc_mem = NULL;
if (ble_gattc_cache_conn_svc_mem) {
nimble_platform_mem_free(ble_gattc_cache_conn_svc_mem);
ble_gattc_cache_conn_svc_mem = NULL;
}
#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES)
nimble_platform_mem_free(ble_gattc_cache_conn_incl_svc_mem);
ble_gattc_cache_conn_incl_svc_mem = NULL;
if (ble_gattc_cache_conn_incl_svc_mem) {
nimble_platform_mem_free(ble_gattc_cache_conn_incl_svc_mem);
ble_gattc_cache_conn_incl_svc_mem = NULL;
}
#endif
nimble_platform_mem_free(ble_gattc_cache_conn_chr_mem);
ble_gattc_cache_conn_chr_mem = NULL;
nimble_platform_mem_free(ble_gattc_cache_conn_dsc_mem);
ble_gattc_cache_conn_dsc_mem = NULL;
if (ble_gattc_cache_conn_chr_mem) {
nimble_platform_mem_free(ble_gattc_cache_conn_chr_mem);
ble_gattc_cache_conn_chr_mem = NULL;
}
if (ble_gattc_cache_conn_dsc_mem) {
nimble_platform_mem_free(ble_gattc_cache_conn_dsc_mem);
ble_gattc_cache_conn_dsc_mem = NULL;
}
}
int
@@ -2167,12 +2178,14 @@ ble_gattc_cache_conn_init()
/* Free memory first in case this function gets called more than once. */
ble_gattc_cache_conn_free_mem();
#if !MYNEWT_VAL(MP_RUNTIME_ALLOC)
ble_gattc_cache_conn_mem = nimble_platform_mem_malloc(
OS_MEMPOOL_BYTES(max_ble_gattc_cache_conns, sizeof(struct ble_gattc_cache_conn)));
if (ble_gattc_cache_conn_mem == NULL) {
rc = BLE_HS_ENOMEM;
goto err;
}
#endif
rc = os_mempool_init(&ble_gattc_cache_conn_pool, max_ble_gattc_cache_conns,
sizeof(struct ble_gattc_cache_conn), ble_gattc_cache_conn_mem,
@@ -2182,12 +2195,14 @@ ble_gattc_cache_conn_init()
goto err;
}
#if !MYNEWT_VAL(MP_RUNTIME_ALLOC)
ble_gattc_cache_conn_svc_mem = nimble_platform_mem_malloc(
OS_MEMPOOL_BYTES(max_svcs, sizeof(struct ble_gattc_cache_conn_svc)));
if (ble_gattc_cache_conn_svc_mem == NULL) {
rc = BLE_HS_ENOMEM;
goto err;
}
#endif
rc = os_mempool_init(&ble_gattc_cache_conn_svc_pool, max_svcs,
sizeof(struct ble_gattc_cache_conn_svc), ble_gattc_cache_conn_svc_mem,
@@ -2198,12 +2213,14 @@ ble_gattc_cache_conn_init()
}
#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES)
#if !MYNEWT_VAL(MP_RUNTIME_ALLOC)
ble_gattc_cache_conn_incl_svc_mem = nimble_platform_mem_malloc(
OS_MEMPOOL_BYTES(max_incl_svcs, sizeof(struct ble_gattc_cache_conn_incl_svc)));
if (ble_gattc_cache_conn_incl_svc_mem == NULL) {
rc = BLE_HS_ENOMEM;
goto err;
}
#endif
rc = os_mempool_init(&ble_gattc_cache_conn_incl_svc_pool, max_incl_svcs,
sizeof(struct ble_gattc_cache_conn_incl_svc), ble_gattc_cache_conn_incl_svc_mem,
@@ -2213,12 +2230,15 @@ ble_gattc_cache_conn_init()
goto err;
}
#endif
#if !MYNEWT_VAL(MP_RUNTIME_ALLOC)
ble_gattc_cache_conn_chr_mem = nimble_platform_mem_malloc(
OS_MEMPOOL_BYTES(max_chrs, sizeof(struct ble_gattc_cache_conn_chr)));
if (ble_gattc_cache_conn_chr_mem == NULL) {
rc = BLE_HS_ENOMEM;
goto err;
}
#endif
rc = os_mempool_init(&ble_gattc_cache_conn_chr_pool, max_chrs,
sizeof(struct ble_gattc_cache_conn_chr), ble_gattc_cache_conn_chr_mem,
@@ -2228,12 +2248,14 @@ ble_gattc_cache_conn_init()
goto err;
}
#if !MYNEWT_VAL(MP_RUNTIME_ALLOC)
ble_gattc_cache_conn_dsc_mem = nimble_platform_mem_malloc(
OS_MEMPOOL_BYTES(max_dscs, sizeof(struct ble_gattc_cache_conn_dsc)));
if (ble_gattc_cache_conn_dsc_mem == NULL) {
rc = BLE_HS_ENOMEM;
goto err;
}
#endif
rc = os_mempool_init(&ble_gattc_cache_conn_dsc_pool, max_dscs,
sizeof(struct ble_gattc_cache_conn_dsc), ble_gattc_cache_conn_dsc_mem,
+24 -2
View File
@@ -134,10 +134,12 @@ ble_gatts_svc_entry_alloc(void)
struct ble_gatts_svc_entry *entry;
entry = os_memblock_get(&ble_gatts_svc_entry_pool);
#if !MYNEWT_VAL(MP_RUNTIME_ALLOC)
/* if dynamic services are enabled, try to allocate from heap */
if (entry == NULL) {
entry = nimble_platform_mem_malloc(sizeof *entry);
}
#endif
if (entry != NULL) {
memset(entry, 0, sizeof *entry);
}
@@ -148,12 +150,16 @@ ble_gatts_svc_entry_alloc(void)
static void
ble_gatts_svc_entry_free(struct ble_gatts_svc_entry *entry)
{
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
os_memblock_put(&ble_gatts_svc_entry_pool, entry);
#else
if (os_memblock_from(&ble_gatts_svc_entry_pool, entry)) {
os_memblock_put(&ble_gatts_svc_entry_pool, entry);
}
else {
nimble_platform_mem_free(entry);
}
#endif
}
static struct ble_gatts_clt_cfg *
@@ -162,10 +168,12 @@ ble_gatts_clt_cfg_alloc(void)
struct ble_gatts_clt_cfg *cfg;
cfg = os_memblock_get(&ble_gatts_clt_cfg_pool);
#if !MYNEWT_VAL(MP_RUNTIME_ALLOC)
/* if dynamic services are enabled, try to allocate from heap */
if (cfg == NULL) {
cfg = nimble_platform_mem_malloc(sizeof *cfg);
}
#endif
if (cfg != NULL) {
memset(cfg, 0, sizeof *cfg);
}
@@ -175,12 +183,16 @@ ble_gatts_clt_cfg_alloc(void)
static void
ble_gatts_clt_cfg_free(struct ble_gatts_clt_cfg *cfg)
{
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
os_memblock_put(&ble_gatts_clt_cfg_pool, cfg);
#else
if (os_memblock_from(&ble_gatts_clt_cfg_pool, cfg)) {
os_memblock_put(&ble_gatts_clt_cfg_pool, cfg);
}
else {
nimble_platform_mem_free(cfg);
}
#endif
}
#endif
@@ -1649,6 +1661,9 @@ ble_gatts_stop(void)
ble_gatts_free_mem();
ble_gatts_free_svc_defs();
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
ble_att_svr_reset();
#endif
ble_att_svr_stop();
}
@@ -1681,6 +1696,7 @@ ble_gatts_start(void)
goto done;
}
#if !MYNEWT_VAL(MP_RUNTIME_ALLOC)
if (ble_hs_max_client_configs > 0) {
ble_gatts_clt_cfg_mem = nimble_platform_mem_malloc(
OS_MEMPOOL_BYTES(ble_hs_max_client_configs,
@@ -1690,20 +1706,26 @@ ble_gatts_start(void)
goto done;
}
}
#endif
if (ble_hs_max_services > 0) {
#if MYNEWT_VAL(BLE_DYNAMIC_SERVICE)
#if !MYNEWT_VAL(MP_RUNTIME_ALLOC)
ble_gatts_svc_entry_mem =
nimble_platform_mem_malloc(ble_hs_max_services * sizeof(struct ble_gatts_svc_entry));
nimble_platform_mem_calloc(1, ble_hs_max_services * sizeof(struct ble_gatts_svc_entry));
if (ble_gatts_svc_entry_mem == NULL) {
rc = BLE_HS_ENOMEM;
goto done;
}
#endif
#else
ble_gatts_svc_entries =
nimble_platform_mem_malloc(ble_hs_max_services * sizeof *ble_gatts_svc_entries);
if (ble_gatts_svc_entries == NULL) {
#endif
rc = BLE_HS_ENOMEM;
goto done;
}
#endif
}
#if MYNEWT_VAL(BLE_DYNAMIC_SERVICE)
+6 -1
View File
@@ -55,6 +55,7 @@ static void ble_hs_event_start_stage2(struct ble_npl_event *ev);
static void ble_hs_timer_sched(int32_t ticks_from_now);
struct os_mempool ble_hs_hci_ev_pool;
/* It is not recommended to use MP_RUNTIME_ALLOC when the block size is 4 bytes. */
static os_membuf_t ble_hs_hci_os_event_buf[
OS_MEMPOOL_SIZE(BLE_HS_HCI_EVT_COUNT, sizeof (struct ble_npl_event))
];
@@ -617,8 +618,12 @@ ble_hs_enqueue_hci_event(uint8_t *hci_evt)
ble_npl_event_init(ev, ble_hs_event_rx_hci_ev, hci_evt);
ble_npl_eventq_put(ble_hs_evq, ev);
} else {
/* Either ev is NULL or queue doesn't exist */
/* Either ev is NULL or queue doesn't exist */
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
ble_transport_free(BLE_HCI_EVT, hci_evt);
#else
ble_transport_free(hci_evt);
#endif
}
}
+4
View File
@@ -31,10 +31,14 @@
static SLIST_HEAD(, ble_hs_conn) ble_hs_conns;
static struct os_mempool ble_hs_conn_pool;
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
static os_membuf_t *ble_hs_conn_elem_mem = NULL;
#else
static os_membuf_t ble_hs_conn_elem_mem[
OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_MAX_CONNECTIONS),
sizeof (struct ble_hs_conn))
];
#endif
static const uint8_t ble_hs_conn_null_addr[6];
+10 -3
View File
@@ -39,6 +39,7 @@ static ble_npl_event_fn ble_hs_flow_event_cb;
static struct ble_npl_event ble_hs_flow_ev;
#if !MYNEWT_VAL(MP_RUNTIME_ALLOC)
/* Connection handle associated with each mbuf in ACL pool */
static uint16_t ble_hs_flow_mbuf_conn_handle[ MYNEWT_VAL(BLE_TRANSPORT_ACL_FROM_LL_COUNT) ];
@@ -55,6 +56,7 @@ ble_hs_flow_mbuf_index(const struct os_mbuf *om)
return idx;
}
#endif
static int
ble_hs_flow_tx_num_comp_pkts(void)
@@ -160,13 +162,18 @@ ble_hs_flow_acl_free(struct os_mempool_ext *mpe, void *data, void *arg)
struct ble_hs_conn *conn;
const struct os_mbuf *om;
uint16_t conn_handle;
int idx;
int rc;
om = data;
idx = ble_hs_flow_mbuf_index(om);
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
// For runtime allocation, get the connection handle from HCI ACL data
const struct hci_data_hdr *hdr = (void *)om->om_data;
conn_handle = BLE_HCI_DATA_HANDLE(hdr->hdh_handle_pb_bc);
#else
int idx = ble_hs_flow_mbuf_index(om);
conn_handle = ble_hs_flow_mbuf_conn_handle[idx];
#endif
/* Free the mbuf back to its pool. */
rc = os_memblock_put_from_cb(&mpe->mpe_mp, data);
@@ -209,7 +216,7 @@ ble_hs_flow_connection_broken(uint16_t conn_handle)
void
ble_hs_flow_track_data_mbuf(struct os_mbuf *om)
{
#if MYNEWT_VAL(BLE_HS_FLOW_CTRL)
#if MYNEWT_VAL(BLE_HS_FLOW_CTRL) && !MYNEWT_VAL(MP_RUNTIME_ALLOC)
const struct hci_data_hdr *hdr;
int idx = ble_hs_flow_mbuf_index(om);
+12
View File
@@ -302,7 +302,11 @@ static struct ble_hs_hci_sup_cmd ble_hs_hci_sup_cmd;
* from fragmenting outgoing packets and sending them (and ultimately freeing
* them).
*/
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
static os_membuf_t *ble_hs_hci_frag_data = NULL;
#else
static os_membuf_t ble_hs_hci_frag_data[BLE_HS_HCI_FRAG_MEMPOOL_SIZE];
#endif
static struct os_mbuf_pool ble_hs_hci_frag_mbuf_pool;
static struct os_mempool ble_hs_hci_frag_mempool;
@@ -578,7 +582,11 @@ ble_hs_hci_cmd_tx(uint16_t opcode, const void *cmd, uint8_t cmd_len,
}
done:
if (ble_hs_hci_ack != NULL) {
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
ble_transport_free(BLE_HCI_EVT, (uint8_t *) ble_hs_hci_ack);
#else
ble_transport_free((uint8_t *) ble_hs_hci_ack);
#endif
ble_hs_hci_ack = NULL;
}
@@ -608,7 +616,11 @@ ble_hs_hci_rx_ack(uint8_t *ack_ev)
{
if (ble_npl_sem_get_count(&ble_hs_hci_sem) > 0) {
/* This ack is unexpected; ignore it. */
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
ble_transport_free(BLE_HCI_EVT, ack_ev);
#else
ble_transport_free(ack_ev);
#endif
return;
}
BLE_HS_DBG_ASSERT(ble_hs_hci_ack == NULL);
+4
View File
@@ -1630,7 +1630,11 @@ ble_hs_hci_evt_process(struct ble_hci_ev *ev)
rc = entry->cb(ev->opcode, ev->data, ev->length);
}
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
ble_transport_free(BLE_HCI_EVT, (uint8_t *)ev);
#else
ble_transport_free((uint8_t *)ev);
#endif
return rc;
}
+4
View File
@@ -28,10 +28,14 @@
static SLIST_HEAD(, ble_hs_periodic_sync) g_ble_hs_periodic_sync_handles;
static struct os_mempool ble_hs_periodic_sync_pool;
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
static os_membuf_t *ble_hs_psync_elem_mem = NULL;
#else
static os_membuf_t ble_hs_psync_elem_mem[
OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_MAX_PERIODIC_SYNCS),
sizeof (struct ble_hs_periodic_sync))
];
#endif
struct ble_hs_periodic_sync *
ble_hs_periodic_sync_alloc(void)
+4
View File
@@ -33,11 +33,15 @@ _Static_assert(sizeof (struct ble_l2cap_hdr) == BLE_L2CAP_HDR_SZ,
struct os_mempool ble_l2cap_chan_pool;
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
static os_membuf_t *ble_l2cap_chan_mem = NULL;
#else
static os_membuf_t ble_l2cap_chan_mem[
OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_L2CAP_MAX_CHANS) +
MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM),
sizeof (struct ble_l2cap_chan))
];
#endif
STATS_SECT_DECL(ble_l2cap_stats) ble_l2cap_stats;
STATS_NAME_START(ble_l2cap_stats)
+4
View File
@@ -33,10 +33,14 @@ STAILQ_HEAD(ble_l2cap_coc_srv_list, ble_l2cap_coc_srv);
static struct ble_l2cap_coc_srv_list ble_l2cap_coc_srvs;
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
static os_membuf_t *ble_l2cap_coc_srv_mem = NULL;
#else
static os_membuf_t ble_l2cap_coc_srv_mem[
OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM),
sizeof(struct ble_l2cap_coc_srv))
];
#endif
static struct os_mempool ble_l2cap_coc_srv_pool;
+4
View File
@@ -162,10 +162,14 @@ static ble_l2cap_sig_rx_fn * const ble_l2cap_sig_dispatch[] = {
static uint8_t ble_l2cap_sig_cur_id;
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
static os_membuf_t *ble_l2cap_sig_proc_mem = NULL;
#else
static os_membuf_t ble_l2cap_sig_proc_mem[
OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_L2CAP_SIG_MAX_PROCS),
sizeof (struct ble_l2cap_sig_proc))
];
#endif
static struct os_mempool ble_l2cap_sig_proc_pool;
+4
View File
@@ -146,10 +146,14 @@ ble_sm_state_dispatch[BLE_SM_PROC_STATE_CNT] = {
#endif
};
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
static os_membuf_t *ble_sm_proc_mem = NULL;
#else
static os_membuf_t ble_sm_proc_mem[
OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_SM_MAX_PROCS),
sizeof (struct ble_sm_proc))
];
#endif
static struct os_mempool ble_sm_proc_pool;
@@ -241,7 +241,11 @@ hci_h4_sm_completed(struct hci_h4_sm *h4sm)
assert(h4sm->frame_cb);
rc = h4sm->frame_cb(h4sm->pkt_type, h4sm->buf);
if (rc != 0) {
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
ble_transport_free(h4sm->pkt_type, h4sm->buf);
#else
ble_transport_free(h4sm->buf);
#endif
}
h4sm->buf = NULL;
}
@@ -64,6 +64,12 @@ extern "C" {
/* Host-to-controller command. */
#define BLE_HCI_TRANS_BUF_CMD 3
#define BLE_HCI_NONE 0x00
#define BLE_HCI_CMD 0x01
#define BLE_HCI_ACL 0x02
#define BLE_HCI_SCO 0x03
#define BLE_HCI_EVT 0x04
void ble_transport_init(void);
esp_err_t ble_buf_alloc(void);
@@ -199,7 +205,11 @@ struct os_mbuf *ble_transport_alloc_acl_from_ll(void);
struct os_mbuf *ble_transport_alloc_iso_from_ll(void);
/* Generic deallocator for cmd/evt buffers */
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
void ble_transport_free(uint8_t type, void *buf);
#else
void ble_transport_free(void *buf);
#endif
/* Register put callback on acl_from_ll mbufs (for ll-hs flow control) */
int ble_transport_register_put_acl_from_ll_cb(os_mempool_put_fn *cb);
+50
View File
@@ -144,9 +144,11 @@ ble_transport_alloc_evt(int discardable)
buf = try_alloc_evt(&pool_evt_lo);
} else {
buf = try_alloc_evt(&pool_evt);
#if !MYNEWT_VAL(MP_RUNTIME_ALLOC)
if (!buf) {
buf = try_alloc_evt(&pool_evt_lo);
}
#endif
}
return buf;
@@ -242,6 +244,45 @@ ble_transport_alloc_iso_from_ll(void)
#endif
}
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
void
ble_transport_free(uint8_t type, void *buf)
{
struct ble_hci_ev *ev = buf;
bool discardable = false;
// HCI command
if (type == BLE_HCI_CMD) {
os_memblock_put(&pool_cmd, buf);
return;
}
assert(type == BLE_HCI_EVT);
// HCI low prio event
if (ev->opcode == BLE_HCI_EVCODE_LE_META) {
switch (ev->data[0]) {
case BLE_HCI_LE_SUBEV_ADV_RPT:
case BLE_HCI_LE_SUBEV_EXT_ADV_RPT:
discardable = true;
break;
default:
break;
}
}
if (discardable) {
os_memblock_put(&pool_evt_lo, buf);
#if BLE_TRANSPORT_IPC
hci_ipc_put(HCI_IPC_TYPE_EVT_DISCARDABLE);
#endif
} else {
os_memblock_put(&pool_evt, buf);
#if BLE_TRANSPORT_IPC
hci_ipc_put(HCI_IPC_TYPE_EVT);
#endif
}
}
#else
void
ble_transport_free(void *buf)
{
@@ -261,6 +302,7 @@ ble_transport_free(void *buf)
assert(0);
}
}
#endif // MYNEWT_VAL(MP_RUNTIME_ALLOC)
void
ble_transport_ipc_free(void *buf)
@@ -314,6 +356,10 @@ ble_transport_acl_put(struct os_mempool_ext *mpe, void *data, void *arg)
void ble_buf_free(void)
{
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
return;
#endif
os_msys_buf_free();
nimble_platform_mem_free(pool_evt_buf);
@@ -334,6 +380,10 @@ void ble_buf_free(void)
esp_err_t ble_buf_alloc(void)
{
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
return ESP_OK;
#endif
if (os_msys_buf_alloc()) {
return ESP_ERR_NO_MEM;
}
+4
View File
@@ -103,7 +103,11 @@ hci_uart_tx_char(void *arg)
ch = tx->buf[tx->idx];
tx->idx++;
if (tx->idx == tx->len) {
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
ble_transport_free(BLE_HCI_EVT, tx->buf);
#else
ble_transport_free(tx->buf);
#endif
OS_ENTER_CRITICAL(sr);
STAILQ_REMOVE_HEAD(&tx_q, tx_q_next);
OS_EXIT_CRITICAL(sr);
+4
View File
@@ -99,7 +99,11 @@ hci_uart_tx_char(void *arg)
ch = tx->buf[tx->idx];
tx->idx++;
if (tx->idx == tx->len) {
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
ble_transport_free(BLE_HCI_CMD, tx->buf);
#else
ble_transport_free(tx->buf);
#endif
OS_ENTER_CRITICAL(sr);
STAILQ_REMOVE_HEAD(&tx_q, tx_q_next);
OS_EXIT_CRITICAL(sr);
+6
View File
@@ -71,6 +71,8 @@ struct os_mempool {
SLIST_HEAD(,os_memblock);
/** Name for memory block */
const char *name;
/** The number of allocated blocks. */
uint32_t mp_alloc_blocks;
};
/**
@@ -78,6 +80,10 @@ struct os_mempool {
* (struct os_mempool_ext *).
*/
#define OS_MEMPOOL_F_EXT 0x01
/* Flag to indicate runtime allocation mode */
#define OS_MEMPOOL_F_RUNTIME 0x02
/* Flag to indicate reuse block for runtime allocation mode */
#define OS_MEMPOOL_F_REUSED 0x04
struct os_mempool_ext;
+10 -2
View File
@@ -66,6 +66,9 @@ static struct ble_npl_event ble_hs_ev_stop;
extern void os_msys_init(void);
extern void os_mempool_module_init(void);
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
extern void os_mempool_deinit(void);
#endif
/**
* Called when the host stop procedure has completed.
@@ -93,6 +96,9 @@ esp_err_t esp_nimble_init(void)
esp_err_t ret;
#endif
#if !SOC_ESP_NIMBLE_CONTROLLER || !CONFIG_BT_CONTROLLER_ENABLED
/* Initialize the global memory pool */
os_mempool_module_init();
/* Initialize the function pointers for OS porting */
npl_freertos_funcs_init();
@@ -117,8 +123,6 @@ esp_err_t esp_nimble_init(void)
/* Initialize default event queue */
ble_npl_eventq_init(&g_eventq_dflt);
/* Initialize the global memory pool */
os_mempool_module_init();
os_msys_init();
#endif
@@ -165,6 +169,10 @@ esp_err_t esp_nimble_deinit(void)
npl_freertos_mempool_deinit();
#endif
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
os_mempool_deinit();
#endif
return ESP_OK;
}
+170 -2
View File
@@ -25,6 +25,7 @@
#include <stdbool.h>
#include "syscfg/syscfg.h"
#include "modlog/modlog.h"
#include "esp_nimble_mem.h"
#if !MYNEWT_VAL(OS_SYSVIEW_TRACE_MEMPOOL)
#define OS_TRACE_DISABLE_FILE_API
#endif
@@ -132,9 +133,12 @@ os_mempool_init_internal(struct os_mempool *mp, uint16_t blocks,
return OS_INVALID_PARM;
}
/* For runtime allocation mode, membuf can be NULL */
#if !MYNEWT_VAL(MP_RUNTIME_ALLOC)
if ((!membuf) && (blocks != 0)) {
return OS_INVALID_PARM;
}
#endif
if (membuf != NULL) {
/* Blocks need to be sized properly and memory buffer should be
@@ -155,6 +159,22 @@ os_mempool_init_internal(struct os_mempool *mp, uint16_t blocks,
mp->name = name;
SLIST_FIRST(mp) = membuf;
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
if (membuf == NULL) {
/* Runtime allocation mode */
mp->mp_membuf_addr = 0;
mp->mp_flags |= OS_MEMPOOL_F_RUNTIME;
#if MYNEWT_VAL(MP_BLOCK_REUSED)
mp->mp_flags |= OS_MEMPOOL_F_REUSED;
mp->mp_alloc_blocks = 0;
#endif
SLIST_FIRST(mp) = NULL;
STAILQ_INSERT_TAIL(&g_os_mempool_list, mp, mp_list);
return OS_OK;
}
#endif
if (blocks > 0) {
os_mempool_poison(mp, membuf);
os_mempool_guard(mp, membuf);
@@ -255,6 +275,28 @@ os_mempool_clear(struct os_mempool *mp)
return OS_INVALID_PARM;
}
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
/* For runtime allocation mode, check whether all blocks have been freed */
if (mp->mp_flags & OS_MEMPOOL_F_RUNTIME) {
assert(mp->mp_num_free == mp->mp_num_blocks);
/* For block reused mode, free all allocated blocks */
if (mp->mp_flags & OS_MEMPOOL_F_REUSED) {
void *temp_ptr;
block_ptr = SLIST_FIRST(mp);
while (block_ptr) {
temp_ptr = block_ptr;
block_ptr = SLIST_NEXT(block_ptr, mb_next);
nimble_platform_mem_free(temp_ptr);
}
mp->mp_alloc_blocks = 0;
}
/* Only reset statistics */
SLIST_FIRST(mp) = NULL;
mp->mp_min_free = mp->mp_num_blocks;
return OS_OK;
}
#endif
true_block_size = OS_MEMPOOL_TRUE_BLOCK_SIZE(mp);
/* cleanup the memory pool structure */
@@ -287,7 +329,11 @@ os_mempool_clear(struct os_mempool *mp)
os_error_t
os_mempool_ext_clear(struct os_mempool_ext *mpe)
{
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
mpe->mpe_mp.mp_flags &= ~OS_MEMPOOL_F_EXT;
#else
mpe->mpe_mp.mp_flags = 0;
#endif
mpe->mpe_put_cb = NULL;
mpe->mpe_put_arg = NULL;
@@ -299,6 +345,13 @@ os_mempool_is_sane(const struct os_mempool *mp)
{
struct os_memblock *block;
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
/* Runtime mode cannot verify sanity */
if (mp->mp_flags & OS_MEMPOOL_F_RUNTIME) {
assert(0);
}
#endif
/* Verify that each block in the free list belongs to the mempool. */
SLIST_FOREACH(block, mp, mb_next) {
if (!os_memblock_from(mp, block)) {
@@ -318,6 +371,13 @@ os_memblock_from(const struct os_mempool *mp, const void *block_addr)
uintptr_t baddr32;
uint32_t end;
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
/* Runtime allocation mode doesn't support from */
if (mp->mp_flags & OS_MEMPOOL_F_RUNTIME) {
assert(0);
}
#endif
static_assert(sizeof block_addr == sizeof baddr32,
"Pointer to void must be 32-bits.");
@@ -348,6 +408,64 @@ os_memblock_get(struct os_mempool *mp)
/* Check to make sure they passed in a memory pool (or something) */
block = NULL;
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
/* Runtime allocation mode */
if (mp && mp->mp_flags & OS_MEMPOOL_F_RUNTIME) {
bool need_alloc = false;
void *allocated_block;
uint32_t alloc_size;
OS_ENTER_CRITICAL(sr);
if (mp->mp_num_free) {
if (mp->mp_flags & OS_MEMPOOL_F_REUSED) {
if (SLIST_FIRST(mp) != NULL) {
block = SLIST_FIRST(mp);
SLIST_FIRST(mp) = SLIST_NEXT(block, mb_next);
} else if (mp->mp_alloc_blocks < mp->mp_num_blocks) {
need_alloc = true;
mp->mp_alloc_blocks++;
}
} else {
need_alloc = true;
}
/* Decrement number free by 1 */
mp->mp_num_free--;
if (mp->mp_min_free > mp->mp_num_free) {
mp->mp_min_free = mp->mp_num_free;
}
}
OS_EXIT_CRITICAL(sr);
/* Allocate outside critical section to avoid holding lock too long */
if (need_alloc) {
alloc_size = OS_MEMPOOL_TRUE_BLOCK_SIZE(mp);
allocated_block = nimble_platform_mem_malloc(alloc_size);
if (allocated_block) {
/* Initialize poison and guard */
os_mempool_poison(mp, allocated_block);
os_mempool_guard(mp, allocated_block);
/* Save mempool pointer for block */
block = (struct os_memblock *)(allocated_block);
} else {
// Should not happen
OS_ENTER_CRITICAL(sr);
mp->mp_num_free++;
OS_EXIT_CRITICAL(sr);
esp_rom_printf("%s malloc failed, size=%u\n", __func__, alloc_size);
}
} else if (block) {
os_mempool_poison_check(mp, block);
os_mempool_guard_check(mp, block);
}
return block;
}
#endif
if (mp) {
OS_ENTER_CRITICAL(sr);
/* Check for any free */
@@ -386,6 +504,33 @@ os_memblock_put_from_cb(struct os_mempool *mp, void *block_addr)
os_trace_api_u32x2(OS_TRACE_ID_MEMBLOCK_PUT_FROM_CB, (uint32_t)(uintptr_t)mp,
(uint32_t)(uintptr_t)block_addr);
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
if (mp->mp_flags & OS_MEMPOOL_F_RUNTIME) {
bool need_free = true;
os_mempool_guard_check(mp, block_addr);
/* Runtime allocation mode - free directly */
OS_ENTER_CRITICAL(sr);
if (mp->mp_flags & OS_MEMPOOL_F_REUSED) {
block = (struct os_memblock *)block_addr;
SLIST_NEXT(block, mb_next) = SLIST_FIRST(mp);
SLIST_FIRST(mp) = block;
need_free = false;
}
mp->mp_num_free++;
assert(mp->mp_num_blocks >= mp->mp_num_free);
OS_EXIT_CRITICAL(sr);
/* Free outside critical section */
if (need_free) {
free(block_addr);
} else {
os_mempool_poison(mp, block_addr);
}
return OS_OK;
}
#endif
os_mempool_guard_check(mp, block_addr);
os_mempool_poison(mp, block_addr);
@@ -426,8 +571,13 @@ os_memblock_put(struct os_mempool *mp, void *block_addr)
}
#if MYNEWT_VAL(OS_MEMPOOL_CHECK)
/* Check that the block we are freeing is a valid block! */
assert(os_memblock_from(mp, block_addr));
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
if (!(mp->mp_flags & OS_MEMPOOL_F_RUNTIME))
#endif
{
/* Check that the block we are freeing is a valid block! */
assert(os_memblock_from(mp, block_addr));
}
/*
* Check for duplicate free.
@@ -485,3 +635,21 @@ os_mempool_module_init(void)
{
STAILQ_INIT(&g_os_mempool_list);
}
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
void
os_mempool_deinit(void)
{
struct os_mempool *mp = NULL;
mp = STAILQ_FIRST(&g_os_mempool_list);
// All mempool blocks should be reclaimed after nimble deinit
while (mp) {
if (mp->mp_flags & OS_MEMPOOL_F_RUNTIME) {
os_mempool_clear(mp);
}
mp = STAILQ_NEXT(mp, mp_list);
}
}
#endif
+33 -26
View File
@@ -114,9 +114,13 @@ static os_membuf_t *ble_freertos_ev_buf = NULL;
#else
struct os_mempool ble_freertos_ev_pool;
#if MYNEWT_VAL(MP_RUNTIME_ALLOC)
static os_membuf_t *ble_freertos_ev_buf = NULL;
#else
static os_membuf_t ble_freertos_ev_buf[
OS_MEMPOOL_SIZE(BLE_TOTAL_EV_COUNT, sizeof (struct ble_npl_event_freertos))
];
#endif
#endif
@@ -176,7 +180,7 @@ npl_freertos_event_init(struct ble_npl_event *ev, ble_npl_event_fn *fn,
{
struct ble_npl_event_freertos *event = NULL;
#if OS_MEM_ALLOC
if (!os_memblock_from(&ble_freertos_ev_pool,ev->event)) {
if (!ev->event) {
ev->event = os_memblock_get(&ble_freertos_ev_pool);
}
#else
@@ -217,7 +221,7 @@ npl_freertos_eventq_init(struct ble_npl_eventq *evq)
{
struct ble_npl_eventq_freertos *eventq = NULL;
#if OS_MEM_ALLOC
if (!os_memblock_from(&ble_freertos_evq_pool,evq->eventq)) {
if (!evq->eventq) {
evq->eventq = os_memblock_get(&ble_freertos_evq_pool);
eventq = (struct ble_npl_eventq_freertos*)evq->eventq;
BLE_LL_ASSERT(eventq);
@@ -399,7 +403,7 @@ npl_freertos_mutex_init(struct ble_npl_mutex *mu)
{
struct ble_npl_mutex_freertos *mutex = NULL;
#if OS_MEM_ALLOC
if (!os_memblock_from(&ble_freertos_mutex_pool,mu->mutex)) {
if (!mu->mutex) {
mu->mutex = os_memblock_get(&ble_freertos_mutex_pool);
mutex = (struct ble_npl_mutex_freertos *)mu->mutex;
@@ -546,7 +550,7 @@ npl_freertos_sem_init(struct ble_npl_sem *sem, uint16_t tokens)
{
struct ble_npl_sem_freertos *semaphor = NULL;
#if OS_MEM_ALLOC
if (!os_memblock_from(&ble_freertos_sem_pool,sem->sem)) {
if (!sem->sem) {
sem->sem = os_memblock_get(&ble_freertos_sem_pool);
semaphor = (struct ble_npl_sem_freertos *)sem->sem;
@@ -708,7 +712,7 @@ npl_freertos_callout_init(struct ble_npl_callout *co, struct ble_npl_eventq *evq
struct ble_npl_callout_freertos *callout = NULL;
#if OS_MEM_ALLOC
if (!os_memblock_from(&ble_freertos_co_pool, co->co)) {
if (!co->co) {
co->co = os_memblock_get(&ble_freertos_co_pool);
callout = (struct ble_npl_callout_freertos *)co->co;
BLE_LL_ASSERT(callout);
@@ -1151,7 +1155,7 @@ int npl_freertos_mempool_init(void)
{
int rc = -1;
#if SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED
#if SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED && !MYNEWT_VAL(MP_RUNTIME_ALLOC)
ble_freertos_ev_buf = nimble_platform_mem_malloc(OS_MEMPOOL_SIZE(BLE_TOTAL_EV_COUNT, sizeof (struct ble_npl_event_freertos)) * sizeof(os_membuf_t));
if(!ble_freertos_ev_buf) {
goto _error;
@@ -1159,14 +1163,17 @@ int npl_freertos_mempool_init(void)
#endif
#if CONFIG_BT_CONTROLLER_ENABLED
/* It is not recommended to use MP_RUNTIME_ALLOC when the block size is 4 bytes. */
ble_freertos_evq_buf = nimble_platform_mem_malloc(OS_MEMPOOL_SIZE(BLE_TOTAL_EVQ_COUNT, sizeof (struct ble_npl_eventq_freertos)) * sizeof(os_membuf_t));
if(!ble_freertos_evq_buf) {
goto _error;
}
#if !MYNEWT_VAL(MP_RUNTIME_ALLOC)
ble_freertos_co_buf = nimble_platform_mem_malloc(OS_MEMPOOL_SIZE(BLE_TOTAL_CO_COUNT, sizeof (struct ble_npl_callout_freertos)) * sizeof(os_membuf_t));
if(!ble_freertos_co_buf) {
goto _error;
}
#endif
ble_freertos_sem_buf = nimble_platform_mem_malloc(OS_MEMPOOL_SIZE(BLE_TOTAL_SEM_COUNT, sizeof (struct ble_npl_sem_freertos)) * sizeof(os_membuf_t));
if(!ble_freertos_sem_buf) {
goto _error;
@@ -1215,28 +1222,28 @@ int npl_freertos_mempool_init(void)
_error:
#if CONFIG_BT_CONTROLLER_ENABLED
if(ble_freertos_evq_buf) {
if (ble_freertos_evq_buf) {
nimble_platform_mem_free(ble_freertos_evq_buf);
ble_freertos_evq_buf = NULL;
ble_freertos_evq_buf = NULL;
}
if(ble_freertos_co_buf) {
if (ble_freertos_co_buf) {
nimble_platform_mem_free(ble_freertos_co_buf);
ble_freertos_co_buf = NULL;
ble_freertos_co_buf = NULL;
}
if(ble_freertos_sem_buf) {
if (ble_freertos_sem_buf) {
nimble_platform_mem_free(ble_freertos_sem_buf);
ble_freertos_sem_buf = NULL;
ble_freertos_sem_buf = NULL;
}
if(ble_freertos_mutex_buf) {
if (ble_freertos_mutex_buf) {
nimble_platform_mem_free(ble_freertos_mutex_buf);
ble_freertos_mutex_buf = NULL;
ble_freertos_mutex_buf = NULL;
}
#endif
#if SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED
if(ble_freertos_ev_buf) {
if (ble_freertos_ev_buf) {
nimble_platform_mem_free(ble_freertos_ev_buf);
ble_freertos_ev_buf = NULL;
ble_freertos_ev_buf = NULL;
}
return -1;
#endif
@@ -1248,28 +1255,28 @@ _error:
void npl_freertos_mempool_deinit(void)
{
#if SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED
if(ble_freertos_ev_buf) {
if (ble_freertos_ev_buf) {
nimble_platform_mem_free(ble_freertos_ev_buf);
ble_freertos_ev_buf = NULL;
ble_freertos_ev_buf = NULL;
}
#endif
#if CONFIG_BT_CONTROLLER_ENABLED
if(ble_freertos_evq_buf) {
if (ble_freertos_evq_buf) {
nimble_platform_mem_free(ble_freertos_evq_buf);
ble_freertos_evq_buf = NULL;
ble_freertos_evq_buf = NULL;
}
if(ble_freertos_co_buf) {
if (ble_freertos_co_buf) {
nimble_platform_mem_free(ble_freertos_co_buf);
ble_freertos_co_buf = NULL;
ble_freertos_co_buf = NULL;
}
if(ble_freertos_sem_buf) {
if (ble_freertos_sem_buf) {
nimble_platform_mem_free(ble_freertos_sem_buf);
ble_freertos_sem_buf = NULL;
ble_freertos_sem_buf = NULL;
}
if(ble_freertos_mutex_buf) {
if (ble_freertos_mutex_buf) {
nimble_platform_mem_free(ble_freertos_mutex_buf);
ble_freertos_mutex_buf = NULL;
ble_freertos_mutex_buf = NULL;
}
#endif
}