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

floating point in cortex m0, always reset.

hi,I write an algorithm running in cortex M0. It has some floating point multiplication.But the program always resets when encounter a floating point multiplication.And the code showed below:

    for (k = 0; k < 4; k++) {
                        tmpx =   dbuffer[0] * a[k + 1];
                        dbuffer[k + 1] = dbuffer[k + 1] - tmpx;
    }


dbuffer[] and a[] are float array. tmpx is a float variable. When I debug the program, the M0 resets at line "tmpx = dbuffer[0] * a[k + 1];" .And the value of dbuffer[0] is 1429983,a[k+1] is 0.00974910986.
I have tested this multiplication in a new project.And the code goes well and result is right.The test code is like below:

            float a = 1429983;
            float b = 0.00974910986;
            float c;
            c = a* b;


So, I know M0 use softVFP. I have seen asm code such as __aeabi_fmul corresponding to my code.
Could anybody tell me what's wrong with my code?
Thank you very much.

Parents
  • I suggest that you single step through the assembly instructions of the source line and post these assembly instructions along with the instruction causes the reset to this forum.

    Information like the register values of the related registers would help too.

Reply
  • I suggest that you single step through the assembly instructions of the source line and post these assembly instructions along with the instruction causes the reset to this forum.

    Information like the register values of the related registers would help too.

Children
  • Thank you for your reply.
    When I step into the assembly code,the code runs well and the cpu never reset.It's so weird.
    But when debug in C code, then reset again.
    below is the assembly code:

        28: {
        29:   float a1;
        30:         float tmp1,tmp2;
        31:   int k;
        32:   float dbuffer[5];
        33:   int j;
    0x00028FFC B5FF      PUSH     {r0-r7,lr}
    0x00028FFE B087      SUB      sp,sp,#0x1C
    0x00029000 4607      MOV      r7,r0
    0x00029002 460E      MOV      r6,r1
        34:   a1 = a[0];
        35:  // if ((!((!rtIsInf(a[0])) && (!rtIsNaN(a[0])))) || (a[0] == 0.0) || (!(a[0] !=1.0)))
        36:         if (1)
        37:         {
    0x00029004 6830      LDR      r0,[r6,#0x00]
    0x00029006 9006      STR      r0,[sp,#0x18]
        38:                                          a1 = a[0];
        39:   } else {
        40:     for (k = 0; k < 5; k++) {
        41:       b[k] /= a1;
        42:     }
        43:
        44:     for (k = 0; k < 4; k++) {
        45:       a[k + 1] /= a1;
        46:     }
        47:
        48:     a[0] = 1.0;
        49:   }
        50:
    0x00029008 6830      LDR      r0,[r6,#0x00]
    0x0002900A 9006      STR      r0,[sp,#0x18]
        51:   for (k = 0; k < 4; k++) {
    0x0002900C 2400      MOVS     r4,#0x00
    0x0002900E E007      B        0x00029020
        52:     dbuffer[k + 1] = zi[k];
        53:   }
        54:
    0x00029010 00A1      LSLS     r1,r4,#2
    0x00029012 980A      LDR      r0,[sp,#0x28]
    0x00029014 5841      LDR      r1,[r0,r1]
    0x00029016 1C60      ADDS     r0,r4,#1
    0x00029018 0080      LSLS     r0,r0,#2
    0x0002901A AA01      ADD      r2,sp,#0x04
    0x0002901C 5011      STR      r1,[r2,r0]
    0x0002901E 1C64      ADDS     r4,r4,#1
    0x00029020 2C04      CMP      r4,#0x04
    0x00029022 DBF5      BLT      0x00029010
        55:   for (j = 0; j < 424; j++) {
    0x00029024 2500      MOVS     r5,#0x00
    0x00029026 E043      B        0x000290B0
        56:     for (k = 0; k < 4; k++) {
    0x00029028 2400      MOVS     r4,#0x00
    0x0002902A E007      B        0x0002903C
        57:       dbuffer[k] = dbuffer[k + 1];
        58:     }
    0x0002902C 1C60      ADDS     r0,r4,#1
    0x0002902E 0080      LSLS     r0,r0,#2
    0x00029030 A901      ADD      r1,sp,#0x04
    0x00029032 5808      LDR      r0,[r1,r0]
    0x00029034 00A1      LSLS     r1,r4,#2
    0x00029036 AA01      ADD      r2,sp,#0x04
    0x00029038 5050      STR      r0,[r2,r1]
    0x0002903A 1C64      ADDS     r4,r4,#1
    0x0002903C 2C04      CMP      r4,#0x04
    0x0002903E DBF5      BLT      0x0002902C
        59:     dbuffer[4] = 0.0;
    0x00029040 2000      MOVS     r0,#0x00
    0x00029042 9005      STR      r0,[sp,#0x14]
        60:     for (k = 0; k < 5; k++) {
    0x00029044 2400      MOVS     r4,#0x00
    0x00029046 E013      B        0x00029070
        61:       tmpx =   x[j] * b[k];
    0x00029048 00A2      LSLS     r2,r4,#2
    0x0002904A 58B9      LDR      r1,[r7,r2]
    0x0002904C 00AB      LSLS     r3,r5,#2
    0x0002904E 9A09      LDR      r2,[sp,#0x24]
    0x00029050 58D0      LDR      r0,[r2,r3]
    0x00029052 F7EDF976  BL.W     __aeabi_fmul (0x00016342)
    0x00029056 4919      LDR      r1,[pc,#100]  ; @0x000290BC
    0x00029058 6008      STR      r0,[r1,#0x00]
        62:                         dbuffer[k] = dbuffer[k] +tmpx;
        63:
        64:     }
    0x0002905A 00A1      LSLS     r1,r4,#2
    0x0002905C AA01      ADD      r2,sp,#0x04
    0x0002905E 5850      LDR      r0,[r2,r1]
    0x00029060 4916      LDR      r1,[pc,#88]  ; @0x000290BC
    0x00029062 6809      LDR      r1,[r1,#0x00]
    0x00029064 F7EDF914  BL.W     __aeabi_fadd (0x00016290)
    0x00029068 00A1      LSLS     r1,r4,#2
    0x0002906A AA01      ADD      r2,sp,#0x04
    0x0002906C 5050      STR      r0,[r2,r1]
        60:     for (k = 0; k < 5; k++) {
        61:       tmpx =   x[j] * b[k];
        62:                         dbuffer[k] = dbuffer[k] +tmpx;
        63:
        64:     }
    0x0002906E 1C64      ADDS     r4,r4,#1
    0x00029070 2C05      CMP      r4,#0x05
    0x00029072 DBE9      BLT      0x00029048
        65:     for (k = 0; k < 4; k++) {
    0x00029074 2400      MOVS     r4,#0x00
    0x00029076 E014      B        0x000290A2
        66:                         tmpx =   dbuffer[0] * a[k + 1];
    0x00029078 1C62      ADDS     r2,r4,#1
    0x0002907A 0092      LSLS     r2,r2,#2
    0x0002907C 58B1      LDR      r1,[r6,r2]
    0x0002907E 9801      LDR      r0,[sp,#0x04]
    0x00029080 F7EDF95F  BL.W     __aeabi_fmul (0x00016342)
    0x00029084 490D      LDR      r1,[pc,#52]  ; @0x000290BC
    0x00029086 6008      STR      r0,[r1,#0x00]
        67:                         dbuffer[k + 1] = dbuffer[k + 1] - tmpx;
        68:     }
        69:
    0x00029088 1C61      ADDS     r1,r4,#1
    0x0002908A 0089      LSLS     r1,r1,#2
    0x0002908C AA01      ADD      r2,sp,#0x04
    0x0002908E 5850      LDR      r0,[r2,r1]
    0x00029090 490A      LDR      r1,[pc,#40]  ; @0x000290BC
    0x00029092 6809      LDR      r1,[r1,#0x00]
    0x00029094 F7EDF94D  BL.W     __aeabi_fsub (0x00016332)
    0x00029098 1C61      ADDS     r1,r4,#1
    0x0002909A 0089      LSLS     r1,r1,#2
    0x0002909C AA01      ADD      r2,sp,#0x04
    0x0002909E 5050      STR      r0,[r2,r1]
    0x000290A0 1C64      ADDS     r4,r4,#1
    0x000290A2 2C04      CMP      r4,#0x04
    0x000290A4 DBE8      BLT      0x00029078
        70:     y[j] = dbuffer[0];
        71:   }
    0x000290A6 00AA      LSLS     r2,r5,#2
    0x000290A8 9901      LDR      r1,[sp,#0x04]
    0x000290AA 9810      LDR      r0,[sp,#0x40]
    0x000290AC 5081      STR      r1,[r0,r2]
    
    
    
    

    .

    and the whole c function.

    
    void filter(float b[5], float a[5], const float x[424], const float zi[4],
                float y[424])
    {
      float a1;
            float tmp1,tmp2;
      int k;
      float dbuffer[5];
      int j;
      a1 = a[0];
     // if ((!((!rtIsInf(a[0])) && (!rtIsNaN(a[0])))) || (a[0] == 0.0) || (!(a[0] !=1.0)))
            if (1)
            {
                                             a1 = a[0];
      } else {
        for (k = 0; k < 5; k++) {
          b[k] /= a1;
        }
    
        for (k = 0; k < 4; k++) {
          a[k + 1] /= a1;
        }
    
        a[0] = 1.0;
      }
    
      for (k = 0; k < 4; k++) {
        dbuffer[k + 1] = zi[k];
      }
    
      for (j = 0; j < 424; j++) {
        for (k = 0; k < 4; k++) {
          dbuffer[k] = dbuffer[k + 1];
        }
        dbuffer[4] = 0.0;
        for (k = 0; k < 5; k++) {
          tmpx =   x[j] * b[k];//reset here!!!!
                            dbuffer[k] = dbuffer[k] +tmpx;
    
        }
        for (k = 0; k < 4; k++) {
                            tmpx =   dbuffer[0] * a[k + 1];
                            dbuffer[k + 1] = dbuffer[k + 1] - tmpx;
        }
    
        y[j] = dbuffer[0];
      }
    }
    
    
    

    .

    Because it doesn't reset when step into assembly.Which register should I post?
    Thanks again.

  • I would rule out that the floating point code itself causes the reset.

    What about interrupts in your system?
    Did you check for stack overflows?

  • The default stack, in startup_arch.s is usually very small. If you hold your arrays in local/auto variables it's going to break unless you make the stack sufficiently large.

    Does it end up in the Hard Fault Handler?

  • Thank you,Reinhard,I resize the stack size and cut my code to 100 point filter.Then the program runs well.So,it's obviously caused by stack overflow.

  • hi,Westonsupermare,Thank you for reply.It's indeed caused by stack overflow.
    By the way, I'd like to ask another question:How can I know the program ends up in the Hard Fault Handler?

  • If you stop the debugger you could observe where it's stuck, often a while(1) loop.

    You can break-point the handler. You can have the handler output status/diagnostic information on the serial port.