|
13 | 13 | #include <zephyr/kernel.h>
|
14 | 14 | #include <zephyr/arch/cpu.h>
|
15 | 15 | #include <zephyr/sys/byteorder.h>
|
| 16 | +#include <zephyr/logging/log_ctrl.h> |
16 | 17 | #include <zephyr/logging/log.h>
|
17 | 18 | #include <zephyr/sys/util.h>
|
18 | 19 |
|
|
26 | 27 | #include <zephyr/bluetooth/hci.h>
|
27 | 28 | #include <zephyr/bluetooth/buf.h>
|
28 | 29 | #include <zephyr/bluetooth/hci_raw.h>
|
| 30 | +#include <zephyr/bluetooth/hci_vs.h> |
29 | 31 |
|
30 | 32 | #define LOG_MODULE_NAME hci_uart
|
31 | 33 | LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
@@ -281,49 +283,99 @@ static int h4_send(struct net_buf *buf)
|
281 | 283 | #if defined(CONFIG_BT_CTLR_ASSERT_HANDLER)
|
282 | 284 | void bt_ctlr_assert_handle(char *file, uint32_t line)
|
283 | 285 | {
|
284 |
| - uint32_t len = 0U, pos = 0U; |
285 |
| - |
286 | 286 | /* Disable interrupts, this is unrecoverable */
|
287 | 287 | (void)irq_lock();
|
288 | 288 |
|
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); |
291 | 303 |
|
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--; |
296 | 311 | }
|
297 |
| - len++; |
| 312 | + } else { |
| 313 | + LOG_ERR("Can't create Fatal Error HCI event: %s at %d", __FILE__, __LINE__); |
298 | 314 | }
|
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); |
301 | 319 | }
|
302 | 320 |
|
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"); |
314 | 364 | }
|
315 |
| - uart_poll_out(hci_uart_dev, 0x00); |
316 | 365 | }
|
317 | 366 |
|
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"); |
322 | 368 |
|
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; |
325 | 377 | }
|
326 |
| -#endif /* CONFIG_BT_CTLR_ASSERT_HANDLER */ |
| 378 | +#endif /* CONFIG_BT_HCI_VS_FATAL_ERROR */ |
327 | 379 |
|
328 | 380 | static int hci_uart_init(void)
|
329 | 381 | {
|
|
0 commit comments