Remote-flashing an AVR board from an ARM

Okay, I admit it, we’re building something quite big this time. And robotic. So big, that it needs some embedded brains of the ARM scale (SmartQ7) and a microcontroller, that does all the dirty work (e.g. controls motors, gathers data from sensors and feeds that stuff to an ARM for processing.) However, disconnecting the micro for flashing, or running around with an ISP programmer is not an option.this thing moves pretty much.

So I decided to get SmartQ7 to actually flash this stuff. Since we’re running an atmega2560 on the main bot (really, we needed all those PWMs, INTs and GPIOs, not the code space, but a college insisted on putting everything to the max). So I borrowed from him some arduino board based on m1280 that’s quite compatible (actually – only flash size differs and I still think we could have pulled the same stuff with atmega640). Since I’m not using arduino IDE or libraries, the only thing that was left from arduino – the bootloader. It works with avrdude, and that’s enough.

The SmartQ7 is currently running a buildroot-based linux distro, with several new packages hacked into it. One of them is avrdude, the thing that we just can’t live without.
Getting it to cross-compile is pretty straight-forward, since it’s based on autotools that are quite well supported by buildroot.
You can get my buildroot package of avrdude via this link

It is already bundled with a patchset from ubuntu, that adds some features, including autoresetting of boards, that have DTR wired to the reset circuit. This will make your work even more comfortable.
Note, that the binary will be called arm-linux-avrdude

Now, it’s time to compile everything. I won’t go into detail, just point out some things that worth remembering.

We’ll need openssh, avrdude, wpa_supplicant (remember to check that in menuconfig). It’s also a good idea to include udev. then just type make.

Once you’ve transfered the whole filesystem on the SD card, you’ll need several files to edit. One of them is /etc/init.d/rcS
We can put some of out stuff right below, and we’ll need to bring up wifi here. Hope you’ve checked udhcpc, right?
On SmartQ wifi is enabled via :
echo 1 > /sys/devices/platform/smartq_gpio/wifi_en
Once we’ve anabled that, we turn on wpa_supplicant. We need this config:
/etc/wpa_supplicant.conf
Fill your values and you’re good.
ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group=0
ap_scan=1

network={
ssid="Astra"
proto=RSN
key_mgmt=WPA-PSK
pairwise=CCMP TKIP
group=CCMP TKIP
psk="MyReallyLongPass"
}

The resulting script looks somewhat like that:

1
2
3
4
5
6
7
echo 1 > /sys/devices/platform/smartq_gpio/wifi_en
sleep 1
echo "Activating wireless"
wpa_supplicant -B -c/etc/wpa_supplicant.conf -ieth0 -Dwext
sleep 5
udhcpc eth0
echo "System active"

Then we’ll need to edit /etc/sshd_config to allow passwordless auth via a public key. Just edit that to be /etc/authorized_keys and then put your publickey there.

That’s it, if everything is correct, the tablet will boot and come online via wireless. You’ll see the ip obtained on the screen.

Now you can just ssh there. That’s quite cool, now we can move on to setting up a Makefile. Arduino-fans are out of luck, since I prefer pure C and hate arduino. Let’s do it via Makefiles, like real people do. In my case the flash target looks somewhat like that:

1
2
3
4
5
6
7
8
flash:	$(PROJECT).hex
ifeq ($(REMOTE),"YES")
		@echo "Remote flashing in progress"
		scp $(PROJECT).hex $(REMOTE_USER)@$(REMOTE_HOST):/tmp/$(PROJECT).hex
		ssh -l $(REMOTE_USER) $(REMOTE_HOST) $(AVRDUDE) -c $(PROG) -p $(MCU) -P $(PORT) -b $(BAUD) -u -U flash:w:/tmp/$(PROJECT).hex
else
		sudo $(AVRDUDE) -c $(PROG) -p $(MCU) -P $(PORT) -b $(BAUD) -u -U flash:w:$(PROJECT).hex
endif

Note the variables that are worth setting up. I do it ib different profile files, that are part of my Makefile-fu =). Setting up REMOTE to “YES” enables the “remote” downloading of firmware: the resulting hex file is first transfered via ssh to the /tmp of my SmartQ7 and then flashed to the board. /tmp is worth being mounted as tmpfs, btw.

Oh, and do not forget to turn on usb host power. Just in case you’re host-powered. You want to control SmartQ from your PC via wifi – there’s an app Makefile for that!
You can just place the following magic in smq.mk and -include into you own Makefile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#This is a helper Makefile that allows to control different functions of SmartQ 7 via a makefile iface
 
 
smq-log:
	ssh -l $(REMOTE_USER) $(REMOTE_HOST) "echo '$(TEXT)' > /dev/tty0"
sw-gpio:
	ssh -l $(REMOTE_USER) $(REMOTE_HOST) "echo $(STATE) > /sys/devices/platform/smartq_gpio/$(GFILE)"
 
sw-lcd:
	ssh -l $(REMOTE_USER) $(REMOTE_HOST) "echo $(STATE) > /sys/devices/platform/s3c-lcd/$(GFILE)"
 
hostpwr-on:
	STATE=1 GFILE=usbhostpwr_en $(MAKE) sw-gpio
hostpwr-off:
	STATE=0 GFILE=usbhostpwr_en $(MAKE) sw-gpio
otgpwr-on:
	STATE=1 GFILE=usbpwr_en $(MAKE) sw-gpio
otgpwr-off:
	STATE=0 GFILE=usbpwr_en $(MAKE) sw-gpio
led1-on:
	STATE=1 GFILE=led1_en $(MAKE) sw-gpio
led1-off:
	STATE=0 GFILE=led1_en $(MAKE) sw-gpio
led2-on:
	STATE=1 GFILE=led2_en $(MAKE) sw-gpio
led2-off:
	STATE=0 GFILE=led2_en $(MAKE) sw-gpio
lcd-on:
	STATE=1 GFILE=backlight_power $(MAKE) sw-lcd
	STATE=1 GFILE=lcd_power $(MAKE) sw-lcd	
	STATE=100 GFILE=backlight_level $(MAKE) sw-lcd
lcd-off:
	STATE=0 GFILE=backlight_level $(MAKE) sw-lcd
	STATE=0 GFILE=lcd_power $(MAKE) sw-lcd	
	STATE=0 GFILE=backlight_power $(MAKE) sw-lcd
 
 
backlight-%:
	STATE=$* GFILE=backlight_level $(MAKE) sw-lcd
 
ssh:  
	-ssh -l $(REMOTE_USER) $(REMOTE_HOST)

And hey, it works!

Leave a Reply