Raspberry Pi: assembly ARM power-on/off LED

Ancora devo abituarmi all’idea di poter passare una domenica senza toccare un libro universitario. Quante ne ho passate cercando disperatamente di memorizzare e ripassare (in realtà rare volte sono arrivato alla fase di ripasso 😛 ) qualche argomento per gli esami sempre troppo vicini.

Era arrivata l’ora di riempire un pò questo blog, un blog nato come passatempo serale… e che ho lasciato nel dimenticatoio per troppo tempo.

Quale miglior argomento di un pò di codice assembly ARM e GPIO per ricominciare??

Raspberry Pi LED

Lo scopo è quello riuscire ad accendere e spegnere un misero led (OK or ACT led per le specifiche Raspberry) collegato al 16esimo pin GPIO (pdf to ARM peripherals) tramite codice scritto direttamente in assembly.

1) Download e Settings ARM Toolchain

La prima cosa da fare è installare una toolchain di sviluppo per processori ARM. Se non volere compilarvi gcc a “manella” potete utilizzare questa toolchain pronta per l’uso ( disponibile per Windows/Linux/MacOS): YAGARTO

Una volta scaricato ed aperto il .dmg, vi chiederà di spostare il file .app in una cartella ed eseguirlo in modo tale da copiare i file binari di gcc in essa.

[sourcecode language=”bash”]unicondor@iMac:yagarto-4.7.2> ls
Binutils.webloc COPYING.LIBGLOSS COPYING3.LIB GNU.webloc arm-none-eabi lib source.txtCOPYING COPYING.NEWLIB GCC.webloc Newlib.webloc bin libexec tools
COPYING.LIB COPYING3 GDB.webloc YAGARTO.webloc include share version.txt
[/sourcecode]

Ora non ci resta altro che includere il percorso di tale cartella nella variabile locale relativo ai vari PATH della nostra shell.

[sourcecode language=”bash”]
unicondor@iMac:yagarto-4.7.2> export PATH=$PATH:$PWD/bin
[/sourcecode]

Se tutto è andato nel verso giusto avrete un output del genere, dove la variabile $PATH conterrà anche il path ai binari di gcc per ARM.

[sourcecode language=”bash”]
unicondor@iMac:yagarto-4.7.2> echo $PATH
/Library/Frameworks/Python.framework/Versions/2.7/bin:/opt/local/bin:/opt/local/sbin:/opt/local/bin:/opt/local/sbin:/opt/local/bin:/opt/local/sbin:/Library/Frameworks/Python.framework/Versions/2.7/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin:<strong>/Users/unicondor/Documents/Arm_toolchain/yagarto-4.7.2/bin</strong>
[/sourcecode]

2) Download template sviluppo

Per facilitarci ancora di più il compito possiamo procurarci questo template. Composto da una serie di files (sotto elencati) che ci aiuteranno nella compilazione dei nostri sorgenti

[sourcecode language=”text”]
source/
main.s
kernel.ld
LICENSE
Makefile
[/sourcecode]

Dove:
main.s sarà il nostro file sorgenti scritto direttamente in assembly ARM
kernel.ld è usato dal linker per mappare correttamente le zone di memoria (qualche interessante articolo si potrebbe scrivere su questo file)
Makefile spero non ci sia bisogno di spiegazioni 😛

3) Main.s

Ecco il file più importante, il file sorgente scritto direttamente in ARM assembly

[sourcecode language=”bash”]

/*
* .section is a directive to our assembler telling it to place this code first.
* .globl is a directive to our assembler, that tells it to export this symbol
* to the elf file. Convention dictates that the symbol _start is used for the
* entry point, so this all has the net effect of setting the entry point here.
* Ultimately, this is useless as the elf itself is not used in the final
* result, and so the entry point really doesn’t matter, but it aids clarity,
* allows simulators to run the elf, and also stops us getting a linker warning
* about having no entry point.
*/
.section .init
.globl _start
_start:

/*
* This command loads the physical address of the GPIO region into r0.
*/
ldr r0,=0x20200000

/*
* Our register use is as follows:
* r0=0x20200000 the address of the GPIO region.
* r1=0x00040000 a number with bits 18-20 set to 001 to put into the GPIO
* function select to enable output to GPIO 16.
* then
* r1=0x00010000 a number with bit 16 high, so we can communicate with GPIO 16.
*/
mov r1,#1
lsl r1,#18

/*
* Set the GPIO function select.
*/
str r1,[r0,#4]

/*
* Set the 16th bit of r1.
*/
mov r1,#1
lsl r1,#16

/*
* Set GPIO 16 to low, causing the LED to turn on.
*/
str r1,[r0,#40]

/*
* Loop over this forevermore
*/
loop$:
b loop$
[/sourcecode]

Nella sezione references trovate altri esempi da cui questo è stato preso. E’ molto semplice ed intuitivo da capire, inoltre è anche ben commentato per cui posso evitare di spiegare cosa fa 😀

Non dobbiamo fare altro che aggiungere il main.s nella cartella source del template prima scaricato e lanciare la compilazione. Infine avremo il nostro bel kernel.img da poter inserire nella nostra scheda SD e rimpiazzarlo con quello ufficiale di Raspian.

Se tutto e’ andato nel verso giusto, appena inserita l’alimentazione al nostro raspberry si accendera’ il LED ACT…. forse 😛

References

http://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/index.html

GitHub

https://github.com/flaviopace/ARM_Assembly_PowerOff-PowerOn_led

Raspberry PI: Sensore di Temperatura ed Umidità

Raspberry PI DHT11
Raspberry Pi e DHT11 Sensore

15 agosto e la sera esco con camicia e felpa, quale miglior giorno per provare il mio nuovo sensore di temperatura ed umidità tramite il Raspberry Pi ? 😛

il Sensore in questione (DHT11) è uno di quelli “cinesi” che si trovano a pochi euro in qualsiasi negozio online. Ha un range di misurazione della temperatura tra 0-50°C & un range di umidità tra 20-95%.

Online si trovano miriadi di link su come collegarlo al nostro Raspberry Pi, La foto allegata all’inizio del post vi mostra il mio schema…

Bhe ammetto che si capisce molto poco, forse meglio utilizzarne uno preso dal web 😀

Sensor dht11 wiring
Schema collegamento DHT11
DHT11_Pins
Dettaglio Pins DHT11

Una volta collegato il nostro sensore al Raspberry PI (io uso il connettore Adafruit ) non vi resta che scaricare le librerie per l’interfacciamento con il sensore

[sourcecode language=”bash”]

$ git clone git://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code.git
$ cd Adafruit-Raspberry-Pi-Python-Code
$ cd Adafruit_DHT_Driver

[/sourcecode]

Bene, una volta scaricato il binario ( già compilato per il nostro processore) possiamo eseguirlo direttamente dalla shell dei comandi

[sourcecode language=”bash”]
root@raspberrypi: ./Adafruit_DHT 11 4
Using pin #4
Data (40): 0x24 0x0 0x1c 0x0 0x40
Temp = 28 *C, Hum = 36 %
[/sourcecode]

Dove “11” indica il modello del sensore, ed il “4” indica il PIN GPIO a cui è collegato.

Non sarebbe bello avere un grafico con l’andamento della temperatura ed accessibile ovunque tramite web??

Esistono molto modi (e molte API) per esportare i dati sul web, io ho utilizzato le API che google docs mette a disposizione.

1) Creazione Spreadsheet

Prima di tutto andiamo su google docs e creiamo il nostro spreadsheet dove andremo ad inserire i nostri dati

Creazione spreadsheet
Creazione spreadsheet

1) Installazione Ed esecuzione della libreria Python

Per poter fare upload dei dati presi dal sensore, possiamo utilizzare una libreria che ci semplifica di molto le operazioni per l’interfacciamento con google. La libreria in questione si chiama GSpread

[sourcecode language=”bash”]
wget http://pypi.python.org/packages/source/g/gspread/gspread-0.0.13.tar.gz#md5=d413ad08805f3f0a1e9d5f9bebe5d35b
tar -zxvf gspread-0.0.13.tar.gz
cd gspread-0.0.13
sudo python setup.py install
[/sourcecode]

Una volta installata dobbiamo modificare alcuni opzioni: andiamo nella directory Adafruit-Raspberry-Pi-Python-Code/Adafruit_DHT_Driver ed editiamo il file Adafruit_DHT_googledocs.ex.py nei seguenti punti:

[sourcecode language=”python”]
# ===========================================================================
# Google Account Details
# ===========================================================================

# Account details for google docs
email = ‘you@somewhere.com’
password = ‘my_password’
spreadsheet = ‘Temperature_Flavio_Home’
..
..
..
output = subprocess.check_output(["./Adafruit_DHT", "11", "4"]);

[/sourcecode]

Inserendo rispettivamente i dati del nostro account di google, il modello del nostro sensore (DHT11 nel mio caso) ed il pin a cui è collegato (4)

Se tutto è andato nel verso giusto avremo come output della shell

[sourcecode language=”python”]
pi@raspberrypi ~/Adafruit-Raspberry-Pi-Python-Code/Adafruit_DHT_Driver $ sudo python Adafruit_DHT_googledocs.ex.py
Using pin #4
Data (40): 0x25 0x0 0x1a 0x0 0x3f
Temp = 26 *C, Hum = 37 %

Temperature: 26.0 C
Humidity: 37.0 %
Wrote a row to Temperature_Flavio_Home
Using pin #4
Data (40): 0x25 0x0 0x1a 0x0 0x3f
Temp = 26 *C, Hum = 37 %

Temperature: 26.0 C
Humidity: 37.0 %
Wrote a row to Temperature_Flavio_Home
Using pin #4
Data (40): 0x24 0x0 0x1a 0x0 0x3e
Temp = 26 *C, Hum = 36 %
[/sourcecode]

Mentre se apriamo il nostro spreadsheet vedremo in real-time i valori letti dal nostro Raspberry Pi 😀

Questo è il grafico della mia stanza…

https://docs.google.com/spreadsheet/ccc?key=0AvfMfLVFJ7CPdHlNVzlzNmNNM01JMGZTTlA4bGl2WkE&usp=sharing

graph temperature Dragonetti
graph temperature Dragonetti

Raspberry Pi: Eseguire vncserver all’avvio

Raspberry Pi

Finalmente è arrivato a casa il Raspberry Pi. Settimane di attesa per poter smanettare un pò vicino a questo fantastico “giocattolino”.

Assieme a mio fratello abbiamo cercato di installare subito vncserver, ma le soluzioni che si trovano online : running-vncserver-at-startup , hanno bisogno dell’avvio del server grafico per poter lanciare correttamente il demone di vncserver.

Per ovvirare a questa limitazione, la mia soluzione avvia il demone di vncserver tramite lo script di avvio: /etc/rc.local 

[sourcecode language=”bash”]
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
printf "My IP address is %s\n" "$_IP"
fi

#Start Vnc Server
export USER=pi
vncserver :1

exit 0

[/sourcecode]

Prima di lanciare il comando di avvio del server, ho dovuto esportare la variabile globale USER altrimenti il demone non riusciva a leggere correttamente i file di configurazione che avevo editato in /home/pi/.vnc e mi dava il seguente errore:

"Starting vncserver: Starting VNC server: 3: root vncserver: The USER
environments variable is not set"

Al primo avvio vi chiederà di inserire la password di accesso, poi la setterà in automatico ad ogni riavvio.