From 304180d19280f7f2f19f6fb5ad4707bf08aa4e55 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 24 Oct 2023 10:32:59 +0200 Subject: [PATCH 1/3] nimble/transport: Add auto syscfg for monitor This adds common syscfg that is defined when monitor is used. --- nimble/transport/syscfg.monitor.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nimble/transport/syscfg.monitor.yml b/nimble/transport/syscfg.monitor.yml index 7cfbc416fd..4defd910bc 100644 --- a/nimble/transport/syscfg.monitor.yml +++ b/nimble/transport/syscfg.monitor.yml @@ -54,5 +54,8 @@ syscfg.defs: length value will be split. value: 128 +syscfg.defs.'BLE_MONITOR_UART || BLE_MONITOR_RTT': + BLE_MONITOR: 1 + syscfg.restrictions: - '!(BLE_MONITOR_UART && BLE_MONITOR_RTT)' From 6426c8fc306048f3f344399352bdecff4b1284af Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 20 Oct 2023 17:20:26 +0200 Subject: [PATCH 2/3] nimble/transport: Add common HCI RX task This adds common task for implementing HCI RX. Any transport can simply register its own function for RX that will be run in separate task whenever triggered by dedicated API. This for example allows to easily implement handling HCI RX in a task instead of in an interrupt since handling RX in an interrupt doesn't work well with monitor enabled. If selected transport doesn't register its function, all rx_task code will be compiled out since there won't be any references to that code. --- nimble/transport/include/nimble/transport.h | 5 ++ nimble/transport/src/rx_task.c | 84 +++++++++++++++++++++ nimble/transport/syscfg.yml | 8 ++ 3 files changed, 97 insertions(+) create mode 100644 nimble/transport/src/rx_task.c diff --git a/nimble/transport/include/nimble/transport.h b/nimble/transport/include/nimble/transport.h index fcb3297cf7..f5a30780b6 100644 --- a/nimble/transport/include/nimble/transport.h +++ b/nimble/transport/include/nimble/transport.h @@ -35,6 +35,11 @@ struct os_mbuf; /* Initialization */ void ble_transport_init(void); +/* Common HCI RX task functions */ +typedef void ble_transport_rx_func_t(void *arg); +void ble_transport_rx_register(ble_transport_rx_func_t *func, void *arg); +void ble_transport_rx(void); + /* Allocators for supported data types */ void *ble_transport_alloc_cmd(void); void *ble_transport_alloc_evt(int discardable); diff --git a/nimble/transport/src/rx_task.c b/nimble/transport/src/rx_task.c new file mode 100644 index 0000000000..076990cdd3 --- /dev/null +++ b/nimble/transport/src/rx_task.c @@ -0,0 +1,84 @@ +/* + * 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 +#include +#if MYNEWT +#include +#endif +#include +#include +#include + +#if !defined(MYNEWT) || MYNEWT_VAL(BLE_TRANSPORT_RX_STACK_SIZE) > 0 + +static ble_transport_rx_func_t *rx_func; +static void *rx_func_arg; + +#if MYNEWT +OS_TASK_STACK_DEFINE(rx_stack, MYNEWT_VAL(BLE_TRANSPORT_RX_STACK_SIZE)); +static struct os_task rx_task; +#endif + +static struct ble_npl_eventq rx_eventq; +static struct ble_npl_event rx_event; + +static void +rx_event_func(struct ble_npl_event *ev) +{ + rx_func(rx_func_arg); +} + +static void +rx_task_func(void *arg) +{ + struct ble_npl_event *ev; + + ble_npl_eventq_init(&rx_eventq); + + while (1) { + ev = ble_npl_eventq_get(&rx_eventq, BLE_NPL_TIME_FOREVER); + ble_npl_event_run(ev); + } +} + +void +ble_transport_rx_register(ble_transport_rx_func_t *func, void *arg) +{ + assert(func && !rx_func); + + rx_func = func; + rx_func_arg = arg; + + ble_npl_event_init(&rx_event, rx_event_func, NULL); + +#ifdef MYNEWT + os_task_init(&rx_task, "hci_rx_task", rx_task_func, NULL, + MYNEWT_VAL(BLE_TRANSPORT_RX_PRIO), OS_WAIT_FOREVER, rx_stack, + MYNEWT_VAL(BLE_TRANSPORT_RX_STACK_SIZE)); +#endif +} + +void +ble_transport_rx(void) +{ + ble_npl_eventq_put(&rx_eventq, &rx_event); +} + +#endif diff --git a/nimble/transport/syscfg.yml b/nimble/transport/syscfg.yml index 7e8ea9357d..877c3db24c 100644 --- a/nimble/transport/syscfg.yml +++ b/nimble/transport/syscfg.yml @@ -110,6 +110,14 @@ syscfg.defs: of ISO buffers available for controller. value: MYNEWT_VAL(BLE_TRANSPORT_ISO_COUNT) + BLE_TRANSPORT_RX_PRIO: + description: Priority of RX task + type: task_priority + value: 126 + BLE_TRANSPORT_RX_STACK_SIZE: + description: Stack size of RX task + value: + # import monitor and defunct settings from separate file to reduce clutter in main file $import: - "@apache-mynewt-nimble/nimble/transport/syscfg.monitor.yml" From 888d531752cbd1cd55afdb6ce0d142ad99f360c4 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 20 Oct 2023 17:23:08 +0200 Subject: [PATCH 3/3] nimble/transport/nrf53: Move RX from interrupt to task This adds option to move RX from interrupt to task. This is enforced if monitor is used since montor code cannot be used from interrupts. --- .../transport/nrf5340/src/nrf5340_ble_hci.c | 31 ++++++++++++++----- nimble/transport/nrf5340/syscfg.yml | 28 +++++++++++++++++ 2 files changed, 51 insertions(+), 8 deletions(-) create mode 100644 nimble/transport/nrf5340/syscfg.yml diff --git a/nimble/transport/nrf5340/src/nrf5340_ble_hci.c b/nimble/transport/nrf5340/src/nrf5340_ble_hci.c index 7f3c5efe27..c6e69f4062 100644 --- a/nimble/transport/nrf5340/src/nrf5340_ble_hci.c +++ b/nimble/transport/nrf5340/src/nrf5340_ble_hci.c @@ -36,6 +36,20 @@ static struct hci_ipc_sm g_hci_ipc_sm; +static void +rx_func(void *arg) +{ + uint8_t *buf; + int len; + + len = ipc_nrf5340_available_buf(IPC_RX_CHANNEL, (void **)&buf); + while (len > 0) { + len = hci_ipc_rx(&g_hci_ipc_sm, buf, len); + ipc_nrf5340_consume(IPC_RX_CHANNEL, len); + len = ipc_nrf5340_available_buf(IPC_RX_CHANNEL, (void **)&buf); + } +} + static int nrf5340_ble_hci_acl_tx(struct os_mbuf *om) { @@ -95,15 +109,13 @@ nrf5340_ble_hci_iso_tx(struct os_mbuf *om) static void nrf5340_ble_hci_trans_rx(int channel, void *user_data) { - uint8_t *buf; - int len; + assert(channel == IPC_RX_CHANNEL); - len = ipc_nrf5340_available_buf(channel, (void **)&buf); - while (len > 0) { - len = hci_ipc_rx(&g_hci_ipc_sm, buf, len); - ipc_nrf5340_consume(channel, len); - len = ipc_nrf5340_available_buf(channel, (void **)&buf); - } +#if MYNEWT_VAL(BLE_TRANSPORT_NRF5340_RX_TASK) + ble_transport_rx(); +#else + rx_func(NULL); +#endif } static void @@ -111,6 +123,9 @@ nrf5340_ble_hci_init(void) { SYSINIT_ASSERT_ACTIVE(); +#if MYNEWT_VAL(BLE_TRANSPORT_NRF5340_RX_TASK) + ble_transport_rx_register(rx_func, NULL); +#endif ipc_nrf5340_recv(IPC_RX_CHANNEL, nrf5340_ble_hci_trans_rx, NULL); } diff --git a/nimble/transport/nrf5340/syscfg.yml b/nimble/transport/nrf5340/syscfg.yml new file mode 100644 index 0000000000..2b05734078 --- /dev/null +++ b/nimble/transport/nrf5340/syscfg.yml @@ -0,0 +1,28 @@ +# 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. + +syscfg.defs: + BLE_TRANSPORT_NRF5340_RX_TASK: + description: > + Use separate task for RX. This is required and enabled by default + if monitor is used, optional otherwise. + value: 0 + +syscfg.vals.BLE_MONITOR: + BLE_TRANSPORT_NRF5340_RX_TASK: 1 + BLE_TRANSPORT_RX_PRIO: 1 + BLE_TRANSPORT_RX_STACK_SIZE: 120