-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cpu/cortexm_common: additional information on hardfault #3333
Conversation
( | ||
"movs r0, #4 \n" /* r0 = 0x4 */ | ||
"mov r1, lr \n" /* r1 = lr */ | ||
"tst r1, r0 \n" /* if(lr & 0x4) */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tst lr, #4
should be enough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not for Cortex M0(+), because tst
requires 2 Lo-Registers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, I guess the ite eq
instruction is missing as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exactly.
Am 8. Juli 2015 11:10:40 MESZ, schrieb Joakim Gebart notifications@github.com:
- volatile unsigned int r2;
- volatile unsigned int r3;
- volatile unsigned int r12;
- volatile unsigned int lr; /* Link register. */
- volatile unsigned int pc; /* Program counter. */
- volatile unsigned int psr;/* Program status register. */
- /* Stackpointer of exception stackframe */
- uint32_t* sp;
- /* Get stackpointer where exception stackframe lies and store in
sp */- __ASM volatile
- (
*/"movs r0, #4 \n" /\* r0 = 0x4
*/"mov r1, lr \n" /\* r1 = lr
*/"tst r1, r0 \n" /\* if(lr & 0x4)
I see, I guess the
ite eq
instruction is missing as well?
Reply to this email directly or view it on GitHub:
https://github.com/RIOT-OS/RIOT/pull/3333/files#r34128870
regarding the trampoline function, see https://github.com/eistec/contiki/blob/mulle-master/cpu/arm/k60/interrupt-vector-k60.c#L295 and https://github.com/eistec/contiki/blob/mulle-master/cpu/arm/k60/fault-handlers.c#L28 for a small example. The hardfault handler example in the links above is taken slightly modified from the excellent book The Definitive Guide to ARM® Cortex®-M3 and Cortex®-M4 Processors |
To get this even more robust it might be wise to check the value of the stack pointer before calling the C handler, and if it is not valid (e.g. outside of RAM), set it to the reset value ( |
I like that! |
I needed to introduce new variables in the common linker script to get the RAM bounds. There was no other way to get this information, wasn't it? |
@daniel-k I think it is probably necessary to modify the linker scripts unless you are going to rely on assumptions about the ordering of sections etc. Will you update this PR with those changes? |
What do you mean? I already modified the linker script etc. see daniel-k@3563455 |
Sorry, I accidentally commented inside the commit instead of in the change list. |
This is where the unification of our Cortex-M platform code pays off! |
Absolutely! :-) |
@daniel-k |
psp shouldn't matter since in ISR context we will be using msp for stacking |
@gebart |
Regarding the clobber registers: now that there are inputs to the asm block, they get loaded to r2-r4 by the compiler before executing the inline assembly. I guess when not specifying them, the compiler might load the variables to r0-r2. But didn't test that. |
I like this solution. |
ACK |
please squash |
I opened daniel-k#1 for kinetis_common support. Tested on k60. |
puts("\nContext before hardfault:"); | ||
|
||
/* TODO: printf in ISR context might be a bad idea */ | ||
printf("r0: 0x%x\nr2: 0x%x\nr3: 0x%x\nr3: 0x%x\n", r0, r1, r2, r3); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
r3 twice and r1 missing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
split the string into multiple lines like:
printf("r0: 0x%x\n"
"r1: 0x%x\n"
"r2: 0x%x\n"
"r3: 0x%x\n",
r0, r1, r2, r3);
it would be useful to have all other registers saved to the stack before printing so that we can get a complete image of the register state |
... but let's make the improvements as follow-up PRs. ACK as soon as the printf format is fixed and the kinetis_common ldscript is updated. |
@gebart |
ACK |
nack. I do like the idea of this PR, but I am strongly opposing to compile this in per default. I would actually opt for putting this code in |
@haukepetersen |
@haukepetersen I can concede to enable this on |
I have a follow up to this PR in the pipe on my side which will introduce some additional help to further investigate the source of the fault when running with a debugger attached. |
I guess we really need to rediscuss DEVELHELP at the next dev meeting. I'd also not want to have this compiled in by default... |
DEVELHELP is fine for me (and IMHO this is exactly the stuff that I would expect to be activated when DEVELHELP is active) |
ACK, please squash. |
wait with the merge until after the dev meeting |
caeb7aa
to
32aac8d
Compare
Squashed |
So, what is the status on this? Can it be merged? |
I don't know about the outcomes of the dev meeting. As far as there are no objections about wrapping it with DEVELHELP I guess this can be merged now. I'm busy until next week, but if you want to merge it already, go for it :) |
I wasn't in the dev meeting either, but I was proposed @kushalsingh007 to use this PR for debugging hard faults on arduino-due. When I looked it up, I saw that this PR was ACK'd but postponed, so I was just wondering. @gebart do you know anything? |
I missed the greater part of the meeting because of scheduling conflicts, but from what I gathered at the end of the session was that this would be OK inside DEVELHELP. @kaspar030, @OlegHahm or @haukepetersen may have more information. |
@daniel-k you should add your name to the top of the file with |
32aac8d
to
dabaf82
Compare
dabaf82
to
7a86344
Compare
@gebart Done. And also rebased. Should we merge directly? |
Yes, @gebart is right. Inside DEVELHELP it's fine. Go ahead! |
What about the failed xtimer tests with strider? Known issue and safe to merge? |
cpu/cortexm_common: additional information on hardfault
Strider is just there to test Strider, as long as it isn't working properly we can safely ignore it :-). |
And xtimer test is not even merged, so you were probably looking at the wrong build. |
I was so annoyed by debugging hardfaults on my platform (cortex m0+) that I added some helper for much nicer debugging. My problem always was that when the cpu goes to hardfault, I couldn't figure out where the error happened because the backtace in GDB didn't work.
This PR outputs additional information before calling
core_panic(...)
. The most useful is the value of the program counter when the exception was raised. I don't know if you want to merge this, but I wanted to share at least.When debugging with GDB use like this:
Now GDB resets the cpu and stops at the instruction that caused the hardfault in the first place.
Concerning the broken backtrace in case someone is interested (and for documentary purposes for myself):
The Cortex M* architecture has 2 running modes, Thread mode and Handler mode. Both have their own stack (registers
psp
= Process sp andmsp
= Main sp). Depending on the mode the cpu is in, the given stackpointer is aliased assp
.RIOT runs the reset handler and every interrupt in Handler mode (maybe also parts of the scheduling, not sure), whereas each thread runs in Thread mode. That's why backtrace from inside a hardfault doesn't work.
Additionally, given that ISRs run in Handler mode, this is why doing crazy stuff inside a ISR leads to problems, because the main stack is not very large.