export binary/jtag-ice smd programming

Hey guys,
After 2 days of wasted time, I came to the conclusion that the export binary function of the Arduino IDE is not properly working.
I have a custom made board that uses a SAMD21 with no USB port, so no bootloader can be used.
I use Atmel studio 7 with jtag ICE programmer.
I can connect to my board just fine using the SWD header.
Read voltage and device signature is OK.
All the fuses are correct.
Once I export a binary of my sketch from the arduino IDE(I have the arduino zero-programmer port selected), load it into Atmel, and program the chip, it flashes successfully, but nothing happens. The code never executes.

There is nothing wrong with my flashing procedure because I flashed several other boards that had a usb port with a bootloader, and they worked fine.

The problem is that Arduino's IDE exported binary is messed up.

To confirm that, I uploaded a sketch to another board that had a usb port, then connect the jtag ICE and exported the resulting hex, then uploading that hex to the board in question, and TADA it works.

I obviously cannot keep uploading sketches to a secondary board using USB, just to dump the hex and upload it again to a new board.

Try this:
File > Preferences > Show verbose output during: > upload (check) > OK
Sketch > Upload (doesn't matter if it fails)
After the upload completes examine the output in the black console window at the bottom of the Arduino IDE window until you find the command used to upload to the Arduino. This will give you the location of the .bin file that is uploaded.
Upload that .bin file.

This cuts out the Export Compiled Binary process so you know the .bin file you're working with is good. The Export Compiled Binary process should just be a copy + rename and a diff of the two files on my computer shows they are identical.

Note that you will also find a .hex file in the temporary build folder along with the .bin file so that might also be worth a try.

pert:
Try this:
File > Preferences > Show verbose output during: > upload (check) > OK
Sketch > Upload (doesn't matter if it fails)
After the upload completes examine the output in the black console window at the bottom of the Arduino IDE window until you find the command used to upload to the Arduino. This will give you the location of the .bin file that is uploaded.
Upload that .bin file.

This cuts out the Export Compiled Binary process so you know the .bin file you're working with is good. The Export Compiled Binary process should just be a copy + rename and a diff of the two files on my computer shows they are identical.

Note that you will also find a .hex file in the temporary build folder along with the .bin file so that might also be worth a try.

Thank you for your help, this is exactly what I did, I used the generated bin file, I also looked inside the temp folder and used the generated hex file, same problem.
If I upload the sketch to another board through the USB port + bootloader, then dump the resulting hex directly from the board using the ICE programmer, then that hex file works on the board that doesn't have a bootloader nor a usb port.

At least now you know your original hypothesis ("that the export binary function of the Arduino IDE is not properly working.") is wrong.

When the .bin file is uploaded via the Arduino IDE, using the command you see in the console, it works fine. So the problem lies somewhere in the difference between that command and the way you're attempting to flash the .bin file.

pert:
At least now you know your original hypothesis ("that the export binary function of the Arduino IDE is not properly working.") is wrong.

When the .bin file is uploaded via the Arduino IDE, using the command you see in the console, it works fine. So the problem lies somewhere in the difference between that command and the way you're attempting to flash the .bin file.

You are right, it seems that the problem I'm having is that the board needs to have a bootloader in order to execute the sketch binary, if I upload the standalone binary without any bootloader it does not execute. As I mentioned before Im using Jtag ice to upload to flash with Atmel studio 7. Since my board does not have a usb port, I can't flash a bootloader and upload using usb serial. What I ended up doing is use another board with usb and bootloader installed, upload the sketch from arduino IDE, then export the whole flash and upload it into the board in question.

Things are getting weirder, now only the code inside setup() is executed, and then it stops, no loop. The sketch is a simple led blink. Could the crystal be faulty?

EDIT: nope swapped crystal two times, still same problem. Setup() code works, but no loop.

the board needs to have a bootloader in order to execute the sketch binary

That's expected behavior. Arduino Zero sketches are built to run at a non-zero start address in flash, because the bootloader starts at zero. At reset, the chip extracts some data about where to start from location zero in flash, so there MUST be something there.

This is different from the AVRs, which:

  • have a separate bootloader section at the end of memory, and a fuse that tells them to start there, so normal sketches still start at zero.
  • actually start execution at either zero or the start of the bootloader section, rather than extracting startup info. So if you start at the beginning of the bootloader section when no bootloader is loaded, you go along executing useless but harmless instructions until the PC wraps around and reaches 0 (where your sketch would start executing.)

westfw:
That's expected behavior. Arduino Zero sketches are built to run at a non-zero start address in flash, because the bootloader starts at zero. At reset, the chip extracts some data about where to start from location zero in flash, so there MUST be something there.

This is different from the AVRs, which:

  • have a separate bootloader section at the end of memory, and a fuse that tells them to start there, so normal sketches still start at zero.
  • actually start execution at either zero or the start of the bootloader section, rather than extracting startup info. So if you start at the beginning of the bootloader section when no bootloader is loaded, you go along executing useless but harmless instructions until the PC wraps around and reaches 0 (where your sketch would start executing.)

Interesting, that makes sense now. I got the bootloader problem sorted, but I still have a weird problem, setup() code executes, and loop() code execute only once, then everything freeze. Delays don't work either. Could I be so unlucky that all the 3 crystals I tried are bad?

I dunno. Are you running "Blink" or something more complicated?
ARMs will trap invalid memory accesses that an AVR would ignore, and probably just hang up as a result (not having an operating system to give you a "segmentation violation" error.)

westfw:
I dunno. Are you running "Blink" or something more complicated?
ARMs will trap invalid memory accesses that an AVR would ignore, and probably just hang up as a result (not having an operating system to give you a "segmentation violation" error.)

Its a simple led blink. One thing I noticed is if I disconnect the sensing pins vcc and gnd of the swd connector, the board does not boot at all, could it be a power line noise problem? I have filtering caps in place.
I know that Jtag ice does not provide power, it uses vcc and gnd pins to sense the voltage of the mcu, can't figure out why the mcu doesn't start at all if those are disconnected even tho im providing it with regulated 3.3v. hmmm.

Update: It seems that the loop() function executes, but if I put anything related to time or timers in it, the MCU freezes, a simple delay() will make it freeze. It does also randomly freeze with or without any delays.
Here is my fuses if it helps

ADC_LINEARITY_0 = 0x08
ADC_LINEARITY_1 = 0x04
ADC_BIASCAL = 0x03
OSC32K_CAL = 0x37
USB_TRANSN = 0x05
USB_TRANSP = 0x1D
USB_TRIM = 0x03
DFLL48M_COARSE_CAL = 0x20
DFLL48M_FINE_CAL = 0x200
ROOM_TEMP_VAL_INT = 0x1E
ROOM_TEMP_VAL_DEC = 0x00
HOT_TEMP_VAL_INT = 0x55
HOT_TEMP_VAL_DEC = 0x00
ROOM_INT1V_VAL = 0x00
HOT_INT1V_VAL = 0xFE
ROOM_ADC_VAL = 0xB81
HOT_ADC_VAL = 0xD7E
NVMCTRL_BOOTPROT = 0x07
NVMCTRL_EEPROM_SIZE = 0x07
BOD33USERLEVEL = 0x07
BOD33_EN = [X]
BOD33_ACTION = 0x01
WDT_ENABLE = [ ]
WDT_ALWAYSON = [ ]
WDT_PER = 0x0B
WDT_WINDOW_0 = [X]
WDT_WINDOW_1 = 0x05
WDT_EWOFFSET = 0x0B
WDT_WEN = [ ]
BOD33_HYST = [ ]
NVMCTRL_REGION_LOCKS = 0xFFFF

OTP4_WORD_0 = 0x40004007 (valid)
OTP4_WORD_1 = 0x81F4ADDC (valid)
OTP4_WORD_2 = 0xFFFFFE00 (valid)
TEMP_LOG_WORD_0 = 0x5501E (valid)
TEMP_LOG_WORD_1 = 0xD7EB81FE (valid)
USER_WORD_0 = 0xD8E0C7FF (valid)
USER_WORD_1 = 0xFFFFFC5D (valid)

Is this the correct way to concatenate arduino compiled sketch and bootloader hex file?
Arduino sketch:

:102000000080002021220000092200000922000097
.
.
.
.
:0400000300002221B6
:00000001FF

bootloader sketch:

:1000000070040020E9120000D1120000D11200009B
.
.
.
:04000005000012F1F4
:00000001FF

Resulting file:

:1000000070040020E9120000D1120000D11200009B
.
.
.
:04000005000012F1F4
:102000000080002021220000092200000922000097
.
.
.
.
:0400000300002221B6
:00000001FF

It sounds like this is the solution:

Amazing! that solved the problem. Thank you :slight_smile: