Scheduler problem writing to internal flash

cmp1104 wrote on Monday, January 07, 2013:

I am using FreeRTOS v. 7.02 and an EFM32 microcontroller with IAR.  I have a task that executes periodically by timing out waiting for a semaphore.  The task collects some data and writes it to the internal flash of the microcontroller.  Without the write to flash functionality, I have confirmed that the task executes as expected (correct timing, data collection, etc.).  However when I put the flash functionality in place, the task executes once (i.e., writes one set of data to flash) and then appears to get lost in the scheduler.  From the RTOS plugin I can see that when things get lost the scheduler lists the task as in the running state. 

I know that writting to flash means that the code needs to execute from RAM.  The EFM32 memory module does this already.  I am also disabling interrupts prior to writing to flash and re-enabling when done.  Is it possible that by dissabling the interrupts that the RTOS RTC tick interrupt is not executing and therefore the scheduler gets confused?

Any insight would be appreciated.


davedoors wrote on Monday, January 07, 2013:

The EFM32 is a Cortex-M3 so if interrupts are left disabled for a long time the SysTick will generate lots of tick interrupts but all of them except one will just be lost. That will have the effect of the time kept by the kernel slipping against actual time, but nothing else.

I have had behavior like that before and it turned out that the task was stuck in a polling loop inside a third party driver library function. The plug in said the task was Running, and it was, it was sat in a loop waiting for a bit to get set that never got set.

cmp1104 wrote on Monday, January 07, 2013:

Thanks for the reply.  So it sounds like missing a SysTick interrupt is not a big deal.

The program is getting hung up in vListInsert at:
for( pxIterator = ( xListItem * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext )

This is within an else statement that warns this point could be reached if 1) Stack overflow 2) Incorrect interrupt priority assignment 3) Calling an API function from within a critical section 4) Using a queue or semaphore before it has been initialized or the scheduler started.

I am pretty sure 2, 3, 4 are not the cause.  After the one successful write to flash I used the xTaskGetSchedulerState function to verify that the scheduler was still running.  I don’t think it is a stack overflow either.

davedoors wrote on Monday, January 07, 2013:

If the tick interrupt was still executing, and you have stack overflow checking switched on ( then FreeRTOS would catch a stack overflow, but if the tick interrupt was not running you would have to manually check in the debugger. Manually checking is easy if you have the state viewer plug in because you can have the plug in show the stack high water mark. Do you know what the plug in is reporting as the high water mark for that task?

xTaskGetSchedulerState() is not going to help much here because it will just report what it thinks the state is, in this case, it has been started and is not suspended so it will report that it is running.

How are you disabling interrupts? The proper way is to call taskENTER_CRITICAL() and taskEXIT_CRITICAL() because they will keep a nesting count, but if the flash write driver disables and enables interrupts itself the critical section nest count could get messed up. Do you know if the drivers that write to the flash enables interrupts even if they were disabled when the function is called.

Do the drivers that write to the flash use any interrupts or try to configure the systick timer to generate delays?

cmp1104 wrote on Monday, January 07, 2013:

1.  In my FreeRTOS Config file I have configCHECK_FOR_STACK_OVERFLOW = 2.  I have a vApplicationStackOverflowHook function and I know I am not hitting that.  With my plugin the “Min Free Stack” is reported as >256. 
2. To disable the interrupts I am using the EM defined function INT_Disable() (and re-enabling them using INT_Enable).  The function is supposed to disable interrupts at the CPU level and protect critical sections of code.  Like the taskENTER_CRITICAL() and taskEXIT_CRITICAL() functions the EM functions use a counter to track entering and exiting protected sections of code.  I did a quick quick and placed taskENTER_CRITICAL() and taskEXIT_CRITICAL()  before and after my call to the flash writing function and removed the EM interrupt disabling and enabling functions and got the same behavior.
3. The EM functions that write to flash do not have any interrupts enabled.  In their flash manipulation functions I did not see any reference to using the systick.

My plug-in also consistently reports that the “# Waiting Rx”  is 2 for the semaphore I am trying to block on after I write to flash.  I am not sure how this fits in.  It is as though the scheduler thinks there are two tasks waiting for this semaphore.  (There are not, only one task uses this particular semaphore.)  

cmp1104 wrote on Tuesday, January 08, 2013:

Ok, I think I found the issue though I do not understand why the problem occurred in first place.  In my WriteToFlash function I start with INT_Disable and then call after function to find an empty memory location in flash (GetEmpty).  Even though in GetEmpty I am just reading from flash I called Int_Disable and Int_Enable.  When I return to my write function I call Int_Enable just before exiting.  If I remove the second use of Int_Disable, Int_Enable the code works as expected and the RTOS scheduler does not get “corrupted”.