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 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 config BT_RPMSG_NRF53
bool "nRF53 configuration of RPMsg" bool "nRF53 configuration of RPMsg"
default y if (BOARD_NRF5340PDK_NRF5340_CPUAPP || BOARD_NRF5340PDK_NRF5340_CPUAPPNS) 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; 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) static void stm32wb_start_ble(void)
{ {
SHCI_C2_Ble_Init_Cmd_Packet_t ble_init_cmd_packet = { 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) void TM_EvtReceivedCb(TL_EvtPacket_t *hcievt)
{ {
struct net_buf *buf; k_fifo_put(&ipm_rx_events_fifo, hcievt);
struct bt_hci_acl_hdr acl_hdr; }
TL_AclDataSerial_t *acl;
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) { hcievt = k_fifo_get(&ipm_rx_events_fifo, K_FOREVER);
case HCI_EVT:
BT_DBG("EVT: hcievt->evtserial.evt.evtcode: 0x%02x", k_sem_take(&ipm_busy, K_NO_WAIT);
hcievt->evtserial.evt.evtcode);
switch (hcievt->evtserial.evt.evtcode) { switch (hcievt->evtserial.type) {
case BT_HCI_EVT_VENDOR: case HCI_EVT:
/* Vendor events are currently unsupported */ BT_DBG("EVT: hcievt->evtserial.evt.evtcode: 0x%02x",
BT_ERR("Unknown evtcode type 0x%02x",
hcievt->evtserial.evt.evtcode); hcievt->evtserial.evt.evtcode);
goto out; switch (hcievt->evtserial.evt.evtcode) {
default: case BT_HCI_EVT_VENDOR:
buf = bt_buf_get_evt(hcievt->evtserial.evt.evtcode, false, /* Vendor events are currently unsupported */
K_FOREVER); 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; 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); 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) static void TM_AclDataAck(void)
@ -476,6 +495,13 @@ static int bt_ipm_open(void)
{ {
int err; 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 */ /* Take BLE out of reset */
ipcc_reset(); ipcc_reset();