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
