Strange stack problem

sblancodiez wrote on Thursday, September 26, 2013:

Hello there,

I am using the Cortex M4F port for an Infineon XMC4500 and I have a strange problem. I am developing a test task that writes and reads the S25FL032 flash memory. To ensure each operation is done in one go I am trying with a critical section per operation. The problem is, I get BusFaults and strange problems (for example, it makes one complete write/read loop and in the next loop, the first exit of a critical section returns to 0x000000, like if the stack was wrong.

I have checked the SP register and it is always higher thsn the top of stack that the Wittenstein Stateviewer states for the task, which makes me paranoid like if there was some problem with the stack. I am using big stack capacities.

All the code inside the flash driver is peripheral related and there are no interrupts. I have a BusFault handler but it doesnt help because lr is usually garbage or vPortCriticalEnd last asm instruction.

The most strange thing, I discovered that if I eliminate the Bad rate calculation function it doesnt hang up. I checked the function and it is just some calculations. Tomorrow I can post some more info, I knlw this is vague, but if there arent interrupts, just one task, no FreeRTOS API calls except the critical sections… Anyone has any idea what could be wrong or what I can check? Is it normal that the sp register and the stateviewer are not matching? The BusFaults do not happen without critical sections.


rtel wrote on Thursday, September 26, 2013:

When you return from the function, is zero really what is popped off the stack as the return address? Or does zero get loaded into the PC unexpectedly?

To determine this:

  1. Step through the assembly instructions up to the instruction that returns from the function - it will be something like a BX LR or POP PC instruction. What is the instruction?

  2. When you get to the instruction that returns from the function note the SP value.

  3. In the memory window look to see what is on the stack at the value pointed to by SP. Is it (or the instruction after it, depending on how the return is managed by the assembly instruction) the real return address, or 0?

If it is 0 then there could be a genuine stack or SP corruption. If it is the real return address then there may be some changes to the startup files that will help.

Where did the startup files you are using come from?


sblancodiez wrote on Friday, September 27, 2013:

Sir, you have saved me from more days of wondering why something so simple was not working. My greatest thanks and kudos to you.

I was using the linker script and startup file Dave generated (although I am not using Dave) and checking with the one in the FreeRTOS demo I saw the PendSV handler was defined with Veneer in the Dave one and as simple .long in the FreeRTOS one.

There is still one mistery though; before doing this I followed your advice and tried checking the registers and memory data and I feel my debugger is laughing at me hard or something.

SP always points to a place that according to the StateViewer plugin is out of the stack for the task. For example, for my QSPI task, StateViewer says the start of the stack is @ 0x10001328 and the top is @ 0x10001a1c. While in the task sp points to 0x10001b08, which isn’t in any other task stack as reported by StateViewer.

I thought, well, maybe StateViewer isn’t getting the addresses right. Using the memory view makes it worse, as the adress pointed by sp always have 0xA5A5A5A5 or what I think is another RAM address, not code addresses. So, I am missing something here?

I am using latest Eclipse, GNU ARM plugin, GCC ARM stack, J-Link GDB server.

Thank you a lot once again :slight_smile:

rtel wrote on Friday, September 27, 2013:

I’m glad your problem was resolved. Check back when I release the current crop of XMC4nnn demos as there may be some modifications to try and prevent other people from experiencing the same problem as you.

I can’t explain why the stack pointer you are seeing appears to be outside of the stack space, unless it genuinely is off course - do you have run time stack checking turned on?

I will be using Dave today so I will try and replicate what you are seeing.


sblancodiez wrote on Tuesday, October 01, 2013:

Hello Barry,

Yes, I have stack checking enabled. Since your tip everything is working great, this is how it should work!

As for what I told you about how I see the stack, check the following screen capture. As you can see, SP points to a place none of the tasks seem to be using. It is working very well so I would think the problem is with StateViewer and not with RTOS itself. I am using ARM GCC and plain Eclipse. If you thin the problem is with StateViewer I can send an email just to let them know.

As for the startup file, how come SVC_Handler and SysTick are kept Veneered? The problem then was the PendSV assembler code that broke with the Veneer wrapping?

Thank you for your help:-)

rtel wrote on Tuesday, October 01, 2013:

As for the startup file, how come SVC_Handler and SysTick are kept Veneered?

They are just standard functions, whereas the PendSV handler cannot use the veneer because it is written in assembler and requires access to the registers exactly as they were when the interrupt was taken, not after a veneer function call.

The veneers are required as a work around to an errata on the XMC4000. Even with the veneer removed the “bx lr” instruction at the end of vPortPendSVHandler in port.c needs to be replaced with two instructions “push {lr}; pop {pc}”. The latest version in SVN does this with a pre-processor macro. Ugly, I know. (actually, I just checked, its not checked into SVN yet, but it will be soon).

I’m wondering if the “top of stack” as shown in the state viewer is the top of the stack as it was the last time the task was switched out, rather than the top of the stack space available to the task?


sblancodiez wrote on Wednesday, October 02, 2013:

I will try and see if the top of stack changes with time.

As for the vPortPendSVHandler, should I change it now then?

rtel wrote on Wednesday, October 02, 2013:

The latest version of the GCC Cortex-M4F PendSVHandler (in port.c) ends as follows:

  "  msr psp, r0              \n"
#ifdef WORKAROUND_PMU_CM001  /* XMC4000 errata workaround. */
  #if WORKAROUND_PMU_CM001 == 1
    "  push { r14 }          \n"
    "  pop { pc }            \n"
#endif /* WORKAROUND_PMU_CM001 */
  "  bx r14                \n"
  "                    \n"
  "  .align 2              \n"
  "pxCurrentTCBConst: .word pxCurrentTCB  \n"

Only the bit between the #if and #endif is different/new.


rtel wrote on Wednesday, October 02, 2013:

Actually - I think to be correct, all the pre-processor lines should likewise be included in the quotes (") and end with a \n, just like all the other lines, otherwise they are invisible to the assembler.


sblancodiez wrote on Wednesday, October 02, 2013:

And wouldn’t vPortSVCHandler need the same modification?

I have been checking the latest commits and I understand you intend to have two versions of the PendSVHandler and use the define in FreeRTOSConfig.h to direct to one version or the other, is that correct?

Sorry I can’t be of much help, if there is anything you want me to test or try tell me.

rtel wrote on Wednesday, October 02, 2013:

The code in my previous but one post was the pendSV handler.

However, since posting this I note the preprocessor is having no effect in inline assembler.


sblancodiez wrote on Wednesday, October 02, 2013:

Hello Richard,

I checked the stack thing and you were right, Top of stack is the last FreeRTOS saw when changing task, everything seems all right there :slight_smile:

As for the PendSV and SVCHandler, forgive my ignorance, but in the port there are handlers for both PendSV (void xPortPendSVHandler( void )) and SVC(void vPortSVCHandler( void )), both are naked asm functions that end with “bx r14” and both are Veneered in the original Infineon startup file, so the question was whether the same patch was neccesary in SVC_Handler.

I don’t know ARM asm, I see PendSV starts with “mrs r0, psp” and SVC doesn’t, so maybe that’s why not, but just in case I thought it would be better to ask.

As for the inline assembly, perhaps if you use asm() in each line the end result is the same but you can have preprocessor in the middle as the function must still be parsed by the C compiler? Just guessing.

Thank you

rtel wrote on Wednesday, October 02, 2013:

Actually, having looked again, the code I posted in a few messages above was correct after all. Ignore my other waffling on the pre-processor.

PendSV is the only one that needs changing. The other functions are still called through veneers, so just return to the veneer.


sblancodiez wrote on Wednesday, October 02, 2013:

Ok Richard, thanks. I’ll wait a few days for the code to be in the repo and then will try it out.

sblancodiez wrote on Wednesday, October 02, 2013:

Sorry to disturb you again, but just to be clear.

I am checking the repo and I see the commit r2045 is to fix the PendSV issue but it doesn’t include any change in the port assembler. I do see, though, that you are overriding the Veneer handler when the workaround is active.

+#if WORKAROUND_PMU_CM001 == 1

  • #define xPortPendSVHandler PendSV_Handler_Veneer
  • #define xPortPendSVHandler PendSV_Handler

This commit was yesterday so I guess this is not it or it is just part of it. If you want, I would like to test what you think is the solution, so what should I do? Is it the commit + what you told me earlier, just the commit or just what you told me earlier?

Thank you

rtel wrote on Wednesday, October 02, 2013:

The demo application is committed, and I think that is what you are looking at, but the port layer that it uses is not committed…yet. There is probably no reason why it can’t be committed, but I don’t have time to check it now. If you send me an email using the business contact link on I can send it to you if you like.