This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

stack overflow when first thread is started

Hi

I have just ported my code that was working without a RTOS to CMSIS RTOS and its loaded onto my cortex m3 arm and my code gets through by board initialization but as I get a stack overflow when the RTOS tries to start the first task.

I have configured 0x8200 bytes for my stack, 7 tasks, 2000 bytes for the default thread and 800 bytes for the other 6 threads. The thread viewer shows two additional threads, timer and idle.
My stack is located in the esram and is using all available bytes there.

I really do not have any idea what I have done wrong in allocating memory for the stack or in configuring the RTOS. I feel I missed something in the setup.

I was thinking about backing off the 7 threads and just try to start 1 and see if that overflows.

Is it possible to relocate my stack to my DDR memory space at 0xA0000000 so I can make the available stack size bigger? I don't know if throwing more memory at it will really solve this problem.

Does anyone have any ideas about what might be wrong or how I might go about debugging this overflow issue?

  • Well the trick would be to actually know, or figure out, what your code is actually using, and why. If you have excessively large auto/local variable allocations in a function called by all threads, then that's going to blow out all the stacks.

    Understand your code, your call trees. Review the static analysis generated by Keil (Project.htm)

    External memory can hold the stacks, it will be SLOW, but you could use a massive allocation for each, paint it with a clear fill character, and then periodically figure out what the high/low water marks are for each of the stacks.

    If the stacks are still excessively large for the tightly coupled SRAM you need to review the coding style and the interplay of the routines causing the problem, and where appropriate change the memory uses, or refactor.

  • I agree that one needs to understand the data requirements of each task. But this code has been running without error before I ported it to using the RTOS mostly mailboxes and delay calls and now I have stack problems.

    I allocate space for the stack in my scatter file and by configuring the total stack size in startup_m2sxxx.s.

    The stack overflow is happening even before the thread is called for the first time. That is what I don't understand. The thread as not even had a chance to use its stack and its already overflow?

    With CMSIS-RTOS is there some parameter or setting or function that needs to be executed/configured besides the RTX_CM3.lib that sets the task stack size?

    This code has been running without the RTOS so I feel confident that the total stack size is large enough. But the RTOS is now cutting that up into individual stacks so maybe that is a issue because before a routine could use the entire stack space if it needed to now its restricted.

    
    FLASH_LOAD 0x00000000 0x00080000      ; load region size_region
    {
        ER_RO 0x00000000 0x40000    ; load address = execution address
        {
            *.o (RESET, +First)
            *(InRoot$$Sections)
             * (+RO)
             * (INITDATA)
        }
    
        ER_RW 0x20000000 0x7200
        {
            bootjump.o (.data)
            bootjump.o (.text)
            ; programFPGA code will be copied to 0x20000000 when
            ; reprogramming FPGA
        }
    
    
        ER_RW2 0x20007200 0x82E0
        {
            startup_m2sxxx.o (STACK)
        }
    
        ER_BOOT_MSG 0x200082E0 0x10
        {
            ; reserved for bootloader info to application
        }
    
        ER_BOOT 0xA0000000 0x40000
        {
           ; reserved for boot loader to load image
        }
    
        ER_DDR 0xA0040000 0x20000  ; RW data  DDR 256MB
        {
           * (+RW +ZI)
        }
    }
    
    MDDR_RAM 0xA0060000 0x9FFA0000
    {
        ER_DDR2 0xA0060000 UNINIT 0x9FFA0000  ; RW data  DDR
        {
           * (HEAP)
        }
    }
    
    

  • A test I just ran was to create only 1 task and give it 3000 bytes which is way over what it needs and I still got a stack overflow. So there has to be something else going on with the RTOS and thread stacks.

    Its like the RTOS does not know anything about the stack. It seems to think its zero size I guess.

    I stopped the main/default thread that initializes the system and creates the thread right when it is going to osDelay() which will give up control to the next thread. I looked at the system and thread viewer and the task that will run next is only using 2% of the stack. The osTimerThread (RTOS thread) is using 40%. this is not any of the my threads.

    I have a break point at the start of the next thread but it gets a stack overflow before even getting to its first instruction.

    I don't see any reason for the that thread's stack to overflow when it has not even been able to run yet. That is what I don't understand.

  • It is possible that something else corrupts stack memory making the OS think it overflows...?

  • I started to debug the createTask function and found that it calls rt_alloc_mem (os_stack_mem, thread_def->size) and during the allocation of memory I get a hard fault when it tries to "insert list element" by writing to a mem pool pointer p.

    /* Insert new list element into the memory list */ p = (MEMP *)(((U32)p_new) + sizeof(MEMP));

    this is the store instruction that faults: STR r1,[r0,#0x00] r1 = 0x40093b2c r0 - 0xA0049c18 where r1 = p* r0 = p_new* MEMP is a memory pool data structure

    This memory pool is os_stack_size = 0xE98 and created during KernelInitialize() by a call to rt_init_mem() and osTimerThread (stacksize = 0xC8)is created ok and taking some memory from this stack memory pool.

    So at least one thread was created and there is a lot of stack memory left for my thread.

    when createThread is called with my thread it goes through the same processing but throws a hard fault at the line above. I cannot see any of the variables so I do not know what is causing this.

    The RTOS is not compiled debug I assume.

    This does not make sense to me right now. Why a hard fault?

  • Good thought but I think that is not a problem. It appears this "stack memory pool" that is created by rt_init_mem from the kernelInitialize() call allocates it at memory address (os_stack_mem) is at 0xA0048b48

    Nothing else is running during initialization so there cannot be any other thread of anything to step on the stack memory.

    os_stack_mem 0xa0049b48 Data 3736 size rtx_conf_cm.o(.bss)

    If you have any other ideas, please let me know

  • Here is some additional information I found. I did not have the "if (!osKernelRunning)" when I ran. Apparently I was calling osKernelInitialize twice. It is called automatically before my main task runs which I did not realize.

    I can successfully create my timer task.

    So that was my problem it seems. Don't call KernelInitialize twice