Atmega1281-FreeRTOS SRAM (probably) overflow

Go To Last Post
29 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Heya AVRFreaks!

Im trying to build a homecontrol device using the atmega1281 (STK501) and FreeRTOS kernel (V6.1.1). This is my first piece of code larger than "receive, transmite data through USART" or "PWM to move some servo" so be gentle :oops:

After i implant some test tasks, that worked fine, and code starts to get bigger (at about 4 tasks) the device started to reset. I deleted 2 tasks and everything worked fine. While the code was growing these resets starts again. When Im shortening Stack sizes of the tasks and TOTAL_HEAP_SIZE to minimum the prject works until code become a little bigger and starts reset again.
I assume from all these that this happens due to SRAM overflow but since my experince is tiny, like a small almond, im not sure about it and i have no idea how i shall check and fix it.
Im all ears and anticipate for ideas :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What's the % program & Ram for working program compared to non-working versions and do these numbers include the overhead for the RTOS ?

Clawson says if your ram is something over 80%, you're asking for trouble. If it is stack overflow, you can use external ram I/F and save the day.

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

GCC informed me that there is plenty of room in ram even for a good socker game :D

I had to search in order to find the avr-size usage and change the makefile (stacking experience never harmed anyone).

Size after:
AVR Memory Usage

----------------

Device: atmega1281

Program:   13156 bytes (10.0% Full)
(.text + .data + .bootloader)
Data:       1872 bytes (22.9% Full)
(.data + .bss + .noinit)
EEPROM:        1 bytes (0.0% Full)
(.eeprom)

So i suppose that the good news is that i don't need an externa ram and the bad news is that i have to keep searching for the weird reset pitfall :roll:

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Which case is that for ? What's the usage for the "about 4 tasks" case ?

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

When I add some commented parts to a task although the GCC insists that there is no problem with the SRAM usage the atmega stops moving.

Size after:
AVR Memory Usage

----------------

Device: atmega1281

Program:   13648 bytes (10.4% Full)
(.text + .data + .bootloader)
Data:       1872 bytes (22.9% Full)
(.data + .bss + .noinit)
EEPROM:        1 bytes (0.0% Full)
(.eeprom)

I tried to give some extra space to the stack of that particular task but doesnt seem to work either :(

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There could be a few things to check.
- Stack overflow, which you already checked
- Check if you have an interrupt which does not have an handler routine.
- Check if you have functions that are called by more than one task. Make sure those function are re-entrance, i.e. has proper locks (atomic, mutex, semaphore, ...).
- Share variables that are used by more than one task. Make sure have proper locks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kevbin wrote:
I had to search in order to find the avr-size usage and change the makefile
Be aware that avr-size only reports statically allocated data. How are the stack sizes specified in FreeRTOS? Unless they are specified in a way that results in them being statically allocated they won't show up in the avr-size output.

What you probably need is additional information about the dynamic requirements, i.e. how much stack space does each task need (including the worst-case space for all ISRs you're using). You can determine this empirically by seeding each stack with a known value, running the tasks (making sure that all paths through the code are taken), and then determining how much of the stack space each task is "unused".

Another strategy is to use a static analysis tool to determine the worst-case stack use of each task. There have been several discussions of stack use analysis on this forum and someone (ezharkov perhaps) posted code for a tool that works for a well-defined subset of all possible applications. You'd probably have to modify it to compute stack use for multiple tasks.

See the thread below, for example, for more information.
https://www.avrfreaks.net/index.p...

Don Kinzer
ZBasic Microcontrollers
http://www.zbasic.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Each task has a stack, and that space is specified in the xTaskCreate() function. The minimum stack size is set in the FreeRTOSConfig.h file:

#define configMINIMAL_STACK_SIZE			( ( unsigned portSHORT ) 150 )

This is in bytes. The above is the setting I used in my complicated application on an ATmega2560 and may be larger than a minimum on the m1280.

In the .c file where I kept each task's code, I defined:

#define FOCUS_STACK_SIZE		( configMINIMAL_STACK_SIZE + 200 )	// My stack must be THIS big! ;-)

and then used it in the xTaskCreate call:

	xTaskCreate( vFocusTask, (signed portCHAR*) taskName , FOCUS_STACK_SIZE, NULL, uxPriority, ( xTaskHandle * ) NULL );

Another thin you can do is turn on Stack Overflow Check in the FreeRTOS. The specification is documented, but I used the highest level:

#define configCHECK_FOR_STACK_OVERFLOW  2

You must also supply a routine for FreeRTOS to call when a stack overflow is detected. My routine should work in your m1280:

void 
vApplicationStackOverflowHook( void* pxTask, void* pcTaskName )
/*---------------------------------------------------------------------------*\
Usage:
	called by task system when a stack overflow is noticed
Description:
	Stack overflow handler -- Shut down all interrupts, send serious complaint
    to command port.
Arguments:
	pxTask - pointer to task handle
	pcTaskName - pointer to task name
Results:
	
Notes:
	This routine will never return - forces a drive reboot.
	
	This routine is referenced in the task.c file of FreeRTOS as an extern.
\*---------------------------------------------------------------------------*/
{
	char* pC;
	uint16_t baud;
	 
	/* shut down all interrupts */
	cli();

	/* take over the command buffer to generate our error message */
	pC = (char*) pcmdBuffer;
	strcpy_P( pC, cmd_CRLF );
	strcat_P( pC, cmd_CRLF );
	strcat_P( pC, cmd_StkOvrflw );
	pC += strlen( pC );
	itoa( (int) pxTask, pC, 16 );
	strcat_P( pC, cmd_SPACE );
	strcat_P( pC, cmd_QUOTE );
	strcat( pC, (char*) pcTaskName );
	strcat_P( pC, cmd_QUOTE );
	strcat_P( pC, cmd_CRLF );
	strcat_P( pC, cmd_CRLF );

	pC = (char*) pcmdBuffer;

	/* Force the UART control register to be the way we want, just in case */

	UCSR0C = ( _BV( UCSZ01 ) | _BV( UCSZ00 ) );	// 8 data bts
	UCSR0B = _BV( TXEN0 );						// only enable transmit
	UCSR0A = 0;

	/* Calculate the baud rate register value from the equation in the
	 * data sheet.  This calculation rounds to the nearest factor, which
	 * means the resulting rate may be either faster or slower than the
	 * desired rate (the old calculation was always faster).
	 *
	 * If the system clock is one of the Magic Frequencies, this 
	 * computation will result in the exact baud rate
	 */
	baud = ( ( ( configCPU_CLOCK_HZ / ( ( 16UL * cmdBAUD_RATE ) / 2UL ) ) + 1UL ) / 2UL ) - 1UL;
	UBRR0 = baud;

	/* Send out the message, without interrupts.  Hardwired to USART 0 */
	while ( *pC )
	{
		while (!(UCSR0A & (1 << UDRE0)));
		UDR0 = *pC;
		pC++;
	}

	/*  Restart the app 
	 *
	 *  We use the watchdog timer to do this so all of the system's registers
	 *  and counters are reset..
	 */

	wdt_enable(WDTO_250MS);		// enable watchdog, 1/4 sec timeout

	// Force watchdog timeout
	while (1);
}
/*---------------------------------------------------------------------------*\
HISTORY:
4/15/2008 9:07:02 AM, Sbell
	- Created

vApplicationStackOverflowHook() END
\*---------------------------------------------------------------------------*/

There's one other gotcha in FreeRTOS that can cause chip reset: Calling a non-ISR function in an ISR. This will always lead to heart-ache.

Hope this helps!

STu

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oh, and one other thing: The space for the task info (TCB) and it's stack is allocated using vPortMalloc which uses heap space you have pre-allocated using the setting in FreeRTOSConfig.h:

#define configTOTAL_HEAP_SIZE   ( (size_t ) ( 5500 ) )

Make sure you allocate enough spavce for all the tasks you intend to create, plus the space you intend to dynamically allocate using vPortMalloc().

Stu

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

stu_san wrote:
The space for the task info (TCB) and it's stack is allocated using vPortMalloc which uses heap space you have pre-allocated [...]
This confirms my conjecture that the RAM required for tasks is not reflected in the avr-size output.

Don Kinzer
ZBasic Microcontrollers
http://www.zbasic.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Firstly a great thank for the help! :)

i've raised the stack size of the tasks and it didnt make any difference so i suppose my stack doesnt overflow. I ll check this, though, just to be sure, if nothing else work.

Quote:

This confirms my conjecture that the RAM required for tasks is not reflected in the avr-size output.

Indeed. From a very rough calculation i added the bytes from stack (3 tasks running. 2 of them with minimal stack size of 85 and one with 255. That means 425 bytes) along with the defined Heap size of 1500. That raises the SRAM usage at about 2K more than what avr-size reports.

 Data:       1872 bytes (22.9% Full)
(.data + .bss + .noinit) 

And this makes a total of about 4K SRAM in use.
The weird thing is that when I give some extra space to heap (make it 2K-2.5K), when the m1281 is on the edge of reseting or not, it stops working. When i definite it at 1.5K again it works just fine.

As hnhoan said

Quote:
There could be a few things to check.

and I ll double check them again for sure. But if everything is ok with my programming (I believe in miracles :P ) is there anything that can consume the rest 4K of SRAM? Or is there any possibility that SRAM is not defined as 8K but as 4k instead?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It's easy to consume 4K of stack. int foo[2000] at the beginning of a subroutine will do that until the subroutine returns, or putting it at the beginning of main will allocate it forever. An interrupt or recursion can eat a lot of stack. None of that will show on avr-size. It's also possible to overwrite RAM by indexing off the end of an array, or using a null pointer, or using a handle to an unlocked heap pointer.

Try allocating a big dummy array. If that doesn't change the the behavior then it's probably not a simple stack problem.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Wow! to be honest I am impressed by the simplicity and the efficiency of your solution! Great idea!
Already tried the dummy array of 1500 ints and nothing chanced so I suppose im not out of space. I have to check again for possibly overwriting ram as you said and this seems the most possible reason for my problem, since its not ram, concerning my programming experience. Thnaks again!
(damn, I'm still impressed! very clever idea :shock: )

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well there is one other thing to check: if the dummy array is the last thing in allocated RAM, and isn't used for anything, then a stack overrun won't bomb the program until it goes entirely through that to sensitive data.

$ avr-objdump -t --section=.bss yourelf.elf | sort

will tell you if that is the case.
[Edit] Now that I think about it, better to allocate the dummy array in local storage at the beginning of main. Then the entire stack would be shifted down and overflow would cause the same behaviour, only a lot faster :)

Last Edited: Tue. Feb 15, 2011 - 03:58 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Once you make the choice of using an RTOS then it's generally the case (with the proviso that fragmentation may be an issue) that malloc() will become your new friend. For small automatics up to (say) 32 bytes then continue to have them created on the task stack. But for any "large blob" use malloc() from the shared, system heap and don't forget to check the returned pointer for being NULL ! Be aware that the fragmentation issue will be worse if you have a lot of tasks all sharing heap usage - you may want to keep most of the data heavy stuff in a single task to avoid this and try to watch the sequence of malloc()s and free()s to avoid fragmentation as much as possible.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You said, with 2 task, it's ok. Have you let it run for a long time ? If after a long time, if the problem occurs, you may have a memory leak somewhere or a bad pointer. Validate all memory allocation that there are none that has gone AWOL.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

First off, sorry for the late post. I have not been able to follow 'Freaks as often as I once did.

dkinzer wrote:
stu_san wrote:
The space for the task info (TCB) and it's stack is allocated using vPortMalloc which uses heap space you have pre-allocated [...]
This confirms my conjecture that the RAM required for tasks is not reflected in the avr-size output.
Yes. Each task is cut from the FreeRTOS heap. The heap allocated to FreeRTOS' heap manager is static; it is reflected in the standard RAM measurements. It's set aside in .bss, IIRC.

Kevbin wrote:
From a very rough calculation i added the bytes from stack (3 tasks running. 2 of them with minimal stack size of 85 and one with 255. That means 425 bytes) along with the defined Heap size of 1500. That raises the SRAM usage at about 2K more than what avr-size reports.
Ummm, no. The 425 bytes are pulled from the 100 bytes of FreeRTOS heap (along with the TCB overhead). It depends on whether you use a static or dynamic allocation for your arrays. The task information and the stack for each task is allocated out of the heap provided to the FreeRTOS heap manager. If you use pvPortMalloc() to allocate any dynamic storage, that too will come from the heap provided to FreeRTOS.

In your calculations, the 2*85 + 255 bytes of stack comes out of the FreeRTOS heap (along with, of course, the space allocated for the TCB (Task Control Block).

Cliff wrote:
Once you make the choice of using an RTOS then it's generally the case (with the proviso that fragmentation may be an issue) that malloc() will become your new friend.
I would say in this case that pvPortMalloc() is his best fried. the system supplied malloc() will pull space from whatever is left of RAM after allocating all the static structures, including the FreeRTOS heap.

On the other hand, global variables are still allocated from the system heap, not from the FreeRTOS heap. If there is a task that requires a buffer to be allocated and deallocated often, it may make better sense to statically allocate is as a global and avoid malloc/pvPortMalloc completely. I would certainly put any variable/buffers that interface to an ISR into a global!

Cliff wrote:
For small automatics up to (say) 32 bytes then continue to have them created on the task stack. But for any "large blob" use malloc() from the shared, system heap and don't forget to check the returned pointer for being NULL ! Be aware that the fragmentation issue will be worse if you have a lot of tasks all sharing heap usage - you may want to keep most of the data heavy stuff in a single task to avoid this and try to watch the sequence of malloc()s and free()s to avoid fragmentation as much as possible.
Now this is very true. The default FreeRTOS heap manager (type 1) is pretty stupid. Type 2 is usually good enough but does not re-coelesce very well. Type 3 is supposed to be the "high-zoot" version, although I have never used it.

A coworker added some code to the Type 2 heap manager (and called it "2.5") that would coelesce chunks of freed memory that were next to each other. His usage was temporary storage for logging and the chunks were usually allocated and then deallocated at roughly the same time. This left "bubbles" of free space at the top of the heap. His modified heap manager looked for those and combined them into one big freespace on-the-fly. If you run into problems, let me know and I'll post the code.

Stu

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Stu,

I don't know FreeRTOS that well but I have worked on systems where there's more than one system heap for malloc() (or variants) and it was quite possible to run into the stupid situation where one heap became starved while there were still megabytes left on one of the others (this was a "big" system with three heaps split something like 6MB, 3MB, 3MB). I fought and fought to get the heaps coalesced to avoid the stupid situation. But basically it started with 12MB, the other two (independently written) software systems each started by making a 3MB alloc of the main heap then they each ran their own mallocators on their now "private" heaps as they considered their software systems proprietary and while they were willing to start with one 3MB malloc() from the OS heap they wouldn't trust anything but their own malloc()s. So I cannot envisage any reason why anyone would ever design a system with more than one heap - the more so if RAM is a scarce resource (12MB in a digital TV decoder is not a large heap!).

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This slimy bug still tortures me :?

Quote:

Yes. Each task is cut from the FreeRTOS heap. The heap allocated to FreeRTOS' heap manager is static; it is reflected in the standard RAM measurements. It's set aside in .bss, IIRC.
Although I define heap size to 2500

#define configTOTAL_HEAP_SIZE		( (size_t ) ( 2500 ) )

the avr-size still remains as it was with 1500 bytes of Heap size

Data:       1838 bytes (22.4% Full)
(.data + .bss + .noinit)

and I cant see the bytes of the heap to be reflected to any of the avr-size output.. Shall I be warned by this or it is normal to happen?
I use the heap manager type 1 as i dont delete or create any task after the scheduler starts running and so far I dont use any pvPortMalloc() since my larger varaibles are 10-15bytes arrays.

Quote:

Have you let it run for a long time ? If after a long time, if the problem occurs, you may have a memory leak somewhere or a bad pointer.

One of the tasks created is a software clock (it will be an RTC later but it helps for debuging for now) and the longest time i have left it is about 9 hours with no problem.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

and I cant see the bytes of the heap to be reflected to any of the avr-size output.. Shall I be warned by this or it is normal to happen?

Nope avr-size shows you exactly what it says - the sum of the contents of .data, .bss and (more unlikely) .noinit - the heap and the stack are not part of those so don't appear there.

For the general avr-gcc case (but not necessarily FreeRTOS) see this diagram:

which is explained on this page:

http://www.nongnu.org/avr-libc/u...

avr-size only tells you about the cyan and green bits in this diagram.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are there any tools that can be used to debug a RTOS app. ? How do you track heap usage in a multi-MB RAM app. like a digital recorder ?

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

How do you track heap usage in a multi-MB RAM app. like a digital recorder ?

Well most RTOS (big ones like Nucleus Plus or VXworks) not only have RTOS_malloc() they also have RTOS_get_free() or similar. But one way to do it is simply to run a loop making a stupidly large malloc() and iterating downwards. You stop when the return is a non-0 value (the malloc worked) then free() the block. This, of course, just tells you how big the largest free block is.

As for debugging RTOS, again for "real ones" like Nucleus/VxWorks/pSos/etc. you actually use an RTOS-aware debugger and it does all the usual stuff but also lets you view task switching events, sem4's and so on.

Some people would call Linux an RTOS (but not very RT!). I do. It clearly has very powerful debugging available. Not just gdb but all the utilities and /sys + /proc info that tells you what's going on. Even something like "top" can be very useful. (it's a bit like Task Manager in Windows I guess)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kevbin wrote:
This slimy bug still tortures me :? Although I define heap size to 2500

#define configTOTAL_HEAP_SIZE		( (size_t ) ( 2500 ) )

the avr-size still remains as it was with 1500 bytes of Heap size

Data:       1838 bytes (22.4% Full)
(.data + .bss + .noinit)

and I cant see the bytes of the heap to be reflected to any of the avr-size output.. Shall I be warned by this or it is normal to happen?

This is not normal. Since (I hope) you are using a makefile, request a map file be generated. You should find the space allocated under .bss to heap_1.o. In my case, it it looks like:
.bss            0x00800270     0x1bc5 load address 0x00028828
                0x00800270                PROVIDE (__bss_start, .)
 *(.bss)
 .bss           0x00800270        0x0 d:/winavr-20100110/bin/../lib/gcc/avr/4.3.3/../../../../avr/lib/avr6/crtm2560.o
 .bss           0x00800270        0x0 obj/MPB.o
 .bss           0x00800270     0x177d obj/heap_2p5.o
 .bss           0x008019ed        0x0 obj/list.o

where 0x177d (6013) bytes are allocated to heap_2p5.o (my heap manager). When I last compiled this I believe I had 6000 bytes allocated to the heap. (Ya gotta love that ATmega2560! Xmegas are even better! :D)

clawson wrote:
I don't know FreeRTOS that well but I have worked on systems where there's more than one system heap for malloc() (or variants) and it was quite possible to run into the stupid situation where one heap became starved while there were still megabytes left on one of the others
That is, unfortunately, the situation here. I set my heap space to take almost all of the free space left after global allocation to avoid this. (There is a problem with this approach: FreeRTOS needs "native" stack to wake up; all initialization runs in the native stack until the tasks are awakened. I had to be careful with my I/O and task initialization routines to not overrun the FreeRTOS heap during wakeup.)

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

At last an evidence of what is not right!!!

.bss            0x00800284      0x68a load address 0x00002ea2
                0x00800284                PROVIDE (__bss_start, .)
 *(.bss)
 .bss           0x00800284        0x0 f:/programmes/winavr/bin/../lib/gcc/avr/4.3.0/../../../../avr/lib/avr51/crtm1281.o
 .bss           0x00800284        0x0 main.o
 .bss           0x00800284        0x0 ParTest/ParTest.o
 .bss           0x00800284        0x4 serial/serial.o
 .bss           0x00800288        0x1 regtest.o
                0x00800288                xRegTestError
 .bss           0x00800289        0x0 lcd.o
 .bss           0x00800289       0x5a ../../Source/tasks.o
                0x00800289                pxCurrentTCB
 .bss           0x008002e3        0x0 ../../Source/queue.o
 .bss           0x008002e3        0x0 ../../Source/list.o
 .bss           0x008002e3       0x3a ../../Source/croutine.o
                0x008002e3                pxCurrentCoRoutine
 .bss           0x0080031d      0x5de ../../Source/portable/MemMang/heap_1.o
 .bss           0x008008fb        0x0 

It seems that 1500 bytes are assigned to freertos heap even though i have defineted

#define configTOTAL_HEAP_SIZE		( (size_t ) ( 2500 ) )

Heap size doesnt change when changes are made to configTOTAL_HEAP_SIZE. Do you have any idea why this happens? :roll:

stu_san you made my week start with a great smile!!! This bug was torturing me the last 3 weeks and it was a very painful (mentally) 3 weeks period! I own you a great thank!!!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, it's either misspelled, overridden, ignored, or you didn't recompile the needed modules after changing the definition.

Try grepping HEAP_SIZE from the top level
$grep -R HEAP_SIZE *

and make clean

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kevbin wrote:
It seems that 1500 bytes are assigned to freertos heap even though i have defined

#define configTOTAL_HEAP_SIZE		( (size_t ) ( 2500 ) )

Heap size doesn't change when changes are made to configTOTAL_HEAP_SIZE. Do you have any idea why this happens? :roll:

Is the definition in FreeRTOSConfig.h? Is that file used in the compilation of the heap_1.c file? If either of the answers to these questions is "no", you have your answer.

I also think you should do a "make clean" and recompile all modules. Perhaps your dependency walker is not seeing the changes to FreeRTOSConfig.h.

Stu

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My suggestion with stack over/underflows (if this is the case) is to use JTAG and data breakpoints (with masked range). This works much like a simplified MPU.

Debugging OS without dedicated tools can be painful. I wonder how FreeRTOS (which is written in C) checks task stack under/overflow run-time (even with statical allocation of these stacks).. It must be aware calling a function, if SREG_I is set, requires 2*2/3 pushes + all extra arguments actually before each foo() is called. Even more when prologues are called. Some, like printf, have variable arg count. And the foo itself can have autos on the stack - pretty complicated.

If there is a method of run-time stack range check in C, perhaps this can be easily ported to regular no-OS applications, similar to assert()?
Like:

#include 
assert_safe_call(foo(foo_arg)); //check before call if there is a space for asm("push"), as foo_arg can be a huge structure.

Who knows how to check this with AVR-GCC in run-time?

No RSTDISBL, no fun!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

After all it seems that the overflow was not the issue but just a little symptom of the hell that was hiding in the depts of my project :D

i tried to make clean by command and suddenly everything stopped working. Indeed Stu and dak664 the compiler was not cleaning before building (as i thought it was doing so long) and now that i have cleaned.. as said before, nothing works :)
At least i have my problem face to face now and im not searching all around the code.

A million thanks to all of you guys! Pity I cant thank you otherway, like buying you a beer, but if i ever be around your places ( or you be in Greece) i ll send a message for the beer and i do keep my promises 8)
Thanks again!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
as said before, nothing works

RT is a challenge without appropriate tools. Provided examples work perfectly till the moment some task trips over its shoelace. Well known blue screen apperas and only /reset button works then.

No RSTDISBL, no fun!