Skip to content

Commit 9a53dac

Browse files
committed
samples: Bluetooth: hci_uart: Reuse hci_vs_err_assert
Reuse hci_vs_err_assert implementation to generate the HCI vendor-specific hardware error event. Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
1 parent b8b40c4 commit 9a53dac

File tree

1 file changed

+82
-30
lines changed
  • samples/bluetooth/hci_uart/src

1 file changed

+82
-30
lines changed

samples/bluetooth/hci_uart/src/main.c

Lines changed: 82 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <zephyr/kernel.h>
1414
#include <zephyr/arch/cpu.h>
1515
#include <zephyr/sys/byteorder.h>
16+
#include <zephyr/logging/log_ctrl.h>
1617
#include <zephyr/logging/log.h>
1718
#include <zephyr/sys/util.h>
1819

@@ -26,6 +27,7 @@
2627
#include <zephyr/bluetooth/hci.h>
2728
#include <zephyr/bluetooth/buf.h>
2829
#include <zephyr/bluetooth/hci_raw.h>
30+
#include <zephyr/bluetooth/hci_vs.h>
2931

3032
#define LOG_MODULE_NAME hci_uart
3133
LOG_MODULE_REGISTER(LOG_MODULE_NAME);
@@ -281,49 +283,99 @@ static int h4_send(struct net_buf *buf)
281283
#if defined(CONFIG_BT_CTLR_ASSERT_HANDLER)
282284
void bt_ctlr_assert_handle(char *file, uint32_t line)
283285
{
284-
uint32_t len = 0U, pos = 0U;
285-
286286
/* Disable interrupts, this is unrecoverable */
287287
(void)irq_lock();
288288

289-
uart_irq_rx_disable(hci_uart_dev);
290-
uart_irq_tx_disable(hci_uart_dev);
289+
if (IS_ENABLED(CONFIG_BT_HCI_VS_FATAL_ERROR)) {
290+
struct net_buf *buf;
291+
292+
/* Prepare vendor specific HCI error event */
293+
buf = hci_vs_err_assert(file, line);
294+
if (buf != NULL) {
295+
uint32_t len;
296+
uint8_t *data;
297+
298+
/* Disable interrupt driven, and use polling to be able to transmit while
299+
* being in highest priority ISR.
300+
*/
301+
uart_irq_rx_disable(hci_uart_dev);
302+
uart_irq_tx_disable(hci_uart_dev);
291303

292-
if (file) {
293-
while (file[len] != '\0') {
294-
if (file[len] == '/') {
295-
pos = len + 1;
304+
/* Send the event over UART */
305+
data = &buf->data[0];
306+
len = buf->len;
307+
while (len) {
308+
uart_poll_out(hci_uart_dev, *data);
309+
data++;
310+
len--;
296311
}
297-
len++;
312+
} else {
313+
LOG_ERR("Can't create Fatal Error HCI event: %s at %d", __FILE__, __LINE__);
298314
}
299-
file += pos;
300-
len -= pos;
315+
316+
LOG_ERR("Halting system");
317+
} else {
318+
LOG_ERR("Controller assert in: %s at %d", file, line);
301319
}
302320

303-
uart_poll_out(hci_uart_dev, H4_EVT);
304-
/* Vendor-Specific debug event */
305-
uart_poll_out(hci_uart_dev, 0xff);
306-
/* 0xAA + strlen + \0 + 32-bit line number */
307-
uart_poll_out(hci_uart_dev, 1 + len + 1 + 4);
308-
uart_poll_out(hci_uart_dev, 0xAA);
309-
310-
if (len) {
311-
while (*file != '\0') {
312-
uart_poll_out(hci_uart_dev, *file);
313-
file++;
321+
/* Flush the logs before locking the CPU */
322+
LOG_PANIC();
323+
324+
while (true) {
325+
k_cpu_idle();
326+
};
327+
328+
CODE_UNREACHABLE;
329+
}
330+
#endif /* CONFIG_BT_CTLR_ASSERT_HANDLER */
331+
332+
#if defined(CONFIG_BT_HCI_VS_FATAL_ERROR)
333+
void k_sys_fatal_error_handler(unsigned int reason, const struct arch_esf *esf)
334+
{
335+
/* Disable interrupts, this is unrecoverable */
336+
(void)irq_lock();
337+
338+
/* Generate an error event only when there is a stack frame */
339+
if (esf != NULL) {
340+
struct net_buf *buf;
341+
342+
/* Prepare vendor specific HCI error event */
343+
buf = hci_vs_err_stack_frame(reason, esf);
344+
if (buf != NULL) {
345+
uint32_t len;
346+
uint8_t *data;
347+
348+
/* Disable interrupt driven, and use polling to be able to transmit while
349+
* being in highest priority ISR.
350+
*/
351+
uart_irq_rx_disable(hci_uart_dev);
352+
uart_irq_tx_disable(hci_uart_dev);
353+
354+
/* Send the event over UART */
355+
data = &buf->data[0];
356+
len = buf->len;
357+
while (len) {
358+
uart_poll_out(hci_uart_dev, *data);
359+
data++;
360+
len--;
361+
}
362+
} else {
363+
LOG_ERR("Can't create Fatal Error HCI event.\n");
314364
}
315-
uart_poll_out(hci_uart_dev, 0x00);
316365
}
317366

318-
uart_poll_out(hci_uart_dev, line >> 0 & 0xff);
319-
uart_poll_out(hci_uart_dev, line >> 8 & 0xff);
320-
uart_poll_out(hci_uart_dev, line >> 16 & 0xff);
321-
uart_poll_out(hci_uart_dev, line >> 24 & 0xff);
367+
LOG_ERR("Halting system");
322368

323-
while (1) {
324-
}
369+
/* Flush the logs before locking the CPU */
370+
LOG_PANIC();
371+
372+
while (true) {
373+
k_cpu_idle();
374+
};
375+
376+
CODE_UNREACHABLE;
325377
}
326-
#endif /* CONFIG_BT_CTLR_ASSERT_HANDLER */
378+
#endif /* CONFIG_BT_HCI_VS_FATAL_ERROR */
327379

328380
static int hci_uart_init(void)
329381
{

0 commit comments

Comments
 (0)