I added ring buffer and UART ASYNCH interface to asset_tracke_v2. I added CONFIG_RING_BUFFER = y, CONFIG_SERIAL = y and CONFIG_UART_ASYC_API = y to prj.conf file. The build is successful, but a warning is shown as below. The files for serial communication are attached. These files are working well on a nRF5340 based project. The same functionality, I want to implement on nRF9160.
[244/332] Building C object zephyr/drivers/serial/CMakeFiles/drivers__serial.dir/uart_nrfx_uarte.c.obj
C:\firmware\firmware\zephyr\drivers\serial\uart_nrfx_uarte.c:1427:13: warning: 'uarte_nrfx_isr_async' defined but not used [-Wunused-function]
1427 | static void uarte_nrfx_isr_async(const struct device *dev)
| ^~~~~~~~~~~~~~~~~~~~
[311/332] Linking C executable zephyr\zephyr_pre0.elf
[315/332] Linking C executable zephyr\zephyr_pre1.elf
[320/332] Building C object zephyr/CMakeFiles/zephyr_final.dir/dev_handles.c.obj
[322/332] No install step for 'mcuboot_subimage'
[323/332] Completed 'mcuboot_subimage'
[324/332] Linking C executable zephyr\zephyr.elf
Memory region Used Size Region Size %age Used
FLASH: 293252 B 392704 B 74.68%
SRAM: 131816 B 211736 B 62.25%
IDT_LIST: 0 GB 2 KB 0.00%
[325/332] Generating zephyr/mcuboot_primary.hex
[326/332] Generating zephyr/mcuboot_primary_app.hex
[327/332] Generating ../../zephyr/app_update.bin
[328/332] Generating ../../zephyr/dfu_application.zip
[329/332] Generating ../../zephyr/app_signed.hex
[330/332] Generating ../../zephyr/app_test_update.hex
[331/332] Generating ../../zephyr/app_moved_test_update.hex
[332/332] Generating zephyr/merged.hex
//*******************serial port API **********
#include <sys/ring_buffer.h>
#include "serial_api.h"
//********************************** BMS ********************
unsigned int bms_tx_get_from_queue(void)
{
uint8_t *data_ptr;
// Try to claim any available bytes in the FIFO
bms_bytes_claimed = ring_buf_get_claim(&bms_tx_fifo, &data_ptr, CONFIG_BMS_UART_TX_BUF_SIZE);
if(bms_bytes_claimed > 0) {
// Start a UART transmission based on the number of available bytes
uart_tx(bms_uart, data_ptr, bms_bytes_claimed, SYS_FOREVER_MS);
}
return bms_bytes_claimed;
}
void bms_uart_async_callback(const struct device *uart_dev, struct uart_event *evt, void *user_data)
{
static struct bms_msg_queue_item bms_new_message;
switch (evt->type) {
case UART_TX_DONE:
// Free up the written bytes in the TX FIFO
ring_buf_get_finish(&bms_tx_fifo, bms_bytes_claimed);
// If there is more data in the TX fifo, start the transmission
if(bms_tx_get_from_queue() == 0) {
// Or release the semaphore if the TX fifo is empty
k_sem_give(&bms_tx_done);
bms_transmit_done = true;
}
break;
case UART_RX_RDY:
memcpy(bms_new_message.bytes, evt->data.rx.buf + evt->data.rx.offset, evt->data.rx.len);
bms_new_message.length = evt->data.rx.len;
if(k_msgq_put(&bms_rx_msgq, &bms_new_message, K_NO_WAIT) != 0){
/*printk("Error: Uart1 RX message queue full!\n");*/
}
break;
case UART_RX_BUF_REQUEST:
uart_rx_buf_rsp(bms_uart, bms_buf_next, CONFIG_BMS_UART_BUF_SIZE);
break;
case UART_RX_BUF_RELEASED:
bms_buf_next = evt->data.rx_buf.buf;
break;
case UART_RX_DISABLED:
k_sem_give(&bms_rx_disabled);
break;
default:
break;
}
}
void bms_uart_init(void)
{
bms_uart = device_get_binding("UART_1");
if (bms_uart == NULL) {
printk("Failed to get UART1 binding\n");
return;
}
uart_callback_set(bms_uart, bms_uart_async_callback, NULL);
uart_rx_enable(bms_uart, bms_double_buffer[0], CONFIG_BMS_UART_BUF_SIZE, BMS_UART_RX_TIMEOUT_MS);
}
// Function to send UART data, by writing it to a ring buffer (FIFO) in the application
// WARNING: This function is not thread safe! If you want to call this function from multiple threads a semaphore should be used
unsigned int bms_uart_send(const uint8_t * data_ptr, uint32_t data_len)
{
while(1) {
// Try to move the data into the TX ring buffer
uint32_t written_to_buf = ring_buf_put(&bms_tx_fifo, data_ptr, data_len);
data_len -= written_to_buf;
// In case the UART TX is idle, start transmission
if(k_sem_take(&bms_tx_done, K_NO_WAIT) == 0) {
bms_tx_get_from_queue();
}
// In case all the data was written, exit the loop
if(data_len == 0) break;
// In case some data is still to be written, sleep for some time and run the loop one more time
k_msleep(10);
data_ptr += written_to_buf;
}
return 0;
}