Benutzer:Rdiez/ArduinoDue: Unterschied zwischen den Versionen
Rdiez (Diskussion | Beiträge) (No Ethernet PHY) |
Rdiez (Diskussion | Beiträge) (Several small fixes and improvements.) |
||
Zeile 29: | Zeile 29: | ||
** No floating point support. | ** No floating point support. | ||
* 84 MHz clock frequency. | * 84 MHz clock frequency. | ||
− | * 2 x 256 | + | * 2 x 256 KiB Flash. |
− | * 64 + 32 | + | * 64 + 32 KiB RAM. |
* The "native" USB port and can do High Speed USB 2.0 (480 Mbit/s). | * The "native" USB port and can do High Speed USB 2.0 (480 Mbit/s). | ||
* JTAG port | * JTAG port | ||
Zeile 184: | Zeile 184: | ||
Leading bit: 1 # Always set to 1 according to the IEEE standard 1149.1 | Leading bit: 1 # Always set to 1 according to the IEEE standard 1149.1 | ||
− | Note that, if you connect the JTAG_RST signal and you JTAG probe holds it | + | Note that, if you connect the JTAG_RST signal and you JTAG probe actively holds it high most of the time, the ATmega16U2 AVR microcontroller may no longer be able to trigger a reset when you connect to the 'Programming' USB serial port. |
+ | |||
+ | I read in OpenOCD's source file ''tcl/target/at91sam3XXX.cfg'' that the maximum JTAG speed for this kind of chip is F_CPU/6. | ||
+ | If the CPU is running at the normal speed of 84 MHz, the maximum JTAG clock would be 14 MHz then. | ||
+ | |||
+ | The firmware must not use instruction WFE (Wait For Event), as this stops the CPU clock and breaks the JTAG connection. | ||
If you abruptly disconnect the JTAG cable, you may leave breakpoints behind that, when triggered, will forever freeze the CPU. The JTAG logic on the CPUs does not normally detect the loss of the JTAG debugger, so always disconnect gracefully or reset the device after debugging. | If you abruptly disconnect the JTAG cable, you may leave breakpoints behind that, when triggered, will forever freeze the CPU. The JTAG logic on the CPUs does not normally detect the loss of the JTAG debugger, so always disconnect gracefully or reset the device after debugging. | ||
Zeile 208: | Zeile 213: | ||
It may be possible to trigger a RSTC PROCRST from GDB or OpenOCD in order to reset the core and stop at the first instruction. Another way to stop the CPU right after a CPU reset could be flag C_SNAPSTALL in the "Debug Halting Control and Status" register at address 0xE000EDF0, but I haven't had time to check it out yet, please [[Benutzer:rdiez|drop me a line]] if you do. | It may be possible to trigger a RSTC PROCRST from GDB or OpenOCD in order to reset the core and stop at the first instruction. Another way to stop the CPU right after a CPU reset could be flag C_SNAPSTALL in the "Debug Halting Control and Status" register at address 0xE000EDF0, but I haven't had time to check it out yet, please [[Benutzer:rdiez|drop me a line]] if you do. | ||
− | A good workaround is to add an initial delay in the firmware before it actually starts playing with the hardware, as the wrong I/O or system clock configuration could render the JTAG interface unusable. This way, there is a window of opportunity for a JTAG debugger to take control after a hardware reset, and you can debug most of the start-up sequence properly. The downside is that the boot process always takes a little longer, even if you are not debugging it. | + | A good workaround is to add an initial delay in the firmware before it actually starts playing with the hardware, as the wrong I/O or system clock configuration could render the JTAG interface unusable. This way, there is a window of opportunity for a JTAG debugger to take control after a hardware reset, and you can debug most of the start-up sequence properly. The downside is that the boot process always takes a little longer, even if you are not debugging it. The SAM3X starts at 4 MHz upon reset, so it is probably a good idea to ramp the clock up before the initial delay, |
+ | so that you can use a fast JTAG clock right from the start. | ||
== OpenOCD Reset Issues == | == OpenOCD Reset Issues == | ||
Zeile 247: | Zeile 253: | ||
It is best to create separate configuration files for the JTAG adapter and for the Arduino Due board, so the OpenOCD command-line arguments look like this: | It is best to create separate configuration files for the JTAG adapter and for the Arduino Due board, so the OpenOCD command-line arguments look like this: | ||
− | openocd -f your-jtag-adapter.cfg -f target/ | + | openocd -f your-jtag-adapter.cfg -f target/at91sam3ax_8x.cfg -f arduino-due.cfg |
− | Configuration file ''target/ | + | Configuration file ''target/at91sam3ax_8x.cfg'' comes with OpenOCD version 0.8.0, so it should be able to find it automatically. |
+ | For older OpenOCD versions use file ''at91sam3XXX.cfg'' instead. | ||
== Connecting with a Bus Pirate v3.5 == | == Connecting with a Bus Pirate v3.5 == | ||
Zeile 255: | Zeile 262: | ||
=== Caveats === | === Caveats === | ||
− | The [http://dangerousprototypes.com/docs/Bus_Pirate Bus Pirate] is very slow as a JTAG adapter, you should expect speeds under 1 | + | The [http://dangerousprototypes.com/docs/Bus_Pirate Bus Pirate] is very slow as a JTAG adapter, you should expect speeds under 1 KiB/s when downloading new firmware to the Arduino Due. If you manually patch OpenOCD version 0.8.0 so that setting "buspirate_speed fast" works, you can expect transfer rates of 8 KiB/s. |
Firmware version v6.1 (current as of feb 2013) has a bug that might make you physically disconnect the USB cable often. | Firmware version v6.1 (current as of feb 2013) has a bug that might make you physically disconnect the USB cable often. | ||
Zeile 266: | Zeile 273: | ||
I was surprised that just connecting the JTAG adapter powers the Bus Pirate, or at least the PWR LED turns on. Although it must be some partial current leakage, because connecting the USB cable makes the PWR LED shine brighter. The trouble is, that low current seems to be enough to keep the PIC running. Therefore, if you need to disconnect the Bus Pirate USB cable due to the bug described above, you will have to disconnect either the Arduino Due USB cable or the JTAG cable too. | I was surprised that just connecting the JTAG adapter powers the Bus Pirate, or at least the PWR LED turns on. Although it must be some partial current leakage, because connecting the USB cable makes the PWR LED shine brighter. The trouble is, that low current seems to be enough to keep the PIC running. Therefore, if you need to disconnect the Bus Pirate USB cable due to the bug described above, you will have to disconnect either the Arduino Due USB cable or the JTAG cable too. | ||
− | OpenOCD cannot slow down the Bus Pirate's JTAG clock, which always runs at a fixed rate. | + | The Bus Pirate firmware normally has the JTAG clock speed feature disabled, and the OpenOCD driver lacks the necessary support for it, |
+ | therefore the OpenOCD cannot slow down the Bus Pirate's JTAG clock, which always runs at a fixed rate of around 750 Kbit/s. | ||
+ | This fixed clock rate only becomes an issue if the SAM3X switches to its internal 32 KHz oscillator, which may happen if your SAM3X firmware enters some power-saving mode. You should avoid switching the SAM3X clock to a low frequency in your Arduino Due firmware if you plan to debug it over JTAG with the Bus Pirate. | ||
=== Configuration File === | === Configuration File === | ||
Zeile 276: | Zeile 285: | ||
buspirate_port /dev/buspirate | buspirate_port /dev/buspirate | ||
− | # | + | # In order for the 'fast' setting to work you will probably need to manually patch OpenOCD (as of version 0.8.0). |
buspirate_speed normal # 'normal' or 'fast'. | buspirate_speed normal # 'normal' or 'fast'. | ||
Zeile 553: | Zeile 562: | ||
= Memory Map = | = Memory Map = | ||
− | 0x0008 0000 - | + | 0x0008 0000 - 0x000B FFFF 256 KiB flash bank 0 |
− | 0x2000 0000 - 0x2000 FFFF 64 | + | 0x000C 0000 - 0x000F FFFF 256 KiB flash bank 1 |
− | 0x2007 0000 - 0x2007 FFFF 64 | + | Both banks above provide 512 KiB of contiguous flash memory |
− | 0x2008 0000 - 0x2008 7FFF 32 | + | 0x2000 0000 - 0x2000 FFFF 64 KiB SRAM0 |
+ | 0x2007 0000 - 0x2007 FFFF 64 KiB mirrored SRAM0, so that it's consecutive with SRAM1 | ||
+ | 0x2008 0000 - 0x2008 7FFF 32 KiB SRAM1 | ||
0x2010 0000 - 0x2010 107F 4224 bytes of NAND flash controller buffer | 0x2010 0000 - 0x2010 107F 4224 bytes of NAND flash controller buffer | ||
Version vom 6. Juni 2013, 19:43 Uhr
Dies sind die persönlichen Benutzerseiten von rdiez, bitte nicht verändern! Ausnahmen sind nur einfache Sprachkorrekturen wie Tippfehler, falsche Präpositionen oder Ähnliches. Alles andere bitte nur dem Benutzer melden! |
Inhaltsverzeichnis
Why the Arduino Due
This was my selection criteria:
- Popular platform, well supported, reasonably priced.
- Open-source hardware.
Hopefully this will lead to lower prices and longer availability. - 32-bit CPU with good toolchain support.
After having some negative experiences with GCC's PowerPC and AVR support, which are supposed to be stable after so many years of widespread usage, the ARM port looks much more polished. - High Speed (480 Mbps) USB tranfers (effective throughput up to 35 MB/s or 280 Mbit/s).
This is about time, the USB 2.0 spec was released in April 2000 (!).
Most ARM microcontrollers support only the 11 Mbit/s mode (as of 2013).
Other candidates:
- The Beagle Bone was mostly sold out at the time.
- The Raspeberry Pi is designed to act as an USB Host, and not as an USB Device.
Specs
The Arduino Due has a 144-pin AT91SAM3X8E microcontroller with the following features:
- ARM Cortex-M3 core:
- Implements the ARMv7-M architecture, which is a 32-bit architecture.
- Supports all of the base Thumb-2 instruction set, where instructions can be 16-bit or 32-bit long.
- Supports only Thumb-2, does not support the original 32-bit ARM instruction set.
- Hardware multiplication and division.
- Memory Protection Unit with 8 regions.
- Limited support for unaligned memory accesses.
- Choice of several modes with different privilege levels (user, supervisor...).
- Support for single-bit atomic operations with (bit-banding)
- No floating point support.
- 84 MHz clock frequency.
- 2 x 256 KiB Flash.
- 64 + 32 KiB RAM.
- The "native" USB port and can do High Speed USB 2.0 (480 Mbit/s).
- JTAG port
Inadequate as a Learning and Hacking Platform
The Arduino Due is surprisingly inadequate as a learning and hacking platform:
- The board comes with no "Getting Started" information whatsoever.
The only piece of paper in the package sports some marketing blurb and tries to justify the price with statement "The people who made your board were reasonably paid". It should at least mention that you may want to load the blinking demo sketch, in order to check if the board is minimally working. - It is relatively expensive compared to more powerful platforms like the Rasperry Pi, the Beagle Bone and many of the microcontroller evaluation boards.
Due to the low availability 4 months after release date I ended up paying 59 € for it, and that hurts if you manage to fry it during your experiments. - The development environment has no integrated debugger (!).
- Launching a program, however small, takes a few seconds.
That is quite a long time for such a modern board, it goes on your nerves. Maybe it is due to the beta development environment version 1.5.2 I tested, but why is it still beta? The release date was 22nd October 2012, more than 4 months ago. - It can only interface at 3.3 V level.
The Bus Pirate v3.5 has a CD4066B analog switch that uses an external reference voltage.
There are warnings all over the place that you can damage the board with a 5 V level, but why is there no protection circuitry? For hackers and learners such a safety feature would be a welcomed addition. How about some integrated 5 V capability too? With a small CPLD or FPGA you could probably choose your voltage level on a pin basis. - The board has a single user LED and no user buttons whatsoever, let alone any kind of display or sound ability.
You need extra hardware for the most simple of tests. - There is no Ethernet connector, even though the microcontroller does support it. What is worse, there is no way to manually add an Ethernet PHY, because the right pins are simply not accessible.
- Serious hackers will need a JTAG-based hardware debugger, which costs at least 50 €.
There are some cheap USB-Blaster clones for 10 € in Ebay, but I haven't been able to make mine work properly yet.
The Arduino designers added a separate 8-bit AVR CPU in order to update the main microcontroller firmware over the "programming" USB port. What a complete waste of time! They could have added some existing JTAG-over-USB chip, or they could have made one themselves by connecting that little AVR to the JTAG wires. - The JTAG header is smaller than usual, it has a 1.27 mm pitch (Samtec 0.05" micro header) instead of the normal 2.54 mm (0.1").
Most hackers will have to pay extra for an adapter like Olimex' ARM-JTAG-20-10. If you have an Atmel JTAGICE3, look for an adapter in the box. - You'll probably need buy extra USB cables too.
The board has 2 USB ports, the "native" USB socket is of type Micro-A, and the "programming" one is of type Micro-B. It may be my bad luck, but all devices I use have the Mini-B connector (Bus Pirate, USB-Blaster, AVR JTAGICE3, Wind River probe...), so I didn't have the right cable at hand. Of course there isn't one in the Arduino Due box either. Wasn't USB supposed to be standard? Apparently, there is a type of USB cable that fits in both Micro-A and Micro-B connectors, but the documentation offers no advice about this either. I wonder why there are 2 types of Micro USB connectors then, it's just confusing. To top it all, both sockets have such a tight grip that I worry they will break or wear out soon if I need to plug and unplug USB cables often. - The supplied software library is of low quality and is poorly documented too.
There is no provision for proper data communications between the host and the Arduino Due, the environment can only display console text. There are also nasty surprises, like the 128-byte (actually 127) buffer for outgoing serial communications over USB. There is no way to tell whether there is space left in the buffer before sending data (there is no flow control), so you may end up losing bytes without warning. - Linux issues:
- The Linux installation instructions are not together in a single page.
- If the Arduino environment does not detect any suitable port, all ports options are greyed out with not further explanation.
Also, after selecting the Arduino Due in the Tools/Board menu, it was not clear which option to select under Tools/Programmer. - It was not clear that the reason why your account may need "dialout" privileges is because /dev/ttyACM0 belongs to that group. One web page stated "No driver installation is necessary for Linux.", but fails to mention that you will probably need to configure things manually. I tried the suggested "sudo usermod", but it took me a while to realise that this change does not take place immediately. You probably don't have to restart the PC, but that is what I tried, and it did the trick.
- There is no Ubuntu or Debian package that remembers where it came from and updates itself automatically, like Jitsi or VirtualBox do.
- Atmel (the CPU manufacturer) offers little Linux support and tends to keep JTAG debugging documentation secret.
Reset Handling
SAM3X Reset
The SAM3X performs a reset in the following situations:
- Power-up.
- The user presses the RESET button.
This asserts the MASTER-RESET signal, which also goes to the RESET pin next to the 3.3V and 5V reference voltage pins.
Note that this does NOT reset the ATmega16U2 AVR microcontroller, so that the 'Programming' USB connection is not affected. - The ATmega16U2 presses the RESET button (virtually) every time you connect to the 'Programming' USB serial port.
Under Linux, setting the port speed with command "stty -F /dev/ttyACM0 115200" is enough to trigger the reset. Note that the 1200 bps speed triggers an 'erase' procedure, see below. - A JTAG debugger can assert the JTAG_RESET signal, which is connected to MASTER-RESET too.
- The firmware can request a reset with NVIC SYSRESETREQ, RSTC PROCRST and the like.
On reset, the SAM3X CPU looks at flag GPNVM1:
- If GPNVM1 is 0, the CPU runs the built-in SAM-BA bootloader.
- If GPNVM1 is 1, the CPU runs the user's firmware from flash memory.
Last Resort Rescue Button
In order to avoid 'bricking' the SAM3X CPU by flashing a defective firmware, there is an ERASE pushbutton on the board, which deletes the whole flash memory and clears the GPNVM1 bit. Note that you need to hold the button for at least 220 ms (see the AT91SAM3X8E datasheet).
Such a "last resort" hardware solution is necessary for the following reasons:
- You may not have a JTAG probe at hand.
- The firmware may disable the JTAG interface in order get more standard I/O pins, or reconfigure it as a Serial Wire debug interface.
- The firmware may switch to the internal 32 KHz oscillator, or may keep changing the system clock in a tight loop. Depending on your JTAG probe, this might hinder the JTAG connection.
The small ATmega16U2 AVR microcontroller on the Arduino Due also presses the ERASE button (virtually) when you configure the serial interface over the 'Programming' USB port to 1200 bps, see below for more information.
Note that the user firmware can reconfigure the ERASE / PC0 pin as a general-purpose I/O. I did not want to risk my board, so I am not sure if you could rescue it afterwards by say holding down the RESET and ERASE buttons at the same time. Therefore, you should generally avoid reconfiguring PC0 in order to prevent confusion (at least). If worse comes to worst, you may find some pointers in section "Entering Programming Mode" on the AT91SAM3X8E datasheet.
SAM-BA Bootloader
On start-up, the built-in SAM-BA bootloader performs some minimal SAM3X configuration (like setting the system clock) and waits for a serial connection over the first UART interface or over USB, whichever comes first.
Note that the SAM-BA bootloader resides in an internal ROM and cannot be modified. Its code is secret, as it implements the firmware security feature, and cannot be seen or stepped through with a JTAG debugger.
USB Ports
The SAM3X's first UART interface (RX is PA8, TX is PA9) is connected to the ATmega16U2 AVR microcontroller, which acts as a USB-to-serial converter. The corresponding USB port is labelled as "PROGRAMMING" on the board's backside. The serial port connection parameters do matter, always use 115200 8N1 when connecting to SAM-BA. If you set the serial port speed to 1200 bps, the ATmega16U2 will trigger an ERASE procedure on the SAM3X. Under Linux, you can achieve that with command "stty -F /dev/ttyACM0 1200". Note that connecting at 1200 bps with 'picocom' does not seem to trigger the ERASE, but conneting with 'minicom' does (?).
The SAM3X's USB port is labelled as "NATIVE". The serial port connection parameters do not actually matter for this port, as transfers are always performed at the maximum USB speed available. However, if your firmware uses the standard Arduino libraries, configuring the 'Native' serial port to a speed of 1200 bps will trigger an ERASE procedure. You cannot rely on this method in real life, for it will no longer work if your firmware crashes or freezes.
The above means that you can talk to the SAM-BA bootloader on any of the 2 USB ports on the Arduino Due. Having 2 such ports does not actually make a lot of sense, see section "Inadequate as a Learning and Hacking Platform" above for more information. The 'Programming' USB port is more convenient if your firmware uses it as a logging console, because its associated serial port does not close when you manually reset the SAM3X CPU with the RESET button. Keep in mind that just connecting to that serial port will trigger an initial reset. The 'Native' USB port is faster, but, unless your firmware waits for a USB connection on start-up (for example, with "while (!SerialUSB);"), you will lose the first log messages, because the serial port will close on reset and you will have to reconnect after the firmware is already running.
The SAM-BA Protocol
The bootloader understands a very simple procotol with a few commands to read from and write to memory addresses. Atmel supplies a GUI tool that understands this protocol, and the Arduino environment comes with an open-source, command-line tool called 'bossac' to that effect.
In order to test the SAM-BA communication, press the ERASE button on the board for at least 220 ms, connect to one of the USB ports and issue the following command:
bossac --port=ttyACM0 --info
On my Arduino Due, I get the following information:
Device : ATSAM3X8 Chip ID : 285e0a60 Version : v1.1 Dec 15 2010 19:25:04 Address : 524288 Pages : 2048 Page Size : 256 bytes Total Size : 512KB Planes : 2 Lock Regions : 32 Locked : none Security : false Boot Flash : false
You can actually type SAM-BA commands manually. For example:
picocom -b 115200 -p n -d 8 /dev/ttyACM0 # Type 'T' (in uppercase) and then '#' to enter Terminal Mode. # Type 'V (in uppercase) and then '#' to display version information. # Type Ctrl+A, Ctrl+X in oder to exit picocom.
On my Arduino Due, the version information displayed with this method is:
v1.1 Dec 15 2010 19:25:04
Firmware Update
Downloading with the Arduino environment
This is what happens when you click on the "Upload" button in the Arduino environment:
- The 'Programming' USB port gets opened with a speed of 1200 bps, which makes the ATmega16U2 trigger an 'erase' procedure on the SAM3X. The SAM3X boots then into SAM-BA and waits.
- The 'bossac' tool connects to SAM-BA over the ATmega16U2 with a speed of 115200 bps and performs the following steps:
- Erase the entire flash (unnecessary after the 'erase' procedure above, but it's very quick).
- Write the flash contents with the new firmware.
- Verify the flash contents (which is optional).
- Set the GPNVM1 bit to 1, so that the new firmware will boot upon reset (instead of the SAM-BA bootloader).
- Reset the SAM3X. The new firmware should start now.
With version 1.5.2 of the Arduino environment, you can only download the firmware over the 'Programming' USB interface. If you try to use the 'Native' USB port, you get a "No device found on ttyACM0" error message. However, you can then copy the 'bossac' command line from the build output window, remove the '-U false' argument, and run it on a command console, and then it works. It's also much faster than the 'Programming' USB port.
Downloading over JTAG
You can download new firmware to the SAM3X over JTAG with GDB and OpenOCD, just use GDB's 'load' command. GDB sets the $pc to the entry point, so just type 'continue' afterwards in order to start the new firmware. See below for more information about debugging over JTAG.
GDB understands the ELF file format and flattens it automatically upon firmware upload, but you probably want to generate a "bin" file as part of the standard makefile in order to be able to flash the board later on with the 'bossac' tool. Otherwise, you will have to connect the JTAG adapter every time you want to update the firmware.
How to Set the GPNVM1 bit
If you want the firmware to automatically run after a reset, you'll have to set the GPNVM1 bit to 1, see above for more information. There are several ways to do that:
- You can set the GPNVM bits with command "at91sam3 gpnvm" in OpenOCD.
Run the 'bossac' tool with the '-d' argument in order to see the memory write sequence needed to set that bit from other environments. - If you are connected with the 'Programming' USB interface, or you are connected with the 'Native' USB interface but your are using the Arduino libraries and the firmware works, or SAM-BA is already running:
- You can download your firmware with bossac, if you have generated the corresponding .bin file. Just append "--boot=1" to bossac the command line.
- You can download some example sketch with the Arduino environment. You will have to download your firmware over JTAG again.
- You can issue commands "stty -F /dev/ttyACM0 1200" and "bossac --port=ttyACM0 --boot=1".
You will have to download your firmware over JTAG again, or the CPU will attempt to run the just-erased firmware upon reset.
- Otherwise, use the manual, fail-safe method:
- Hold the ERASE button for at least 220 ms.
- Press the RESET button, in case the SAM3X is running the just-erased firmware.
- Connect to any of the USB ports and issue command "bossac --port=ttyACM0 --boot=1".
You will have to download your firmware over JTAG again, or the CPU will attempt to run the just-erased firmware upon reset.
Debugging over JTAG
Connecting over JTAG
When connected to the Arduino Due, OpenOCD discovers a JTAG IDCODE of 0x4BA00477. The JTAG Instruction Register has a length of 4 bits.
The IDCODE breakdown, using my script to decode JTAG IDCODEs, is as follows:
Decoding of JTAG IDCODE 0x4BA00477 (1268778103, 0b01001011101000000000010001110111): Version: 0b0100 (0x4, 4) Part number: 0b1011101000000000 (0xBA00, 47616) Manufacturer: 0b01000111011 (0x23B, 571) # Name: ARM Ltd. Leading bit: 1 # Always set to 1 according to the IEEE standard 1149.1
Note that, if you connect the JTAG_RST signal and you JTAG probe actively holds it high most of the time, the ATmega16U2 AVR microcontroller may no longer be able to trigger a reset when you connect to the 'Programming' USB serial port.
I read in OpenOCD's source file tcl/target/at91sam3XXX.cfg that the maximum JTAG speed for this kind of chip is F_CPU/6. If the CPU is running at the normal speed of 84 MHz, the maximum JTAG clock would be 14 MHz then.
The firmware must not use instruction WFE (Wait For Event), as this stops the CPU clock and breaks the JTAG connection.
If you abruptly disconnect the JTAG cable, you may leave breakpoints behind that, when triggered, will forever freeze the CPU. The JTAG logic on the CPUs does not normally detect the loss of the JTAG debugger, so always disconnect gracefully or reset the device after debugging.
Debugging from the start
Getting the initialisation code right in your firmware is often hard, so the capability to debug the start-up code out of a core reset can save a lot of time and frustration. It is also important that the system behaves exactly the same under the debugger as in real life, otherwise you may never be able to reproduce and debug a problem when connected with a JTAG probe. Unfortunately, the SAM3X controller on the Arduino Due falls short precisely in these areas, like many other microcontrollers I know.
Say you make your JTAG adapter toggle the JTAG_SRST signal as part of a "reset halt" command. This signal is connected to the MASTER-RESET signal on the board and to the SAM3X's NRSTB pin, and I have found out empirically that no JTAG communication can take place while that pin remains asserted, it looks like the JTAG logic gets reset too (but this is not clearly documented). When the reset is deasserted, the CPU immediately starts running the user firmware. However, it takes some time for OpenOCD to reconnect over JTAG and issue a CPU halt request. In the mean time, the firmware may have initialised and even used some peripherals. Once the CPU is stopped, you may issue a CPU core-only reset, or even reset all CPU peripherals, but you cannot assert the JTAG_SRST signal again. On the Arduino Due, pin NRST is not connected, and if any other peripherals (like Arduino shields) are connected to the MASTER-RESET signal, they will not get reset again before the CPU firmware starts the second time around. Therefore, you will not be able to debug the same start-up situation as during power-up or after a manual reset.
The key component missing is some sort of JTAG command like "reset the complete board and wait at the first instruction". Therefore, it is best to avoid using the MASTER-RESET signal on your designs, which means that you should not use the RESET pin available on the Arduino Board. In any case, it is generally good practice to keep all peripherals in reset mode until the firmware decides to activate them, preferrably one by one. If there are separate reset lines, the firmware can then selectively reset peripherals, should they get stuck.
The OpenOCD documentation states how the reset logic should work:
In the best case, OpenOCD can hold SRST, then reset the TAPs via TRST and send commands through JTAG to halt the CPU at the reset vector before the 1st instruction is executed. Then when it finally releases the SRST signal, the system is halted under debugger control before any code has executed. This is the behavior required to support the "reset halt" and "reset init" commands.
You may think that it is possible to emulate a CPU core reset with a GDB script by setting the $pc, the stack pointer, disabling interrupts and so on. However, a real core reset may be necessary under certain circumstances. For example, the watchdog can only be programmed once in the firmware.
It may be possible to trigger a RSTC PROCRST from GDB or OpenOCD in order to reset the core and stop at the first instruction. Another way to stop the CPU right after a CPU reset could be flag C_SNAPSTALL in the "Debug Halting Control and Status" register at address 0xE000EDF0, but I haven't had time to check it out yet, please drop me a line if you do.
A good workaround is to add an initial delay in the firmware before it actually starts playing with the hardware, as the wrong I/O or system clock configuration could render the JTAG interface unusable. This way, there is a window of opportunity for a JTAG debugger to take control after a hardware reset, and you can debug most of the start-up sequence properly. The downside is that the boot process always takes a little longer, even if you are not debugging it. The SAM3X starts at 4 MHz upon reset, so it is probably a good idea to ramp the clock up before the initial delay, so that you can use a fast JTAG clock right from the start.
OpenOCD Reset Issues
The reset shortcoming described above becomes apparent when using OpenOCD, although OpenOCD itself seems to have additional issues too. The behaviour below was ascertained with OpenOCD version 0.7.0-dev, using configuration setting "reset_config srst_only srst_pulls_trst srst_open_drain".
If you type 'reset' on the OpenOCD console, the firmware starts twice, I tested it by printing a welcome banner in the firmware.
Manually pressing the RESET button on the Arduino Due confuses OpenOCD, the JTAG connection no longer works correctly. Command "scan_chain" continues to work, but "jtag init" does not. Issue a 'reset' command on the OpenOCD console to restore the JTAG connection.
Command 'reset halt' resets the CPU but cannot not stop the SAM3X afterwards. However, typing a 'halt' command afterwards does work. See routine "my_reset_and_halt" in my configuration file.
Furthermore, if the CPU is currently running, command 'soft_reset_halt' does reset the SAM3X but does not manage to halt it the first time around, and there is no error message at all. A second attempt does work, and this problem does not exist if the CPU was already halted. Nevertheless, the SAM3X does not stop at the first instruction after reset, but much further ahead. Reset config options "sysresetreq" and "vectreset" did not make any difference. When the SAM3X eventually stops, the CPU register values in GDB (including $pc) are out of sync with the ones displayed in the OpenOCD console (which are the correct ones), but there is a work-around, look for command "gdb_sync" in the OpenOCD help.
Hardware breakpoints tend to be ignored when resetting the CPU, even with 'soft_reset_halt'. Software breakpoints cannot be used anyway for firmware locations in flash memory.
On the other hand, command 'halt' seems to reliably stop the CPU in all situations, assuming that the JTAG connection is not broken.
OpenOCD performs a SAM3X reset on shutdown, which I wasn't expecting either.
Software Reset Sources
I have kept this section here for reference purposes.
Software reset sources are:
- NVIC, which is described in the Cortex-M3 standard:
- SYSRESETREQ is intended to force a large system reset of all major components except for debug, the actual behaviour is manufacturer specific.
It is not entirely clear in the AT91SAM3X8E datasheet, but it looks like this triggers a RSTC PROCRST. I don't know whether the peripherals (RSTC PERRST) are affected. - VECTRESET resets the ARM core only, with the exception of debug components. When debugging, it should be issued when the core is halted.
- SYSRESETREQ is intended to force a large system reset of all major components except for debug, the actual behaviour is manufacturer specific.
- RSTC, which is Atmel specific:
- RSTC PROCRST resets the CPU core and watchdog.
- RSTC PERRST resets the CPU peripherals only. Normally used together with PROCRST.
- RSTC EXTRST asserts the NRST pin, which is not connected on the Arduino Due.
The Cortex-M3 core contains a CoreSight unit that manages the debug interfaces (JTAG, SWD, Trace, ...), so you may find more debugging information in CoreSight's documentation.
Starting OpenOCD
It is best to create separate configuration files for the JTAG adapter and for the Arduino Due board, so the OpenOCD command-line arguments look like this:
openocd -f your-jtag-adapter.cfg -f target/at91sam3ax_8x.cfg -f arduino-due.cfg
Configuration file target/at91sam3ax_8x.cfg comes with OpenOCD version 0.8.0, so it should be able to find it automatically. For older OpenOCD versions use file at91sam3XXX.cfg instead.
Connecting with a Bus Pirate v3.5
Caveats
The Bus Pirate is very slow as a JTAG adapter, you should expect speeds under 1 KiB/s when downloading new firmware to the Arduino Due. If you manually patch OpenOCD version 0.8.0 so that setting "buspirate_speed fast" works, you can expect transfer rates of 8 KiB/s.
Firmware version v6.1 (current as of feb 2013) has a bug that might make you physically disconnect the USB cable often. The bug title is "Issue 65: Binary Mode misbehaves after receiving 20 zeroes at once" and was reported here. If OpenOCD hangs or crashes, it will not be able to connect to the Bus Pirate again. The only work-around I found to date is to disconnect and reconnect the USB cable to the Bus Pirate. It also happens if you stop OpenOCD with Ctrl+C, because OpenOCD does not seem to properly shutdown the connection to the Bus Pirate upon receiving that signal. This is a major pain, because you need to telnet to OpenOCD on another window and issue a "shutdown" command in order to properly terminate OpenOCD every time. You can partially automate this with a command like this:
echo shutdown | telnet localhost 4444
I was surprised that just connecting the JTAG adapter powers the Bus Pirate, or at least the PWR LED turns on. Although it must be some partial current leakage, because connecting the USB cable makes the PWR LED shine brighter. The trouble is, that low current seems to be enough to keep the PIC running. Therefore, if you need to disconnect the Bus Pirate USB cable due to the bug described above, you will have to disconnect either the Arduino Due USB cable or the JTAG cable too.
The Bus Pirate firmware normally has the JTAG clock speed feature disabled, and the OpenOCD driver lacks the necessary support for it, therefore the OpenOCD cannot slow down the Bus Pirate's JTAG clock, which always runs at a fixed rate of around 750 Kbit/s. This fixed clock rate only becomes an issue if the SAM3X switches to its internal 32 KHz oscillator, which may happen if your SAM3X firmware enters some power-saving mode. You should avoid switching the SAM3X clock to a low frequency in your Arduino Due firmware if you plan to debug it over JTAG with the Bus Pirate.
Configuration File
Remember to enable the Bus Pirate support when building OpenOCD, use the "--enable-buspirate" switch when configuring the build. This is the OpenOCD configuration file I am using at the moment:
interface buspirate buspirate_port /dev/buspirate # In order for the 'fast' setting to work you will probably need to manually patch OpenOCD (as of version 0.8.0). buspirate_speed normal # 'normal' or 'fast'. # The Bus Pirate can supply power (3.3 V and 5 V) to an external circuit, # but we do not need to power anything over JTAG. buspirate_vreg 0 # voltage regulator: enabled = 1, disabled = 0 # There are two ways to configure the JTAG connection: # 1) Connect JTAG_VREF and let the Bus Pirate use the target board's voltage. # - Set the mode to "open drain/open collector", which means high=Hi-Z, low=ground. # - Enable the pull-ups, which connects them to the target's JTAG_VREF, # effectively making high=JTAG_VREF. # This is the mode we are using at the moment, as it is also the safest. # 2) Do not connect JTAG_VREF. The JTAG signals will be driven at 3.3 V. # - Set the mode to "normal", which means high=3.3 V, low=ground. # - Disable the pull-ups. # This would work for us too, as the Arduino Due's JTAG interface uses 3.3 V as well. buspirate_mode open-drain # 'normal' or 'open-drain' buspirate_pullup 1 # pullup state: enabled = 1, disabled = 0
USB Information
The IDs for the 'Programming' USB interface are:
USB Vendor ID: 0x2341 (Arduino) USB Product ID: 0x003d ('Programming' USB interface)
The IDs above do not change unless you reprogram the 8-bit AVR firmware on the board, which is normally never the case.
The IDs for the 'Native' USB interface depend on the firmware running on the AT91SAM3X8E microcontroller:
If the board is running the Arduino firmware:
USB Vendor ID: 0x2341 (Arduino) USB Product ID: 0x003e ('Native' USB interface)
If you press the Erase button and the board is running Atmel's SAM-BA bootloader:
USB Vendor ID: 0x03eb (Atmel) USB Product ID: 0x6124 (SAM-BA)
lsusb -v Information for the 'Programming' USB Interface
Bus 001 Device 010: ID 2341:003d Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 1.10 bDeviceClass 2 Communications bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 8 idVendor 0x2341 idProduct 0x003d bcdDevice 0.01 iManufacturer 1 Arduino (www.arduino.cc) iProduct 2 Arduino Due Prog. Port iSerial 220 7523230323535180A120 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 62 bNumInterfaces 2 bConfigurationValue 1 iConfiguration 0 bmAttributes 0xc0 Self Powered MaxPower 100mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 2 Communications bInterfaceSubClass 2 Abstract (modem) bInterfaceProtocol 1 AT-commands (v.25ter) iInterface 0 CDC Header: bcdCDC 10.01 CDC ACM: bmCapabilities 0x06 sends break line coding and serial state CDC Union: bMasterInterface 0 bSlaveInterface 1 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x82 EP 2 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0008 1x 8 bytes bInterval 255 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 1 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 10 CDC Data bInterfaceSubClass 0 Unused bInterfaceProtocol 0 iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x04 EP 4 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 1 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x83 EP 3 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 1 Device Status: 0x0000 (Bus Powered)
lsusb -v Information for the 'Native' USB Interface
Note that if your firmware is not using the standard Arduino sketch library, you will get different values here.
Bus 001 Device 011: ID 2341:003e Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x2341 idProduct 0x003e bcdDevice 1.00 iManufacturer 1 Arduino LLC iProduct 2 Arduino Due iSerial 0 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 100 bNumInterfaces 3 bConfigurationValue 1 iConfiguration 0 bmAttributes 0xc0 Self Powered MaxPower 500mA Interface Association: bLength 8 bDescriptorType 11 bFirstInterface 0 bInterfaceCount 2 bFunctionClass 2 Communications bFunctionSubClass 2 Abstract (modem) bFunctionProtocol 1 AT-commands (v.25ter) iFunction 0 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 2 Communications bInterfaceSubClass 2 Abstract (modem) bInterfaceProtocol 0 None iInterface 0 CDC Header: bcdCDC 1.10 CDC Call Management: bmCapabilities 0x01 call management bDataInterface 1 CDC ACM: bmCapabilities 0x06 sends break line coding and serial state CDC Union: bMasterInterface 0 bSlaveInterface 1 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0010 1x 16 bytes bInterval 16 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 1 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 10 CDC Data bInterfaceSubClass 0 Unused bInterfaceProtocol 0 iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x83 EP 3 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 0 No Subclass bInterfaceProtocol 0 None iInterface 0 HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.01 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 101 Report Descriptors: ** UNAVAILABLE ** Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x84 EP 4 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 1 Device Qualifier (for other device speed): bLength 10 bDescriptorType 6 bcdUSB 2.00 bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 bNumConfigurations 1 Device Status: 0x0000 (Bus Powered)
Memory Map
0x0008 0000 - 0x000B FFFF 256 KiB flash bank 0 0x000C 0000 - 0x000F FFFF 256 KiB flash bank 1 Both banks above provide 512 KiB of contiguous flash memory 0x2000 0000 - 0x2000 FFFF 64 KiB SRAM0 0x2007 0000 - 0x2007 FFFF 64 KiB mirrored SRAM0, so that it's consecutive with SRAM1 0x2008 0000 - 0x2008 7FFF 32 KiB SRAM1 0x2010 0000 - 0x2010 107F 4224 bytes of NAND flash controller buffer
The default vector table is at 0x0008 0000 (the start of flash):
0x00080000 : initial stack pointer 0x00080004 : firmware entry point address
For more information, look at section "embedded memories" in the AT91SAM3X8E datasheet.
Feedback
Some of the information on this page is pure guesswork. If you know better, please drop me a line.