feat(nimble): Added npl for btdm sofware arch

This commit is contained in:
ShenWeilong
2026-03-27 19:56:34 +08:00
parent 8589109b05
commit 095d93bd11
8 changed files with 1170 additions and 27 deletions
+1 -1
View File
@@ -715,7 +715,7 @@ ble_hs_enqueue_hci_event(uint8_t *hci_evt)
ev = os_memblock_get(&ble_hs_hci_ev_pool);
if (ev && ble_hs_evq->eventq) {
if (ev) {
memset (ev, 0, sizeof *ev);
ble_npl_event_init(ev, ble_hs_event_rx_hci_ev, hci_evt);
ble_npl_eventq_put(ble_hs_evq, ev);
+1 -2
View File
@@ -104,8 +104,7 @@ ble_hs_periodic_sync_free(struct ble_hs_periodic_sync *psync)
return;
}
if ((psync->lost_ev).event != NULL)
ble_npl_event_deinit(&psync->lost_ev);
ble_npl_event_deinit(&psync->lost_ev);
#if MYNEWT_VAL(BLE_HS_DEBUG)
memset(psync, 0xff, sizeof *psync);
+112 -1
View File
@@ -207,6 +207,117 @@ extern "C" {
#endif
#if SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED
#if CONFIG_BT_DUAL_MODE_ARCH
#include "btdm_endian.h"
static inline void
put_le16(void *buf, uint16_t x)
{
btdm_put_le16(buf, x);
}
static inline void
put_le24(void *buf, uint32_t x)
{
btdm_put_le24(buf, x);
}
static inline void
put_le32(void *buf, uint32_t x)
{
btdm_put_le32(buf, x);
}
static inline void
put_le64(void *buf, uint64_t x)
{
btdm_put_le64(buf, x);
}
static inline uint16_t
get_le16(const void *buf)
{
return btdm_get_le16(buf);
}
static inline uint32_t
get_le24(const void *buf)
{
return btdm_get_le24(buf);
}
static inline uint32_t
get_le32(const void *buf)
{
return btdm_get_le32(buf);
}
static inline uint64_t
get_le64(const void *buf)
{
return btdm_get_le64(buf);
}
static inline void
put_be16(void *buf, uint16_t x)
{
btdm_put_be16(buf, x);
}
static inline void
put_be24(void *buf, uint32_t x)
{
btdm_put_be24(buf, x);
}
static inline void
put_be32(void *buf, uint32_t x)
{
btdm_put_be32(buf, x);
}
static inline void
put_be64(void *buf, uint64_t x)
{
btdm_put_be64(buf, x);
}
static inline uint16_t
get_be16(const void *buf)
{
return btdm_get_be16(buf);
}
static inline uint32_t
get_be24(const void *buf)
{
return btdm_get_be24(buf);
}
static inline uint32_t
get_be32(const void *buf)
{
return btdm_get_be32(buf);
}
static inline uint64_t
get_be64(const void *buf)
{
return btdm_get_be64(buf);
}
static inline void
swap_in_place(void *buf, int len)
{
btdm_swap_in_place(buf, len);
}
static inline void
swap_buf(uint8_t *dst, const uint8_t *src, int len)
{
btdm_swap_buf(dst, src, len);
}
#else // CONFIG_BT_DUAL_MODE_ARCH
void r_put_le16(void *buf, uint16_t x);
#define put_le16 r_put_le16
@@ -260,7 +371,7 @@ void r_swap_in_place(void *buf, int len);
void r_swap_buf(uint8_t *dst, const uint8_t *src, int len);
#define swap_buf r_swap_buf
#endif // CONFIG_BT_DUAL_MODE_ARCH
#else
void put_le16(void *buf, uint16_t x);
+627 -23
View File
@@ -182,24 +182,24 @@ struct os_mqueue {
/** @cond INTERNAL_HIDDEN */
#if SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED
#if CONFIG_BT_DUAL_MODE_ARCH
#include "ble_mbuf.h"
/* Reuse the controller's APIs. Make sure that we have the same structure. */
static_assert(sizeof(struct os_mbuf_pool) == sizeof(struct ble_mbuf_pool),
"Error: size of os_mbuf_pool");
static_assert(sizeof(struct os_mbuf_pkthdr) == sizeof(struct ble_mbuf_pkthdr),
"Error: size of os_mbuf_pkthdr");
static_assert(sizeof(struct os_mbuf) == sizeof(struct ble_mbuf), "Error: size of os_mbuf");
/*
* Called by OS_MBUF_LEADINGSPACE() macro
*/
static inline uint16_t
_os_mbuf_leadingspace(struct os_mbuf *om)
{
uint16_t startoff;
uint16_t leadingspace;
startoff = 0;
if (OS_MBUF_IS_PKTHDR(om)) {
startoff = om->om_pkthdr_len;
}
leadingspace = (uint16_t) (OS_MBUF_DATA(om, uint8_t *) -
((uint8_t *) &om->om_databuf[0] + startoff));
return (leadingspace);
return _ble_mbuf_leadingspace((struct ble_mbuf *)om);
}
/** @endcond */
@@ -216,19 +216,11 @@ _os_mbuf_leadingspace(struct os_mbuf *om)
*/
#define OS_MBUF_LEADINGSPACE(__om) _os_mbuf_leadingspace(__om)
/** @cond INTERNAL_HIDDEN */
/* Called by OS_MBUF_TRAILINGSPACE() macro. */
static inline uint16_t
_os_mbuf_trailingspace(struct os_mbuf *om)
{
struct os_mbuf_pool *omp;
omp = om->om_omp;
return (&om->om_databuf[0] + omp->omp_databuf_len) -
(om->om_data + om->om_len);
return _ble_mbuf_trailingspace((struct ble_mbuf *)om);
}
/** @endcond */
@@ -244,8 +236,557 @@ _os_mbuf_trailingspace(struct os_mbuf *om)
*/
#define OS_MBUF_TRAILINGSPACE(__om) _os_mbuf_trailingspace(__om)
/**
* MSYS is a system level mbuf registry. Allows the system to share
* packet buffers amongst the various networking stacks that can be running
* simultaeneously.
*
* Mbuf pools are created in the system initialization code, and then when
* a mbuf is allocated out of msys, it will try and find the best fit based
* upon estimated mbuf size.
*
* os_msys_register() registers a mbuf pool with MSYS, and allows MSYS to
* allocate mbufs out of it.
*
* @param new_pool The pool to register with MSYS
*
* @return 0 on success, non-zero on failure
*/
static inline int
os_msys_register(struct os_mbuf_pool *mp)
{
return ble_msys_register((struct ble_mbuf_pool *)mp);
}
/**
* Allocate a mbuf from msys. Based upon the data size requested,
* os_msys_get() will choose the mbuf pool that has the best fit.
*
* @param dsize The estimated size of the data being stored in the mbuf
* @param leadingspace The amount of leadingspace to allocate in the mbuf
*
* @return A freshly allocated mbuf on success, NULL on failure.
*/
static inline struct os_mbuf *
os_msys_get(uint16_t dsize, uint16_t leadingspace)
{
return (struct os_mbuf *)ble_msys_get(dsize, leadingspace);
}
/**
* De-registers all mbuf pools from msys.
*/
static inline void
os_msys_reset(void)
{
ble_msys_reset();
}
/**
* Allocate a packet header structure from the MSYS pool. See
* os_msys_register() for a description of MSYS.
*
* @param dsize The estimated size of the data being stored in the mbuf
* @param user_hdr_len The length to allocate for the packet header structure
*
* @return A freshly allocated mbuf on success, NULL on failure.
*/
static inline struct os_mbuf *
os_msys_get_pkthdr(uint16_t dsize, uint16_t user_hdr_len)
{
return (struct os_mbuf *)ble_msys_get_pkthdr(dsize, user_hdr_len);
}
/**
* Count the number of blocks in all the mbuf pools that are allocated.
*
* @return total number of blocks allocated in Msys
*/
static inline int
os_msys_count(void)
{
return ble_msys_count();
}
/**
* Return the number of free blocks in Msys
*
* @return Number of free blocks available in Msys
*/
static inline int
os_msys_num_free(void)
{
return ble_msys_num_free();
}
/**
* Initialize a pool of mbufs.
*
* @param omp The mbuf pool to initialize
* @param mp The memory pool that will hold this mbuf pool
* @param buf_len The length of the buffer itself.
* @param nbufs The number of buffers in the pool
*
* @return 0 on success, error code on failure.
*/
static inline int
os_mbuf_pool_init(struct os_mbuf_pool *omp, struct os_mempool *mp, uint16_t buf_len,
uint16_t nbufs)
{
return ble_mbuf_pool_init((struct ble_mbuf_pool *)omp, (struct btdm_mempool *)mp, buf_len,
nbufs);
}
/**
* Get an mbuf from the mbuf pool. The mbuf is allocated, and initialized
* prior to being returned.
*
* @param omp The mbuf pool to return the packet from
* @param leadingspace The amount of leadingspace to put before the data
* section by default.
*
* @return An initialized mbuf on success, and NULL on failure.
*/
static inline struct os_mbuf *
os_mbuf_get(struct os_mbuf_pool *omp, uint16_t leadingspace)
{
return(struct os_mbuf *)ble_mbuf_get((struct ble_mbuf_pool *)omp, leadingspace);
}
/**
* Allocate a new packet header mbuf out of the os_mbuf_pool.
*
* @param omp The mbuf pool to allocate out of
* @param user_pkthdr_len The packet header length to reserve for the caller.
*
* @return A freshly allocated mbuf on success, NULL on failure.
*/
static inline struct os_mbuf *
os_mbuf_get_pkthdr(struct os_mbuf_pool *omp, uint8_t user_pkthdr_len)
{
return (struct os_mbuf *)ble_mbuf_get_pkthdr((struct ble_mbuf_pool *)omp, user_pkthdr_len);
}
/**
* Duplicate a chain of mbufs. Return the start of the duplicated chain.
*
* @param omp The mbuf pool to duplicate out of
* @param om The mbuf chain to duplicate
*
* @return A pointer to the new chain of mbufs
*/
static inline struct os_mbuf *
os_mbuf_dup(struct os_mbuf *m)
{
return (struct os_mbuf *)ble_mbuf_dup((struct ble_mbuf *)m);
}
/**
* Locates the specified absolute offset within an mbuf chain. The offset
* can be one past than the total length of the chain, but no greater.
*
* @param om The start of the mbuf chain to seek within.
* @param off The absolute address to find.
* @param out_off On success, this points to the relative offset
* within the returned mbuf.
*
* @return The mbuf containing the specified offset on
* success.
* NULL if the specified offset is out of bounds.
*/
static inline struct os_mbuf *
os_mbuf_off(const struct os_mbuf *om, int off, uint16_t *out_off)
{
return (struct os_mbuf *)ble_mbuf_off((struct ble_mbuf *)om, off, out_off);
}
/*
* Copy data from an mbuf chain starting "off" bytes from the beginning,
* continuing for "len" bytes, into the indicated buffer.
*
* @param m The mbuf chain to copy from
* @param off The offset into the mbuf chain to begin copying from
* @param len The length of the data to copy
* @param dst The destination buffer to copy into
*
* @return 0 on success;
* -1 if the mbuf does not contain enough data.
*/
static inline int
os_mbuf_copydata(const struct os_mbuf *m, int off, int len, void *dst)
{
return ble_mbuf_copydata((struct ble_mbuf *)m, off, len, dst);
}
/**
* @brief Calculates the length of an mbuf chain.
*
* Calculates the length of an mbuf chain. If the mbuf contains a packet
* header, you should use `OS_MBUF_PKTLEN()` as a more efficient alternative to
* this function.
*
* @param om The mbuf to measure.
*
* @return The length, in bytes, of the provided mbuf
* chain.
*/
static inline uint16_t
os_mbuf_len(const struct os_mbuf *om)
{
return ble_mbuf_len((struct ble_mbuf *)om);
}
/**
* Append data onto a mbuf
*
* @param om The mbuf to append the data onto
* @param data The data to append onto the mbuf
* @param len The length of the data to append
*
* @return 0 on success, and an error code on failure
*/
static inline int
os_mbuf_append(struct os_mbuf *m, const void *data, uint16_t len)
{
return ble_mbuf_append((struct ble_mbuf *)m, data, len);
}
/**
* Reads data from one mbuf and appends it to another. On error, the specified
* data range may be partially appended. Neither mbuf is required to contain
* an mbuf packet header.
*
* @param dst The mbuf to append to.
* @param src The mbuf to copy data from.
* @param src_off The absolute offset within the source mbuf
* chain to read from.
* @param len The number of bytes to append.
*
* @return 0 on success;
* OS_EINVAL if the specified range extends beyond
* the end of the source mbuf chain.
*/
static inline int
os_mbuf_appendfrom(struct os_mbuf *dst, const struct os_mbuf *src, uint16_t src_off,
uint16_t len)
{
return ble_mbuf_appendfrom((struct ble_mbuf *)dst, (struct ble_mbuf *)src, src_off, len);
}
/**
* Release a mbuf back to the pool
*
* @param mb The Mbuf to release back to the pool
*
* @return 0 on success, -1 on failure
*/
static inline int
os_mbuf_free(struct os_mbuf *mb)
{
return ble_mbuf_free((struct ble_mbuf *)mb);
}
/**
* Free a chain of mbufs
*
* @param om The starting mbuf of the chain to free back into the pool
*
* @return 0 on success, -1 on failure
*/
static inline int
os_mbuf_free_chain(struct os_mbuf *om)
{
return ble_mbuf_free_chain((struct ble_mbuf *)om);
}
/**
* Adjust the length of a mbuf, trimming either from the head or the tail
* of the mbuf.
*
* @param mp The mbuf chain to adjust
* @param req_len The length to trim from the mbuf. If positive, trims
* from the head of the mbuf, if negative, trims from the
* tail of the mbuf.
*/
static inline void
os_mbuf_adj(struct os_mbuf *mp, int req_len)
{
ble_mbuf_adj((struct ble_mbuf *)mp, req_len);
}
/**
* Performs a memory compare of the specified region of an mbuf chain against a
* flat buffer.
*
* @param om The start of the mbuf chain to compare.
* @param off The offset within the mbuf chain to start the
* comparison.
* @param data The flat buffer to compare.
* @param len The length of the flat buffer.
*
* @return 0 if both memory regions are identical;
* A memcmp return code if there is a mismatch;
* INT_MAX if the mbuf is too short.
*/
static inline int
os_mbuf_cmpf(const struct os_mbuf *om, int off, const void *data, int len)
{
return ble_mbuf_cmpf((struct ble_mbuf *)om, off, data, len);
}
/**
* Compares the contents of two mbuf chains. The ranges of the two chains to
* be compared are specified via the two offset parameters and the len
* parameter. Neither mbuf chain is required to contain a packet header.
*
* @param om1 The first mbuf chain to compare.
* @param offset1 The absolute offset within om1 at which to
* start the comparison.
* @param om2 The second mbuf chain to compare.
* @param offset2 The absolute offset within om2 at which to
* start the comparison.
* @param len The number of bytes to compare.
*
* @return 0 if both mbuf segments are identical;
* A memcmp() return code if the segment contents
* differ;
* INT_MAX if a specified range extends beyond the
* end of its corresponding mbuf chain.
*/
static inline int
os_mbuf_cmpm(const struct os_mbuf *om1, uint16_t offset1, const struct os_mbuf *om2,
uint16_t offset2, uint16_t len)
{
return ble_mbuf_cmpm((struct ble_mbuf *)om1, offset1, (struct ble_mbuf *)om2, offset2, len);
}
/**
* Increases the length of an mbuf chain by adding data to the front. If there
* is insufficient room in the leading mbuf, additional mbufs are allocated and
* prepended as necessary. If this function fails to allocate an mbuf, the
* entire chain is freed.
*
* The specified mbuf chain does not need to contain a packet header.
*
* @param omp The mbuf pool to allocate from.
* @param om The head of the mbuf chain.
* @param len The number of bytes to prepend.
*
* @return The new head of the chain on success;
* NULL on failure.
*/
static inline struct os_mbuf *
os_mbuf_prepend(struct os_mbuf *om, int len)
{
return (struct os_mbuf *)ble_mbuf_prepend((struct ble_mbuf *)om, len);
}
/**
* Prepends a chunk of empty data to the specified mbuf chain and ensures the
* chunk is contiguous. If either operation fails, the specified mbuf chain is
* freed and NULL is returned.
*
* @param om The mbuf chain to prepend to.
* @param len The number of bytes to prepend and pullup.
*
* @return The modified mbuf on success;
* NULL on failure (and the mbuf chain is freed).
*/
static inline struct os_mbuf *
os_mbuf_prepend_pullup(struct os_mbuf *om, uint16_t len)
{
return (struct os_mbuf *)ble_mbuf_prepend_pullup((struct ble_mbuf *)om, len);
}
/**
* Copies the contents of a flat buffer into an mbuf chain, starting at the
* specified destination offset. If the mbuf is too small for the source data,
* it is extended as necessary. If the destination mbuf contains a packet
* header, the header length is updated.
*
* @param om The mbuf chain to copy into.
* @param off The offset within the chain to copy to.
* @param src The source buffer to copy from.
* @param len The number of bytes to copy.
*
* @return 0 on success; nonzero on failure.
*/
static inline int
os_mbuf_copyinto(struct os_mbuf *om, int off, const void *src, int len)
{
return ble_mbuf_copyinto((struct ble_mbuf *)om, off, src, len);
}
/**
* Attaches a second mbuf chain onto the end of the first. If the first chain
* contains a packet header, the header's length is updated. If the second
* chain has a packet header, its header is cleared.
*
* @param first The mbuf chain being attached to.
* @param second The mbuf chain that gets attached.
*/
static inline void
os_mbuf_concat(struct os_mbuf *first, struct os_mbuf *second)
{
ble_mbuf_concat((struct ble_mbuf *)first, (struct ble_mbuf *)second);
}
/**
* Increases the length of an mbuf chain by the specified amount. If there is
* not sufficient room in the last buffer, a new buffer is allocated and
* appended to the chain. It is an error to request more data than can fit in
* a single buffer.
*
* @param om The head of the chain to extend.
* @param len The number of bytes to extend by.
*
* @return A pointer to the new data on success;
* NULL on failure.
*/
static inline void *
os_mbuf_extend(struct os_mbuf *om, uint16_t len)
{
return ble_mbuf_extend((struct ble_mbuf *)om, len);
}
/**
* Rearrange a mbuf chain so that len bytes are contiguous,
* and in the data area of an mbuf (so that OS_MBUF_DATA() will
* work on a structure of size len.) Returns the resulting
* mbuf chain on success, free's it and returns NULL on failure.
*
* If there is room, it will add up to "max_protohdr - len"
* extra bytes to the contiguous region, in an attempt to avoid being
* called next time.
*
* @param om The mbuf chain to make contiguous
* @param len The number of bytes in the chain to make contiguous
*
* @return The contiguous mbuf chain on success, NULL on failure.
*/
static inline struct os_mbuf *
os_mbuf_pullup(struct os_mbuf *om, uint16_t len)
{
return (struct os_mbuf *)ble_mbuf_pullup((struct ble_mbuf *)om, len);
}
/**
* Removes and frees empty mbufs from the front of a chain. If the chain
* contains a packet header, it is preserved.
*
* @param om The mbuf chain to trim.
*
* @return The head of the trimmed mbuf chain.
*/
static inline struct os_mbuf *
os_mbuf_trim_front(struct os_mbuf *om)
{
return (struct os_mbuf *)ble_mbuf_trim_front((struct ble_mbuf *)om);
}
/**
* Increases the length of an mbuf chain by inserting a gap at the specified
* offset. The contents of the gap are indeterminate. If the mbuf chain
* contains a packet header, its total length is increased accordingly.
*
* This function never frees the provided mbuf chain.
*
* @param om The mbuf chain to widen.
* @param off The offset at which to insert the gap.
* @param len The size of the gap to insert.
*
* @return 0 on success; SYS_[...] error code on failure.
*/
static inline int
os_mbuf_widen(struct os_mbuf *om, uint16_t off, uint16_t len)
{
return ble_mbuf_widen((struct ble_mbuf *)om, off, len);
}
/**
* Creates a single chained mbuf from m1 and m2 utilizing all
* the available buffer space in all mbufs in the resulting
* chain. In other words, ensures there is no leading space in
* any mbuf in the resulting chain and trailing space only in
* the last mbuf in the chain. Mbufs from either chain may be
* freed if not needed. No mbufs are allocated. Note that mbufs
* from m2 are added to the end of m1. If m1 has a packet
* header, it is retained and length updated. If m2 has a packet
* header it is discarded. If m1 is NULL, NULL is returned and
* m2 is left untouched.
*
* @param m1 Pointer to first mbuf chain to pack
* @param m2 Pointer to second mbuf chain to pack
*
* @return struct os_mbuf* Pointer to resulting mbuf chain
*/
static inline struct os_mbuf *
os_mbuf_pack_chains(struct os_mbuf *m1, struct os_mbuf *m2)
{
return (struct os_mbuf *)ble_mbuf_pack_chains((struct ble_mbuf *)m1, (struct ble_mbuf *)m2);
}
#else // CONFIG_BT_DUAL_MODE_ARCH
/*
* Called by OS_MBUF_LEADINGSPACE() macro
*/
static inline uint16_t
_os_mbuf_leadingspace(struct os_mbuf *om)
{
uint16_t startoff;
uint16_t leadingspace;
startoff = 0;
if (OS_MBUF_IS_PKTHDR(om)) {
startoff = om->om_pkthdr_len;
}
leadingspace = (uint16_t) (OS_MBUF_DATA(om, uint8_t *) -
((uint8_t *) &om->om_databuf[0] + startoff));
return (leadingspace);
}
/** @endcond */
/**
* Returns the leading space (space at the beginning) of the mbuf.
* Works on both packet header, and regular mbufs, as it accounts
* for the additional space allocated to the packet header.
*
* @param __omp Is the mbuf pool (which contains packet header length.)
* @param __om Is the mbuf in that pool to get the leadingspace for
*
* @return Amount of leading space available in the mbuf
*/
#define OS_MBUF_LEADINGSPACE(__om) _os_mbuf_leadingspace(__om)
/** @cond INTERNAL_HIDDEN */
/* Called by OS_MBUF_TRAILINGSPACE() macro. */
static inline uint16_t
_os_mbuf_trailingspace(struct os_mbuf *om)
{
struct os_mbuf_pool *omp;
omp = om->om_omp;
return (&om->om_databuf[0] + omp->omp_databuf_len) -
(om->om_data + om->om_len);
}
/** @endcond */
/**
* Returns the trailing space (space at the end) of the mbuf.
* Works on both packet header and regular mbufs.
*
* @param __omp The mbuf pool for this mbuf
* @param __om Is the mbuf in that pool to get trailing space for
*
* @return The amount of trailing space available in the mbuf
*/
#define OS_MBUF_TRAILINGSPACE(__om) _os_mbuf_trailingspace(__om)
#if SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED
/**
* Initializes an mqueue. An mqueue is a queue of mbufs that ties to a
* particular task's event queue. Mqueues form a helper API around a common
@@ -704,8 +1245,71 @@ int r_os_mbuf_widen(struct os_mbuf *om, uint16_t off, uint16_t len);
*/
struct os_mbuf *r_os_mbuf_pack_chains(struct os_mbuf *m1, struct os_mbuf *m2);
#define os_mbuf_pack_chains r_os_mbuf_pack_chains
#endif // CONFIG_BT_DUAL_MODE_ARCH
#else
/*
* Called by OS_MBUF_LEADINGSPACE() macro
*/
static inline uint16_t
_os_mbuf_leadingspace(struct os_mbuf *om)
{
uint16_t startoff;
uint16_t leadingspace;
startoff = 0;
if (OS_MBUF_IS_PKTHDR(om)) {
startoff = om->om_pkthdr_len;
}
leadingspace = (uint16_t) (OS_MBUF_DATA(om, uint8_t *) -
((uint8_t *) &om->om_databuf[0] + startoff));
return (leadingspace);
}
/** @endcond */
/**
* Returns the leading space (space at the beginning) of the mbuf.
* Works on both packet header, and regular mbufs, as it accounts
* for the additional space allocated to the packet header.
*
* @param __omp Is the mbuf pool (which contains packet header length.)
* @param __om Is the mbuf in that pool to get the leadingspace for
*
* @return Amount of leading space available in the mbuf
*/
#define OS_MBUF_LEADINGSPACE(__om) _os_mbuf_leadingspace(__om)
/** @cond INTERNAL_HIDDEN */
/* Called by OS_MBUF_TRAILINGSPACE() macro. */
static inline uint16_t
_os_mbuf_trailingspace(struct os_mbuf *om)
{
struct os_mbuf_pool *omp;
omp = om->om_omp;
return (&om->om_databuf[0] + omp->omp_databuf_len) -
(om->om_data + om->om_len);
}
/** @endcond */
/**
* Returns the trailing space (space at the end) of the mbuf.
* Works on both packet header and regular mbufs.
*
* @param __omp The mbuf pool for this mbuf
* @param __om Is the mbuf in that pool to get trailing space for
*
* @return The amount of trailing space available in the mbuf
*/
#define OS_MBUF_TRAILINGSPACE(__om) _os_mbuf_trailingspace(__om)
/**
* Initializes an mqueue. An mqueue is a queue of mbufs that ties to a
* particular task's event queue. Mqueues form a helper API around a common
+2
View File
@@ -0,0 +1,2 @@
This Nimble Porting Layer is used for ESP32 series chips (e.g. ESP32-H4 and new chips).
and NOT applicable to ESP32/ESP32-C3/ESP32-S3/ESP32-C2 (refer to npl/freertos).
@@ -0,0 +1,318 @@
/*
* SPDX-FileCopyrightText: 2015-2022 The Apache Software Foundation (ASF)
*
* SPDX-License-Identifier: Apache-2.0
*
* SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD
*/
#ifndef _NIMBLE_NPL_OS_H_
#define _NIMBLE_NPL_OS_H_
#include <stdint.h>
#include "btdm_osal.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(array) \
(sizeof(array) / sizeof((array)[0]))
#endif
#define BLE_NPL_OS_ALIGNMENT (4) /*ble_npl_get_os_alignment()*/
#define BLE_NPL_TIME_FOREVER portMAX_DELAY
/* This should be compatible with TickType_t */
typedef uint32_t ble_npl_time_t;
typedef int32_t ble_npl_stime_t;
struct ble_npl_event {
struct btdm_osal_event event;
};
struct ble_npl_eventq {
struct btdm_osal_eventq eventq;
};
struct ble_npl_callout {
struct btdm_osal_callout co;
};
struct ble_npl_mutex {
struct btdm_osal_mutex mutex;
};
struct ble_npl_sem {
struct btdm_osal_sem sem;
};
/*
* Simple APIs are just defined as static inline below, but some are a bit more
* complex or require some global state variables and thus are defined in .c
* file instead and static inline wrapper just calls proper implementation.
* We need declarations of these functions and they are defined in header below.
*/
static inline bool
ble_npl_os_started(void)
{
return xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED;
}
static inline void *
ble_npl_get_current_task_id(void)
{
return xTaskGetCurrentTaskHandle();
}
static inline void
ble_npl_eventq_init(struct ble_npl_eventq *evq)
{
return btdm_osal_eventq_init(&evq->eventq);
}
static inline void
ble_npl_eventq_deinit(struct ble_npl_eventq *evq)
{
return btdm_osal_eventq_deinit(&evq->eventq);
}
static inline struct ble_npl_event *
ble_npl_eventq_get(struct ble_npl_eventq *evq, ble_npl_time_t tmo)
{
return (void *)btdm_osal_eventq_get(&evq->eventq, tmo) - offsetof(struct ble_npl_eventq, eventq);
}
static inline void
ble_npl_eventq_put(struct ble_npl_eventq *evq, struct ble_npl_event *ev)
{
btdm_osal_eventq_put(&evq->eventq, &ev->event);
}
static inline void
ble_npl_eventq_remove(struct ble_npl_eventq *evq, struct ble_npl_event *ev)
{
btdm_osal_eventq_remove(&evq->eventq, &ev->event);
}
static inline void
ble_npl_event_run(struct ble_npl_event *ev)
{
btdm_osal_event_run((struct btdm_osal_event *)ev);
}
static inline bool
ble_npl_eventq_is_empty(struct ble_npl_eventq *evq)
{
return btdm_osal_eventq_is_empty(&evq->eventq);
}
static inline void
ble_npl_event_init(struct ble_npl_event *ev, ble_npl_event_fn *fn, void *arg)
{
btdm_osal_event_init(&ev->event, (btdm_osal_event_fn *)fn, arg);
}
static inline void
ble_npl_event_deinit(struct ble_npl_event *ev)
{
btdm_osal_event_deinit(&ev->event);
}
static inline void
ble_npl_event_reset(struct ble_npl_event *ev)
{
btdm_osal_event_reset(&ev->event);
}
static inline bool
ble_npl_event_is_queued(struct ble_npl_event *ev)
{
return btdm_osal_event_is_queued(&ev->event);
}
static inline void *
ble_npl_event_get_arg(struct ble_npl_event *ev)
{
return btdm_osal_event_get_arg(&ev->event);
}
static inline void
ble_npl_event_set_arg(struct ble_npl_event *ev, void *arg)
{
return btdm_osal_event_set_arg(&ev->event, arg);
}
static inline ble_npl_error_t
ble_npl_mutex_init(struct ble_npl_mutex *mu)
{
return btdm_osal_mutex_init(&mu->mutex);
}
static inline ble_npl_error_t
ble_npl_mutex_deinit(struct ble_npl_mutex *mu)
{
return btdm_osal_mutex_deinit(&mu->mutex);
}
static inline ble_npl_error_t
ble_npl_mutex_pend(struct ble_npl_mutex *mu, ble_npl_time_t timeout)
{
return btdm_osal_mutex_pend(&mu->mutex, timeout);
}
static inline ble_npl_error_t
ble_npl_mutex_release(struct ble_npl_mutex *mu)
{
return btdm_osal_mutex_release(&mu->mutex);
}
static inline ble_npl_error_t
ble_npl_sem_init(struct ble_npl_sem *sem, uint16_t tokens)
{
return btdm_osal_sem_init(&sem->sem, tokens);
}
static inline ble_npl_error_t
ble_npl_sem_deinit(struct ble_npl_sem *sem)
{
return btdm_osal_sem_deinit(&sem->sem);
}
static inline ble_npl_error_t
ble_npl_sem_pend(struct ble_npl_sem *sem, ble_npl_time_t timeout)
{
return btdm_osal_sem_pend(&sem->sem, timeout);
}
static inline ble_npl_error_t
ble_npl_sem_release(struct ble_npl_sem *sem)
{
return btdm_osal_sem_release(&sem->sem);
}
static inline uint16_t
ble_npl_sem_get_count(struct ble_npl_sem *sem)
{
return btdm_osal_sem_get_count(&sem->sem);
}
static inline int
ble_npl_callout_init(struct ble_npl_callout *co, struct ble_npl_eventq *evq,
ble_npl_event_fn *ev_cb, void *ev_arg)
{
return btdm_osal_callout_init(&co->co, &evq->eventq, (btdm_osal_event_fn *)ev_cb, ev_arg);
}
static inline void
ble_npl_callout_deinit(struct ble_npl_callout *co)
{
return btdm_osal_callout_deinit(&co->co);
}
static inline ble_npl_error_t
ble_npl_callout_reset(struct ble_npl_callout *co, ble_npl_time_t ticks)
{
return btdm_osal_callout_reset(&co->co, ticks);
}
static inline void
ble_npl_callout_stop(struct ble_npl_callout *co)
{
return btdm_osal_callout_stop(&co->co);
}
static inline bool
ble_npl_callout_is_active(struct ble_npl_callout *co)
{
return btdm_osal_callout_is_active(&co->co);
}
static inline ble_npl_time_t
ble_npl_callout_get_ticks(struct ble_npl_callout *co)
{
return btdm_osal_callout_get_ticks(&co->co);
}
static inline ble_npl_time_t
ble_npl_callout_remaining_ticks(struct ble_npl_callout *co, ble_npl_time_t time)
{
return btdm_osal_callout_remaining_ticks(&co->co, time);
}
static inline void
ble_npl_callout_set_arg(struct ble_npl_callout *co, void *arg)
{
return btdm_osal_callout_set_arg(&co->co, arg);
}
static inline ble_npl_time_t
ble_npl_time_get(void)
{
return btdm_osal_time_get();
}
static inline ble_npl_error_t
ble_npl_time_ms_to_ticks(uint32_t ms, ble_npl_time_t *out_ticks)
{
return btdm_osal_time_ms_to_ticks(ms, out_ticks);
}
static inline ble_npl_error_t
ble_npl_time_ticks_to_ms(ble_npl_time_t ticks, uint32_t *out_ms)
{
return btdm_osal_time_ticks_to_ms(ticks, out_ms);
}
static inline ble_npl_time_t
ble_npl_time_ms_to_ticks32(uint32_t ms)
{
return btdm_osal_time_ms_to_ticks32(ms);
}
static inline uint32_t
ble_npl_time_ticks_to_ms32(ble_npl_time_t ticks)
{
return btdm_osal_time_ticks_to_ms32(ticks);
}
static inline void
ble_npl_time_delay(ble_npl_time_t ticks)
{
vTaskDelay(ticks);
}
// #if NIMBLE_CFG_CONTROLLER
// static inline void
// ble_npl_hw_set_isr(int irqn, uint32_t addr)
// {
// return btdm_osal_hw_set_isr(irqn, addr);
// }
// #endif
static inline uint32_t
ble_npl_hw_enter_critical(void)
{
return btdm_osal_hw_enter_critical();
}
static inline void
ble_npl_hw_exit_critical(uint32_t ctx)
{
btdm_osal_hw_exit_critical(ctx);
}
static inline bool
ble_npl_hw_is_in_critical(void)
{
return btdm_osal_hw_is_in_critical();
}
#ifdef __cplusplus
}
#endif
#endif /* _NPL_H_ */
@@ -0,0 +1,26 @@
/*
* SPDX-FileCopyrightText: 2015-2022 The Apache Software Foundation (ASF)
*
* SPDX-License-Identifier: Apache-2.0
*
* SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD
*/
#ifndef _NIMBLE_PORT_FREERTOS_H
#define _NIMBLE_PORT_FREERTOS_H
#include "nimble/nimble_npl.h"
#ifdef __cplusplus
extern "C" {
#endif
void nimble_port_freertos_init(TaskFunction_t host_task_fn);
void nimble_port_freertos_deinit(void);
#ifdef __cplusplus
}
#endif
#endif /* _NIMBLE_PORT_FREERTOS_H */
@@ -0,0 +1,83 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include <stddef.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "nimble/nimble_port.h"
#if CONFIG_BT_CONTROLLER_ENABLED
#include "esp_bt.h"
#endif
static TaskHandle_t host_task_h = NULL;
/**
* @brief esp_nimble_enable - Initialize the NimBLE host
*
* @param host_task
* @return esp_err_t
*/
esp_err_t esp_nimble_enable(void *host_task)
{
/*
* Create task where NimBLE host will run. It is not strictly necessary to
* have separate task for NimBLE host, but since something needs to handle
* default queue it is just easier to make separate task which does this.
*/
xTaskCreatePinnedToCore(host_task, "nimble_host", NIMBLE_HS_STACK_SIZE,
NULL, (configMAX_PRIORITIES - 4), &host_task_h, NIMBLE_CORE);
return ESP_OK;
}
/**
* @brief esp_nimble_disable - Disable the NimBLE host
*
* @return esp_err_t
*/
esp_err_t esp_nimble_disable(void)
{
if (host_task_h) {
vTaskDelete(host_task_h);
host_task_h = NULL;
}
return ESP_OK;
}
/**
* @brief nimble_port_freertos_init - Adapt to native nimble api
*
* @param host_task_fn
*/
void
nimble_port_freertos_init(TaskFunction_t host_task_fn)
{
esp_nimble_enable(host_task_fn);
}
/**
* @brief nimble_port_freertos_deinit - Adapt to native nimble api
*
*/
void
nimble_port_freertos_deinit(void)
{
esp_nimble_disable();
}