Hi everyone,
at the moment we are trying to upgrade our nRF9160 software form the SDK v1.8.0 to the newer version SDK2.0.0.
The main issue of the migration is our UART implementation. In the last version the UART implementation worked like a charm and we were able to transfer large packages without any issues, but with the new version we are having difficulties with the larger packages.
We are sending certificates and keys to the nRF9160 to be able to establish a secure MQTT connection. The length of these certificates and keys vary form approximately 1200 to 1800 bytes. Smaller packages all approximately 1 to 500 bytes are valid transactions and show a "/r/n" at their end, but with the larger data transfers the received length does not correspond with the original package length. For example a certificate command is 1736 bytes long and the received length is 1721.
In the old SDK v1.8.0 we got another transmission with the rest of the package, but in the new SDK version the rest of the transmission is just missing.
The following code is our UART implementation. After every successfully received and processed command the function "uart_reinit" is triggered to be able to receive again.
#include <zephyr/zephyr.h>
#include <zephyr/drivers/uart.h>
#include <zephyr/logging/log.h>
#include <stdlib.h>
#include <general_definitions.h>
#include <uart_communication.h>
#include <led_config.h>
#include <device_uart_interface.h>
#include <scheduler.h>
#include <mqtt.h>
static K_MEM_SLAB_DEFINE(uart_slab, BUF_SIZE, 2, 4);
uint8_t *buf;
char uart_receive_buf[UART_RECEIVE_BUFFER_SIZE];
uint32_t uart_receive_index;
uint32_t uart_last_receive_time;
uint32_t previous_uart_length = 0;
LOG_MODULE_REGISTER(uart_communication,LOG_LEVEL_INF);
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// uart callback
void uart_callback(const struct device *dev,
struct uart_event *evt,
void *user_data)
{
struct device *uart = user_data;
int err;
uint32_t first_bracket_offset = 0;
switch (evt->type) {
case UART_TX_DONE:
LOG_INF("UART_TX_DONE");
break;
case UART_TX_ABORTED:
LOG_INF("UART_TX_ABORTED");
break;
case UART_RX_RDY:
// Save it to uart receive buffer
LOG_INF("UART_RX_RDY");
//LOG_INF("UART: Content buffer address: 0x%x", evt->data.rx.buf);
//LOG_INF("UART: Content buffer: %s", evt->data.rx.buf);
//LOG_INF("UART: Offset: %d", evt->data.rx.offset);
//LOG_INF("UART: Length: %d", evt->data.rx.len);
if ((evt->data.rx.buf[previous_uart_length + evt->data.rx.len - 2] == '\r') &&
(evt->data.rx.buf[previous_uart_length + evt->data.rx.len - 1] == '\n'))
{
if(k_sem_take(&uart_sem, K_NO_WAIT) == 0)
{
uart_rx_disable(uart);
while(first_bracket_offset < 4096 && evt->data.rx.buf[previous_uart_length + first_bracket_offset] != 0x7B)
{
first_bracket_offset++;
}
if(evt->data.rx.buf[previous_uart_length + first_bracket_offset] == 0x7B && evt->data.rx.len > 10)
{
// LOG_INF("uart_receive_buf with saftey_index: %s", evt->data.rx.buf);
// memcpy(uart_receive_buf, evt->data.rx.buf + first_bracket_offset, evt->data.rx.len);
memcpy(uart_receive_buf, evt->data.rx.buf, evt->data.rx.len + previous_uart_length);
scheduler_dip_parse.data = uart_receive_buf;
scheduler_dip_parse.cmd_len = evt->data.rx.len;
previous_uart_length = 0;
memset(mqtt_recv_operation,0x0,MQTT_RECV_OPERATION_LENGTH);
k_work_submit_to_queue(&oem_workqueue, &scheduler_dip_parse.work);
}
else
{
uart_rx_enable(uart, buf, BUF_SIZE, 100);
k_sem_give(&uart_sem);
}
}
}
else
{
previous_uart_length = previous_uart_length + evt->data.rx.len;
}
break;
case UART_RX_BUF_REQUEST:
{
LOG_INF("UART_RX_BUF_REQUEST");
uint8_t *buf;
err = k_mem_slab_alloc(&uart_slab, (void **)&buf, K_NO_WAIT);
__ASSERT(err == 0, "Failed to allocate slab");
err = uart_rx_buf_rsp(uart, buf, BUF_SIZE);
__ASSERT(err == 0, "Failed to provide new buffer");
break;
}
case UART_RX_BUF_RELEASED:
LOG_INF("UART_RX_BUF_RELEASED");
k_mem_slab_free(&uart_slab, (void **)&evt->data.rx_buf.buf);
break;
case UART_RX_DISABLED:
LOG_INF("UART_RX_DISABLED");
break;
case UART_RX_STOPPED:
LOG_INF("UART_RX_STOPPED");
break;
}
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// init uart
void uart_init(void)
{
int err = 0;
uart = device_get_binding("UART_0");
__ASSERT(uart, "Failed to get the device");
err = k_mem_slab_alloc(&uart_slab, (void **)&buf, K_NO_WAIT);
__ASSERT(err == 0, "Failed to alloc slab");
err = uart_callback_set(uart, uart_callback, (void *)uart); // set callback
__ASSERT(err == 0, "Failed to set callback");
err = uart_rx_enable(uart, buf, BUF_SIZE, 100); // enable receiving
__ASSERT(err == 0, "Failed to enable RX");
previous_uart_length = 0;
if(err == 0)
{
uart_initialization_status = true;
}
}
void uart_reinit(void)
{
int err = 0;
memset(uart_receive_buf,0x0,UART_RECEIVE_BUFFER_SIZE);
uart_receive_index = 0;
k_sem_give(&uart_sem);
previous_uart_length = 0;
if(!mqtt_output)
{
err = uart_rx_enable(uart, buf, BUF_SIZE, 100); // enable receiving
__ASSERT(err == 0, "Failed to enable RX");
}
k_sleep(K_MSEC(10));
}
I looked through the different SDK release notes from 1.8.0 up to 2.0.0. I did not find any major changes in the UART section and also my attempts to fix the problem did not work. I hope somebody is able to help me with this problem.
Best regards,
Andreas