0
\$\begingroup\$

My STM32F4 Discovery is crashing when I try to run the sin or sinf function with the FPU enabled and with the FPU disabled.

for (; i < 1023; ++i){
    ftemp = sin (c*t);        // Crashes here
    temp =  buffer[i] * ftemp;
    buffer[i] = temp;
    t += step;
}

When I use the sinf function, this loop crashes on its second iteration. When using plain sin, it crashes after between 768 and 1023 iterations (I've exhaustively tested). What is causing this?

Note: When using the FPU, I configured it like so: http://www.coocox.org/forum/topic.php?id=1292

EDIT:

I have since worked out that the HardFault_Handler() is being invoked. This is with the FPU completely disabled

EDIT:

I'm apparently accessing an invalid memory address. I read the PC from the stack and it is 0x00000000! How is that possible? (The program counter is the 7th 32 bit word on the stack)

The program counter is the 7th 32 bit word on the stack

\$\endgroup\$
  • \$\begingroup\$ Try to use objdump to find the corresponding machine code being executed. If you are set up for gdb, put a breakpoint there and single step through the failure. Try to see if it depends on the argument. Possibilities include disagreement about floating point ABI, illegal value, functions the compiler thinks exist which didn't get linked, linker putting things in memory which doesn't exist, illegal use of ARM mode on a thumb-only core, and yes, toolchain bugs. \$\endgroup\$ – Chris Stratton Aug 24 '13 at 14:25
  • \$\begingroup\$ You need to find the program flow that gets you to the point where you would be loading the PC from an invalid stack frame - if what you think you see above is really what is happening. If it is, you've either run away, or overwritten your stack - in either case, the problem is earlier. \$\endgroup\$ – Chris Stratton Aug 25 '13 at 23:47
  • \$\begingroup\$ I was able to resolve this by modifying the argument to my sin / sinf function. I have no idea why this even caused a problem in the first place since my arguments were always floats and the sine function is supposed to take in an argument of any range. \$\endgroup\$ – user929404 Aug 27 '13 at 9:22
2
\$\begingroup\$

Do you have a systick handler function? Otherwise, the default handler will get called after a set amount of time (at least with that start-up file).

Edit, in reply to comments:

All of the ARM Cortex microcontrollers have a built in 24 bit system timer, which is referred to as the systick. The timer counts down from a value you can configure to zero and when it reaches zero it fires the systick interrupt. Its main purpose is to provide timing to the software - for example you can set it up to fire the interrupt every millisecond, which can be quite useful for timing or running an operating system.

The systick interrupt needs to have a handler - in your startup file it is set to the default handler, which is essentially an infinite loop. The handler does not have to do anything, it can just be an empty function,

void SysTick_Handler(void)
{
}

but for most uses you will want to increment your own counter, to keep track of milliseconds for example,

uint32_t sys_count=0;
void SysTick_Handler(void)
{
    ++sys_count;
}

or run part of the operating system.

\$\endgroup\$
  • \$\begingroup\$ No I don't. 2 Questions: 1) What does the systick handler function look like, 2) If I remove calls to the method in question, my program works correctly. I have run it for close to half an hour at a time \$\endgroup\$ – user929404 Aug 24 '13 at 8:13
  • \$\begingroup\$ I've updated my answer in relation to your first question, but I'm not quite sure which calls you are referring to in your second question. \$\endgroup\$ – Ian G Aug 24 '13 at 10:55
  • 1
    \$\begingroup\$ This is a comment (and a long shot guess at that), not an answer. Adding detail didn't make it more relevant. \$\endgroup\$ – Chris Stratton Aug 24 '13 at 14:25
  • 1
    \$\begingroup\$ Unfortunately, I don't have enough reputation to comment. However, it doesn't seem to be a long shot in reference to the use of sin (not sinf), where @user929404 says that it fails between 768 and 1023 iterations - this (likely) rules out most faults, except perhaps divide by zero, as the function does work. I have additionally before left out the systick handler and had very peculiar behaviour that was incredibly difficult to find the cause of, hence why I have posted this answer. \$\endgroup\$ – Ian G Aug 24 '13 at 20:25
  • 1
    \$\begingroup\$ @IanG I think you only need a sysTick handler if you enable the sysTick interupt in the first place. \$\endgroup\$ – user929404 Aug 27 '13 at 9:24
2
\$\begingroup\$

To determine the cause of the fault you need to create separate handlers for each of the faults rather than map them all to the default handler. Then when the fault occurs you will be able to determine the cause by looking to see which handler was executed. If a hard fault occurs then you can look at various registers to find the details of what caused the fault.

Edit: It's a little tricky to track down a hard fault. Here's a good explanation: Debugging Hard Fault & Other Exceptions on ARM Cortex-M3 and ARM Cortex-M4 microcontrollers

\$\endgroup\$
  • 1
    \$\begingroup\$ This is a comment, not an answer \$\endgroup\$ – Chris Stratton Aug 24 '13 at 14:23
  • 2
    \$\begingroup\$ @ChrisStratton I think my response was more helpful than your comment to the original question, or a WAG that it is caused by the SysTick interrupt. By providing different handlers for each type of fault the OP can most easily home in on the cause of the fault and the instruction that causes it. Your suggestion requires that he single-step through up to 1023 iterations of the sin function, or try random arguments to look for a pattern. \$\endgroup\$ – Joe Hass Aug 24 '13 at 19:01
  • \$\begingroup\$ @JoeHass Thanks. It is a hard fault, now I need to work out why \$\endgroup\$ – user929404 Aug 24 '13 at 21:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.