Hi,
I am programming with nrf52833,ncs v2.9.0,generating peripheral_uart to peripheral_hid_keyboard sdk.
And now with working serial times,err happend and log is Not able to allocate UART receive buffer.
LOG is
E: No connection for handle 0 E: No connection for handle 0 W: Not able to allocate UART receive buffer, UART_RX_BUF_REQUEST W: Not able to allocate UART receive buffer, UART_RX_DISABLED W: Not able to allocate UART receive buffer, uart_work_handler
My code is
static const struct device *uart = DEVICE_DT_GET(DT_CHOSEN(nordic_nus_uart)); static void uart_cb(const struct device *dev, struct uart_event *evt, void *user_data) { ARG_UNUSED(dev); static size_t aborted_len; uart_data_t *buf; static uint8_t *aborted_buf; static bool disable_req; switch (evt->type) { case UART_TX_DONE: LOG_INF("UART_TX_DONE"); if ((evt->data.tx.len == 0) || (!evt->data.tx.buf)) { return; } if (aborted_buf) { buf = CONTAINER_OF(aborted_buf, uart_data_t, data[0]); aborted_buf = NULL; aborted_len = 0; } else { buf = CONTAINER_OF(evt->data.tx.buf, uart_data_t, data[0]); } k_free(buf); buf = k_fifo_get(&fifo_uart_tx_data, K_NO_WAIT); if (!buf) { return; } if (uart_tx(uart, buf->data, buf->len, SYS_FOREVER_MS)) { LOG_WRN("Failed to send data over UART, UART_TX_DONE"); } break; case UART_RX_RDY: LOG_INF("UART_RX_RDY"); buf = CONTAINER_OF(evt->data.rx.buf, uart_data_t, data[0]); // 防止缓冲区溢出 if (buf->len + evt->data.rx.len <= sizeof(buf->data)) { buf->len += evt->data.rx.len; } else { LOG_WRN("UART RX buffer overflow detected"); buf->len = sizeof(buf->data); // 截断处理 } //buf->len += evt->data.rx.len; if (disable_req) { return; } if ((evt->data.rx.buf[buf->len - 1] == '\n') || (evt->data.rx.buf[buf->len - 1] == '\r')) { disable_req = true; uart_rx_disable(uart); } break; case UART_RX_DISABLED: LOG_INF("UART_RX_DISABLED"); disable_req = false; buf = k_malloc(sizeof(*buf)); if (buf) { buf->len = 0; uart_rx_enable(uart, buf->data, sizeof(buf->data), UART_WAIT_FOR_RX); } else { LOG_WRN("Not able to allocate UART receive buffer, UART_RX_DISABLED"); k_work_reschedule(&uart_work, UART_WAIT_FOR_BUF_DELAY); return; } break; case UART_RX_BUF_REQUEST: LOG_INF("UART_RX_BUF_REQUEST"); buf = k_malloc(sizeof(*buf)); if (buf) { buf->len = 0; uart_rx_buf_rsp(uart, buf->data, sizeof(buf->data)); } else { LOG_WRN("Not able to allocate UART receive buffer, UART_RX_BUF_REQUEST"); } break; case UART_RX_BUF_RELEASED: LOG_INF("UART_RX_BUF_RELEASED"); buf = CONTAINER_OF(evt->data.rx_buf.buf, uart_data_t, data[0]); if (buf->len > 0) { k_fifo_put(&fifo_uart_rx_data, buf); //LOG_INF("k_fifo_put buf addr:%p", buf); } else { k_free(buf); } break; case UART_TX_ABORTED: LOG_INF("UART_TX_ABORTED"); if (!aborted_buf) { aborted_buf = (uint8_t *)evt->data.tx.buf; } aborted_len += evt->data.tx.len; buf = CONTAINER_OF((void *)aborted_buf, uart_data_t, data); if(!buf) { LOG_ERR("Invalid buffer in UART_TX_ABORTED"); return; } uart_tx(uart, &buf->data[aborted_len], buf->len - aborted_len, SYS_FOREVER_MS); break; default: break; } } static void uart_work_handler(struct k_work *item) { uart_data_t *buf; buf = k_malloc(sizeof(*buf)); //LOG_INF("uart_work_handler buf addr:%p", buf); if (buf) { buf->len = 0; } else { LOG_WRN("Not able to allocate UART receive buffer, uart_work_handler"); k_work_reschedule(&uart_work, UART_WAIT_FOR_BUF_DELAY); return; } uart_rx_enable(uart, buf->data, sizeof(buf->data), UART_WAIT_FOR_RX); } static bool uart_test_async_api(const struct device *dev) { const struct uart_driver_api *api = (const struct uart_driver_api *)dev->api; return (api->callback_set != NULL); } static int uart_init(void) { int err; int pos; uart_data_t *rx; uart_data_t *tx; if (!device_is_ready(uart)) { return -ENODEV; } rx = k_malloc(sizeof(*rx)); if (rx) { rx->len = 0; } else { return -ENOMEM; } k_work_init_delayable(&uart_work, uart_work_handler); if (IS_ENABLED(CONFIG_BT_NUS_UART_ASYNC_ADAPTER) && !uart_test_async_api(uart)) { /* Implement API adapter */ uart_async_adapter_init(async_adapter, uart); uart = async_adapter; } err = uart_callback_set(uart, uart_cb, NULL); if (err) { k_free(rx); LOG_ERR("Cannot initialize UART callback"); return err; } if (IS_ENABLED(CONFIG_UART_LINE_CTRL)) { while (true) { uint32_t dtr = 0; uart_line_ctrl_get(uart, UART_LINE_CTRL_DTR, &dtr); if (dtr) { break; } /* Give CPU resources to low priority threads. */ k_sleep(K_MSEC(100)); } err = uart_line_ctrl_set(uart, UART_LINE_CTRL_DCD, 1); if (err) { LOG_WRN("Failed to set DCD, ret code %d", err); } err = uart_line_ctrl_set(uart, UART_LINE_CTRL_DSR, 1); if (err) { LOG_WRN("Failed to set DSR, ret code %d", err); } } tx = k_malloc(sizeof(*tx)); if (tx) { pos = snprintf(tx->data, sizeof(tx->data), "Starting ...\r\n"); if ((pos < 0) || (pos >= sizeof(tx->data))) { k_free(rx); k_free(tx); LOG_ERR("snprintf returned %d", pos); return -ENOMEM; } tx->len = pos; } else { k_free(rx); return -ENOMEM; } err = uart_tx(uart, tx->data, tx->len, SYS_FOREVER_MS); if (err) { k_free(rx); k_free(tx); LOG_ERR("Cannot display welcome message (err: %d)", err); return err; } err = uart_rx_enable(uart, rx->data, sizeof(rx->data), UART_WAIT_FOR_RX); if (err) { LOG_ERR("Cannot enable uart reception (err: %d)", err); /* Free the rx buffer only because the tx buffer will be handled in the callback */ k_free(rx); } return err; }
Best regard
Martin