简体   繁体   中英

Hard Fault Error on Arm 4 microcontroller

I have a problem with my Tiva C controller which is very strange and I would like some help with it, basically it crashes on an sprintf line with no obvious reason to do so. My application is simply a smart toy which can be controlled through Bluetooth in various modes. For the modes we use a finite state machine code and for reading the current acceleration for the toy just for monitoring only and it is sent every once in a while using a periodic timer which generates a periodic interrupt every couple of secs to update the value of acceleration

Now the reading of acceleration is done by a simple function reading goes fine until trying to store that reading inside a string and the program just throws a hard fault. This function (which reads the acceleration) works fine in all other modes of toy car except this new mode it always crashes and throws the hard fault error. My current thinking is that it might be due to too many function calls so the stack is getting full but how can I know whether the stack is full or not?

This is the line that it crashes:

sprintf(acceleration,"x%.2f y%.2f z%.2f", X_Axis1, Y_Axis1, Z_Axis1); 

It's a simple sprintf which stores the value read from the acceleration axis x , y and z then stores in acceleration variable any idea why this is happening?

This is also the fault report on keil inside the timer handler I used to call a ReadAccel() function which I made which works in all modes except the most recent one so I thought I would move the code inside the function inside the timer handler to save a bit from the stack but it still gave a hard fault 在此处输入图片说明

If someone can redirect me to how to figure out if this is a stack full error I would be very thankful since I think this is what it is .

void TIMER2A_Handler(void)
{
        char acceleration[22];
        RawX_Axis1=ReadAccelX();
        X_Axis1 = RawX_Axis1 * 0.00390625+0.35;
        RawY_Axis1=ReadAccelY();
        Y_Axis1 = RawY_Axis1 * 0.00390625+0.08;
        RawZ_Axis1=ReadAccelZ();
        Z_Axis1 = (RawY_Axis1 *  0.00390625)+1.08;
        sprintf(acceleration,"x%.2f y%.2f z%.2f",X_Axis1,Y_Axis1,Z_Axis1); 
        UARTSend(UART3_BASE,acceleration);
        UARTCharPut(UART3_BASE,'\n');
        TIMER2_RIS_R = 0xFFFFFFFF;
        TIMER2_ICR_R = 0xFFFFFFFF;  
}

First try it without a call to sprintf, just send a hard coded string in UARTSend . If that stops the crash, then you need to find out why the sprintf is causing the crash. I see two problems:

  • possibility of stack overflow (ha ha)
  • possibility of buffer overrun.

You allocate a 22 byte buffer for your sprintf, that might be too small since it only allows six characters for each acceleration (including the possible minus sign and decimal point). Try formatting and sending each acceleration individually. it might also alleviate a potential stack overflow in sprintf.

Also, try using a simplified inline string conversion. eg cast each number to an int after multiplying it by 100 (gives you a 2 dp fixed point number) and use simple division and mod by 10 and addition to 0x30 (ASCII 0 ) to create the string.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM