- 1 Un po’ di teoria
- 2 Come fare
- 3 Come ci siamo arrivati
- 4 Risultati e limiti
OCCHIO La procedura con stlink non sembra funzionare su tutti i computer. Non sappiamo perché. La prova si ha quando, dopo aver fatto st-flash
, non vediamo il caratteristico lampeggio. Inoltre il device non si presenta in USB (da lsusb
non lo vediamo; su dmesg
ci sono solo errori). Incrocia le dita!
La procedura con usb-ttl per ora è stata testata su un solo computer.
Un po’ di teoria¶
In generale per caricare un programma su un stm32 serve usare il programmatore st-link v2. Il programmatore costa poco e funziona bene, ma magari vogliamo farne a meno.
Questo si può fare sfruttando la porta USB. Prima però è necessario mettere un bootloader adatto. Ovvero:
si mette usando l’stlink (in teoria se ne può fare a meno, ancora non ci sono riuscito) un programma sul chip. Questo programma fa così: quando parte fa un pattern coi led molto riconoscibile; poi rimane in ascolto sulla porta usb per alcuni secondi(www.onetransistor.eu/2017/11/stm32-blue...; se nessuno gli dice niente, fa partire un secondo programma che ha in memoria.
Questo secondo programma dovrà quindi essere scritto sull’indirizzo 0x8002000
, e dovrà pertanto essere a conoscenza che questo è l’indirizzo da cui parte.
Come fare¶
Caricare il bootloader¶
Metodo con ST-LINK¶
wget 'https://github.com/rogerclarkmelbourne/STM32duino-bootloader/blob/master/binaries/generic_boot20_pc13.bin?raw=true'
st-flash write generic_boot20_pc13.bin 0x8000000
Dovreste vedere che il led verde fa un blink caratteristico per meno di un secondo. Lo rifà ogni volta che premete reset o che staccate e riattaccate la corrente. Se lo fa, ha funzionato tutto.
Se non lo fa… capita. Da alcuni computer questa procedura non ci funziona e non capiamo perché. Prova con il metodo successivo.
Se funziona, scollega l’stlink e collega il cavo microusb
Per sicurezza, lo sha1sum è 4c863edb4512a7d520c26f89dfd2c531f7d91908
Metodo con usb-ttl¶
se non avete un stlink, o se sul vostro computer non funziona bene, potete usare un usb-ttl (esempi: cp2102
, ft232
, pl2303
). In questo caso il programma che vi serve è stm32flash
(apt-get install stm32flash
).
Collegate il tx del vostro usb-ttl al pin A9
e l’rx al pin A10
. Collegate anche la massa. Collegate l’usb-ttl al computer. Dovrebbe comparire il device /dev/ttyUSB0
.
Spostate il jumper BOOT0
al valore 1
, premete reset, quindi fate
wget 'https://github.com/rogerclarkmelbourne/STM32duino-bootloader/blob/master/binaries/generic_boot20_pc13.bin?raw=true'
stm32flash -w generic_boot20_pc13.bin -v /dev/ttyUSB0
a questo punto spostate il jumper BOOT0
al valore 0
, ri-premete reset.
Dovreste vedere il led verde sulla board blinkare in modo “caratteristico” per meno di un secondo. Ci siete riusciti!
Staccate l’usb-ttl e collegate il cavo microusb
Caricare il programma vero¶
Attaccando il cavo microusb dovreste vedere /dev/ttyACM0
.
Scaricate il linker script usb stm32f103c8t6-usb.ld
, dalla directory di un qualsiasi vostro progetto fate
questo vi fa un file main.bin
che è adatto ad essere messo sull’USB.
a questo punto lanciamo lo script upload-usb main.bin
make LDSCRIPT=../../stm32f103c8t6-usb.ld clobber all && sudo ../upload-usb main.bin
Subito dopo aver lanciato lo script dobbiamo premere reset (comunque lo script ci dovrebbe guidare un minimo).
Caricarlo senza essere root¶
nell’esempio di prima serve fare sudo. è meglio se invece vi date i permessi per le cose giuste. Create un file /etc/udev/rules.d/70-dfu-util-stm32.rules
con contenuto:
ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="1eaf", ATTRS{idProduct}=="0003", MODE="664", GROUP="plugdev"
ora fate sudo udevadm control --reload-rules
e ora potrete fare tutto senza sudo!
Come ci siamo arrivati¶
La maggior parte delle guide spiegano solo come fare a caricare il bootloader, e non come si prosegue dopo: danno per scontato che si voglia usare l’IDE di arduino. A parte che anche in quel caso non è per nulla ovvio, il problema è che non spiegano come fare altrimenti.
Questo mi sembra l’unico post un po’ utile: www.onetransistor.eu/2017/11/stm32-blue...
Caricare il bootloader¶
In teoria si dovrebbe poter caricare tutto anche via usb-ttl. Noi all’inizio non ci siamo riusciti, e abbiamo usato l’stlink. Dopo siamo riusciti anche con un semplice usb-ttl
L’indirizzo su cui caricare (0x8000000
) l’abbiamo copiato facendo make -n flash
da un makefile precedente che ci funzionava con l’stlink.
Interagire col bootloader¶
Quando facciamo così vediamo che all’avvio i led fanno un blink caratteristico, segno che il bootloader è partito. Bene.
Vediamo anche che esiste /dev/ttyACM0
, ma se ci andiamo con picocom ci spara un messaggio di benvenuto inutile. Fanculo.
Copiare da arduino¶
dato che tutti usano arduino, seguiamo i passi fatti da arduino. Questo post (già citato) spiega bene: www.onetransistor.eu/2017/11/stm32-blue...
Durante l’"upload sketch" ho lanciato ps
in modo aggressivo finché non ho beccato il comando che girava:
/home/gordo/.arduino15/packages/stm32duino/tools/stm32tools/2018.9.24/linux/maple_upload ttyACM0 2 1EAF:0003 /tmp/arduino_build_27355/Blink.ino.bin
vado a guardare il file, che è uno script bash, e vedo che lancia il dfu-util
con i comandi che poi ho inserito anche in upload-usb
.
Provo a lanciarlo e però non mi funziona. Poi noto (sempre sull’articolo di prima):
When you reset the board, for a short moment of time while bootloader is running, it appears as DFU device, then switches to serial port.
che chiarisce che il tempismo è importante! Bisogna premere reset e subito dopo lanciare il comando, così funziona!
A quel punto si tratta solo di fare uno scriptino che automatizzi il tutto, cioè upload-usb
Abbiamo fatto anche un altro scriptino più adatto ad essere usato durante lo sviluppo chiamato upload-usb-auto
Il linker!¶
I programmi così non funzionano! Serve fare come dice questo: http://kevincuzner.com/2018/06/28/building-a-usb-bootloader-for-an-stm32/
Ovvero cambiare di poco il file .ld
Risultati e limiti¶
Il tutto è stato testato con freertos (almeno cose semplici).
Tra le cose testate con successo, riportiamo con giubilo la programmazione di un PWM che pilota un servo motore sg90, il cui codice e’ in un tgz in allegato a questa pagina, insieme alla documentazione filmografica.
Tra le cose testate con successo, riportiamo con giubilo il prelievo della temperatura da un termometro, il cui codice e’ in un tgz in allegato a questa pagina, insieme alla documentazione filmografica.
della correttezza del linker script non sono sicuro (in particolare sulla ram: l’ho riaumentata a 20k e “funziona”, ma poi magari esplode tutto chi lo sa).