I was trying to write a register context saving/restoring when I came across a weird behaviour.
My code (sorry, tried to format tens of times, but the editor WANTS to make asm a table):
When the exception is returned from, the calling function:
msg = "returned from SVC\r\n";
serial_io.put_string(msg, util_str_len(msg)+1);
asm volatile (
);
msg = "cpsr = ";
util_word_to_hex(scratchpad, tmp1);
serial_io.put_string(scratchpad, 9);
serial_io.put_string("\r\n", 3);
outputs "returned from SVC" and "cpsr = 60000013".
Why the "00000002"? the barriers don't seem to have any effect.
It can be quite difficult to debug without having a display or a communications channel to a computer.
Remember that you can blink the LEDs.
One blink + long delay means this ...
Two blinks + long delay means that ...
Three blinks + long delay ... etc. ...
If you have more than one LED available, then you can switch between them; or you can blink LED 1 X times, then blink LED 2 Y times, then have a few seconds delay.
Note: I sometimes connect a small Cortex-M to one pin, which I can send data through.
Eg. for instance, if I have a problem on a STM32F427, and I can't use the UART for debugging, I bit-bang the data on a GPIO pin to a STM32F103.
The STM32F103 watches one GPIO pin and when a data-byte is received, it can output it on a connected SPI-display.
-Or it can transmit the data to a computer via the UART.
You can easily receive 16 bits at a time on the GPIO pins with the STM32F103, so it's a great little tool.
Good ideas, but not quite appropriate in my case: I don't know whether the processor's i-mask is somehow set, or the interrupt handling has gone nuts. I might get some sense if I could get a couple of 32-bit values when the problem hits, so LEDs are not very working solution. From the led I know that it at least visited the command interpreter loop, but whether it runs there isolated from the rest of the world or left for better code and left the LED lit, I don't know.
If I add too much led blinking with delays, gdb gets upset and I can't debug. That's why it's hard to use serial for debugging in the first place. The serial seems to work as long as a debuggee that uses interrupts is not started (or hasn't taken the interrupts in the use yet). I once put some serial output in the interrupt handler - the gdb refused to load a program: too much "garbage" instead of ACK.
The other problem is, that I only have one USB/serial cable for RPi (3,3V), and this RPi 2B is my first ARM-board ever. I have one atMega-board, but it's 5V, so better not connect... My other USB/serial cable is for the atMega, it's 5V.
I also don't have a DVI display nor a DVI cable, and writing a graphics driver on top of everything (and as "blindfolded" as now) is a bit heavy thing to do... The same goes with USB-driver.
I guess if I had one more cable, it would be 3,3V - 5V adjustable JTAG.
Summa summarum: Children, don't try this at home!
[EDIT]
Oh, and I forgot - in the command interpreter loop, the first thing is to go and get a command packet...
The program doesn't actually loop...
(It must be this terrible flu - it's participating actively in driving me nuts...)
[/EDIT]
Flu is always terrible.
I know it's not appropriate for this kind of debugging, but if you at some other point needs a 32-bit value and you only have a LED, try this:
repeat(32){ LED(1); delay_ms(200); LED(0); delay_ms(100); LED(value >> 31) &1; value = value << 1; delay_ms(500); LED(0); delay_ms(100); } delay_ms(5000);
This should give you enough time to write the bit values down on a piece of paper.
The quick flashes are there in order to separate the bits visually.
JTAG should not need to be 5V; I think it only needs to be 3.3V, even for 5V devices. It just needs 5V tolerant I/O-pins.
(I prefer JTAG-lock-pick Tiny 2 myself; it's both JTAG and SWD and works very well with all the targets I know; furthermore I think it's compatible with the KEIL tools). Freddie Chopin might be able to tell you more about it.
Your LED idea is clever! Maybe I'll try next time.
I think I'm getting a scent of what's going on. The debuggee interrupt doesn't return where it should.
I guess I have to check my context handling still more carefully - especially the stacks. To avoid overflowing the debuggee's stacks I switch into mine, and then switch back at return.
I copied the breakpoint command and cont command that gdb sends, then I used gdb upto loading the program, disconnected and switched to terminal where I gave the breakpoint command and cont-command manually.
And I finally got to see something...
I got carried away...
Bus Blaster ( Bus Blaster - DP ) could be an option...