0

I'm trying to use one UART in three same priority tasks like the code below, but what is happening is confusing for me! In fact, I want any task to send a string once per second, so I should have 3 statements in terminal each second, but the UART transmit function only works once and the 2 other transmit functions are omitted.

When I change the task priorities to high, normal and low it works well. How can I fix this issue without changing the priority of tasks?

In fact, I don’t want to have a complicated RTOS program. I just want a simple multitasking program with no semaphores or mutexes! I hope it would be possible because I don’t want to add complexity to my program. (Note that if I add a wait for UART ready function the program works fine, but it is not a common method in microcontroller programming).

 /* Create the thread(s) */
 /* definition and creation of defaultTask */
 osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128);
 defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
 /* definition and creation of myTask02 */
 osThreadDef(myTask02, StartTask02, osPriorityNormal, 0, 128);
 myTask02Handle = osThreadCreate(osThread(myTask02), NULL);
 /* definition and creation of myTask03 */
 osThreadDef(myTask03, StartTask03, osPriorityNormal, 0, 128);
 myTask03Handle = osThreadCreate(osThread(myTask03), NULL);
void StartDefaultTask(void const * argument)
{
 /* Infinite loop */
 for(;;)
 {
 //while (HAL_UART_GetState (&huart2) != HAL_UART_STATE_READY);
 HAL_UART_Transmit(&huart2,(uint8_t*)"T1\r\n",sizeof("T1\r\n")-1,100);
 osDelay(1000);
 }
}
void StartTask02(void const * argument)
{
 /* Infinite loop */
 for(;;)
 {
 //while (HAL_UART_GetState (&huart2) != HAL_UART_STATE_READY);
 HAL_UART_Transmit(&huart2,(uint8_t*)"T2\r\n",sizeof("T2\r\n")-1,100);
 osDelay(1000);
 }
}
void StartTask03(void const * argument)
{
 /* Infinite loop */
 for(;;)
 {
 //while (HAL_UART_GetState (&huart2) != HAL_UART_STATE_READY);
 HAL_UART_Transmit(&huart2,(uint8_t*)"T3\r\n",sizeof("T3\r\n")-1,100);
 osDelay(1000);
 }
}
asked Jul 13, 2024 at 10:56

1 Answer 1

1

What's the problem with using a mutex? You obviously need some way to prevent the three tasks from accessing the UART at the same time, and a mutex is the obvious way to do it.

Simplest would be to move all the UART functionality (including mutex) into a single function, thus removing that "complexity" from your individual tasks:

static StaticSemaphore_t uart_mutex;
static SemaphoreHandle_t h_uart_mutex = NULL;
void init_mutex(void) // Called before tasks are created
{
 h_uart_mutex = xSemaphoreCreateMutexStatic ( &uart_mutex );
}
void send_string(const char *str)
{
 xSemaphoreTake(h_uart_mutex, ( TickType_t ) 1000);
 HAL_UART_Transmit(&huart2, (uint8_t *)str, strlen(str), 100);
 xSemaphoreGive(h_uart_mutex);
}
void StartTask02(void const * argument)
{
 /* Infinite loop */
 for(;;)
 {
 send_string("T2\r\n");
 osDelay(1000);
 }
}

An alternative would be to have something like a message queue that your tasks feed strings into, and another task that reads them out and sends them to the UART. But this is even more complicated in my opinion, and internally it is probably using a mutex anyway to protect the queue.

answered Jul 13, 2024 at 11:08
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you @pmacfarlane for your perfect answer. The reason why not using mutex or queue is because I am porting an old single thread code with multiple while(1) loops with labels and gotos, for an old person. Whom don’t know the knowledge of using new programming methods like a finite state machine and switch case. He persist on using RTOS with simplest method possible to be as similar to previous code! (He only wants multiple while(1) loops in a RTOS, without the knowledge of using a RTOS) Real life programming requirements seems much harder than a programmer expects. Isn’t it?

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.