Stack problem?
Hallo
I may have some stack/heap problem!?? But im not sure.
Im using the latest FreeRTOS on my LPC2478. I have 5 tasks and they are working fine.
But know I whant to add some graphics task to my project. So I create a new task, which draw some graphics in my framebuffer in a given interval. But when the task runs, then I get an Abort exception. If I check the excpetion cause and extract the assembly where it happens, then its in the context switch rutine.
What I can see in the debugger before the exception(Keil uVision), a structure passed to a graphics function is suddenly out of scope… So when the function returns I get the data abort exception.
My guess is that maybee my stack is to small? The graphics function uses many bytes of RAM. Could that be a the cause?
If I call the graphics function from the main, before the scheduler is started, then there is no problem, but when called from the task I get an exception.
Does tasks run in supervisor mode? or user mode?
This is my stack and heap setup:
UND_Stack_Size EQU 0x00000008
SVC_Stack_Size EQU 0x00000400
ABT_Stack_Size EQU 0x00000008
FIQ_Stack_Size EQU 0x00000008
IRQ_Stack_Size EQU 0x00000400
USR_Stack_Size EQU 0x00000008
ISR_Stack_Size EQU (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size +
FIQ_Stack_Size + IRQ_Stack_Size)
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE USR_Stack_Size
__initial_sp SPACE ISR_Stack_Size
Stack_Top
;// <h> Heap Configuration
;// <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF>
;// </h>
Heap_Size EQU 0x00000000
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
If I look in my Startup.s file, I do not set the user mode stack pointer? Schouldnet I do that?
; Setup Stack for each mode —————————————————-
LDR R0, =Stack_Top
; Enter Undefined Instruction Mode and set its Stack Pointer
MSR CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #UND_Stack_Size
; Enter Abort Mode and set its Stack Pointer
MSR CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #ABT_Stack_Size
; Enter FIQ Mode and set its Stack Pointer
MSR CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #FIQ_Stack_Size
; Enter IRQ Mode and set its Stack Pointer
MSR CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #IRQ_Stack_Size
; Enter Supervisor Mode and set its Stack Pointer
MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #SVC_Stack_Size
EXPORT __initial_sp
; Enter User Mode and set its Stack Pointer
; MSR CPSR_c, #Mode_USR
; IF :DEF:__MICROLIB
; EXPORT __initial_sp
; ELSE
; MOV SP, R0
; SUB SL, SP, #USR_Stack_Size
; ENDIF
; Enter the C code ————————————————————-
IMPORT __main
LDR R0, =__main
BX R0
IF :DEF:__MICROLIB
EXPORT __heap_base
EXPORT __heap_limit
ELSE
; User Initial Stack & Heap
AREA |.text|, CODE, READONLY
IMPORT __use_two_region_memory
EXPORT __user_initial_stackheap
__user_initial_stackheap
LDR R0, = Heap_Mem
LDR R1, =(Stack_Mem + USR_Stack_Size)
LDR R2, = (Heap_Mem + Heap_Size)
LDR R3, = Stack_Mem
BX LR
ENDIF
END
/Thomas
Stack problem?
[sorry if this looks obvious to most of you, but I’ve seen this error happen quite often in multitasked programs]
Thomas,
make sure you do not create large structures on the stack. For example, if your graphic routine uses
void vGraphicTask(void *pvParameters)
{
unsigned char img[320*240];
…
}
then the "img" array will be allocated onto your task stack. If you have no reentrancy issue, i.e. only one instance of the above function will run, then you better use
static unsigned char img[320*240];
(prefix by "static")
In this case, "img" is similar to a global variable (allocated in the ".bss" section in a location statically determined at link time) whose visibility is restricted to the function in which it is declared.
Stack problem?
Also see this thread about which stacks are needed http://sourceforge.net/forum/forum.php?thread_id=3132196&forum_id=382005 (user/system stack is not required to be setup in the start up code) and these pages about stack overflows http://www.freertos.org/Stacks-and-stack-overflow-checking.html http://www.freertos.org/uxTaskGetStackHighWaterMark.html
Stack problem?
Samuel
Thanks for the reponds. I have checked my chain of function call and the structures used are declared static. The static structure is then passed as parameter to the next function. In this function then the parameter suddenly is "out of scope"
Could i try increasing the stack size, to see if that helps me?
I have tried making other changes. In the function I declare a local variable, where I copy the static structure too instead. The structur is only 14 bytes in size.
But still. As soon as I return from the function I get an abort exception!!!…
Here is the function that failes. Its called from a task. The parameter is declared static.
static unsigned long GetCharNdx( FontRecPtr Font)
{
unsigned long CharNdx,CharNdx1,CharNdx2;
…
…
do
{
….
….
if (CharNdx1 == CharNdx2)
return (Font->FirstCharNdx); <- Exception
….
…..
}
while (1);
}
If I look at my abort exception (R14) and extract the cause of the location its in the following program address 0x000AD60:
portRESTORE_CONTEXT ; Restore the context of the highest
0x0000AD58 E59F0028 LDR R0,[PC,#0x0028]
0x0000AD5C E5900000 LDR R0,[R0]
0x0000AD60 E590E000 LDR R14,[R0] 0x0000AD64 E59F0020 LDR R0,[PC,#0x0020]
0x0000AD68 E8BE0002 LDMIA R14!,{R1}
0x0000AD6C E5801000 STR R1,[R0]
0x0000AD70 E8BE0001 LDMIA R14!,{R0}
0x0000AD74 E16FF000 MSR SPSR_cxsf,R0
0x0000AD78 E8DE7FFF LDMIA R14,{R0-R14}^
0x0000AD7C E1A00000 NOP
0x0000AD80 E59EE03C LDR R14,[R14,#0x003C]
0x0000AD84 E25EF004 SUBS PC,R14,#0x00000004
0x0000AD88 40000C04 DD 0x40000C04
0x0000AD8C 40000C38 DD 0x40000C38
0x0000AD90 0000265C DD 0x0000265C
0x0000AD94 00001E8C DD 0x00001E8C
0x0000AD98 E0004000 DD 0xE0004000
Any idea?
Stack problem?
Hi
I have done some more debuging. My grasphics function are some function calling a function, that calls another function etc. Is there a limit on how deep function call can be with RTOS?
I also have added the configCHECK_FOR_STACK_OVERFLOW flag. If I set to "1" I dont get any vApplicationStackOverflowHook call. But when set to "2" the hook function get called and the debugger stopps. The parameters passed to the function are corrupted.
So could the function them self cause a overflow?
Is it possible to increase the used heap size used for the tasks stack?? Would that solve the problem?
My current heap is configured to 13*1024:
#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 104 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) 13 * 1024 )
/Thomas
Stack problem?
why not you just increase the stack given to the task when you create task using xTaskCreate?
Stack problem?
Thanks sotd… that did it!!!
and by the way… DOOOOOHHH :-)