From 5d2c2266751dd4fb48f31d24fc0320ceeb02e94e Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 14 Apr 2018 11:33:29 -0600 Subject: [PATCH] wireless/bluetooth and drivers/wireless/bluetooth: Simply the driver registration/initialization interface. --- arch/arm/src/stm32/Kconfig | 14 +++-- .../{netnsh => }/hciuart/defconfig | 8 +-- drivers/wireless/bluetooth/bt_uart.c | 20 +------ include/nuttx/wireless/bt_driver.h | 53 ------------------- wireless/bluetooth/bt_att.c | 2 +- wireless/bluetooth/bt_conn.c | 2 +- wireless/bluetooth/bt_hcicore.c | 37 ++++++------- wireless/bluetooth/bt_hcicore.h | 46 ++++++++++++++-- wireless/bluetooth/bt_ioctl.c | 10 ++-- wireless/bluetooth/bt_ioctl.h | 8 +-- wireless/bluetooth/bt_l2cap.c | 2 +- wireless/bluetooth/bt_netdev.c | 41 ++++++++++---- 12 files changed, 118 insertions(+), 125 deletions(-) rename configs/stm32f4discovery/{netnsh => }/hciuart/defconfig (94%) diff --git a/arch/arm/src/stm32/Kconfig b/arch/arm/src/stm32/Kconfig index 78f4d05f4f..ba4eaf9c8a 100644 --- a/arch/arm/src/stm32/Kconfig +++ b/arch/arm/src/stm32/Kconfig @@ -7396,10 +7396,16 @@ config STM32_HCIUART_SW_RXFLOW bool "Use Software UART RTS flow control" default n ---help--- - Enable UART RTS flow control using Software. Because STM - Current STM32 have broken HW based RTS behavior (they assert - nRTS after every byte received) Enable this setting workaround - this issue by using software based management of RTS + Enable UART RTS flow control using Software. Current STM32 have + broken HW based RTS behavior (they assert nRTS after every byte + received) Enable this setting workaround this issue by using + software based management of RTS + + If HCI UART DMA is enabled, this is probably the better selection + as well. In that case, the Rx DMA buffer will avoid Rx overrun due + to short, bursty activity. Software RTS management will probably + result in overall better throughput and shoudl still avoid Rx data + overrun conditions. config STM32_HCIUART_UPPER_WATERMARK int "RTS flow control upper watermark (%)" diff --git a/configs/stm32f4discovery/netnsh/hciuart/defconfig b/configs/stm32f4discovery/hciuart/defconfig similarity index 94% rename from configs/stm32f4discovery/netnsh/hciuart/defconfig rename to configs/stm32f4discovery/hciuart/defconfig index b365e7ba6d..0ee3b72d0b 100644 --- a/configs/stm32f4discovery/netnsh/hciuart/defconfig +++ b/configs/stm32f4discovery/hciuart/defconfig @@ -33,9 +33,10 @@ CONFIG_FS_PROCFS=y CONFIG_HAVE_CXX=y CONFIG_HAVE_CXXINITIALIZE=y CONFIG_INTELHEX_BINARY=y -CONFIG_IOB_NBUFFERS=36 -CONFIG_IOB_NCHAINS=8 -CONFIG_IOB_THROTTLE=8 +CONFIG_IOB_BUFSIZE=80 +CONFIG_IOB_NBUFFERS=64 +CONFIG_IOB_NCHAINS=16 +CONFIG_IOB_THROTTLE=16 CONFIG_MAX_TASKS=16 CONFIG_MAX_WDOGPARMS=2 CONFIG_MMCSD_MULTIBLOCK_DISABLE=y @@ -80,6 +81,7 @@ CONFIG_STM32_USART3_HCIUART=y CONFIG_STM32_USART3=y CONFIG_STM32_USART6=y CONFIG_STM32F4DISBB=y +CONFIG_SYSLOG_BUFFER=y CONFIG_USART6_SERIAL_CONSOLE=y CONFIG_USER_ENTRYPOINT="nsh_main" CONFIG_WIRELESS_BLUETOOTH=y diff --git a/drivers/wireless/bluetooth/bt_uart.c b/drivers/wireless/bluetooth/bt_uart.c index 6e71637f36..aca266fd27 100644 --- a/drivers/wireless/bluetooth/bt_uart.c +++ b/drivers/wireless/bluetooth/bt_uart.c @@ -408,30 +408,14 @@ int btuart_register(FAR const struct btuart_lowerhalf_s *lower) lower->rxattach(lower, btuart_rxcallback, upper); - /* And register the driver with the Bluetooth stack. - * - * REVISIT: Wouldn't it be cleaner to have a single call to - * bt_netdev_register() that handled all of the following? - */ + /* And register the driver with the network and the Bluetooth stack. */ - ret = bt_driver_register(&upper->dev); + ret = bt_netdev_register(&upper->dev); if (ret < 0) { wlerr("ERROR: bt_driver_register failed: %d\n", ret); kmm_free(upper); } - else - { - /* And bring up the network driver to serve this device */ - - ret = bt_netdev_register(&upper->dev); - if (ret < 0) - { - wlerr("ERROR: bt_driver_register failed: %d\n", ret); - bt_driver_unregister(&upper->dev); - kmm_free(upper); - } - } return ret; } diff --git a/include/nuttx/wireless/bt_driver.h b/include/nuttx/wireless/bt_driver.h index 2fd3a8d98b..1bbfed3f9e 100644 --- a/include/nuttx/wireless/bt_driver.h +++ b/include/nuttx/wireless/bt_driver.h @@ -72,51 +72,6 @@ struct bt_driver_s * Public Function Prototypes ****************************************************************************/ -/**************************************************************************** - * Name: bt_driver_register - * - * Description: - * Register the Bluetooth low-level driver with the Bluetooth stack. - * This is called from the low-level driver and is part of the driver - * interface prototyped in include/nuttx/wireless/bt_driver.h - * - * This function associates the Bluetooth driver with the Bluetooth stack. - * It must be called *BEFORE* bt_netdev_register(). - * - * REVISIT: This probably should be re-partitioned. It would may more - * sense for the Bluetooth driver to just call bt_netdev_register() and - * have that function call bt_driver_register(). - * - * Input Parameters: - * btdev - An instance of the low-level drivers interface structure. - * - * Returned Value: - * Zero is returned on success; a negated errno value is returned on any - * failure. - * - ****************************************************************************/ - -int bt_driver_register(FAR const struct bt_driver_s *btdev); - -/**************************************************************************** - * Name: bt_driver_unregister - * - * Description: - * Unregister a Bluetooth low-level driver previously registered with - * bt_driver_register. This may be called from the low-level driver and - * is part of the driver interface prototyped in - * include/nuttx/wireless/bt_driver.h - * - * Input Parameters: - * btdev - An instance of the low-level drivers interface structure. - * - * Returned Value: - * None - * - ****************************************************************************/ - -void bt_driver_unregister(FAR const struct bt_driver_s *btdev); - /**************************************************************************** * Name: bt_netdev_register * @@ -124,14 +79,6 @@ void bt_driver_unregister(FAR const struct bt_driver_s *btdev); * Register a network driver to access the Bluetooth layer using a 6LoWPAN * IPv6 or AF_BLUETOOTH socket. * - * This function should be called by the Bluetooth driver *AFTER* it has - * called bt_driver_register(). This function assocated the Bluetooth - * driver with the highe level network stack. - * - * REVISIT: This probably should be re-partitioned. It would may more - * sense for the Bluetooth driver to just call bt_driver_register() and - * let this function performed the Bluetooth stack configuration. - * * Input Parameters: * btdev - An instance of the low-level drivers interface structure. * diff --git a/wireless/bluetooth/bt_att.c b/wireless/bluetooth/bt_att.c index 9e86686d6f..c4a47a3e12 100644 --- a/wireless/bluetooth/bt_att.c +++ b/wireless/bluetooth/bt_att.c @@ -562,7 +562,7 @@ static uint8_t att_mtu_rsp(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf) maxmtu = BLUETOOTH_MAX_FRAMELEN - (sizeof(struct bt_l2cap_hdr_s) + sizeof(struct bt_hci_acl_hdr_s) + - g_btdev.dev->head_reserve); + g_btdev.btdev->head_reserve); if (mtu > maxmtu) { mtu = maxmtu; diff --git a/wireless/bluetooth/bt_conn.c b/wireless/bluetooth/bt_conn.c index d32bccf40a..41f4d4f385 100644 --- a/wireless/bluetooth/bt_conn.c +++ b/wireless/bluetooth/bt_conn.c @@ -178,7 +178,7 @@ static int conn_tx_kthread(int argc, FAR char *argv[]) } wlinfo("passing buf %p len %u to driver\n", buf, buf->len); - g_btdev.dev->send(g_btdev.dev, buf); + g_btdev.btdev->send(g_btdev.btdev, buf); bt_buf_release(buf); } diff --git a/wireless/bluetooth/bt_hcicore.c b/wireless/bluetooth/bt_hcicore.c index bfb81eead9..e959f7f794 100644 --- a/wireless/bluetooth/bt_hcicore.c +++ b/wireless/bluetooth/bt_hcicore.c @@ -852,7 +852,7 @@ static void hci_event(FAR struct bt_buf_s *buf) static int hci_tx_kthread(int argc, FAR char *argv[]) { - FAR const struct bt_driver_s *dev = g_btdev.dev; + FAR const struct bt_driver_s *btdev = g_btdev.btdev; int ret; wlinfo("started\n"); @@ -883,7 +883,7 @@ static int hci_tx_kthread(int argc, FAR char *argv[]) wlinfo("Sending command %04x buf %p to driver\n", buf->u.hci.opcode, buf); - dev->send(dev, buf); + btdev->send(btdev, buf); /* Clear out any existing sent command */ @@ -1121,7 +1121,7 @@ static int hci_initialize(void) memset(hbs, 0, sizeof(*hbs)); hbs->acl_mtu = BT_HOST2LE16(BLUETOOTH_MAX_FRAMELEN - sizeof(struct bt_hci_acl_hdr_s) - - g_btdev.dev->head_reserve); + g_btdev.btdev->head_reserve); hbs->acl_pkts = BT_HOST2LE16(CONFIG_BLUETOOTH_RXTHREAD_NMSGS); ret = bt_hci_cmd_send(BT_HCI_OP_HOST_BUFFER_SIZE, buf); @@ -1262,16 +1262,16 @@ static void rx_queue_init(void) int bt_initialize(void) { - FAR const struct bt_driver_s *dev = g_btdev.dev; + FAR const struct bt_driver_s *btdev = g_btdev.btdev; int ret; - DEBUGASSERT(dev != NULL); + DEBUGASSERT(btdev != NULL); bt_buf_initialize(); cmd_queue_init(); rx_queue_init(); - ret = dev->open(dev); + ret = btdev->open(btdev); if (ret < 0) { wlerr("ERROR: HCI driver open failed (%d)\n", ret); @@ -1297,14 +1297,9 @@ int bt_initialize(void) * interface prototyped in include/nuttx/wireless/bt_driver.h * * This function associates the Bluetooth driver with the Bluetooth stack. - * It must be called *BEFORE* bt_netdev_register(). - * - * REVISIT: This probably should be re-partitioned. It would may more - * sense for the Bluetooth driver to just call bt_netdev_register() and - * have that function call bt_driver_register(). * * Input Parameters: - * dev - An instance of the low-level drivers interface structure. + * btdev - An instance of the low-level drivers interface structure. * * Returned Value: * Zero is returned on success; a negated errno value is returned on any @@ -1312,17 +1307,17 @@ int bt_initialize(void) * ****************************************************************************/ -int bt_driver_register(FAR const struct bt_driver_s *dev) +int bt_driver_register(FAR const struct bt_driver_s *btdev) { - DEBUGASSERT(dev != NULL && dev->open != NULL && dev->send != NULL); + DEBUGASSERT(btdev != NULL && btdev->open != NULL && btdev->send != NULL); - if (g_btdev.dev != NULL) + if (g_btdev.btdev != NULL) { wlwarn("WARNING: Already registered\n"); return -EALREADY; } - g_btdev.dev = dev; + g_btdev.btdev = btdev; return 0; } @@ -1336,16 +1331,16 @@ int bt_driver_register(FAR const struct bt_driver_s *dev) * include/nuttx/wireless/bt_driver.h * * Input Parameters: - * dev - An instance of the low-level drivers interface structure. + * btdev - An instance of the low-level drivers interface structure. * * Returned Value: * None * ****************************************************************************/ -void bt_driver_unregister(FAR const struct bt_driver_s *dev) +void bt_driver_unregister(FAR const struct bt_driver_s *btdev) { - g_btdev.dev = NULL; + g_btdev.btdev = NULL; } /**************************************************************************** @@ -1418,7 +1413,7 @@ FAR struct bt_buf_s *bt_hci_cmd_create(uint16_t opcode, uint8_t param_len) wlinfo("opcode %x param_len %u\n", opcode, param_len); - buf = bt_buf_alloc(BT_CMD, NULL, g_btdev.dev->head_reserve); + buf = bt_buf_alloc(BT_CMD, NULL, g_btdev.btdev->head_reserve); if (!buf) { wlerr("ERROR: Cannot get free buffer\n"); @@ -1459,7 +1454,7 @@ int bt_hci_cmd_send(uint16_t opcode, FAR struct bt_buf_s *buf) if (opcode == BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS) { - g_btdev.dev->send(g_btdev.dev, buf); + g_btdev.btdev->send(g_btdev.btdev, buf); bt_buf_release(buf); return 0; } diff --git a/wireless/bluetooth/bt_hcicore.h b/wireless/bluetooth/bt_hcicore.h index d8506356cf..7deeb8f0b3 100644 --- a/wireless/bluetooth/bt_hcicore.h +++ b/wireless/bluetooth/bt_hcicore.h @@ -60,8 +60,8 @@ /* LMP feature helpers */ -#define lmp_bredr_capable(dev) (!((dev).features[4] & BT_LMP_NO_BREDR)) -#define lmp_le_capable(dev) ((dev).features[4] & BT_LMP_LE) +#define lmp_bredr_capable(btdev) (!((btdev).features[4] & BT_LMP_NO_BREDR)) +#define lmp_le_capable(btdev) ((btdev).features[4] & BT_LMP_LE) /**************************************************************************** * Public Types @@ -123,7 +123,7 @@ struct bt_dev_s /* Registered HCI driver */ - FAR const struct bt_driver_s *dev; + FAR const struct bt_driver_s *btdev; }; /* Connection callback structure */ @@ -241,6 +241,46 @@ struct bt_eir_s; /* Forward reference */ int bt_initialize(void); +/**************************************************************************** + * Name: bt_driver_register + * + * Description: + * Register the Bluetooth low-level driver with the Bluetooth stack. + * This is called from the low-level driver and is part of the driver + * interface prototyped in include/nuttx/wireless/bt_driver.h + * + * This function associates the Bluetooth driver with the Bluetooth stack. + * + * Input Parameters: + * btdev - An instance of the low-level drivers interface structure. + * + * Returned Value: + * Zero is returned on success; a negated errno value is returned on any + * failure. + * + ****************************************************************************/ + +int bt_driver_register(FAR const struct bt_driver_s *btdev); + +/**************************************************************************** + * Name: bt_driver_unregister + * + * Description: + * Unregister a Bluetooth low-level driver previously registered with + * bt_driver_register. This may be called from the low-level driver and + * is part of the driver interface prototyped in + * include/nuttx/wireless/bt_driver.h + * + * Input Parameters: + * btdev - An instance of the low-level drivers interface structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void bt_driver_unregister(FAR const struct bt_driver_s *btdev); + /**************************************************************************** * Name: bt_hci_cmd_create * diff --git a/wireless/bluetooth/bt_ioctl.c b/wireless/bluetooth/bt_ioctl.c index 3e8a7bddb7..acbf907a36 100644 --- a/wireless/bluetooth/bt_ioctl.c +++ b/wireless/bluetooth/bt_ioctl.c @@ -256,22 +256,22 @@ static int btnet_scan_result(FAR struct bt_scanresponse_s *result, * Handle network IOCTL commands directed to this device. * * Input Parameters: - * dev - Reference to the NuttX driver state structure - * cmd - The IOCTL command - * arg - The argument for the IOCTL command + * netdev - Reference to the NuttX driver state structure + * cmd - The IOCTL command + * arg - The argument for the IOCTL command * * Returned Value: * OK on success; Negated errno on failure. * ****************************************************************************/ -int btnet_ioctl(FAR struct net_driver_s *dev, int cmd, unsigned long arg) +int btnet_ioctl(FAR struct net_driver_s *netdev, int cmd, unsigned long arg) { FAR struct btreq_s *btreq = (FAR struct btreq_s *)((uintptr_t)arg); int ret; wlinfo("cmd=%04x arg=%ul\n", cmd, arg); - DEBUGASSERT(dev != NULL && dev->d_private != NULL); + DEBUGASSERT(netdev != NULL && netdev->d_private != NULL); if (btreq == NULL) { diff --git a/wireless/bluetooth/bt_ioctl.h b/wireless/bluetooth/bt_ioctl.h index a98c6570e3..9f59d6deb1 100644 --- a/wireless/bluetooth/bt_ioctl.h +++ b/wireless/bluetooth/bt_ioctl.h @@ -58,9 +58,9 @@ * Handle network IOCTL commands directed to this device. * * Input Parameters: - * dev - Reference to the NuttX driver state structure - * cmd - The IOCTL command - * arg - The argument for the IOCTL command + * netdev - Reference to the NuttX driver state structure + * cmd - The IOCTL command + * arg - The argument for the IOCTL command * * Returned Value: * OK on success; Negated errno on failure. @@ -68,6 +68,6 @@ ****************************************************************************/ struct net_driver_s; /* Forward reference */ -int btnet_ioctl(FAR struct net_driver_s *dev, int cmd, unsigned long arg); +int btnet_ioctl(FAR struct net_driver_s *netdev, int cmd, unsigned long arg); #endif /* __WIRELESS_BLUETOOTH_BT_IOCTL_H */ diff --git a/wireless/bluetooth/bt_l2cap.c b/wireless/bluetooth/bt_l2cap.c index d150d1c32a..c296171a80 100644 --- a/wireless/bluetooth/bt_l2cap.c +++ b/wireless/bluetooth/bt_l2cap.c @@ -180,7 +180,7 @@ void bt_l2cap_encrypt_change(FAR struct bt_conn_s *conn) struct bt_buf_s *bt_l2cap_create_pdu(FAR struct bt_conn_s *conn) { size_t head_reserve = sizeof(struct bt_l2cap_hdr_s) + - sizeof(struct bt_hci_acl_hdr_s) + g_btdev.dev->head_reserve; + sizeof(struct bt_hci_acl_hdr_s) + g_btdev.btdev->head_reserve; return bt_buf_alloc(BT_ACL_OUT, NULL, head_reserve); } diff --git a/wireless/bluetooth/bt_netdev.c b/wireless/bluetooth/bt_netdev.c index 55f109c8bc..089614188b 100644 --- a/wireless/bluetooth/bt_netdev.c +++ b/wireless/bluetooth/bt_netdev.c @@ -993,14 +993,6 @@ static int btnet_properties(FAR struct radio_driver_s *netdev, * Register a network driver to access the Bluetooth layer using a 6LoWPAN * IPv6 or AF_BLUETOOTH socket. * - * This function should be called by the Bluetooth driver *AFTER* it has - * called bt_driver_register(). This function assocated the Bluetooth - * driver with the highe level network stack. - * - * REVISIT: This probably should be re-partitioned. It would may more - * sense for the Bluetooth driver to just call bt_driver_register() and - * let this function performed the Bluetooth stack configuration. - * * Input Parameters: * btdev - An instance of the low-level drivers interface structure. * @@ -1086,12 +1078,31 @@ int bt_netdev_register(FAR const struct bt_driver_s *btdev) radio->r_req_data = btnet_req_data; /* Enqueue frame for transmission */ radio->r_properties = btnet_properties; /* Return radio properties */ - /* Initialize the Bluetooth stack */ + /* Associate the driver in with the Bluetooth stack. + * + * REVISIT: We will eventually need to remember which Bluetooth device + * we a serving. Not a problem now because only a single BLE device is + * supported. + */ + + ret = bt_driver_register(btdev); + if (ret < 0) + { + nerr("ERROR: bt_driver_register() failed: %d\n", ret); + goto errout; + } + + /* Initialize the Bluetooth stack. + * + * REVISIT: This function should be called only once after all BLE + * drivers are registered. Not a problem now because only a single + * BLE device is supported. + */ ret = bt_initialize(); if (ret < 0) { - nerr("ERROR: Failed to initialize Bluetooth: %d\n", ret); + nerr("ERROR: bt_initialize() failed: %d\n", ret); goto errout; } @@ -1099,7 +1110,9 @@ int bt_netdev_register(FAR const struct bt_driver_s *btdev) btnet_ifdown(netdev); - /* Register the device with the OS so that socket IOCTLs can be performed */ + /* Register the network device with the OS so that socket IOCTLs can be + * performed + */ ret = netdev_register(&priv->bd_dev.r_dev, NET_LL_BLUETOOTH); if (ret >= 0) @@ -1107,11 +1120,17 @@ int bt_netdev_register(FAR const struct bt_driver_s *btdev) return OK; } + nerr("ERROR: netdev_register() failed: %d\n", ret); + errout: /* Release wdog timers */ wd_delete(priv->bd_txpoll); + /* Un-initialize semaphores */ + + nxsem_destroy(&priv->bd_exclsem); + /* Free memory and return the error */ kmm_free(priv);