This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Using freertos queue & uart1 with dynamic ble and threads

Hi,

I'm trying to utilise UART1 and freertos queues, with dynamic b;e&threads.

I'm trying to use the serial api for the UART.

I've tested the code below with the freertos_coap_server example, and it works fine.

The freertos queues pass data from the uart handler to the uart thread.

However when I use same code in the ble_thread_dyn_hrs_coap_srv_freertos example

the uart thread never recieves the queue elements from the ISR.

Can you advise?

The code for serial is shown below:

QueueHandle_t cmdMsgQueue;

int32_t init_msg_queue(void) {
cmdMsgQueue = xQueueCreate( UARTCMD_QUEUELENGTH, sizeof(cmdMsg_t) );
if( cmdMsgQueue == NULL ) {
NRF_LOG_ERROR("Creation of cmdQueue failed");
return ERROR;
}
NRF_LOG_INFO("Creation of cmdQueue Succeeded");
return SUCCESS;
}

int32_t cmdmsg_queue_recv(QueueHandle_t *msgQueue, cmdMsg_t *cmdMsg) {
BaseType_t status = xQueueReceive( *msgQueue, ( void * ) cmdMsg, ( TickType_t ) portMAX_DELAY );
if( status != pdTRUE ) {
NRF_LOG_WARNING("cmdmsg_queue_recv: Message recieve failed");
return status;
}

return status;
}

char dataBuf[400];
int dataBufCounter = 0;
static void serial_rx_cb(struct nrf_serial_s const *p_serial, nrf_serial_event_t event) {
static BaseType_t xHigherPriorityTaskWoken;

if (event == NRF_SERIAL_EVENT_RX_DATA) {
char c;
ret_code_t ret = nrf_serial_read(&serial1_uarte, &c, sizeof(c), NULL, 0);
if (ret == NRF_SUCCESS) {
if ((c == '\n') || (c == '\r')) {
cmdMsg_t cmdMsg;
memset(cmdMsg.msg,'\0', dataBufCounter+2);
memcpy(cmdMsg.msg, dataBuf, dataBufCounter+1);
cmdMsg.len = dataBufCounter+1;
otCliOutputFormat("%d\r\n", dataBufCounter+1);
if (cmdMsg.len > UARTCMD_MSGMAXLEN) {
NRF_LOG_WARNING("cmdProcUartISR: Message too long");
return;
} else {
if( xQueueSendFromISR( cmdMsgQueue, (void*)&cmdMsg, &xHigherPriorityTaskWoken ) != pdTRUE )
{
NRF_LOG_WARNING("cmdProcUartISR: Message send failed");
} else {
otCliOutputFormat("sent:%d\r\n", dataBufCounter+1);
}
}
dataBufCounter = 0;
memset(dataBuf,'\0', 400);
} else {
otCliOutputFormat("%d:%c\r\n", dataBufCounter, c);
dataBuf[dataBufCounter] = c;
dataBufCounter++;
}
} else {
otCliOutputFormat("Serial Error\r\n");
}
}
}


NRF_SERIAL_CONFIG_DEF(serial1_config, NRF_SERIAL_MODE_DMA,
&serial1_queues, &serial1_buffs, serial_rx_cb, sleep_handler);


void uart_task(void * arg) {
ret_code_t ret;
otCliOutputFormat("in uart_task\r\n");
int qeueInitRes = init_msg_queue();
char jsonMsg[100];
otCliOutputFormat("\r\nqueue enabled: %d\r\n", qeueInitRes);

//ret = nrf_drv_power_init(NULL);
otCliOutputFormat("in uart_task: power\r\n");
APP_ERROR_CHECK(ret);

ret = nrf_serial_init(&serial1_uarte, &m_uarte1_drv_config, &serial1_config);
otCliOutputFormat("in uart_task: serial\r\n");
APP_ERROR_CHECK(ret);


cmdMsg_t cmdMsg;

static char newline[] = "\n\r";
while (cmdmsg_queue_recv(&cmdMsgQueue, &cmdMsg) == pdTRUE) {
otCliOutputFormat("w: %d:%s\r\n", cmdMsg.len, cmdMsg.msg);
(void)nrf_serial_write(&serial1_uarte, &cmdMsg.msg, cmdMsg.len, NULL, NRF_SERIAL_MAX_TIMEOUT);
(void)nrf_serial_flush(&serial1_uarte, 0);
(void)nrf_serial_write(&serial1_uarte, newline, strlen(newline), NULL, 0);
(void)nrf_serial_flush(&serial1_uarte, 0);
}

}

  • Hi,

    Finally forgot to mention. One difference between the serial uart thread which worked correctly in the

    example without ble, but not in the dynamic ble example was that I had to delete:

    ret = nrf_drv_power_init(NULL);

    line above which initialised power driver

    A further question, is this line necessary for the uart to function correctly.

    Currently the uart1 is accepting input, the only issues seems to be with the freertos queue,

    but will the deletion of the init for power give problems not yet seen?

  • Paul said:
    but will the deletion of the init for power give problems not yet seen?

     Hi Paul,

    I do not think that you can use nrf_drv_powerwith the combination of softdevice. The implementation seems to be accessing POWER/CLOCK registers directly, which are restricted peripherals. So commenting out the initialization of this module actually seems necessary.

    About the queues not working as they should, This is the basic freertos features that should not be affected by the port changes we did. So I am thinking that this is something specific to your app design. It is hard for me to analyze why the queues are not workingas I do not have the picture of other different contexts working in your app. But you can track the path of these queues by stepping into the code in the debug mode.

Related