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/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 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.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)' 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"