drivers: bluetooth: silabs: Add separate thread for BT Link Layer
The BT Link Layer needs to get runtime in a timely manner to keep connections alive and handle other time-critical tasks. This is achieved by adding a separate thread for it with a meta-IRQ priority, which means it can preempt other threads. The driver also has an RX thread that passes HCI messages from the controller to the host stack. This can be a lower priority cooperative thread, as it doesn't have strict timing requirements. Signed-off-by: Kalle Kietäväinen <kalle.kietavainen@silabs.com>
This commit is contained in:
parent
cfe91b8df1
commit
fe5abd0344
3 changed files with 46 additions and 10 deletions
|
@ -41,4 +41,9 @@ config BT_SILABS_EFR32_ACCEPT_LINK_LAYER_STACK_SIZE
|
|||
default 1024
|
||||
help
|
||||
Link layer stack size.
|
||||
|
||||
config BT_SILABS_EFR32_LL_THREAD_PRIO
|
||||
# Hidden option for Co-Operative Link Layer thread priority
|
||||
def_int 0
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
#include <zephyr/drivers/bluetooth.h>
|
||||
#include <zephyr/kernel.h>
|
||||
|
||||
#include <sl_btctrl_linklayer.h>
|
||||
#include <sl_hci_common_transport.h>
|
||||
|
@ -36,12 +37,18 @@ struct hci_data {
|
|||
static K_KERNEL_STACK_DEFINE(slz_ll_stack, CONFIG_BT_SILABS_EFR32_ACCEPT_LINK_LAYER_STACK_SIZE);
|
||||
static struct k_thread slz_ll_thread;
|
||||
|
||||
static K_KERNEL_STACK_DEFINE(slz_rx_stack, CONFIG_BT_DRV_RX_STACK_SIZE);
|
||||
static struct k_thread slz_rx_thread;
|
||||
|
||||
/* Semaphore for Link Layer */
|
||||
K_SEM_DEFINE(slz_ll_sem, 0, 1);
|
||||
|
||||
/* Events mask for Link Layer */
|
||||
static atomic_t sli_btctrl_events;
|
||||
|
||||
/* FIFO for received HCI packets */
|
||||
static struct k_fifo slz_rx_fifo;
|
||||
|
||||
/* FIXME: these functions should come from the SiSDK headers! */
|
||||
void BTLE_LL_EventRaise(uint32_t events);
|
||||
void BTLE_LL_Process(uint32_t events);
|
||||
|
@ -73,8 +80,6 @@ void rail_isr_installer(void)
|
|||
*/
|
||||
uint32_t hci_common_transport_transmit(uint8_t *data, int16_t len)
|
||||
{
|
||||
const struct device *dev = DEVICE_DT_GET(DT_DRV_INST(0));
|
||||
struct hci_data *hci = dev->data;
|
||||
struct net_buf *buf;
|
||||
uint8_t packet_type = data[0];
|
||||
uint8_t event_code;
|
||||
|
@ -99,7 +104,7 @@ uint32_t hci_common_transport_transmit(uint8_t *data, int16_t len)
|
|||
}
|
||||
|
||||
net_buf_add_mem(buf, data, len);
|
||||
hci->recv(dev, buf);
|
||||
k_fifo_put(&slz_rx_fifo, buf);
|
||||
|
||||
sl_btctrl_hci_transmit_complete(0);
|
||||
|
||||
|
@ -140,7 +145,7 @@ done:
|
|||
* or an HCI event to pass upstairs. The BTLE_LL_Process function call will
|
||||
* take care of all of them, and add HCI events to the HCI queue when applicable.
|
||||
*/
|
||||
static void slz_thread_func(void *p1, void *p2, void *p3)
|
||||
static void slz_ll_thread_func(void *p1, void *p2, void *p3)
|
||||
{
|
||||
ARG_UNUSED(p1);
|
||||
ARG_UNUSED(p2);
|
||||
|
@ -155,17 +160,40 @@ static void slz_thread_func(void *p1, void *p2, void *p3)
|
|||
}
|
||||
}
|
||||
|
||||
static void slz_rx_thread_func(void *p1, void *p2, void *p3)
|
||||
{
|
||||
const struct device *dev = p1;
|
||||
struct hci_data *hci = dev->data;
|
||||
|
||||
ARG_UNUSED(p2);
|
||||
ARG_UNUSED(p3);
|
||||
|
||||
while (true) {
|
||||
struct net_buf *buf = k_fifo_get(&slz_rx_fifo, K_FOREVER);
|
||||
|
||||
hci->recv(dev, buf);
|
||||
}
|
||||
}
|
||||
|
||||
static int slz_bt_open(const struct device *dev, bt_hci_recv_t recv)
|
||||
{
|
||||
struct hci_data *hci = dev->data;
|
||||
int ret;
|
||||
|
||||
/* Start RX thread */
|
||||
k_thread_create(&slz_ll_thread, slz_ll_stack,
|
||||
K_KERNEL_STACK_SIZEOF(slz_ll_stack),
|
||||
slz_thread_func, NULL, NULL, NULL,
|
||||
K_PRIO_COOP(CONFIG_BT_DRIVER_RX_HIGH_PRIO), 0,
|
||||
K_NO_WAIT);
|
||||
BUILD_ASSERT(CONFIG_NUM_METAIRQ_PRIORITIES > 0,
|
||||
"Config NUM_METAIRQ_PRIORITIES must be greater than 0");
|
||||
BUILD_ASSERT(CONFIG_BT_SILABS_EFR32_LL_THREAD_PRIO < CONFIG_NUM_METAIRQ_PRIORITIES,
|
||||
"Config BT_SILABS_EFR32_LL_THREAD_PRIO must be a meta-IRQ priority");
|
||||
|
||||
k_fifo_init(&slz_rx_fifo);
|
||||
|
||||
k_thread_create(&slz_ll_thread, slz_ll_stack, K_KERNEL_STACK_SIZEOF(slz_ll_stack),
|
||||
slz_ll_thread_func, NULL, NULL, NULL,
|
||||
K_PRIO_COOP(CONFIG_BT_SILABS_EFR32_LL_THREAD_PRIO), 0, K_NO_WAIT);
|
||||
|
||||
k_thread_create(&slz_rx_thread, slz_rx_stack, K_KERNEL_STACK_SIZEOF(slz_rx_stack),
|
||||
slz_rx_thread_func, (void *)dev, NULL, NULL,
|
||||
K_PRIO_COOP(CONFIG_BT_DRIVER_RX_HIGH_PRIO), 0, K_NO_WAIT);
|
||||
|
||||
rail_isr_installer();
|
||||
sl_rail_util_pa_init();
|
||||
|
|
|
@ -19,4 +19,7 @@ config CORTEX_M_SYSTICK
|
|||
config IDLE_STACK_SIZE
|
||||
default 512 if SOC_GECKO_PM_BACKEND_PMGR
|
||||
|
||||
configdefault NUM_METAIRQ_PRIORITIES
|
||||
default 1 if BT_SILABS_EFR32
|
||||
|
||||
endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue