Hard Fault (again)

joe_her wrote on Friday, June 17, 2016:

While searching for the reason for a hard fault (STM32F4) I found a program path in which the infinite loop has no vTaskDelay().

It was not my intention, and I added a short delay in the loop.

This stopped my hard fault interrupt, and the program works OK now.

Whoever, I suspect that something is wrong. Not having a delay or some wait for queue, should probably consume a lot of CPU time, but should not create a hard fault error.

What should I look for?.

Thanks

Johanan

rtel wrote on Friday, June 17, 2016:

I would agree. If you have an infinite loop that keeps the task in the
Running state (except when tasks of higher priority are running), then
the worst that should happen is lower priority tasks are starved of any
execution time. Your situation must be very specific to your usage
scenario, although without seeing the code or knowing what else the
system is doing makes it hard to be sure.

Did you actually find the instruction that was generating the hard
fault? Maybe that would give a clue.

http://www.freertos.org/Debugging-Hard-Faults-On-Cortex-M-Microcontrollers.html

joe_her wrote on Friday, June 17, 2016:

I have about 7 tasks running, in order to isolate that fault, I removed each task and waited.

Then I set some break-point in the suspected task, and found that infinit loop.

The situation is a bit more complex as now I found that if I stop one other task, then the hard fault stops.

So, it is when these two tasks are executing, I get the problem. I suspect that inserting that task delay in the loop only reduces the probability of the error which will trigger eventually, and I need investigate more.

There are only 2 functions that are used by both tasks, so it must be something in one of them.

Thanks,

Johanan

joe_her wrote on Friday, June 17, 2016:

At the end of a long day, it was an array index > array size, as in 90% of cases.

Pathetic.
However, it looks like the problem was due to a local static variable, that was used in a function without a mutex.
So the question is how does a static local variable in a funcition allocated? on the task stack (should have no problem) or on the heap?
Thanks

Johanan

rtel wrote on Friday, June 17, 2016:

At the end of a long day, it was an array index > array size, as in 90% of cases.

Its the ones that are too obvious to see that keep us ocupied the longest :o)

So the question is how does a static local variable in a funcition allocated? on the task stack (should have no problem) or on the heap?

Neither - it will be allocated by the linker when your application is built - normal C rules apply. Remember if the variable is static then all tasks that call the function (or are created from the function) will share the same copy of the variable.

joe_her wrote on Saturday, June 18, 2016:

This static var is used in a serach function of a sorted list.
The program uses the table a lot, and in many cases it seraches for next value.
it is used to store the last search reasult:


// Search table for id, 
// returns table index if found
// else -1 

int regTabSearch(uint32_t id)
{
	int b = 0, t = 0  ;
	int i = -1;
	static int lastIx = 0;
	if(sorted == 0)
		sortRegTab();

	// check if last or last + 1, for efficency
	if (xSemaphoreTake(regMutex,100) == pdTRUE) // <-- this solved my problem
	{
	if(id == regTab[lastIx].id)   i = lastIx;
	if(id == regTab[lastIx-1].id) i = lastIx-1;
	if(id == regTab[lastIx+1].id) i = lastIx+1;
	if(i != -1) 
			lastIx = i;
	xSemaphoreGive(regMutex);
	if(i != -1) 
			return i;
	}
	// need to search:
	i = 0;
.
.
.

This is not as efficient as I wanted, as if the serch is called from different tasks, this static var changes and becomes meaningless.
So it will be very neat to have a “static” var, which belongs to a certain task.
Any idea how to do this (without adding a paramter to the function)?
somthing like an array that will be indexed according to the calling task?

Johanan

richard_damon wrote on Saturday, June 18, 2016:

Sounds like what you want is some ‘Task Local Storage’ (locations that are per-task). The Task Control Block can have a pointer to a block of storage which works this way. I haven’t had to implement this functionality, but there is ‘newlib’ support currently in the code (conditional on a config flag) to do this for the newlib library to provide a reent block to the library.

rtel wrote on Saturday, June 18, 2016:

FreeRTOS has its own thread local storage. Don’t have a link to hand but Googling “freertos thread loacal storage pointers” will find it.

Regards,
Richard.

Sorry if this email appears abrupt, it was sent from my phone which has a small keyboard.

joe_her wrote on Sunday, June 19, 2016:

Looks like what I need, but I cant find the
configNUM_THREAD_LOCAL_STORAGE_POINTERS
definition in FreeRTOSConfig.h

Niether I (or the linker…) can find vTaskSetThreadLocalStoragePointer() anywhere.
Using FreeRTOS ver 8.0.1

What am I missing?

Should I add the #define myself and recompile all?
Thanks
Johanan

rtel wrote on Sunday, June 19, 2016:

Looks like you need V8.2.1 http://www.freertos.org/History.txt

joe_her wrote on Monday, June 20, 2016:

A bit scared to upgrade version, should I expect problems when upgrading from ver. 8.0.1 (STM32F4)?

Johanan

rtel wrote on Monday, June 20, 2016:

It should be a drop in replacement, as is version 9.0.0.

joe_her wrote on Monday, June 20, 2016:

Will do.
Thanks