Hello All,
Good Morning!
I am working on Cortex m4.
I have read following about hard fault ,
"Bus Fault: detects memory access errors on instruction fetch, data read/write, interrupt vector fetch, and register stacking (save/restore) on interrupt (entry/exit)
Memory Management Fault: detects memory access violations to regions that are defined in the Memory Management Unit (MPU); for example code execution from a memory region with read/write access only.
Usage Fault: detects execution of undefined instructions, unaligned memory access for load/store multiple. When enabled, divide-by-zero and other unaligned memory accesses are also detected. Hard Fault: is caused by Bus Fault, Memory Management Fault, or Usage Fault if their handler cannot be executed"
Can anyone please explain with examples about Bus, Memory, Usage fault?
Can you please share any good links to read more about them in reference with ARM cortex m4 architecture?
Further, I have following code written in C running on cortex m4,
typedef struct {
uint32_t nodeId;
uint32_t systemId;
int8_t serialNumber[16];
}sysConfig_t;
pktHeader_t pktHeader;
uint8_t data[120];
}packet_t;
void *data; //(this is pointer to array, i don't know exact alignment of this array )
packet_t *pkt = (uint8_t *)data;
sysConfig_t *sysData;
sysData = (sysConfig_t *)pkt->data;
printf(" %d %d ",sysData->nodeId, sysData->systemId);
I am getting Hard fault at printf statement. Why?
Can you please help?
According to me cortex m4 is based on arm v6 which supports handling unaligned addresses.
Can we discuss?
Thanks for reading my post.
Thanks
Hemant Undale.
Thanks yasuhikokoumoto
for reply.
I wish problem would have been such simple.....
However this is not case.....
UART is properly working.....
May be we need comments from expert.
Hi hemantraj2007 ,
I guess the UART for the printf was not be clocked.
Best regards,
Yasuhiko Koumoto.
If you are creating misaligned pointers to structs or double words, then you must use the __packed qualifier in order to ensure that the compiler does not use LDRD and LDM instructions, e.g.:
typedef struct { uint64_t value; } unsafe_t; uint64_t func(unsafe_t *p) { return p->value; // Likely produces LDRD }
will likely fault, whereas:
typedef __packed struct { uint64_t value; } safe_t; uint64_t func(safe_t *p) { return p->value; // Likely produces 2x LDR }
should work.
Cortex-M4 implements the ARMv7-M architecture and does support unaligned transactions (assuming that CCR.UNALIGN_TRP is set to zero).
If the HardFault occurs regardless of what is placed in the printf, e.g. printf("helloworld");, then I suspect the problem you are encountering likely relates to not having ported these functions, or semihosting not being supported by the debugger.
hth
Simon.
Hello Simon,
thank you for your information.
It is very helpful for me (I am not the original poster).
At GCC, to add 'packed' attribute to the struct is "__attribute__((__packed__))".
Therefore
typedef __packed struct { uint64_t value; } safe_t;
should be the following.
typedef struct { uint64_t value; } __attribute__((__packed__)) safe_t;
This is just F.Y.I.
Also I verified your statement by the next code.
typedef struct { uint64_t value; } unsafe_t; uint64_t func1(unsafe_t *p) { return p->value; // Likely produces LDRD } typedef struct { uint64_t value; } __attribute__((__packed__)) safe_t; uint64_t func2(safe_t *p) { return p->value; // Likely produces 2x LDR }
The generated source code is below.
func1: ldrd r0, [r0] bx lr func2: mov r3, r0 ldr r0, [r0] @ unaligned ldr r1, [r3, #4] @ unaligned bx lr
Simon Craske
and yasuhikokoumoto
Thanks both of you for nicely post.
For your information, there is an application note on Keil website which you might find useful.
Application Note 209: Using Cortex-M3 and Cortex-M4 Fault Exceptions
This application note shows you various information you can obtain from the Cortex-M4 processor's fault status registers,
which can help you to locate the source of the fault quicker.
I'd like to add a minor contribution to the other answers; it's about debugging in smaller steps.
I suggest that above your existing printf, place the following line:
printf(" [0x%08x] ",sysData); fflush(stdout);
-So you will know what the actual value of sysData is, before you try to print the contents.
This will help you becoming sure of why the error happens.
Note: The fflush(stdout); is necessary, because the "\n" is omitted; however, it's sometimes a good idea to have the fflush(stdout); present, so you are sure that you get the complete debug output, before the execution continues.
Now, when you see the output in the square brackets, make sure the address is divisible by 4 (at least). If it's not divisible by 4, you have an alignment error.
Also, check that the address is within the RAM section (or Flash section); eg. the address should most likely start with 0x200..... - sometimes 0x100.....; depending on the memory configuration for that MCU.
If the address is outside the addressable space (see your MCU's datasheet), then the pointer is incorrect.
If the address is within the allowed address space, and it's divisible by 4, but not divisible by 8, then you're probably facing a LDRD problem as mentioned by sim.
Remember these five main debugging rules:
(Hmm, I don't know if I reproduced them exactly as I was taught, but they're probably close enough to be useful).