There's been some activity around monitor programs lately with a good version by Vanyamba being the most recent. So why another one?
Well AFAIK my monitor is the only one that uses a second Arduino to do all the hard work, so there is very little affect on the Arduino being debugged.
The monitor is divided into two parts, a server and a client.
Server
QUUBmon has a very small server running on the target system, it's about 500 bytes in size and uses no system RAM except about 35 bytes of stack space. Each access to the server is atomic, meaning that all business is done within the ISR. As this normally takes about 100uS I think that's a reasonably small hit on the target program.
The server talks to the other Arduino (the client) via bit banged SPI so it needs three spare pins, but they can be any pins.
The server sits on the watchdog interrupt, an interrupt that is almost never used by Arduinoites as far as I can tell. It could easily be moved to another interrupt though, say a timer and maybe a polled version could be made.
There are two versions of the server software, assembly language and C, but I think C will be the only one supported in future.
Client
The client handles a simple command-line UI via USB to a PC, so all that is needed is a dumb terminal program.
The client is currently able to run on either a 2560- or 328-based Arduino.
Target processors
The software is table-driven so it's easy to add a processor. So far the following are supported (by "support" I mean that the program knows what registers and peripheral devices the processor has and their addresses).
• ATmega2560*
• ATmega328
• ATtiny861
• ATtiny85
• ATtiny84
- When debugging a 2560 or derivative on a 328-based client full mnemonic descriptions of the register bits are not available due to lack of program space to store the strings.
Commands
RD - Read a single byte from the target RAM.
WR - Write a byte to target RAM.
L - Do a HEX dump of 16 bytes (a “line”) from the target RAM.
P - Do a HEX dump of 128 bytes (a “page”) from the target RAM.
REGS - Display the target processors registers (only with an assembly language server)
IO - Display the target processor’s IO registers.
F - Fill target RAM with a value.
SP - Display the target processors stack pointer and the values on the stack.
PER - Display detail about the target processor’s “peripherals”.
WATCH - Periodically sample a memory or IO location on the target processor.
RST - Reset the target processor.
IPC - Find or dump the IPC (Inter Processor Comms) area of RAM on the target system.
SET - Set a variable in the IPC.
DIG - Display all Arduino digital pins on the target system.
AN - Display all Arduino analogue pins the target system.
PIN - Display and control Arduino digital pins.
PC - Display the target processor’s program counter.
INFO - Get information about the target system.
Some examples
QM> DIG
DIG00 PORTE:0 INPUT HIGH
DIG01 PORTE:1 INPUT HIGH
DIG02 PORTE:4 INPUT LOW
DIG03 PORTE:5 INPUT LOW
DIG04 PORTG:5 INPUT LOW
DIG05 PORTE:3 INPUT LOW
DIG06 PORTH:4 INPUT LOW
DIG07 PORTH:3 INPUT LOW
DIG08 PORTH:5 INPUT LOW
DIG09 PORTH:6 INPUT LOW
DIG10 PORTB:4 OUTPUT HIGH
DIG11 PORTB:5 INPUT HIGH
DIG12 PORTB:6 INPUT LOW
DIG13 PORTB:7 OUTPUT LOW
QM> USART
UDR0---->C6-->00 00000000 0:lo 1:lo 2:lo 3:lo 4:lo 5:lo 6:lo 7:lo
UCSR0A-->C0-->62 01100010 0:rxc0 1:TXC0 2:UDRE0 3:fe0 4:dor0 5:upe0 6:U2X0 7:mpcm0
UCSR0B-->C1-->98 10011000 0:RXCIE0 1:txcie0 2:udrie0 3:RXEN0 4:TXEN0 5:ucsz02 6:rxb80 7:txb80
UCSR0C-->C2-->06 00000110 0:umsel01 1:umsel00 2:upm01 3:upm00 4:usbs0 5:UCSZ01 6:UCSZ00 7:ucpol0
UBRR0L-->C4-->10 00010000 0:lo 1:lo 2:lo 3:HI 4:lo 5:lo 6:lo 7:lo
UBRR0H-->C5-->00 ----0000 4:lo 5:lo 6:lo 7:lo
QM> TMR1
GTCCR--->43-->00 0-----00 0:tsm 6:psrasy 7:psrsync
TIMSK1-->6F-->00 --0--000 2:icie1 5:ocie1b 6:ocie1a 7:toie1
TIFR1--->36-->2F --1--111 2:ICF1 5:OCF1B 6:OCF1A 7:TOV1
TCCR1A-->80-->01 0000--01 0:com1a1 1:com1a0 2:com1b1 3:com1b0 6:wgm11 7:WGM10
TCCR1B-->81-->03 00-00011 0:icnc1 1:ices1 3:wgm13 4:wgm12 5:cs12 6:CS11 7:CS10
TCCR1C-->82-->00 00------ 0:foc1a 1:foc1b
TCNT1L-->84-->86 10000110 0:HI 1:lo 2:lo 3:lo 4:lo 5:HI 6:HI 7:lo
TCNT1H-->85-->00 00000000 0:lo 1:lo 2:lo 3:lo 4:lo 5:lo 6:lo 7:lo
OCR1AL-->88-->00 00000000 0:lo 1:lo 2:lo 3:lo 4:lo 5:lo 6:lo 7:lo
OCR1AH-->89-->00 00000000 0:lo 1:lo 2:lo 3:lo 4:lo 5:lo 6:lo 7:lo
OCR1BL-->8A-->00 00000000 0:lo 1:lo 2:lo 3:lo 4:lo 5:lo 6:lo 7:lo
OCR1BH-->8B-->00 00000000 0:lo 1:lo 2:lo 3:lo 4:lo 5:lo 6:lo 7:lo
ICR1L--->86-->00 00000000 0:lo 1:lo 2:lo 3:lo 4:lo 5:lo 6:lo 7:lo
ICR1H--->87-->00 00000000 0:lo 1:lo 2:lo 3:lo 4:lo 5:lo 6:lo 7:lo
QM> PORTB
PINB---->23-->30 00110000 0:lo 1:lo 2:HI 3:HI 4:lo 5:lo 6:lo 7:lo
DDRB---->24-->97 10010111 0:HI 1:lo 2:lo 3:HI 4:lo 5:HI 6:HI 7:HI
PORTB--->25-->10 00010000 0:lo 1:lo 2:lo 3:HI 4:lo 5:lo 6:lo 7:lo
The PER command shows the defined "peripherals" (really a collection of related IO registers), each of these can be used as a command as shown above.
QM> PER
-->PORTB
-->PORTC
-->PORTD
-->TMR0
-->TMR1
-->TMR2
-->SPI
-->USART
-->TWI
-->AC
-->ADC
-->EEPROM
-->MCU
QM> IO
PINB---->23-->30 00110000 0:lo 1:lo 2:HI 3:HI 4:lo 5:lo 6:lo 7:lo
DDRB---->24-->97 10010111 0:HI 1:lo 2:lo 3:HI 4:lo 5:HI 6:HI 7:HI
PORTB--->25-->10 00010000 0:lo 1:lo 2:lo 3:HI 4:lo 5:lo 6:lo 7:lo
PINC---->26-->00 --000000 2:lo 3:lo 4:lo 5:lo 6:lo 7:lo
DDRC---->27-->AA --101010 2:HI 3:lo 4:HI 5:lo 6:HI 7:lo
PORTC--->28-->00 --000000 2:lo 3:lo 4:lo 5:lo 6:lo 7:lo
PIND---->29-->03 00000011 0:lo 1:lo 2:lo 3:lo 4:lo 5:lo 6:HI 7:HI
DDRD---->2A-->00 00000000 0:lo 1:lo 2:lo 3:lo 4:lo 5:lo 6:lo 7:lo
PORTD--->2B-->00 00000000 0:lo 1:lo 2:lo 3:lo 4:lo 5:lo 6:lo 7:lo
TIFR0--->35-->06 -----110 5:OCF0B 6:OCF0A 7:tov0
TIFR1--->36-->2F --1--111 2:ICF1 5:OCF1B 6:OCF1A 7:TOV1
TIFR2--->37-->07 -----111 5:OCF2B 6:OCF2A 7:TOV2
PCIFR--->3B-->00 -----000 5:pcif2 6:pcif1 7:pcif0
list cut for brevity
QM> P 200
00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F
0200: 20 49 50 43 5B 00 00 00 00 02 0A 02 67 65 64 20 IPC[.......ged
0210: 74 6F 20 00 6C 65 64 00 74 42 43 44 45 46 47 48 to .led.tBCDEFGH
0220: 49 4A 4B 4C 4D 4E 4F 50 51 55 52 53 54 56 57 58 IJKLMNOPQURSTVWX
0230: 59 5A 00 2B 01 49 50 43 20 73 63 72 61 74 63 68 YZ.+.IPC scratch
0240: 20 52 41 4D 00 01 00 00 00 00 64 07 4E 08 66 08 RAM......d.N.f.
0250: 02 07 30 07 58 07 16 07 43 1E BD 6D 01 17 32 65 ..0.X...C..m..2e
0260: 01 17 C5 6D 01 11 00 00 00 00 00 00 00 00 00 00 ...m............
0270: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F
I think that's enough for now. If there's any interest I can post more details.
This is currently at about alpha state so not suitable for beginners to play with, but if want to have a look I can clean up and post the code.
Rob