cancel
Showing results for 
Search instead for 
Did you mean: 

UART DMA receive via RTOS

Ala
Senior

hey there

there is a simple question: how can I receive data on my UART in DMA mode using RTOS? recently I ran a project where I just get all the data right when they arrived using UART DMA. but not I what the whole process to be done using RTOS. how can I do that?

11 REPLIES 11
KnarfB
Principal III

If you already have a cyclic DMA receive buffer, there are several options. If the serial data is more or less a countinous data stream you write a consumer task blocking on a semaphore or task event. You also implement the half-full+full handlers/callbacks and let them fire the semaphore/task event, thereby unblocking the task which can now process half of the DMA receive buffer.

You could further decouple the interrupts from the consumer task by using a queue.

If the serial data is only some spontaneous sending of few bytes, you can implement a consumer task having a timer/wait, periodically polling for new data.

Finally, you can combine both approaches.

hth

KnarfB

Ala
Senior

ok then I'll try.

an other question: what to do if I want a task to be done only once in main()?

KnarfB
Principal III

A task can suspend itself and will never be scheduled again (unless Resumed by someone else). In addition, it might be also deleted but I somehow recall that there were issues with that.

dear KnarfB

here is my code

void SENDATTask(void const * arg)
{
	while(1)
	{
	
	if (Sim800_at_sendCommand("AT\r\n", 5000, (char*)SIM800.msg.buff, sizeof(SIM800.msg.buff), 1, "\r\nOK\r\n") == 1)
	{
		osDelay(500);
		HAL_IWDG_Refresh(&hiwdg);  //Reload Watchdog inorder to prevent Micro Reset	
	}
			
	}
	vTaskDelete(SENDATTaskHandle);
	vTaskSuspend(SENDATTaskHandle);
		}
}

eigther I use vTaskDelete() or vTaskSuspend(), the task continues to run... why is that?

KnarfB
Principal III

maybe the MCU resets and restarts because you stopped feeding the watchdog?

I think you're right... so how should I feed watchdog in RTOS type of programming?

KnarfB
Principal III

There is no single best solution. A simple way is putting HAL_IWDG_Refresh in the idle task which runs at lowest prio. Then, the watchdog will timeout either when the scheduler is screwed up (stack overflow,...) or when another task runs in a busy loop, preventing the idle task from running.

Would not enable the watchdog during (early) development.

Do NOT try to suspend a deleted task. That's a bug and also makes no sense.

vTaskDelete(SENDATTaskHandle); 
vTaskSuspend(SENDATTaskHandle); <-- wrong

BTW when using NULL as task handle

vTaskDelete(NULL);

the calling task deletes itself.

thanks I'll do that for sure!