Zobrazují se příspěvky se štítkemGPIO. Zobrazit všechny příspěvky
Zobrazují se příspěvky se štítkemGPIO. Zobrazit všechny příspěvky

sobota 12. ledna 2019

Raspberry Pi programování bez OS

Před nějakou dobou jsem se pokoušel přeložit jednoduchý program pro Raspberry Pi bez takových zbytečností jako je linuxové jádro. :-) A jak na to?

neděle 25. března 2018

Reverzní inženýrství

Začalo to pokusem zprovoznit JTAG pod OpenOCD. S ASIX Presto jsem si s touto kombinací vylámal zuby už dávno ale s RaspberryPi 3 by to mohlo jít.

Nejprve je nutné OpenOCD pro RaspberryPi stáhnout a přeložit (tak například takto):

git clone git://git.code.sf.net/p/openocd/code openocd-code

Dále je potřeba v konfiguraci povolit veškeré požadované rozhraní (hlavně --enable-sysfsgpio --enable-bcm2835gpio ale FTDIčko také není na závadu)

./bootstrap
./configure

A potom už jen make a nainstalovat,

make
sudo make install

všechny potřebné skripty pro jeho používání nalezneme v /usr/local/share/openocd/scripts/

Nyní již stačí správně propojit drátky, kdo má drátků málo, tak použije SWD (SWDIO, SWDCLK, GND) kdo má drátků hodně nebo tak akorát může použít JTAG (TCK, TMS, TDI, TDO, TRST, SRST).

Pro RaspberryPi 3 jsem použil soubor s konfigurací raspberrypi2-native.cfg, zde je možné zvolit zda JTAG nebo SWD.

Po drobném laborování jsem si udělal upravil soubor raspberrypi2.cfg, tak aby bylo možné použít jedno nebo druhé se stejným zapojením:

#
# Config for using Raspberry Pi's expansion header
#
# This is best used with a fast enough buffer but also
# is suitable for direct connection if the target voltage
# matches RPi's 3.3V and the cable is short enough.
#
# Do not forget the GND connection, pin 6 of the expansion header.
#

interface bcm2835gpio

#RPi2 & RPi3
bcm2835gpio_peripheral_base 0x3F000000
#RPi1
#bcm2835gpio_peripheral_base 0x20000000

# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET
# These depend on system clock, calibrated for stock 700MHz
# bcm2835gpio_speed SPEED_COEFF SPEED_OFFSET
#RPi2 & RPi3
bcm2835gpio_speed_coeffs 146203 36
#RPi1
#bcm2835gpio_speed_coeffs 113714 28

# Each of the JTAG lines need a gpio number set: tck tms tdi tdo
# Header pin numbers: 23 22 19 21
bcm2835gpio_jtag_nums 11 25 10 9

# or if you have both connected,
# reset_config trst_and_srst srst_push_pull

# Each of the SWD lines need a gpio number set: swclk swdio
# Header pin numbers: 23 22
bcm2835gpio_swd_nums 11 25

# If you define trst or srst, use appropriate reset_config
# Header pin numbers: TRST - 26, SRST - 18

bcm2835gpio_trst_num 7
# reset_config trst_only

bcm2835gpio_srst_num 18
#reset_config srst_only srst_push_pull

# or if you have both connected,
reset_config trst_and_srst srst_push_pull

OpenOCD spustíme příkazem (pozor na pořadí parametrů):

sudo openocd -f interface/raspberrypi2-native.cfg -c "transport select swd" -f target/stm32f3x.cfg
nebo
sudo openocd -f interface/raspberrypi2-native.cfg -c "transport select jtag" -f target/stm32f3x.cfg

A už nám OpenOCD pěkně čeká na spojení (pozor na Discavery Boardech je třeba odpojit piny STLinku a někdy i tahá za další, takže odpojení a připojení napájení destičky vždy pomohlo).


Po připojení většinou procesor běží, je nutné ho zastavit příkazem:
reset halt

a nyní již můžeme vyčíst registry:


Dále si můžeme nechat zobrazit paměť (šuf obsah FLASH).


Dále se zeptáme na paměťové banky - ověříme si, že FLASH je zde namapována od adresy 0x08000000


A stáhneme si obsah flash paměti





a když už máme FW, tak co se takhle do něho podívat? Využil jsem to jako první seznámení s radare2:

ToDo:

pohrát si s binwalk, nejlépe si vyčíst FW z OpenWRT routeru.
https://www.youtube.com/watch?v=GIU4yJn2-2A
https://www.youtube.com/watch?v=8dXhrOEGHTY
https://www.youtube.com/watch?v=oXSx0Qo2Upk

Jinak OpenOCD bylo nutné přeložit, pro Presto je potřeba ještě přeložit také knihovnu libftdi a potom už svatá trojka.

nebo libftdi je možné nainstalovat sudo apt-get install libusb-1.0 libusb-dev a změnit --prefix na "--prefix=/usr/"

./configure \
--enable-ftdi \
--enable-stlink \
--enable-ti-icdi \
--enable-ulink \
--enable-dummy \
--enable-usb-blaster-2 \
--enable-jlink \
--enable-osbdm \
--enable-opendous \
--enable-aice \
--enable-vsllink \
--enable-usbprog \
--enable-rlink \
--enable-armjtagew \
--enable-parport \
--enable-jtag_vpi \
--enable-usb_blaster_libftdi \
--enable-amtjtagaccel \
--enable-gw16012 \
--enable-ep93xx \
--enable-presto_libftdi \
--enable-openjtag_ftdi \
--enable-buspirate \
--enable-sysfsgpio \
--enable-arm-jtag-ew \
--enable-bcm2835gpio \
--enable-at91rm9200 \
--enable-ft2232_libftdi \
--enable-parport-ppdev \
--enable-parport-giveio \
--enable-remote-bitbang \
--prefix=/home/pi/libftdi1-1.4/libftdi1-1.4/
make
make install

https://pinout.xyz/

pátek 19. února 2016

Vlhkoměr ST HTS221

Nejprve si zavedeme potřebné moduly (1-wire je pro porovnání teploty).

insmod w1-gpio-custom bus0=0,14,0

insmod i2c-gpio-custom bus0=0,16,17

Dále vyhledáme dostupné senzory na I2C sběrnici, HTS221 má adresu 0x5f. Následuje vyčtení registru WHO_I_AM a konfigurace senzoru (přechod ze sleep režimu a zapnutí periodického vzorkování, případně změna vzorků pro výpočet jedné hodnoty).

root@AR150:~# i2cdetect -y 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- 1e --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- 5d -- 5f
60: -- -- -- -- -- -- -- -- -- -- -- 6b -- -- -- --
70: -- -- -- -- -- -- -- --

root@AR150:~# i2cget -y 0 0x5f 0x0f
0xbc
root@AR150:~# i2cget -y 0 0x5f 0x10
0x3f
root@AR150:~# i2cget -y 0 0x5f 0x28
0x7d
root@AR150:~# i2cget -y 0 0x5f 0x29
0xf4
root@AR150:~# i2cget -y 0 0x5f 0x2a
0xed
root@AR150:~# i2cget -y 0 0x5f 0x2b
0x00
root@AR150:~i2cset -y 0 0 0x5f 0x21 0x00 # disable heater
root@AR150:~# i2cget -y 0 0x5f 0x20 # Read Control Register 1
0x00
root@AR150:~# i2cget -y 0 0x5f 0x20
0x00
root@AR150:~# i2cset -y 0 0x5f 0x10 0x81 # use 2 smaple for Temperature and 4 sample for Humidity
root@AR150:~# #i2cset -y 0 0x5f 0x10 0x20 # use 32 smaples for Temperature and 4 sample for Humidity
root@AR150:~# #i2cset -y 0 0x5f 0x10 0x38 # use 256 smaples for Temperature and 4 sample for Humidity
root@AR150:~# i2cset -y 0 0x5f 0x20 0x81 # start 1 Hz measuring
root@AR150:~# #i2cset -y 0 0x5f 0x20 0x81 # start one conversion

Nebo si můžeme pomocí root@AR150:~# i2cdump -y 0 0x5f vyčíst kompletní obsah paměti čidla včetně kalibrace. 


0
1
2
3
4
5
6
7
8
9
a
b
c
d
e
f
0123456789abcdef
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
bc
...............?
10:
3f
00
97
32
98
be
de
a1
9e
b2
fb
00
08
00
80
82
?.?2???????.?.??
20:
81
00
00
00
00
00
00
03
c7
f6
12
01
dd
f7
0a
01
?......?????????
30:
40
90
a1
0d
00
c4
03
00
f6
02
29
d5
ff
ff
ed
02
@???.??.??)?..??
40:
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
................
50:
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
................
60:
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
................
70:
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
................
80:
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
bc
...............?
90:
3f
00
97
32
98
be
de
a1
9e
b2
fb
00
08
00
80
82
?.?2???????.?.??
a0:
81
00
00
00
00
00
00
00
c7
f6
12
01
dd
f7
0a
01
?.......????????
b0:
40
90
a1
0d
00
c4
03
00
f6
02
29
d5
ff
ff
ed
02
@???.??.??)?..??
c0:
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
................
d0:
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
................
e0:
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
................
f0:
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
................

Kalibrace:
40
90
a1
0d
00
c4
03
00
f6
02
29
d5
ff
ff
ed
02

WHO_I_AM         0xbc
bc

HUMIDITY          0xF6C7
c7
f6

TEMP                    0x0112
12
01

Nejprve je třeba udělat výpočet kalibrační křivky, dle hodnot z registrů kalibrace.
Pro teplotu je třeba vzít desetibitové číslo z adresy 0x32 (představuje dolních 8 bitů) a ještě přidat dva bity z adresy 0x35 a vydělíme osmi. V našem případě získáme čísla T0 = 0010100001b => 161/8 = 20,125 °C a T1 = 0100001101b => 269/8 = 33,625 °C. Těmto dvěma bodům odpovídají T0_OUT a T1_OUT, což jsou dvoubajtové znaménkové hodnoty z adres 0x3C, 0x3D (-1) a 0x3E, 0x3F (749). Znaménko v čísle představuje nejvyšší bit (MSB), pokud není nastaven je číslo kladné a stačí vzít zbytek bytů. V opačném případě je číslo záporné a je třeba od maximálního rozsahu čísla (32768) odečíst zbytek bitů a přičíst jedničku a následně celé číslo vynásobit mínus jednou. Rozsah čísla je tedy -32768 až 32767.

Když máme vyčteny souřadnice dvou kalibračních bodů (-1 - 20,125 a 749 - 33,625), tak si můžeme sestrojit kalibrační přímku. Koeficienty rovnice přímky určíte dosazením do dvou rovnic o dvou neznámých (potřebujeme získat neznámé k a q).

f(x) = k*x + q

20,125 = -k + q /*(-1)
33,625 = 749k + q

-20,125 = k - q
33,625 = 749k + q

13,5 = 750k => k = 13,5/750 = 0,018
20,125 = -0,018 + q => q = 20,125 + 0,018 = 20,143



Výpočet teploty z hodnoty provedeme takto:

T = k * x + q = 0,018 * (0x0112) / 8 + 20,143 = 20,7595 °C.

A porovnání s DS1820?


Stejný výpočet provedeme i pro získání vlhkosti:

H0_rH_x2 = 0x40 / 2 = 32 %, H0_T0_OUT = 0x0003 => 3
H1_rH_x2 = 0x90 / 2 = 72 %, H1_T0_OUT = 0xD529 => 54 569

f(x) = k * x + q

32 = k * 3 + q
72 = k * 54 569 + q /*(-1)

32 = 3 * k + q
-72 = -54 569 * k - q

-40 = - 54 566 k

k = 40/54566 = 7,33 * 10-4
q = 31,9978

H = k * x + q = 7,33E-4 * (0xF6C7) / 2 + 31,9978 = 55.15%.

Vlhkoměr má také zabudované vyhřívání pro odstranění kondenzované vlhkosti, stačí ho zapnou a z grafu je patrné, že vlastní substrát čidla se ohrál na téměř 70 °C. Vyzařované teplo dokonce dokázalo ohřát pět milimetrů vzdálený DS1820, viz následující grafy (teplota čidel a vývoj vlhkosti).



#!/bin/sh

i2cset -y 0 0x5f 0x21 0x00 # disable heater
i2cset -y 0 0x5f 0x20 0x81 # start one conversion

Time=`date +"%m.%d.%Y %T"`

T_l=`i2cget -y 0 0x5f 0x2a` # read T_l
T_h=`i2cget -y 0 0x5f 0x2b` # read T_h


H_l=`i2cget -y 0 0x5f 0x28` # read H_l
H_h=`i2cget -y 0 0x5f 0x29` # read H_h

DS18B20=`cat /sys/devices/w1_bus_master1/28-000001f3830f/w1_slave | tail -1`  # read temperature from DS1820

echo -e "$Time\t$T_l\t$T_h\t$H_l\t$H_h\t$DS18B20" # echo to colsole
echo -e "$Time\t$T_l\t$T_h\t$H_l\t$H_h\t$DS18B20" >> /tmp/data.txt # write to file

chmod +x /usr/bin/measure.sh

*/5 * * * * /usr/bin/measure.sh



http://www.st.com/web/en/resource/technical/document/datasheet/DM00116291.pdf