drivers/bluetooth: ipm_stm32: Implement a RX thread

Fasten events handling by unloading callback treatment.
A RX thread is created. IPM RX events are dumped in a FIFO
which is processed in the thread context.

Signed-off-by: Erwan Gouriou <erwan.gouriou@linaro.org>
This commit is contained in:
Erwan Gouriou 2020-03-16 10:58:10 +01:00 committed by Carles Cufí
commit 57a74653df
2 changed files with 74 additions and 43 deletions

View file

@ -99,6 +99,11 @@ config BT_SPI_BLUENRG
endif # BT_SPI
config BT_STM32_IPM_RX_STACK_SIZE
int "STM32 IPM stack size for RX thread"
depends on BT_STM32_IPM
default 256
config BT_RPMSG_NRF53
bool "nRF53 configuration of RPMsg"
default y if (BOARD_NRF5340PDK_NRF5340_CPUAPP || BOARD_NRF5340PDK_NRF5340_CPUAPPNS)

View file

@ -68,6 +68,11 @@ struct aci_set_ble_addr {
static bt_addr_t bd_addr_udn;
/* Rx thread definitions */
K_FIFO_DEFINE(ipm_rx_events_fifo);
static K_THREAD_STACK_DEFINE(ipm_rx_stack, CONFIG_BT_STM32_IPM_RX_STACK_SIZE);
static struct k_thread ipm_rx_thread_data;
static void stm32wb_start_ble(void)
{
SHCI_C2_Ble_Init_Cmd_Packet_t ble_init_cmd_packet = {
@ -139,57 +144,71 @@ static void tryfix_event(TL_Evt_t *tev)
void TM_EvtReceivedCb(TL_EvtPacket_t *hcievt)
{
struct net_buf *buf;
struct bt_hci_acl_hdr acl_hdr;
TL_AclDataSerial_t *acl;
k_fifo_put(&ipm_rx_events_fifo, hcievt);
}
k_sem_take(&ipm_busy, K_NO_WAIT);
static void bt_ipm_rx_thread(void)
{
while (true) {
static TL_EvtPacket_t *hcievt;
struct net_buf *buf = NULL;
struct bt_hci_acl_hdr acl_hdr;
TL_AclDataSerial_t *acl;
switch (hcievt->evtserial.type) {
case HCI_EVT:
BT_DBG("EVT: hcievt->evtserial.evt.evtcode: 0x%02x",
hcievt->evtserial.evt.evtcode);
switch (hcievt->evtserial.evt.evtcode) {
case BT_HCI_EVT_VENDOR:
/* Vendor events are currently unsupported */
BT_ERR("Unknown evtcode type 0x%02x",
hcievt = k_fifo_get(&ipm_rx_events_fifo, K_FOREVER);
k_sem_take(&ipm_busy, K_NO_WAIT);
switch (hcievt->evtserial.type) {
case HCI_EVT:
BT_DBG("EVT: hcievt->evtserial.evt.evtcode: 0x%02x",
hcievt->evtserial.evt.evtcode);
goto out;
default:
buf = bt_buf_get_evt(hcievt->evtserial.evt.evtcode, false,
K_FOREVER);
switch (hcievt->evtserial.evt.evtcode) {
case BT_HCI_EVT_VENDOR:
/* Vendor events are currently unsupported */
BT_ERR("Unknown evtcode type 0x%02x",
hcievt->evtserial.evt.evtcode);
k_sem_give(&ipm_busy);
break;
default:
buf = bt_buf_get_evt(
hcievt->evtserial.evt.evtcode,
false, K_FOREVER);
}
tryfix_event(&hcievt->evtserial.evt);
net_buf_add_mem(buf, &hcievt->evtserial.evt,
hcievt->evtserial.evt.plen + 2);
break;
case HCI_ACL:
acl = &(((TL_AclDataPacket_t *)hcievt)->AclDataSerial);
buf = bt_buf_get_rx(BT_BUF_ACL_IN, K_FOREVER);
acl_hdr.handle = acl->handle;
acl_hdr.len = acl->length;
BT_DBG("ACL: handle %x, len %x",
acl_hdr.handle, acl_hdr.len);
net_buf_add_mem(buf, &acl_hdr, sizeof(acl_hdr));
net_buf_add_mem(buf, (u8_t *)&acl->acl_data,
acl_hdr.len);
break;
default:
BT_ERR("Unknown BT buf type %d",
hcievt->evtserial.type);
TL_MM_EvtDone(hcievt);
k_sem_give(&ipm_busy);
}
tryfix_event(&hcievt->evtserial.evt);
net_buf_add_mem(buf, &hcievt->evtserial.evt,
hcievt->evtserial.evt.plen + 2);
break;
case HCI_ACL:
acl = &(((TL_AclDataPacket_t *)hcievt)->AclDataSerial);
buf = bt_buf_get_rx(BT_BUF_ACL_IN, K_FOREVER);
acl_hdr.handle = acl->handle;
acl_hdr.len = acl->length;
BT_DBG("ACL: handle %x, len %x", acl_hdr.handle, acl_hdr.len);
net_buf_add_mem(buf, &acl_hdr, sizeof(acl_hdr));
net_buf_add_mem(buf, (u8_t *)&acl->acl_data, acl_hdr.len);
break;
default:
BT_ERR("Unknown BT buf type %d", hcievt->evtserial.type);
TL_MM_EvtDone(hcievt);
goto out;
if (hcievt->evtserial.type == HCI_EVT &&
bt_hci_evt_is_prio(hcievt->evtserial.evt.evtcode)) {
bt_recv_prio(buf);
} else {
bt_recv(buf);
}
k_sem_give(&ipm_busy);
}
TL_MM_EvtDone(hcievt);
if (hcievt->evtserial.type == HCI_EVT &&
bt_hci_evt_is_prio(hcievt->evtserial.evt.evtcode)) {
bt_recv_prio(buf);
} else {
bt_recv(buf);
}
out:
k_sem_give(&ipm_busy);
}
static void TM_AclDataAck(void)
@ -476,6 +495,13 @@ static int bt_ipm_open(void)
{
int err;
/* Start RX thread */
k_thread_create(&ipm_rx_thread_data, ipm_rx_stack,
K_THREAD_STACK_SIZEOF(ipm_rx_stack),
(k_thread_entry_t)bt_ipm_rx_thread, NULL, NULL, NULL,
K_PRIO_COOP(CONFIG_BT_RX_PRIO - 1),
0, K_NO_WAIT);
/* Take BLE out of reset */
ipcc_reset();