wireless/bluetooth and drivers/wireless/bluetooth: Simply the driver registration/initialization interface.

This commit is contained in:
Gregory Nutt
2018-04-14 11:33:29 -06:00
parent a374c9daf8
commit 5d2c226675
12 changed files with 118 additions and 125 deletions
+10 -4
View File
@@ -7396,10 +7396,16 @@ config STM32_HCIUART_SW_RXFLOW
bool "Use Software UART RTS flow control" bool "Use Software UART RTS flow control"
default n default n
---help--- ---help---
Enable UART RTS flow control using Software. Because STM Enable UART RTS flow control using Software. Current STM32 have
Current STM32 have broken HW based RTS behavior (they assert broken HW based RTS behavior (they assert nRTS after every byte
nRTS after every byte received) Enable this setting workaround received) Enable this setting workaround this issue by using
this issue by using software based management of RTS 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 config STM32_HCIUART_UPPER_WATERMARK
int "RTS flow control upper watermark (%)" int "RTS flow control upper watermark (%)"
@@ -33,9 +33,10 @@ CONFIG_FS_PROCFS=y
CONFIG_HAVE_CXX=y CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_INTELHEX_BINARY=y CONFIG_INTELHEX_BINARY=y
CONFIG_IOB_NBUFFERS=36 CONFIG_IOB_BUFSIZE=80
CONFIG_IOB_NCHAINS=8 CONFIG_IOB_NBUFFERS=64
CONFIG_IOB_THROTTLE=8 CONFIG_IOB_NCHAINS=16
CONFIG_IOB_THROTTLE=16
CONFIG_MAX_TASKS=16 CONFIG_MAX_TASKS=16
CONFIG_MAX_WDOGPARMS=2 CONFIG_MAX_WDOGPARMS=2
CONFIG_MMCSD_MULTIBLOCK_DISABLE=y CONFIG_MMCSD_MULTIBLOCK_DISABLE=y
@@ -80,6 +81,7 @@ CONFIG_STM32_USART3_HCIUART=y
CONFIG_STM32_USART3=y CONFIG_STM32_USART3=y
CONFIG_STM32_USART6=y CONFIG_STM32_USART6=y
CONFIG_STM32F4DISBB=y CONFIG_STM32F4DISBB=y
CONFIG_SYSLOG_BUFFER=y
CONFIG_USART6_SERIAL_CONSOLE=y CONFIG_USART6_SERIAL_CONSOLE=y
CONFIG_USER_ENTRYPOINT="nsh_main" CONFIG_USER_ENTRYPOINT="nsh_main"
CONFIG_WIRELESS_BLUETOOTH=y CONFIG_WIRELESS_BLUETOOTH=y
+2 -18
View File
@@ -408,30 +408,14 @@ int btuart_register(FAR const struct btuart_lowerhalf_s *lower)
lower->rxattach(lower, btuart_rxcallback, upper); lower->rxattach(lower, btuart_rxcallback, upper);
/* And register the driver with the Bluetooth stack. /* And register the driver with the network and the Bluetooth stack. */
*
* REVISIT: Wouldn't it be cleaner to have a single call to
* bt_netdev_register() that handled all of the following?
*/
ret = bt_driver_register(&upper->dev); ret = bt_netdev_register(&upper->dev);
if (ret < 0) if (ret < 0)
{ {
wlerr("ERROR: bt_driver_register failed: %d\n", ret); wlerr("ERROR: bt_driver_register failed: %d\n", ret);
kmm_free(upper); 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; return ret;
} }
-53
View File
@@ -72,51 +72,6 @@ struct bt_driver_s
* Public Function Prototypes * 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 * 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 * Register a network driver to access the Bluetooth layer using a 6LoWPAN
* IPv6 or AF_BLUETOOTH socket. * 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: * Input Parameters:
* btdev - An instance of the low-level drivers interface structure. * btdev - An instance of the low-level drivers interface structure.
* *
+1 -1
View File
@@ -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) + maxmtu = BLUETOOTH_MAX_FRAMELEN - (sizeof(struct bt_l2cap_hdr_s) +
sizeof(struct bt_hci_acl_hdr_s) + sizeof(struct bt_hci_acl_hdr_s) +
g_btdev.dev->head_reserve); g_btdev.btdev->head_reserve);
if (mtu > maxmtu) if (mtu > maxmtu)
{ {
mtu = maxmtu; mtu = maxmtu;
+1 -1
View File
@@ -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); 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); bt_buf_release(buf);
} }
+16 -21
View File
@@ -852,7 +852,7 @@ static void hci_event(FAR struct bt_buf_s *buf)
static int hci_tx_kthread(int argc, FAR char *argv[]) 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; int ret;
wlinfo("started\n"); 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", wlinfo("Sending command %04x buf %p to driver\n",
buf->u.hci.opcode, buf); buf->u.hci.opcode, buf);
dev->send(dev, buf); btdev->send(btdev, buf);
/* Clear out any existing sent command */ /* Clear out any existing sent command */
@@ -1121,7 +1121,7 @@ static int hci_initialize(void)
memset(hbs, 0, sizeof(*hbs)); memset(hbs, 0, sizeof(*hbs));
hbs->acl_mtu = BT_HOST2LE16(BLUETOOTH_MAX_FRAMELEN - hbs->acl_mtu = BT_HOST2LE16(BLUETOOTH_MAX_FRAMELEN -
sizeof(struct bt_hci_acl_hdr_s) - 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); hbs->acl_pkts = BT_HOST2LE16(CONFIG_BLUETOOTH_RXTHREAD_NMSGS);
ret = bt_hci_cmd_send(BT_HCI_OP_HOST_BUFFER_SIZE, buf); 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) 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; int ret;
DEBUGASSERT(dev != NULL); DEBUGASSERT(btdev != NULL);
bt_buf_initialize(); bt_buf_initialize();
cmd_queue_init(); cmd_queue_init();
rx_queue_init(); rx_queue_init();
ret = dev->open(dev); ret = btdev->open(btdev);
if (ret < 0) if (ret < 0)
{ {
wlerr("ERROR: HCI driver open failed (%d)\n", ret); 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 * interface prototyped in include/nuttx/wireless/bt_driver.h
* *
* This function associates the Bluetooth driver with the Bluetooth stack. * 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: * Input Parameters:
* dev - An instance of the low-level drivers interface structure. * btdev - An instance of the low-level drivers interface structure.
* *
* Returned Value: * Returned Value:
* Zero is returned on success; a negated errno value is returned on any * 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"); wlwarn("WARNING: Already registered\n");
return -EALREADY; return -EALREADY;
} }
g_btdev.dev = dev; g_btdev.btdev = btdev;
return 0; return 0;
} }
@@ -1336,16 +1331,16 @@ int bt_driver_register(FAR const struct bt_driver_s *dev)
* include/nuttx/wireless/bt_driver.h * include/nuttx/wireless/bt_driver.h
* *
* Input Parameters: * Input Parameters:
* dev - An instance of the low-level drivers interface structure. * btdev - An instance of the low-level drivers interface structure.
* *
* Returned Value: * Returned Value:
* None * 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); 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) if (!buf)
{ {
wlerr("ERROR: Cannot get free buffer\n"); 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) 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); bt_buf_release(buf);
return 0; return 0;
} }
+43 -3
View File
@@ -60,8 +60,8 @@
/* LMP feature helpers */ /* LMP feature helpers */
#define lmp_bredr_capable(dev) (!((dev).features[4] & BT_LMP_NO_BREDR)) #define lmp_bredr_capable(btdev) (!((btdev).features[4] & BT_LMP_NO_BREDR))
#define lmp_le_capable(dev) ((dev).features[4] & BT_LMP_LE) #define lmp_le_capable(btdev) ((btdev).features[4] & BT_LMP_LE)
/**************************************************************************** /****************************************************************************
* Public Types * Public Types
@@ -123,7 +123,7 @@ struct bt_dev_s
/* Registered HCI driver */ /* Registered HCI driver */
FAR const struct bt_driver_s *dev; FAR const struct bt_driver_s *btdev;
}; };
/* Connection callback structure */ /* Connection callback structure */
@@ -241,6 +241,46 @@ struct bt_eir_s; /* Forward reference */
int bt_initialize(void); 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 * Name: bt_hci_cmd_create
* *
+5 -5
View File
@@ -256,22 +256,22 @@ static int btnet_scan_result(FAR struct bt_scanresponse_s *result,
* Handle network IOCTL commands directed to this device. * Handle network IOCTL commands directed to this device.
* *
* Input Parameters: * Input Parameters:
* dev - Reference to the NuttX driver state structure * netdev - Reference to the NuttX driver state structure
* cmd - The IOCTL command * cmd - The IOCTL command
* arg - The argument for the IOCTL command * arg - The argument for the IOCTL command
* *
* Returned Value: * Returned Value:
* OK on success; Negated errno on failure. * 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); FAR struct btreq_s *btreq = (FAR struct btreq_s *)((uintptr_t)arg);
int ret; int ret;
wlinfo("cmd=%04x arg=%ul\n", cmd, arg); 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) if (btreq == NULL)
{ {
+4 -4
View File
@@ -58,9 +58,9 @@
* Handle network IOCTL commands directed to this device. * Handle network IOCTL commands directed to this device.
* *
* Input Parameters: * Input Parameters:
* dev - Reference to the NuttX driver state structure * netdev - Reference to the NuttX driver state structure
* cmd - The IOCTL command * cmd - The IOCTL command
* arg - The argument for the IOCTL command * arg - The argument for the IOCTL command
* *
* Returned Value: * Returned Value:
* OK on success; Negated errno on failure. * OK on success; Negated errno on failure.
@@ -68,6 +68,6 @@
****************************************************************************/ ****************************************************************************/
struct net_driver_s; /* Forward reference */ 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 */ #endif /* __WIRELESS_BLUETOOTH_BT_IOCTL_H */
+1 -1
View File
@@ -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) struct bt_buf_s *bt_l2cap_create_pdu(FAR struct bt_conn_s *conn)
{ {
size_t head_reserve = sizeof(struct bt_l2cap_hdr_s) + 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); return bt_buf_alloc(BT_ACL_OUT, NULL, head_reserve);
} }
+30 -11
View File
@@ -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 * Register a network driver to access the Bluetooth layer using a 6LoWPAN
* IPv6 or AF_BLUETOOTH socket. * 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: * Input Parameters:
* btdev - An instance of the low-level drivers interface structure. * 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_req_data = btnet_req_data; /* Enqueue frame for transmission */
radio->r_properties = btnet_properties; /* Return radio properties */ 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(); ret = bt_initialize();
if (ret < 0) if (ret < 0)
{ {
nerr("ERROR: Failed to initialize Bluetooth: %d\n", ret); nerr("ERROR: bt_initialize() failed: %d\n", ret);
goto errout; goto errout;
} }
@@ -1099,7 +1110,9 @@ int bt_netdev_register(FAR const struct bt_driver_s *btdev)
btnet_ifdown(netdev); 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); ret = netdev_register(&priv->bd_dev.r_dev, NET_LL_BLUETOOTH);
if (ret >= 0) if (ret >= 0)
@@ -1107,11 +1120,17 @@ int bt_netdev_register(FAR const struct bt_driver_s *btdev)
return OK; return OK;
} }
nerr("ERROR: netdev_register() failed: %d\n", ret);
errout: errout:
/* Release wdog timers */ /* Release wdog timers */
wd_delete(priv->bd_txpoll); wd_delete(priv->bd_txpoll);
/* Un-initialize semaphores */
nxsem_destroy(&priv->bd_exclsem);
/* Free memory and return the error */ /* Free memory and return the error */
kmm_free(priv); kmm_free(priv);