c++ array initialization leads to hardfault

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

c++ array initialization leads to hardfault

1,256 Views
DanU1
Contributor I

I am running on an i.MX RT1052 processor and I'm getting a hardfault that I'm hoping someone can help me with. I have tracked it down to the line of code causing the fault, but I'm still not sure why. I have a function which declares a local three byte char array with an initializer list. It is the initialization that causes the hardfault. The fault occurs consistently when called from one task, but when called from another it does not generate the fault.

My function is as follows:

static MacID ConvertStringToMacID(etl::string_view string)
{
    char temp[3] = {0};   <<< This is the line that generates the fault.
    MacID macID;
    for(uint8_t i = 0; i < 6; ++i)
    {
        memcpy(temp, &string[i * 3], 2);
        temp[2] = 0;
        macID[i] = strtol(temp, 0, 16);
    }
    return macID;
}

The initialization of the char array generates the following code:

6001594a: ldr r3, [pc, #104] ; (0x600159b4 <EthernetUtils::ConvertStringToMacID(etl::basic_string_view<char, etl::char_traits<char> >)+116>)
6001594c: ldrb r3, [r3, #0]
6001594e: strb r3, [r7, #12]
60015950: add.w r3, r7, #13
60015954: movs r2, #0
60015956: strh r2, [r3, #0]

The fault is generated on the strh instruction and the fault is for Unaligned access. In both cases, r3 contains the current SP plus an offset of 13 which is an odd address. It is not aligned on a 2 or 4 byte boundary.

Whether or not unaligned access generates a fault is configurable but it looks to me like the UNALIGN_TRP bit (bit 3 address 0xE000D14) is clear in both the success and failure cases.

Can anyone help me to understand why I would get a fault on one task but not another?

0 Kudos
6 Replies

1,242 Views
jeremyzhou
NXP Employee
NXP Employee

Hi,

Thank you for your interest in NXP Semiconductor products and for the opportunity to serve you.
After having a brief review of your statement, it's not to figure the hardfalut out, so I was wondering if you can share a sample demo that replicates this hardfault case, then I can some testing by myself.
Looking forward to your reply.
Have a great day,
TIC

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos

1,234 Views
DanU1
Contributor I

Unfortunately, I have been unable to reproduce this with a small test case. Here is a summary of what I have found:

  • My processor is MIMXRT1052
  • I am seeing a consistent hard fault on one task, but never when the same code is called from another task.
  • The fault is occurring on a store half word instruction "strh r2, [r3,#0]"
  • The fault is an Unaligned Access fault
  • In both cases (working and fault) the contents of the r3 register is an odd address. So in both cases the destination address being is not aligned on a 2 or 4 byte boundary.

Should this result in an Unaligned Access fault? And any ideas as to why it would work from one task but not another?

0 Kudos

1,225 Views
jeremyzhou
NXP Employee
NXP Employee

Hi,

Thanks for your reply.

I'd like to like to suggest you check the value of BusFault Address Register (BFAR) to find out the exact address requested by the instruction, in further, maybe you can try the approach as indicated in the post: https://mcuoneclipse.com/2012/11/24/debugging-hard-faults-on-arm-cortex-m/ to trace the hardfault.

Have a great day,
TIC

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos

1,216 Views
DanU1
Contributor I

I'm familiar with the link you provided. I have been using that in my analysis. As far as the BFAR - there is no bus fault so the BFAR is 0.

I have a HardFault_Handler installed and I have verified which instruction is causing the fault. I just don't understand why it would be causing an Unaligned Access fault.

0 Kudos

1,204 Views
jeremyzhou
NXP Employee
NXP Employee

Hi,

Thanks for your reply.
Maybe you can try to declare a global variable: temp[3] instead of the original one, in further, the array is located in a non-cache area, just like the below shows.
AT_NONCACHEABLE_SECTION_ALIGN(char temp[3], 16);

Have a great day,
TIC

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos

1,191 Views
DanU1
Contributor I

Yes you are correct that there are things I can do to work around this. If I change the temp array to be 4 bytes instead of 3, the compiler generates one instruction to store a word for the initialization. This does not generate the fault.

But this doesn't solve the problem. I have a three byte array being initialized. The compiler initializes this as follows:

  • store one byte at temp[0]
  • store a half word to initialize temp[1] and temp[2]

The temp array is on an aligned address. So when the compiler generates a store half word at temp[1] it should know that the destination is not aligned.

I suspect this is a compiler bug. An older version of the compiler generates different code. It will store a half word to initialize temp[0] and temp[1] followed by a store byte to initialize temp[2]. This way the store half word is storing to an aligned address.

But that still doesn't explain why I would have an issue when called from one task but not another.

0 Kudos