Atmel SAMG55 and USB MS Host intermittend problem

przemekg wrote on Monday, September 10, 2018:

Hi , I am running freeRTOS 10.1 on Atmel SAMG55, using Atmel frame work and fatFS.
USB stack is interrupt driven.

I experienced lots of problems with intermittent system freeze during writing files to USB MS.
Writing to the USB MS works fine without RTOS enabled (a simple loop writing short text report file for testing purposes). Once the loop is moved to the RTOS task, then the USB stack freezes during write operation after some iterations (3 - 100…).
Ther is no difference if preemption is enabled or disabled (as only single task is created):

void board_task_usb_debug(void *pvParameters){
	UNUSED(pvParameters);
	for(;;)	{	
		ct_ReportToFile();
		vTaskDelay (500);
	}
}

No other timers or or interrupt sources enabled. FreeRTOS and USB stack interrupt priories set as follow:

#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0x0f    /* Lowest on M4 */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 10

#define UHD_USB_INT_LEVEL 0 /* Highest on M4 */

I’ve got impression that the USB write operation is somehow corrupted by the systick timer, but the USB interrupts are on the higher priority than freertos systick.
Current systick is set to 1000Hz, and I can get up to about 100 successful write operations (about 10 in most cases). If systick is set to 100Hz (and vTaskDelay() set accordingly), then I can get couple of hundreds operations before it freezes.
Massive heap is allocated for that task.

I am missing something? (probably)

richarddamon wrote on Monday, September 10, 2018:

Since you have the USB interrupt at a level higher than (lower value) than configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY it can not use any FreeRTOS interfaces (the FromISR calls).
I would normally expect that a USB driver would use some sort or notification through the RTOS to tell tasks there is something to process so they don’t need to spin wait for a data flag.
Having ISRs at too high of a priority level cause this sort of problems.
If you have configASSERT setup to report these sorts of issues, it helps detect a lot of this klind of issue.

przemekg wrote on Monday, September 10, 2018:

I can see your point. A the moment the USB driver is not aware of the RTOS and it is not using any of the FromISR calls.

However, does it matter if there is only one task running and preemption is disabled ?

I do not have configASSERT setup, but found that the USB stack is freezing waitng for the “uhi_msc_mem_command_ongoing” flag to be zeroed in the folowing function:

Ctrl_status uhi_msc_mem_write_10_ram(uint32_t addr, const void *ram)
{
   ...
	uhi_msc_mem_command_ongoing = true;
	uhi_msc_scsi_write_10(uhi_msc_mem_lun, addr, ram, 1,
			uhi_msc_mem_stop_pooling);
	while (uhi_msc_mem_command_ongoing);   /* stuck here */ 
	if (!uhi_msc_mem_command_status) {
		return CTRL_FAIL;
	}

The program flow in that stack is quite complicated (for me …) and I am not sure where to start with transforming it to RTOS friendly…

richarddamon wrote on Tuesday, September 11, 2018:

One thing to check is that uhi_msc_mem_command_ongoing is actually being checked (looking at the assembly of the loop). If it hasn’t been made volatile, it is possible that the compiler generated code that doesn’t reload the value for memory for each check.

That code should be able to be replaced with a semaphore.
setting the flag to true, would be a take with a timeout of 0, to make sure the semaphore is taken.
The wait loop would be a take with a maximum delay.
The ISR would do a give from ISR to be the equivalent of setting it to zero.

It could also use direct to task notifications.

przemekg wrote on Tuesday, September 11, 2018:

All the flags are declared as volatile, bet there is quie a few of them , used as a callbacks. It is not easy to track the flow, as lot of dependencies are used in the Atmel ASF.

I added and tested the configASSERT, but it does not throw any hints so far.

Trying to find an example of use Atmal SAM with USB host and FreeRTOS now.