Bluetooth: Host: Add choice select whether BT RX
Change CONFIG_BT_RECV_IS_RX_THREAD into a choice:CONFIG_BT_RECV_CONTEXT with the following options (names can be discussed further of course): CONFIG_BT_RECV_BLOCKING CONFIG_BT_RECV_WORKQ_BT CONFIG_BT_RECV_WORKQ_SYS This way users would be able to choose what to run most of the BLE stack on, they wouldn't be forced to a single model. We would default to CONFIG_BT_RECV_BLOCKING so that we wouldn't need to change the system workqueue stack size by default, instead asking users to do so if they select the CONFIG_BT_RECV_WORKQ_SYS option Signed-off-by: Lingao Meng <menglingao@xiaomi.com>
This commit is contained in:
parent
2558d277e2
commit
37e561f42e
12 changed files with 137 additions and 78 deletions
|
@ -15,7 +15,6 @@ config BT_H4
|
||||||
bool "H:4 UART"
|
bool "H:4 UART"
|
||||||
select UART_INTERRUPT_DRIVEN
|
select UART_INTERRUPT_DRIVEN
|
||||||
select BT_UART
|
select BT_UART
|
||||||
select BT_RECV_IS_RX_THREAD
|
|
||||||
depends on SERIAL
|
depends on SERIAL
|
||||||
help
|
help
|
||||||
Bluetooth H:4 UART driver. Requires hardware flow control
|
Bluetooth H:4 UART driver. Requires hardware flow control
|
||||||
|
|
|
@ -340,7 +340,8 @@ static inline void read_payload(void)
|
||||||
|
|
||||||
reset_rx();
|
reset_rx();
|
||||||
|
|
||||||
if (evt_flags & BT_HCI_EVT_FLAG_RECV_PRIO) {
|
if (IS_ENABLED(CONFIG_BT_RECV_BLOCKING) &&
|
||||||
|
(evt_flags & BT_HCI_EVT_FLAG_RECV_PRIO)) {
|
||||||
BT_DBG("Calling bt_recv_prio(%p)", buf);
|
BT_DBG("Calling bt_recv_prio(%p)", buf);
|
||||||
bt_recv_prio(buf);
|
bt_recv_prio(buf);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1216,7 +1216,8 @@ struct bt_gatt_exchange_params {
|
||||||
* @note Shall only be used once per connection.
|
* @note Shall only be used once per connection.
|
||||||
*
|
*
|
||||||
* The Response comes in callback @p params->func. The callback is run from
|
* The Response comes in callback @p params->func. The callback is run from
|
||||||
* the BT RX thread. @p params must remain valid until start of callback.
|
* the context specified by 'config BT_RECV_CONTEXT'.
|
||||||
|
* @p params must remain valid until start of callback.
|
||||||
*
|
*
|
||||||
* This function will block while the ATT request queue is full, except when
|
* This function will block while the ATT request queue is full, except when
|
||||||
* called from the BT RX thread, as this would cause a deadlock.
|
* called from the BT RX thread, as this would cause a deadlock.
|
||||||
|
@ -1457,7 +1458,8 @@ struct bt_gatt_read_params {
|
||||||
* offset.
|
* offset.
|
||||||
*
|
*
|
||||||
* The Response comes in callback @p params->func. The callback is run from
|
* The Response comes in callback @p params->func. The callback is run from
|
||||||
* the BT RX thread. @p params must remain valid until start of callback.
|
* the context specified by 'config BT_RECV_CONTEXT'.
|
||||||
|
* @p params must remain valid until start of callback.
|
||||||
*
|
*
|
||||||
* This function will block while the ATT request queue is full, except when
|
* This function will block while the ATT request queue is full, except when
|
||||||
* called from the BT RX thread, as this would cause a deadlock.
|
* called from the BT RX thread, as this would cause a deadlock.
|
||||||
|
@ -1504,7 +1506,8 @@ struct bt_gatt_write_params {
|
||||||
/** @brief Write Attribute Value by handle
|
/** @brief Write Attribute Value by handle
|
||||||
*
|
*
|
||||||
* The Response comes in callback @p params->func. The callback is run from
|
* The Response comes in callback @p params->func. The callback is run from
|
||||||
* the BT RX thread. @p params must remain valid until start of callback.
|
* the context specified by 'config BT_RECV_CONTEXT'.
|
||||||
|
* @p params must remain valid until start of callback.
|
||||||
*
|
*
|
||||||
* This function will block while the ATT request queue is full, except when
|
* This function will block while the ATT request queue is full, except when
|
||||||
* called from Bluetooth event context. When called from Bluetooth context,
|
* called from Bluetooth event context. When called from Bluetooth context,
|
||||||
|
@ -1693,7 +1696,8 @@ struct bt_gatt_subscribe_params {
|
||||||
* subscription was removed by this method.
|
* subscription was removed by this method.
|
||||||
*
|
*
|
||||||
* The Response comes in callback @p params->func. The callback is run from
|
* The Response comes in callback @p params->func. The callback is run from
|
||||||
* the BT RX thread. @p params must remain valid until start of callback.
|
* the context specified by 'config BT_RECV_CONTEXT'.
|
||||||
|
* @p params must remain valid until start of callback.
|
||||||
* The Notification callback @p params->notify is also called from the BT RX
|
* The Notification callback @p params->notify is also called from the BT RX
|
||||||
* thread.
|
* thread.
|
||||||
*
|
*
|
||||||
|
|
|
@ -49,7 +49,7 @@ enum {
|
||||||
* Helper for the HCI driver to get HCI event flags that describes rules that.
|
* Helper for the HCI driver to get HCI event flags that describes rules that.
|
||||||
* must be followed.
|
* must be followed.
|
||||||
*
|
*
|
||||||
* When CONFIG_BT_RECV_IS_RX_THREAD is enabled the flags
|
* When @kconfig{CONFIG_BT_RECV_BLOCKING} is enabled the flags
|
||||||
* BT_HCI_EVT_FLAG_RECV and BT_HCI_EVT_FLAG_RECV_PRIO indicates if the event
|
* BT_HCI_EVT_FLAG_RECV and BT_HCI_EVT_FLAG_RECV_PRIO indicates if the event
|
||||||
* should be given to bt_recv or bt_recv_prio.
|
* should be given to bt_recv or bt_recv_prio.
|
||||||
*
|
*
|
||||||
|
@ -85,7 +85,7 @@ static inline uint8_t bt_hci_evt_get_flags(uint8_t evt)
|
||||||
* host with data from the controller. The buffer needs to have its type
|
* host with data from the controller. The buffer needs to have its type
|
||||||
* set with the help of bt_buf_set_type() before calling this API.
|
* set with the help of bt_buf_set_type() before calling this API.
|
||||||
*
|
*
|
||||||
* When CONFIG_BT_RECV_IS_RX_THREAD is defined then this API should not be used
|
* When @kconfig{CONFIG_BT_RECV_BLOCKING} is defined then this API should not be used
|
||||||
* for so-called high priority HCI events, which should instead be delivered to
|
* for so-called high priority HCI events, which should instead be delivered to
|
||||||
* the host stack through bt_recv_prio().
|
* the host stack through bt_recv_prio().
|
||||||
*
|
*
|
||||||
|
@ -165,7 +165,7 @@ struct bt_hci_driver {
|
||||||
* is safe to start calling the send() handler.
|
* is safe to start calling the send() handler.
|
||||||
*
|
*
|
||||||
* If the driver uses its own RX thread, i.e.
|
* If the driver uses its own RX thread, i.e.
|
||||||
* CONFIG_BT_RECV_IS_RX_THREAD is set, then this
|
* @kconfig{CONFIG_BT_RECV_BLOCKING} is set, then this
|
||||||
* function is expected to start that thread.
|
* function is expected to start that thread.
|
||||||
*
|
*
|
||||||
* @return 0 on success or negative error number on failure.
|
* @return 0 on success or negative error number on failure.
|
||||||
|
@ -179,7 +179,7 @@ struct bt_hci_driver {
|
||||||
* transport is closed.
|
* transport is closed.
|
||||||
*
|
*
|
||||||
* If the driver uses its own RX thread, i.e.
|
* If the driver uses its own RX thread, i.e.
|
||||||
* CONFIG_BT_RECV_IS_RX_THREAD is set, then this
|
* @kconfig{CONFIG_BT_RECV_BLOCKING} is set, then this
|
||||||
* function is expected to abort that thread.
|
* function is expected to abort that thread.
|
||||||
* @return 0 on success or negative error number on failure.
|
* @return 0 on success or negative error number on failure.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -95,7 +95,7 @@ config BT_BUF_ACL_RX_SIZE
|
||||||
config BT_BUF_ACL_RX_COUNT
|
config BT_BUF_ACL_RX_COUNT
|
||||||
int "Number of incoming ACL data buffers"
|
int "Number of incoming ACL data buffers"
|
||||||
default NET_BUF_RX_COUNT if NET_L2_BT
|
default NET_BUF_RX_COUNT if NET_L2_BT
|
||||||
default 3 if BT_RECV_IS_RX_THREAD
|
default 3 if BT_RECV_BLOCKING
|
||||||
default 6
|
default 6
|
||||||
range 1 64
|
range 1 64
|
||||||
help
|
help
|
||||||
|
@ -126,7 +126,7 @@ config BT_BUF_EVT_RX_SIZE
|
||||||
|
|
||||||
config BT_BUF_EVT_RX_COUNT
|
config BT_BUF_EVT_RX_COUNT
|
||||||
int "Number of HCI Event buffers"
|
int "Number of HCI Event buffers"
|
||||||
default 3 if BT_RECV_IS_RX_THREAD
|
default 3 if BT_RECV_BLOCKING
|
||||||
default 20 if (BT_MESH && !(BT_BUF_EVT_DISCARDABLE_COUNT > 0))
|
default 20 if (BT_MESH && !(BT_BUF_EVT_DISCARDABLE_COUNT > 0))
|
||||||
default 10
|
default 10
|
||||||
range 2 255
|
range 2 255
|
||||||
|
|
|
@ -96,7 +96,6 @@ choice BT_LL_CHOICE
|
||||||
|
|
||||||
config BT_LL_SW_SPLIT
|
config BT_LL_SW_SPLIT
|
||||||
bool "Software-based BLE Link Layer"
|
bool "Software-based BLE Link Layer"
|
||||||
select BT_RECV_IS_RX_THREAD
|
|
||||||
select ENTROPY_GENERATOR
|
select ENTROPY_GENERATOR
|
||||||
select NRF_HW_TIMER0_RESERVED
|
select NRF_HW_TIMER0_RESERVED
|
||||||
select NRF_HW_RTC0_RESERVED
|
select NRF_HW_RTC0_RESERVED
|
||||||
|
|
|
@ -68,19 +68,48 @@ config BT_HCI_RESERVE
|
||||||
Headroom that the driver needs for sending and receiving buffers. Add a
|
Headroom that the driver needs for sending and receiving buffers. Add a
|
||||||
new 'default' entry for each new driver.
|
new 'default' entry for each new driver.
|
||||||
|
|
||||||
config BT_RECV_IS_RX_THREAD
|
|
||||||
# Hidden option set by the HCI driver to indicate that there's
|
choice BT_RECV_CONTEXT
|
||||||
# no need for the host to have its own RX thread.
|
prompt "BT RX Thread Selection"
|
||||||
# If this option has been enabled it is then the responsibility of the
|
default BT_RECV_BLOCKING if BT_LL_SW_SPLIT || BT_H4
|
||||||
# HCI driver to call bt_recv_prio from a higher priority context than
|
default BT_RECV_WORKQ_BT
|
||||||
# bt_recv in order to avoid deadlocks.
|
help
|
||||||
# If this option is disabled then only bt_recv should be called.
|
Selects in which context incoming low priority HCI packets are processed.
|
||||||
bool
|
The host defines some events as high priority to avoid race conditions and deadlocks.
|
||||||
prompt "bt_recv is called from RX thread" if BT_NO_DRIVER
|
High priority events are always processed in the context of the caller of bt_recv()
|
||||||
|
or bt_recv_prio(). The choice will influence RAM usage and how fast incoming HCI
|
||||||
|
packets are processed.
|
||||||
|
|
||||||
|
config BT_RECV_BLOCKING
|
||||||
|
bool "Process HCI packets in the context of bt_recv() and bt_recv_prio()"
|
||||||
|
help
|
||||||
|
When this option is selected, the host will not have its own RX thread.
|
||||||
|
With this option it is the responsibility of the HCI driver to call
|
||||||
|
bt_recv_prio from a higher priority context than bt_recv() in order to avoid deadlocks.
|
||||||
|
|
||||||
|
config BT_RECV_WORKQ_SYS
|
||||||
|
bool "Process low priority HCI packets in the system work queue"
|
||||||
|
help
|
||||||
|
When this option is selected, the host will process incoming low priority HCI packets
|
||||||
|
in the system work queue. The HCI driver shall not call bt_recv_prio().
|
||||||
|
High priority HCI packets will processed in the context of the caller of bt_recv().
|
||||||
|
The application needs to ensure the system workqueue stack size (SYSTEM_WORKQUEUE_STACK_SIZE)
|
||||||
|
is large enough, refer to BT_RX_STACK_SIZE for the recommended minimum.
|
||||||
|
Note: When this option is used, other users of the system work queue will influence the
|
||||||
|
latency of incoming Bluetooth events.
|
||||||
|
|
||||||
|
config BT_RECV_WORKQ_BT
|
||||||
|
bool "Process low priority HCI packets in the bluetooth-specific work queue"
|
||||||
|
help
|
||||||
|
When this option is selected, the host will process incoming low priority HCI packets
|
||||||
|
in the bluetooth-specific work queue. The HCI driver shall not call bt_recv_prio().
|
||||||
|
High priority HCI packets will processed in the context of the caller of bt_recv().
|
||||||
|
The application needs to ensure the bluetooth-specific work queue size is large enough,
|
||||||
|
refer to BT_RX_STACK_SIZE for the recommended minimum.
|
||||||
|
endchoice
|
||||||
|
|
||||||
config BT_RX_STACK_SIZE
|
config BT_RX_STACK_SIZE
|
||||||
int "Size of the receiving thread stack"
|
int "Size of the receiving thread stack"
|
||||||
depends on BT_HCI_HOST || BT_RECV_IS_RX_THREAD
|
|
||||||
default 768 if BT_HCI_RAW
|
default 768 if BT_HCI_RAW
|
||||||
default 3092 if BT_MESH_GATT_CLIENT
|
default 3092 if BT_MESH_GATT_CLIENT
|
||||||
default 2048 if BT_MESH
|
default 2048 if BT_MESH
|
||||||
|
@ -98,7 +127,6 @@ config BT_RX_STACK_SIZE
|
||||||
config BT_RX_PRIO
|
config BT_RX_PRIO
|
||||||
# Hidden option for Co-Operative Rx thread priority
|
# Hidden option for Co-Operative Rx thread priority
|
||||||
int
|
int
|
||||||
depends on BT_HCI_HOST || BT_RECV_IS_RX_THREAD
|
|
||||||
default 8
|
default 8
|
||||||
|
|
||||||
config BT_DRIVER_RX_HIGH_PRIO
|
config BT_DRIVER_RX_HIGH_PRIO
|
||||||
|
|
|
@ -61,10 +61,14 @@
|
||||||
#define HCI_CMD_TIMEOUT K_SECONDS(10)
|
#define HCI_CMD_TIMEOUT K_SECONDS(10)
|
||||||
|
|
||||||
/* Stacks for the threads */
|
/* Stacks for the threads */
|
||||||
#if !defined(CONFIG_BT_RECV_IS_RX_THREAD)
|
#if !defined(CONFIG_BT_RECV_BLOCKING)
|
||||||
static struct k_thread rx_thread_data;
|
static void rx_work_handler(struct k_work *work);
|
||||||
|
static K_WORK_DEFINE(rx_work, rx_work_handler);
|
||||||
|
#if defined(CONFIG_BT_RECV_WORKQ_BT)
|
||||||
|
static struct k_work_q bt_workq;
|
||||||
static K_KERNEL_STACK_DEFINE(rx_thread_stack, CONFIG_BT_RX_STACK_SIZE);
|
static K_KERNEL_STACK_DEFINE(rx_thread_stack, CONFIG_BT_RX_STACK_SIZE);
|
||||||
#endif
|
#endif /* CONFIG_BT_RECV_WORKQ_BT */
|
||||||
|
#endif /* !CONFIG_BT_RECV_BLOCKING */
|
||||||
static struct k_thread tx_thread_data;
|
static struct k_thread tx_thread_data;
|
||||||
static K_KERNEL_STACK_DEFINE(tx_thread_stack, CONFIG_BT_HCI_TX_STACK_SIZE);
|
static K_KERNEL_STACK_DEFINE(tx_thread_stack, CONFIG_BT_HCI_TX_STACK_SIZE);
|
||||||
|
|
||||||
|
@ -82,7 +86,7 @@ struct bt_dev bt_dev = {
|
||||||
.ncmd_sem = Z_SEM_INITIALIZER(bt_dev.ncmd_sem, 0, 1),
|
.ncmd_sem = Z_SEM_INITIALIZER(bt_dev.ncmd_sem, 0, 1),
|
||||||
#endif
|
#endif
|
||||||
.cmd_tx_queue = Z_FIFO_INITIALIZER(bt_dev.cmd_tx_queue),
|
.cmd_tx_queue = Z_FIFO_INITIALIZER(bt_dev.cmd_tx_queue),
|
||||||
#if !defined(CONFIG_BT_RECV_IS_RX_THREAD)
|
#if !defined(CONFIG_BT_RECV_BLOCKING)
|
||||||
.rx_queue = Z_FIFO_INITIALIZER(bt_dev.rx_queue),
|
.rx_queue = Z_FIFO_INITIALIZER(bt_dev.rx_queue),
|
||||||
#endif
|
#endif
|
||||||
#if defined(CONFIG_BT_DEVICE_APPEARANCE_DYNAMIC)
|
#if defined(CONFIG_BT_DEVICE_APPEARANCE_DYNAMIC)
|
||||||
|
@ -3413,6 +3417,22 @@ void hci_event_prio(struct net_buf *buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(CONFIG_BT_RECV_BLOCKING)
|
||||||
|
static void rx_queue_put(struct net_buf *buf)
|
||||||
|
{
|
||||||
|
net_buf_put(&bt_dev.rx_queue, buf);
|
||||||
|
|
||||||
|
#if defined(CONFIG_BT_RECV_WORKQ_SYS)
|
||||||
|
const int err = k_work_submit(&rx_work);
|
||||||
|
#elif defined(CONFIG_BT_RECV_WORKQ_BT)
|
||||||
|
const int err = k_work_submit_to_queue(&bt_workq, &rx_work);
|
||||||
|
#endif /* CONFIG_BT_RECV_WORKQ_SYS */
|
||||||
|
if (err < 0) {
|
||||||
|
BT_ERR("Could not submit rx_work: %d", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* !CONFIG_BT_RECV_BLOCKING */
|
||||||
|
|
||||||
int bt_recv(struct net_buf *buf)
|
int bt_recv(struct net_buf *buf)
|
||||||
{
|
{
|
||||||
bt_monitor_send(bt_monitor_opcode(buf), buf->data, buf->len);
|
bt_monitor_send(bt_monitor_opcode(buf), buf->data, buf->len);
|
||||||
|
@ -3422,16 +3442,16 @@ int bt_recv(struct net_buf *buf)
|
||||||
switch (bt_buf_get_type(buf)) {
|
switch (bt_buf_get_type(buf)) {
|
||||||
#if defined(CONFIG_BT_CONN)
|
#if defined(CONFIG_BT_CONN)
|
||||||
case BT_BUF_ACL_IN:
|
case BT_BUF_ACL_IN:
|
||||||
#if defined(CONFIG_BT_RECV_IS_RX_THREAD)
|
#if defined(CONFIG_BT_RECV_BLOCKING)
|
||||||
hci_acl(buf);
|
hci_acl(buf);
|
||||||
#else
|
#else
|
||||||
net_buf_put(&bt_dev.rx_queue, buf);
|
rx_queue_put(buf);
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
#endif /* BT_CONN */
|
#endif /* BT_CONN */
|
||||||
case BT_BUF_EVT:
|
case BT_BUF_EVT:
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_BT_RECV_IS_RX_THREAD)
|
#if defined(CONFIG_BT_RECV_BLOCKING)
|
||||||
hci_event(buf);
|
hci_event(buf);
|
||||||
#else
|
#else
|
||||||
struct bt_hci_evt_hdr *hdr = (void *)buf->data;
|
struct bt_hci_evt_hdr *hdr = (void *)buf->data;
|
||||||
|
@ -3442,7 +3462,7 @@ int bt_recv(struct net_buf *buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (evt_flags & BT_HCI_EVT_FLAG_RECV) {
|
if (evt_flags & BT_HCI_EVT_FLAG_RECV) {
|
||||||
net_buf_put(&bt_dev.rx_queue, buf);
|
rx_queue_put(buf);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -3450,10 +3470,10 @@ int bt_recv(struct net_buf *buf)
|
||||||
}
|
}
|
||||||
#if defined(CONFIG_BT_ISO)
|
#if defined(CONFIG_BT_ISO)
|
||||||
case BT_BUF_ISO_IN:
|
case BT_BUF_ISO_IN:
|
||||||
#if defined(CONFIG_BT_RECV_IS_RX_THREAD)
|
#if defined(CONFIG_BT_RECV_BLOCKING)
|
||||||
hci_iso(buf);
|
hci_iso(buf);
|
||||||
#else
|
#else
|
||||||
net_buf_put(&bt_dev.rx_queue, buf);
|
rx_queue_put(buf);
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
#endif /* CONFIG_BT_ISO */
|
#endif /* CONFIG_BT_ISO */
|
||||||
|
@ -3464,7 +3484,6 @@ int bt_recv(struct net_buf *buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_BT_RECV_IS_RX_THREAD)
|
|
||||||
int bt_recv_prio(struct net_buf *buf)
|
int bt_recv_prio(struct net_buf *buf)
|
||||||
{
|
{
|
||||||
bt_monitor_send(bt_monitor_opcode(buf), buf->data, buf->len);
|
bt_monitor_send(bt_monitor_opcode(buf), buf->data, buf->len);
|
||||||
|
@ -3475,7 +3494,6 @@ int bt_recv_prio(struct net_buf *buf)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* defined(CONFIG_BT_RECV_IS_RX_THREAD) */
|
|
||||||
|
|
||||||
int bt_hci_driver_register(const struct bt_hci_driver *drv)
|
int bt_hci_driver_register(const struct bt_hci_driver *drv)
|
||||||
{
|
{
|
||||||
|
@ -3554,47 +3572,59 @@ static void init_work(struct k_work *work)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(CONFIG_BT_RECV_IS_RX_THREAD)
|
#if !defined(CONFIG_BT_RECV_BLOCKING)
|
||||||
static void hci_rx_thread(void)
|
static void rx_work_handler(struct k_work *work)
|
||||||
{
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
struct net_buf *buf;
|
struct net_buf *buf;
|
||||||
|
|
||||||
BT_DBG("started");
|
BT_DBG("calling fifo_get_wait");
|
||||||
|
buf = net_buf_get(&bt_dev.rx_queue, K_NO_WAIT);
|
||||||
|
if (!buf) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
while (1) {
|
BT_DBG("buf %p type %u len %u", buf, bt_buf_get_type(buf),
|
||||||
BT_DBG("calling fifo_get_wait");
|
buf->len);
|
||||||
buf = net_buf_get(&bt_dev.rx_queue, K_FOREVER);
|
|
||||||
|
|
||||||
BT_DBG("buf %p type %u len %u", buf, bt_buf_get_type(buf),
|
switch (bt_buf_get_type(buf)) {
|
||||||
buf->len);
|
|
||||||
|
|
||||||
switch (bt_buf_get_type(buf)) {
|
|
||||||
#if defined(CONFIG_BT_CONN)
|
#if defined(CONFIG_BT_CONN)
|
||||||
case BT_BUF_ACL_IN:
|
case BT_BUF_ACL_IN:
|
||||||
hci_acl(buf);
|
hci_acl(buf);
|
||||||
break;
|
break;
|
||||||
#endif /* CONFIG_BT_CONN */
|
#endif /* CONFIG_BT_CONN */
|
||||||
#if defined(CONFIG_BT_ISO)
|
#if defined(CONFIG_BT_ISO)
|
||||||
case BT_BUF_ISO_IN:
|
case BT_BUF_ISO_IN:
|
||||||
hci_iso(buf);
|
hci_iso(buf);
|
||||||
break;
|
break;
|
||||||
#endif /* CONFIG_BT_ISO */
|
#endif /* CONFIG_BT_ISO */
|
||||||
case BT_BUF_EVT:
|
case BT_BUF_EVT:
|
||||||
hci_event(buf);
|
hci_event(buf);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
BT_ERR("Unknown buf type %u", bt_buf_get_type(buf));
|
BT_ERR("Unknown buf type %u", bt_buf_get_type(buf));
|
||||||
net_buf_unref(buf);
|
net_buf_unref(buf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure we don't hog the CPU if the rx_queue never
|
/* Make sure we don't hog the CPU if the rx_queue never
|
||||||
* gets empty.
|
* gets empty.
|
||||||
*/
|
*/
|
||||||
k_yield();
|
if (k_fifo_is_empty(&bt_dev.rx_queue)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_BT_RECV_WORKQ_SYS)
|
||||||
|
err = k_work_submit(&rx_work);
|
||||||
|
#elif defined(CONFIG_BT_RECV_WORKQ_BT)
|
||||||
|
err = k_work_submit_to_queue(&bt_workq, &rx_work);
|
||||||
|
#endif
|
||||||
|
if (err < 0) {
|
||||||
|
BT_ERR("Could not submit rx_work: %d", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* !CONFIG_BT_RECV_IS_RX_THREAD */
|
#endif /* !CONFIG_BT_RECV_BLOCKING */
|
||||||
|
|
||||||
int bt_enable(bt_ready_cb_t cb)
|
int bt_enable(bt_ready_cb_t cb)
|
||||||
{
|
{
|
||||||
|
@ -3633,14 +3663,12 @@ int bt_enable(bt_ready_cb_t cb)
|
||||||
0, K_NO_WAIT);
|
0, K_NO_WAIT);
|
||||||
k_thread_name_set(&tx_thread_data, "BT TX");
|
k_thread_name_set(&tx_thread_data, "BT TX");
|
||||||
|
|
||||||
#if !defined(CONFIG_BT_RECV_IS_RX_THREAD)
|
#if defined(CONFIG_BT_RECV_WORKQ_BT)
|
||||||
/* RX thread */
|
/* RX thread */
|
||||||
k_thread_create(&rx_thread_data, rx_thread_stack,
|
k_work_queue_start(&bt_workq, rx_thread_stack,
|
||||||
K_KERNEL_STACK_SIZEOF(rx_thread_stack),
|
CONFIG_BT_RX_STACK_SIZE,
|
||||||
(k_thread_entry_t)hci_rx_thread, NULL, NULL, NULL,
|
K_PRIO_COOP(CONFIG_BT_RX_PRIO), NULL);
|
||||||
K_PRIO_COOP(CONFIG_BT_RX_PRIO),
|
k_thread_name_set(&bt_workq.thread, "BT RX");
|
||||||
0, K_NO_WAIT);
|
|
||||||
k_thread_name_set(&rx_thread_data, "BT RX");
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_BT_TINYCRYPT_ECC)) {
|
if (IS_ENABLED(CONFIG_BT_TINYCRYPT_ECC)) {
|
||||||
|
@ -3699,9 +3727,9 @@ int bt_disable(void)
|
||||||
/* Abort TX thread */
|
/* Abort TX thread */
|
||||||
k_thread_abort(&tx_thread_data);
|
k_thread_abort(&tx_thread_data);
|
||||||
|
|
||||||
#if !defined(CONFIG_BT_RECV_IS_RX_THREAD)
|
#if defined(CONFIG_BT_RECV_WORKQ_BT)
|
||||||
/* Abort RX thread */
|
/* Abort RX thread */
|
||||||
k_thread_abort(&rx_thread_data);
|
k_thread_abort(&bt_workq.thread);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_BT_TINYCRYPT_ECC)) {
|
if (IS_ENABLED(CONFIG_BT_TINYCRYPT_ECC)) {
|
||||||
|
|
|
@ -341,7 +341,7 @@ struct bt_dev {
|
||||||
/* Last sent HCI command */
|
/* Last sent HCI command */
|
||||||
struct net_buf *sent_cmd;
|
struct net_buf *sent_cmd;
|
||||||
|
|
||||||
#if !defined(CONFIG_BT_RECV_IS_RX_THREAD)
|
#if !defined(CONFIG_BT_RECV_BLOCKING)
|
||||||
/* Queue for incoming HCI events & ACL data */
|
/* Queue for incoming HCI events & ACL data */
|
||||||
struct k_fifo rx_queue;
|
struct k_fifo rx_queue;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -91,7 +91,7 @@ static void send_cmd_status(uint16_t opcode, uint8_t status)
|
||||||
evt->opcode = sys_cpu_to_le16(opcode);
|
evt->opcode = sys_cpu_to_le16(opcode);
|
||||||
evt->status = status;
|
evt->status = status;
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_BT_RECV_IS_RX_THREAD)) {
|
if (IS_ENABLED(CONFIG_BT_RECV_BLOCKING)) {
|
||||||
bt_recv_prio(buf);
|
bt_recv_prio(buf);
|
||||||
} else {
|
} else {
|
||||||
bt_recv(buf);
|
bt_recv(buf);
|
||||||
|
|
|
@ -4,7 +4,7 @@ CONFIG_ZTEST=y
|
||||||
CONFIG_BT=y
|
CONFIG_BT=y
|
||||||
CONFIG_BT_CTLR=n
|
CONFIG_BT_CTLR=n
|
||||||
CONFIG_BT_NO_DRIVER=y
|
CONFIG_BT_NO_DRIVER=y
|
||||||
CONFIG_BT_RECV_IS_RX_THREAD=y
|
CONFIG_BT_RECV_BLOCKING=y
|
||||||
|
|
||||||
CONFIG_BT_HCI_VS_EVT_USER=y
|
CONFIG_BT_HCI_VS_EVT_USER=y
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ CONFIG_BT_HCI=n
|
||||||
CONFIG_BT_HCI_RAW=n
|
CONFIG_BT_HCI_RAW=n
|
||||||
CONFIG_BT_OBSERVER=y
|
CONFIG_BT_OBSERVER=y
|
||||||
CONFIG_BT_NO_DRIVER=y
|
CONFIG_BT_NO_DRIVER=y
|
||||||
CONFIG_BT_RECV_IS_RX_THREAD=y
|
CONFIG_BT_RECV_BLOCKING=y
|
||||||
CONFIG_BT_EXT_ADV=y
|
CONFIG_BT_EXT_ADV=y
|
||||||
|
|
||||||
CONFIG_BT_DEBUG_LOG=y
|
CONFIG_BT_DEBUG_LOG=y
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue