AVR32: uxTaskGetStackHighWaterMark

karsten_klein wrote on Thursday, April 08, 2010:

Hi,
with the function uxTaskGetStackHighWaterMark(NULL), I wanted to check the stack of each task running in the system.
Therefore I called this function an the end of each task (there are 3 tasks running, with different priorities).
Unfortunately it doesnt work. The system crashes immediatedly with an exception (_handle_Bus_Error_Instruction_Fetch).
In the function uxTaskGetStackHighWaterMark() and usTaskCheckFreeStackSpace() I cant see why this should not work.

Any suggestions why this fails ?

Best regards
Karsten

davedoors wrote on Thursday, April 08, 2010:

Can you step into the function to see where the error occurs?

karsten_klein wrote on Thursday, April 08, 2010:

No, not really. I tried already, but by stepping through the function, it seams to work.
I think it has something to with the taskwitch.
If a task is just inside this function, and a task  with higher priority suspends the currently running task, than the exception could happen (but I am not sure).
Regards
Karsten

destremps wrote on Thursday, April 08, 2010:

As an experiment surround your stack checking work with vTaskSuspendAll / xTaskResumeAll.

karsten_klein wrote on Thursday, April 08, 2010:

Yes I think it would work (I will try it tomorrow morning) because the function vTaskList() works as well and  does it in the same way.
But the intention was NOT to suspend all the tasks. I wanted to do the stack checking at the end of each currently running task, in order not to disturb (suspend, block) the other tasks.
But I cant see any reason in the source-code of the function uxTaskGetStackHighWaterMark(NULL) which could be responsable for the exception, even if a task with higher priority suspends the active task which is just inside the uxTaskGetStackHighWaterMark(NULL).

rtel wrote on Thursday, April 08, 2010:

I don’t understand where you are attempting to call uxTaskGetStackHighWaterMark().  What do you mean ‘at the end of each currently running task’.  Do you mean using something like the traceTASK_SWITCHED_OUT() macro?

Regards.

karsten_klein wrote on Thursday, April 08, 2010:

Hi Richard,
thanks for the reply.

Just an example:

void vTaskCode1( void * pvParameters )
{
     for( ;; )
     {
         vTaskDelay( sometime );
         // Task code
         // ……
         // ……
         stack_task1 = uxTaskGetStackHighWaterMark(NULL);
     }
}
/*************************************************/

void vTaskCode2( void * pvParameters )
{
     for( ;; )
     {
         vTaskDelay( sometime );
         // Task code
         // ……
         // ……
         stack_task2 = uxTaskGetStackHighWaterMark(NULL);
     }
}

One task has a higher priority than the other.

Best regards
Karsten

rtel wrote on Thursday, April 08, 2010:

Hmm, I cannot see anything wrong there.  Did you try the suggestion of placing the call inside a critical section?  I don’t think it should need it, but it would be interesting if it cured the problem.

Regards.

karsten_klein wrote on Friday, April 09, 2010:

Hi Richard,
I tried the following for each task.
portENTER_CRITICAL();
    stack_task_1= uxTaskGetStackHighWaterMark(xHandleApplicationTask);
portEXIT_CRITICAL();

Afterwards the exception error DID NOT occur, but the program runs not  very well, respectively it runs very slow.
-Task 1 normally works every 10ms | usStackDepth = 4000 (16kB) | lower priority
-Task 2 normally works every 1ms | usStackDepth = 256 (1kB) | higher priority

I measured the time for  the uxTaskGetStackHighWaterMark(NULL) call:
Inside Task1: about 10ms !!
Inside Task2: about 0,6ms

- During the runtime of uxTaskGetStackHighWaterMark(NULL) in Task1,  Task2 is blocked.
- The active-time of Task1 is as double as normal.
==> This result in the loss of speed, which I can observe.

So, without portENTER_CRITICAL()/EXIT the Task1 will be suspended by Task2, definitely during the execution of uxTaskGetStackHighWaterMark(NULL). Task1 then starts uxTaskGetStackHighWaterMark(NULL) again.

But why is this a problem which results in an exception?
Each call of uxTaskGetStackHighWaterMark(NULL) should do its job by itself, without affecting the other running uxTaskGetStackHighWaterMark(NULL) , isnt it ?
It is something like reentrancy ?

I know now that I cant solve the stackchecking in this way, but I want to understand the reason for the exception.

Best regard
Karsten

rtel wrote on Friday, April 09, 2010:

I would have to run the code to understand what is causing the problem.  Just by looking at the code I would say there should not be a reentrancy problem, but there is obviously something more subtle going on.

Regards.

karsten_klein wrote on Friday, April 09, 2010:

Do you need more information from my side to investigate the problem ?
To send you the whole project does not make sense because you would need the hardware as well to get something to run.
Regards
Karsten

chrismy wrote on Thursday, April 15, 2010:

Hi Karsten,

Did you resolve your problem?  I only ask as I have had a bus_error_data_fetch exception problem with the AVR32’s.  I would be very interested to know how you fixed your exception problem.  In my case it seemed to occur around the time when a context was being switched, but was intermittent and sometimes very hard to make it fail.  In all cases the exception (although a data fetch, not instruction fetch) would occur somewhere within one of the “C” libraries.  I believe my problem (although I’m not yet fully convinced) was to do with the “C” libraries not being re-entrant.  I’ve created a struct _reent for each task and I point the “C” library’s _impure_ptr at the appropriate one each time a context switch is done.  I have not seen an the exception since I’d made these changes.  I can send you more details if that helps.

Cheers,
Chris.