Hi,
I'm trying to increase the UART buffer size for the asynchronous UART API, but I'm encountering an error. When the message size is set to 255, I can successfully receive data from my GPS sensor. However, when I increase the message size to 512, I get an error code of -13 (EACCES) from UART_RX_BUF_REQUEST
. The only variable I changed is #define MSG_SIZE 512.
I would greatly appreciate any insights or suggestions from the forum.
Question:
1. What could be causing this EACCES error when increasing the UART buffer size?
2. What steps can I take to resolve this issue and increase message size to 1024?
Here is the code I use for testing:
main.c
#include <string.h> #include <zephyr/kernel.h> #include <zephyr/device.h> #include <zephyr/drivers/uart.h> #include <zephyr/drivers/gpio.h> #include <zephyr/logging/log.h> #define LOG_MODULE_NAME main LOG_MODULE_REGISTER(LOG_MODULE_NAME); #define MSG_SIZE 512 #define MSG_QUEUE_SIZE 5 struct uart_data{ char msg[MSG_SIZE]; int len; }; K_MSGQ_DEFINE(uart_msgq, sizeof(struct uart_data), MSG_QUEUE_SIZE, 1); #define UART0_NODE DT_NODELABEL(uart0) static const struct device *uart_dev = DEVICE_DT_GET(DT_NODELABEL(uart0)); static const struct gpio_dt_spec ldo = GPIO_DT_SPEC_GET(DT_ALIAS(led0), gpios); static const struct gpio_dt_spec led4 = GPIO_DT_SPEC_GET(DT_ALIAS(led4), gpios); uint8_t uart_double_buffer[2][MSG_SIZE]; uint8_t *uart_buf_next = uart_double_buffer[1]; K_SEM_DEFINE(uart_tx_done, 0, 1); static void uart_cb(const struct device *dev, struct uart_event *evt, void *user_data) { switch (evt->type) { case UART_RX_RDY: LOG_INF("UART_RX_RDY %d byte, offset %d", evt->data.rx.len, evt->data.rx.offset); struct uart_data k_data; char* buf_ptr = evt->data.rx.buf + evt->data.rx.offset; memcpy(k_data.msg, buf_ptr, evt->data.rx.len); k_data.len = evt->data.rx.len; if (k_msgq_put(&uart_msgq, &k_data, K_NO_WAIT)!=0) k_msgq_purge(&uart_msgq); break; case UART_RX_BUF_REQUEST: LOG_INF("UART_RX_BUF_REQUEST"); int ret = uart_rx_buf_rsp(uart_dev, uart_buf_next, MSG_SIZE); LOG_INF("uart_rx_buf_rsp:%d",ret); break; case UART_RX_BUF_RELEASED: LOG_INF("UART_RX_BUF_RELEASED"); // memset(evt->data.rx_buf.buf, 0 , MSG_SIZE); uart_buf_next = evt->data.rx_buf.buf; break; default: LOG_INF("UART evt:%d",evt->type); break; } } int gps_on(void){ if (!gpio_is_ready_dt(&ldo)) { return -1; } int ret = gpio_pin_configure_dt(&ldo, GPIO_OUTPUT_ACTIVE); ret = gpio_pin_configure_dt(&led4, GPIO_OUTPUT_ACTIVE); return 0; } void init_uart(void){ int err; if (!device_is_ready(uart_dev)) LOG_INF("UART device not found!"); err = uart_callback_set(uart_dev, uart_cb, NULL); LOG_INF("uart_callback_set %d",err); err = uart_rx_enable(uart_dev, uart_double_buffer[0], MSG_SIZE, 200); LOG_INF("uart_rx_enable %d",err); } int main(void) { init_uart(); gps_on(); LOG_INF("started"); struct uart_data tx_buf; while (k_msgq_get(&uart_msgq, &tx_buf, K_FOREVER) == 0) { LOG_INF("%s",tx_buf.msg); } return 0; }
KConfig
CONFIG_SERIAL=y CONFIG_UART_ASYNC_API=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=n CONFIG_LOG=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=n CONFIG_RTT_CONSOLE=y CONFIG_USE_SEGGER_RTT=y CONFIG_LOG_BACKEND_RTT=y CONFIG_LOG_BACKEND_UART=n CONFIG_MAIN_STACK_SIZE=4096 CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048
I've already tried the following:
- double MAIN_STACK_SIZE
- double SYSTEM_WORKQUEUE_STACK_SIZE
- searching uart EACCES related problems
- re-visit Nordic academy about UART driver
- Take a look at UART driver documents(https://docs.zephyrproject.org/latest/hardware/peripherals/uart.html#uart-async-api)
Additional Information:
- ncs 2.6.1
- nRF Connect for vs code v2024.3.25, windows
- nRF52832 QFAA