I am using USART_RTOS_Send and USART_RTOS_Receive to send and receive data. It works fine (TX and RX) until I need to change the baud rate. It also works fine to change baud rate if I only transmit (no RX). I believe with FreeRTOS I need to first deinitialize the USART, and then re-initialize with the new baud rate. I do the following:
USART_RTOS_Deinit(&UARThandleFC4);
usart_configFC4.baudrate = 9600;
USART_RTOS_Init(&UARThandleFC4, &UARTt_handleFC4, &usart_configFC4);
The above work fine if I am only transmitting. However, I also need to receive data periodically. I receive data with the following, run in one of my other tasks:
USART_RTOS_Receive(&UARThandleFC4, recv_buffer, sizeof(recv_buffer), &n);
The above won’t return until it receives the number of bytes it is expecting (I set this to ‘1’ to return after each byte). Characters can arrive at any time, so I need to keep listening for them. If I attempt a ‘USART_RTOS_Deinit’ while USART_RTOS_Receive has been started in a different task (blocked until a character arrives), my program gets stuck here:
/* A task can only have an inherited priority if it holds the mutex.
If the mutex is held by a task then it cannot be given from an
interrupt, and if a mutex is given by the holding task then it must
be the running state task. */
configASSERT( pxTCB == pxCurrentTCB );
I just need some way to change baud rate, so I am open to other approaches. Is there a way to exit USART_RTOS_Receive even though no characters have arrived? Is there a way to change the baud rate without the Deinit/Reinit process?
I am using MCUXpresso v10.3.1
SDK_2.x_LPCXpresso54618 version 2.3.0, manifest version 3.2.0
Micro: LPC54606J256ET180
Thanks
已解决! 转到解答。
Dear Matt,
One workaround of this could be relese the event that is waiting in the receive task. For example, when you want to change the baudrate you could release rxevent:
xEventGroupSetBits(handle.rxEvent, RTOS_USART_COMPLETE);
and below the receive, change the baudrate, this is an example:
error = USART_RTOS_Receive(&handle, recv_buffer, sizeof(recv_buffer), &n);
if(flag_change_baudrate == true){
USART_RTOS_Deinit(&handle);
usart_config.baudrate = 9800;
if (0 > USART_RTOS_Init(&handle, &t_handle, &usart_config))
{
vTaskSuspend(NULL);
}
flag_change_baudrate = false;
}
Let me know if this helps you.
Best Regards,
Alexis Andalon
Hello, I’m post here because I have the same problem, but the workaround doesn’t work for me.
I must call USART_RTOS_Deinit() asynchrony no matter if USART_RTOS_Receive is waiting or not. I can not wait until next receiving char to reinit uart.
I there any solution?
Dear Matt,
One workaround of this could be relese the event that is waiting in the receive task. For example, when you want to change the baudrate you could release rxevent:
xEventGroupSetBits(handle.rxEvent, RTOS_USART_COMPLETE);
and below the receive, change the baudrate, this is an example:
error = USART_RTOS_Receive(&handle, recv_buffer, sizeof(recv_buffer), &n);
if(flag_change_baudrate == true){
USART_RTOS_Deinit(&handle);
usart_config.baudrate = 9800;
if (0 > USART_RTOS_Init(&handle, &t_handle, &usart_config))
{
vTaskSuspend(NULL);
}
flag_change_baudrate = false;
}
Let me know if this helps you.
Best Regards,
Alexis Andalon