One of my EE co-workers got hold of an Arduino Zero recently but failed to get it working. I took a looks at this and realized that he had walked into the battle of the arduinos and was trying to use the wrong software. Currently Arduino.cc have not released the Zero but Arduino.org have released an Arduino Zero Pro and this is what we have here. To support this they have issued a version of the Arduino IDE labelled as 1.7.2 but which is really a 1.5ish version with Zero support bolted in. Quite poorly as well from a first look.
So having got the device and an IDE capable of programming it, we can try the basic serial output test as shown below. However, it turns out that the included examples will not work as the default Serial class is the wrong one. To get this working Serial5 needs to be used.
#include <Arduino.h> // for the Arduino Zero #ifdef __SAMD21G18A__ #define Serial Serial5 #endif static int n = 0x10; void setup() { Serial.begin(115200); Serial.println("Serial test - v1.0.0"); } void loop() { Serial.print(n++, HEX); if (n % 0x10 == 0) Serial.println(""); else Serial.print(" "); if (n > 0xff) n = 0x10; delay(30); }
Moving on I thought it would be interesting to try and use this with a WizNet based Ethernet shield I have. So with the board set as Arduino Zero let us build one of the Ethernet demos.
C:\opt\arduino.org-1.7.2\libraries\Ethernet\src\Ethernet.cpp: In member function 'int EthernetClass::begin(uint8_t*)': C:\opt\arduino.org-1.7.2\libraries\Ethernet\src\Ethernet.cpp:19:7: error: 'class SPIClass' has no member named 'beginTransaction' SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
I sincerely hope arduino.cc do a better job than this when they release their version of this interesting board.
Debugging on the Zero
The ability to use gdb to debug the firmware is what makes this board so attractive. The 1.7.2 IDE package includes a copy of OpenOCD with configuration files for communicating with the Zero. While this is not integrated into the current IDE at all it is still possble to start stepping through the firmware. You do need to know something about the way the Arduino IDE handles building files to make use of this however.
OpenOCD is run as a server that mediates communications with the hardware. The following script makes it simple to launch OpenOCD in a separate window on Windows (adjust the Arduino directory path as appropriate). This gives a console showing any OpenOCD output and two TCP/IP ports will be opened. One on 4444 is for communicating with OpenOCD itself. The other on 3333 is for debugging.
@setlocal @set ARDUINO_DIR=C:\opt\arduino.org-1.7.2 @set OPENOCD_DIR=%ARDUINO_DIR%\hardware\tools\OpenOCD-0.9.0-dev-arduino @start "OpenOCD" %OPENOCD_DIR%\bin\openocd ^ --file %ARDUINO_DIR%\hardware\arduino\samd\variants\arduino_zero\openocd_scripts\arduino_zero.cfg ^ --search %OPENOCD_DIR%\share\openocd\scripts %*
To connect for debugging it is necessary to run a suitable version of gdb and set it to use the remote target provided by OpenOCD on localhost:3333. Provided the sources (the arduino .ino file and any .cpp or .h files included with the project) and the .elf binary are specified gdb can start showing symbolic debugging information. This is where the Arduino IDE needs to provide some assistance. The .ino source file is processed to produce some C++ files and then built with g++ but this all happens in a temporary directory with some relatively random name. Looking for the most recent directory in your temporary directory (%TEMP%) will have the build files. From this folder, running arm-none-eabi-gdb.exe and running the following commands in gdb will enable symbols and start controlling the firmware. After that it is normal gdb debugging.
Note that gdb is found at <ARDUINODIR>\hardware\tools\gcc-arm-none-eabi-4.8.3-2014q1\bin\arm-none-eabi-gdb.exe
# gdb commands... directory SKETCHFOLDER\\PROJECTNAME file PROJECTNAME.cpp.elf target remote localhost:3333 monitor reset halt break setup continue
Worked example
Launching OpenOCD using the script described above.
Open On-Chip Debugger 0.9.0-dev-g1deebff (2015-02-19-15:29) Licensed under GNU GPL v2 For bug reports, read http://openocd.sourceforge.net/doc/doxygen/bugs.html Info : only one transport option; autoselect 'cmsis-dap' adapter speed: 500 kHz adapter_nsrst_delay: 100 cortex_m reset_config sysresetreq Info : CMSIS-DAP: SWD Supported Info : CMSIS-DAP: JTAG Supported Info : CMSIS-DAP: Interface Initialised (SWD) Info : CMSIS-DAP: FW Version = 01.1F.0118 Info : SWCLK/TCK = 1 SWDIO/TMS = 1 TDI = 1 TDO = 1 nTRST = 0 nRESET = 1 Info : DAP_SWJ Sequence (reset: 50+ '1' followed by 0) Info : CMSIS-DAP: Interface ready Info : clock speed 500 kHz Info : IDCODE 0x0bc11477 Info : at91samd21g18.cpu: hardware has 4 breakpoints, 2 watchpoints
Launching gdb
GNU gdb (GNU Tools for ARM Embedded Processors) 7.6.0.20140228-cvs Copyright (C) 2013 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "--host=i686-w64-mingw32 --target=arm-none-eabi". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. (gdb) file SerialTest1.cpp.elf Reading symbols from C:\Users\pt111992\AppData\Local\Temp\build1861788453707041664.tmp\SerialTest1.cpp.elf...done. (gdb) directory c:\\src\\Arduino\\SerialTest1 Source directories searched: c:\src\Arduino\SerialTest1;$cdir;$cwd (gdb) target remote localhost:3333 Remote debugging using localhost:3333 0x000028b8 in ?? () (gdb) monitor reset halt target state: halted target halted due to debug-request, current mode: Thread xPSR: 0x21000000 pc: 0x000028b8 msp: 0x20002c08 (gdb) break setup Breakpoint 1 at 0x415e: file SerialTest1.ino, line 12. (gdb) continue Continuing. Note: automatically using hardware breakpoints for read-only addresses. Breakpoint 1, setup () at SerialTest1.ino:12 12 Serial.begin(115200); (gdb) next setup () at SerialTest1.ino:13 13 Serial.println("Serial test - v1.0.0"); (gdb)
And now we are stepping through the code actually running on the Arduino Zero. Awesome!