2021-06-28 10:46 AM
I am using STM32CubeIDE v1.6.1 and am seeing some strangeness.
When I call strcat(), I get a hardfault if the end of the string (where the nul is) being catted to is at an odd address?
Here is code from the .list file:
char s1[20];
strcpy(s1, "--");
800ab50: f107 030c add.w r3, r7, #12
800ab54: 4a65 ldr r2, [pc, #404] ; (800acec <sd_cmdproc_process_packet+0x374>)
800ab56: 6812 ldr r2, [r2, #0]
800ab58: 4611 mov r1, r2
800ab5a: 8019 strh r1, [r3, #0]
800ab5c: 3302 adds r3, #2
800ab5e: 0c12 lsrs r2, r2, #16
800ab60: 701a strb r2, [r3, #0]
strcat(s1, "1");
800ab62: f107 030c add.w r3, r7, #12
800ab66: 4618 mov r0, r3
800ab68: f7f5 fbc4 bl 80002f4 <strlen>
800ab6c: 4603 mov r3, r0
800ab6e: 461a mov r2, r3
800ab70: f107 030c add.w r3, r7, #12
800ab74: 4413 add r3, r2
800ab76: 495e ldr r1, [pc, #376] ; (800acf0 <sd_cmdproc_process_packet+0x378>)
800ab78: 461a mov r2, r3
800ab7a: 460b mov r3, r1
800ab7c: 881b ldrh r3, [r3, #0]
800ab7e: 8013 strh r3, [r2, #0]
strcat(s1, "2");
800ab80: f107 030c add.w r3, r7, #12
800ab84: 4618 mov r0, r3
800ab86: f7f5 fbb5 bl 80002f4 <strlen>
800ab8a: 4603 mov r3, r0
800ab8c: 461a mov r2, r3
800ab8e: f107 030c add.w r3, r7, #12
800ab92: 4413 add r3, r2
800ab94: 4957 ldr r1, [pc, #348] ; (800acf4 <sd_cmdproc_process_packet+0x37c>)
800ab96: 461a mov r2, r3
800ab98: 460b mov r3, r1
800ab9a: 881b ldrh r3, [r3, #0]
800ab9c: 8013 strh r3, [r2, #0]
800ab9e: e1c4 b.n 800af2a <sd_cmdproc_process_packet+0x5b2>
}
the strcat of "1" works, but the strcat of "2" hard faults. I suspect it isalignment error with the "strh".
It is also curious that the calls to strcat() (and strcpy()) do not call the actual functions.
I appologize if I have missed something obvious.
Thanks,
mark
2021-06-29 12:08 PM
OK, so I have resolved it.
In tracking down the Hard Fault, the Usage Fault Status Regsiter indicated it was UNALIGNED.
So I disabled trapping of unaligned accesses by setting the UNALIGN_TRP bit in the CCR to 0. Now it does not Hard Fault.
However, WHY does it generate code like this? And using STM32CubeIDE, is there a way to prevent it from generating code like this?
2021-06-29 01:13 PM
AFAIK SCB_CCR.UNALIGN_TRP is 0 by default after reset for Cortex-M7. So you must have enabled it in your code - startup code, library, whatever.
That's also why compilers work with the default assumption that unaligned accesses are mostly OK for the Cortex-M7 - and, IMO, having unaligned accesses is a major relief in most of the cases.
If you insist on having strictly aligned code, you can try gcc's -mno-unaligned-access switch.
JW
2021-06-29 01:42 PM
thank you for the discussion.
This is my first time using an STM32F7 and the first time I have had to delve this deep in an STM32 part. Lots to learn.
My project was started by selecting the STM32F769I-DISCO board from the new project selector and having it generate the .ioc file and code.
If the generated code is setting the SCB_CCR.UNALIGN_TRP bit, I have been unable to find where. I searched the project and didn't find anything.
I set a breakpoint at "Reset_Handler:" in startup_stm32F769nihx.s (thinking that this is where execution will start and the SCB_CCR.UNALIGN_TRP is already set there (inspecting in the SFR tab). So I am not sure how/where that bit gets set.
If the default behavior of STM32CubeIDE is to configure checking for aligned accesses, then why does it generate code that will fault? Does anyone know WHY it generates code like this?
Thanks,
Mark
2021-06-29 02:46 PM
The "compiler" doesn't know what address any given piece of data or code will be assigned, the "linker" often has more control of that, although it's only party to the details given to it.
In the general case unaligned 16 and 32-bit access is safe. The compiler/optimizer tend to assume this as it yields faster/smaller code.
Might want to look at code generation settings for the Cortex-M0 as that is very unforgiving.
Most of the Cortex-Mx give me headaches with unaligned (byte aligned) data structures in files or serial streams, 64-bit word (doubles) being a particular issue. Although this is still less tedious than the old ARM7 and ARM9, and cases where people wanted to port x86 C code