RPi3 DHT22 fedora-arm/raspbian

 ( makgab | 2016. december 10., szombat - 13:17 )

Üdv!
Próbálom a $subjectet összehozni.
* DHT22
* RPi3 GPIO

A próbapanelon a DHT22-nek a hozzá kapott ellenállást az 1-2 láb közé tettem.
Az RPi3 GPIO-jára a fenti kép alapján kötöttem:

01 pin: DHT22 3.3V power (láb 1)
07 pin: DHT22 DATA (láb 2) # <---- ez a GPIO_04 pin
09 pin: DHT22 GND (láb 4)

A fedora-arm lsmod kimenete:

# lsmod
Module Size Used by
gpio_keys 16384 0
fuse 98304 3
gpio 16384 0
nand 57344 1 gpio
nand_ecc 16384 1 nand
nand_ids 12288 1 nand
mtd 61440 2 gpio,nand
ip6t_rpfilter 16384 1
ip6t_REJECT 16384 2
nf_reject_ipv6 16384 1 ip6t_REJECT
xt_conntrack 16384 15
ip_set 40960 0
nfnetlink 16384 1 ip_set
ebtable_broute 16384 1
bridge 122880 1 ebtable_broute
stp 16384 1 bridge
llc 16384 2 bridge,stp
ebtable_nat 16384 1
ip6table_mangle 16384 1
ip6table_security 16384 1
ip6table_raw 16384 1
ip6table_nat 16384 1
nf_conntrack_ipv6 16384 9
nf_defrag_ipv6 24576 1 nf_conntrack_ipv6
nf_nat_ipv6 16384 1 ip6table_nat
iptable_mangle 16384 1
iptable_security 16384 1
iptable_raw 16384 1
iptable_nat 16384 1
nf_conntrack_ipv4 16384 8
nf_defrag_ipv4 16384 1 nf_conntrack_ipv4
nf_nat_ipv4 16384 1 iptable_nat
nf_nat 24576 2 nf_nat_ipv6,nf_nat_ipv4
nf_conntrack 106496 6 nf_conntrack_ipv6,nf_conntrack_ipv4,nf_nat_ipv6,xt_conntrack,nf_nat_ipv4,nf_nat
ebtable_filter 16384 1
ebtables 24576 3 ebtable_filter,ebtable_nat,ebtable_broute
ip6table_filter 16384 1
ip6_tables 24576 5 ip6table_mangle,ip6table_filter,ip6table_security,ip6table_raw,ip6table_nat
smsc95xx 32768 0
usbnet 40960 1 smsc95xx
mii 16384 2 usbnet,smsc95xx
vc4 86016 1
drm_kms_helper 151552 2 vc4
dwc2 163840 0
drm 319488 4 vc4,drm_kms_helper
fb_sys_fops 16384 1 drm_kms_helper
syscopyarea 16384 1 drm_kms_helper
sysfillrect 16384 1 drm_kms_helper
udc_core 49152 1 dwc2
sysimgblt 16384 1 drm_kms_helper
bcm2835_dma 20480 0
bcm2835_rng 16384 0
bcm2835_wdt 16384 0
leds_gpio 16384 0
nfsd 319488 1
auth_rpcgss 61440 1 nfsd
nfs_acl 16384 1 nfsd
lockd 90112 1 nfsd
grace 16384 2 nfsd,lockd
sunrpc 319488 7 auth_rpcgss,nfsd,nfs_acl,lockd
mmc_block 40960 4
sdhci_iproc 16384 0
sdhci_pltfm 16384 1 sdhci_iproc
sdhci 49152 2 sdhci_pltfm,sdhci_iproc
mmc_core 139264 3 sdhci,mmc_block,sdhci_iproc
pwm_bcm2835 16384 0
i2c_bcm2835 16384 0

A tesztelő cpp kód (fedora-arm codeblocks lefordítja hiba nélkül):

#include < iostream >
#include < iomanip >
#include < sstream >
#include < string >
#include < ctime >
#include < csignal >
#include "pi_dht_read.h"

using namespace std;

const int TYPE = AM2302; // DHT22
const int PIN = 4; // GPIO_04 PIN number

void signalHandler(int signum)
{
cout << "Interrupt signal (" << signum << ") received! " << endl;
exit(signum);
}

int main()
{
signal(SIGTERM, signalHandler);

float rh, temp;
stringstream s_rh, s_temp;
int res;
struct timespec end, current;
struct tm date;
char format[] = "%Y-%m-%d %H:%M:%S.";
char buf[21];
string timestamp;

while (true) {
clock_gettime(CLOCK_MONOTONIC, &end);
end.tv_sec += 5;

clock_gettime(CLOCK_REALTIME, &current);
localtime_r(&current.tv_sec, &date);
strftime(buf, sizeof buf, format, &date);
timestamp = buf;
timestamp.append(to_string(current.tv_nsec).substr(0, 3));

int i = 0;
do {
res = pi_dht_read(TYPE, PIN, &rh, &temp);

sleep_milliseconds(1000);

i++;
} while (res != DHT_SUCCESS && i < 4);

s_rh.str(string());
s_temp.str(string());

if (rh!=0)
s_rh << setprecision(1) << fixed << rh;
else
s_rh << "NULL";

if (temp!=0)
s_temp << setprecision(1) << fixed << temp;
else
s_temp << "NULL";

cout << "'" << timestamp << "' " << s_rh.str() << " %RH " << s_temp.str() << " degC [" << i << "]" << endl;

clock_gettime(CLOCK_MONOTONIC, &current);
// waiting a while...
}

return 0;
}

Futtatáskor nem kapok eredményt vissza (NULL). Mit felejtek el?
(Ez korábban Pi2-n /raspbian/ ment szépen.)

Vagy RPi3 nem fog így menni?

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

Van valakinek DHT22 szenzorhoz minta cpp (vagy python) kódja, ami ment RPi3 eszközzel?

Az adafruitosoknak van minta kodja, benne van a pip-ben egy kesz python modul, az hasznalhato/ irhato az alapjan sajat.

Én hallottam rosszakat pi-dht témában, szerintem a legtisztább egy filléres arduino-t közé tenni.
Ezt leszámítva szerintem két probléma lehet: a felhúzó ellenállás (pullup resistor) nagysága illetve a pi config.txt.
Illetve lehet az adott io port is dög, ez már 3. én ezekkel játszódnék első körben ha mindenképp direktben akarnám pi-ről használni.

Megvan a teljesitmeny es minden hozza, hogy feldolgozza ezt a jelet az rpi, igy miert kellene koze rakni barmit? Ellenallas jo, bar en egy 10k-sat tennek, de nem ez a gond.
El kellene kezdeni meregetni mindent. Latnod kellene, hogy a doksiban is szereplo start signal az van-e es erkezik-e valasz utana ra.

https://github.com/adafruit/Adafruit_Python_DHT/blob/master/source/Raspberry_Pi/pi_dht_read.c#L68

Ha nincs ra eszkoz, akkor visszaraknam a regi rpi-re, ahol ez mukodott, hogy mukodik-e meg ... Vaaaagy a pi_dht_read-et telepakolnam print-ekkel, ami ugyan idozitesi problemakat fog okozni (mukodeskeptelenne teve a kodot), de legalabb lathatova tenne, hogy bejovo impulzus van-e.

Teljesítmény tuti van, csak az pont nem kell hozzá. Pártíz mikroszekundumos jelek mérésére valami fix és kiszámítható dolgot használnék, egy általános célú linux kernel pedig nem ilyen. Persze működik, kivéve amikor nem, erre példa ez a topic.
Mikrokontrollerrel ez egyszerű, van rá lib, gyakorlatilag loop-ban olvasgatod a szenzort és az eredményt tolod ki sorosan, az egész kód megáll pártucat sorban. Csak két dologra kell figyelned, hogy megfelelő portsebességet állíts be (bár ezt a pi oldaláról próbálgatva is megoldhatod automatán), illetve hogy ha 5V-os a uC akkor egy feszültségosztót tegyél be a pi RC és a uC TX lába közé.
És ez akkor is működik ha kernelt cserélsz.

+1

Már rég megcsináltam volna egy kis PIC-kel egy illesztőt, amelyiknek az egyik végén ez a páratartalom és hőmérséklet mérő szenzor van, míg a másikon az R-Pi I2C-n érdeklődik a szenzor sorsa felől. Ma már lényegében az összes PIC megy 3.3 V-ról is, szóval a jelszint sem probléma. Kernel release-enként sem kell forrásból fordítani. Ha kell, a mikrokontrollerben ASCII szöveggé konvertálnám az adatot, hogy ne kelljen sokat bajlódni vele az R-Pi-ben. De ez már annyira részlet kérdés. A mikrokontrollerben nem is kell lennie hardware I2C támogatásnak, simán lehet implementálni software-ből egy slave interface-t.


tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

"...egy általános célú linux kernel pedig nem ilyen. Persze működik, kivéve amikor nem, erre példa ez a topic."

A topik pont nem ezt mutatja, csak annyi a probléma, hogy a gyári kernelben nincs "bcm2835-gpiomem" modul.
Ahogy lent olvasható tökéletesen működött raspbianon.
Elég sok szenzort próbáltam már sima RPi-n (RPi A modell!), gond nélkül mentek! Pedig több olyan mérés is volt, ahol másodpercenként 10 mérést kellett végezni.
Ezzel csak azt akartam mondani, hogy RPi-vel is meg lehet oldani ezeket a feladatokat. (Lehet hogy mikrovezérlővel az ideális.)

Azért az életemet nem bíznám rá. Ez akkor is adott valószínűséggel megy jól - tehát nem garantáltan -, bízunk abban, hogy a magas prioritás elég a kernelnek ahhoz, hogy ne vegye el épp ott a vezérlést, de egy IT vagy DMA még mindig megkeserítheti az életed. Innentől meg valószínűségi dolog ez, s még egy nyamvadt CRC sincs a szenzor felől, hogy kidobjuk a nyilvánvalóan hibás mérési eredményeket. Otthoni sufni tuningnak jó, de komolyabb helyen ezt mikrokontrollerrel kell illeszteni az operációs rendszerrel rendelkező géphez.

Hibaelfedést persze lehet csinálni. FIFO-ba tunkolod a mérési eredményeket, például szám szerint 6-ot. Minden mérést követően szélső értéket keresel, a legkisebbet és legnagyobbat eldobod, a maradék 4-ből számtani közepet számolsz. Ezzel eliminálod a ritkán bekövetkező fals méréseket, de jaj neked, ha 6 mérésen belül volt két hibás mérés.


tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

A kód egy teszt kód volt, nem éles. Bár benne van, hogy 4db mérést csinál.
Éles helyzetben természetesen a hibás mérést figyelni kell, ahogy írtad is. De a fenti egy teszt kód!
Éles környezetben is jól megy az RPi, persze jól meg kell tervezni.

Igen, a lényeg a jó tervezés. A jó tervezés pedig azt is jelenti, hogy az ember felméri, mire képes önállóan az RPi. Amire az jön ki, hog nem képes, arra kell választani alkalmasabb eszközt. Jelen esetben egy mikrovezérlőt :)
(Nem véletlenül van a Málnához tervezett Gertboardokon is valamilyen mikrovezérlő.)

Éles környezetben is jól megy az RPi

Jól megy, csak a feladatra alkalmatlan. Úgy értem, már elvileg sem garantálható, hogy real time feladatot megoldjon. Ez nem szempont egy ilyen operációs rendszernél, s ennek megfelelően nem is tudja. Persze lehet abban reménykedni, hogy nem épp most üt be egy IT vagy zajlik egy nagyobb blokk RAM-ba, vagy RAM-ból DMA-zása. Ettől még működik úgy, hogy az esetek igen nagy százalékában jó eredményt ad vissza az a függvény, amelyik az impulzusok szélességét méri.

Nyilván, ha csak az a feladat, hogy a systray-n kiírja, hány fok van, s mennyire nedves a levegő, arra teljesen jó. Ott az is belefér, ha két óránként egyszer valami eszement hülyeség jelenik meg, amit ráadásul software-esen ki is tudsz szűrni.


tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Éles környezetben (ipari környezetben) is jól működik. Nekem is van évek óta működő ilyen eszközöm.
RPi-re is lehet realtime OS-t tenni, nyilván mikrokontroller az ideális. De most nekem nem ez a célom.

Bocs, de itt a tapasztalat kevés. Ha tudod, hogy elvileg hibázhat, ott a potenciális hibalahetőség, s csak a szerencsének köszönhetően nem jön elő a hiba, attól az még tervezési hiba, az továbbra is rossz. Ez ilyen. Amolyan nagyjából jó, többnyire jó, általában jó, de nem garantáltan jó.


tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Igen, az adott célt tökéletesen ellátja az adott helyen.

Khmm...
Mióta szopsz már ezzel, ami "tökéletesen ellátja"?
No offense, de erről a "vadász, vadász..." klasszikus jut az eszembe...

Ha nem volt érthető, akkor nem fogalmaztam világosan:
* Eddig raspbian-on minden tökéletesen működött és most is működik.
* Most csak szerettem volna megnézni ugyanezt fedora-arm OS-en. Mivel a Fedora Remix/Pidora "megállt", ezért ezen próbálkozom. Tetszik is, de mivel általános arm architektúra, ezért lehet (ill. biztos), hogy a gpiomem nincs belefordítva a kernelbe. Ha lesz időm talán fordítok majd egy ilyet. Vagy megnézek egy korábbi Fedora Remix/Pidora-t.

Tehát működik az eredeti projekt, ez csak egy teszt volt. Kíváncsi voltam a fedora-arm-ra RPi-n.

* Eddig raspbian-on minden tökéletesen működött és most is működik.

Nem. Csak a működés látszatát kelti, a megoldás elvi hibás véleményem szerint. Az más kérdés, hogy Fedorán még ezt sem sikerült egyelőre összehozni. Viszont jelen topic vége felé lévő megoldást nézd meg, az még akár működhet is. Úgy értem, üzembiztosan, elvileg is jól akár.


tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Dallas buszon kommunikál ha jól tudom.
Ekkor:
modprobe w1-gpio
modprobe w1-therm

És a /sys-ben valami w1 kezdetű mappa alatt megtalálod azonosítószáma alapján az eszközt, a fájlt kiolvasva pedig az értékeket.

erősen kevered a ds18b20-al...

KoviX

Igen, utánanéztem. Látom a DHT22 kezelését, bár a Dallas-féle 1wire-s busznak néz ki, sajnos eddig nem implementálták ebben a kernelmodulban. Kár, mert igencsak leegyszerűsítené ennek a toknak az alkalmazását.

Nem volt még R-Pi-m, de az a 7-es láb nem valami szinkron órajel? A GPIO_GCLK valami ilyesmit sugall. Lehet, az adatot inkább a 12-es lábra kötném, s a programon is ennek megfelelően módosítanék.


tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Ott is ugyanaz: NULL
:(

De remélem, a programot is átírtad hozzá, hogy azt a bitet kezelje.

Anélkül, hogy ránéztem volna a kódra: a felhúzó ellenállásból következik, hogy huzalozott VAGY kapcsolatot álmodott a gyártó, tehát a kimeneteknek nyitott kollektorosnak - vagy open drain, de ez most a lényeg szempontjából ugyanaz - kell lenniük. Ha két irányú a kommunikáció, akkor ezt úgy lehet kezelni, hogy adatként konstans 0-t teszel a kimenetre, majd ha alacsony szintet, tehát 0-t akarsz hajtani kifelé, akkor kifelé forgatod a portodat, ha magas szintet, azaz 1-t szeretnél küldeni, akkor befelé forgatod. Ekkor nagy impedanciás lesz a kimeneted, de a felhúzó ellenállás miatt magas szint alakul majd ki.

Hasonlóképpen befelé kell forgatnod a portot, ha azt bemenetként használod, s közben figyelned kell, ha úgy tetszik, mintát kell venned, mi jön befelé.

Úgy látom, itt csak aszinkron kommunikáció jöhet szóba, így az időzítésnek fontos szerep jut, nem tudom, hogy ezt egy általános célú operációs rendszer kernele képes-e, akarja-e teljesíteni. Mindenesetre szerintem real time kernel kell hozzá, hacsak nem annyira lassú és az időkre érzéketlen a kommunikáció, hogy szinte bármi belefér.


tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Átírtam persze, de milyen kernel modul kell a működéshez?
A wiringpi-t is próbáltam (v2.32), azt írta emailben Gordon, hogy a Pi3 is támogatott.
Lefordul, települ, de:

~# sudo /usr/local/bin/gpio readall
Unable to determine hardware version. I see: Hardware : Generic DT based system
,
- expecting BCM2708 or BCM2709.
If this is a genuine Raspberry Pi then please report this
to projects @ drogon.net. If this is not a Raspberry Pi then you
are on your own as wiringPi is designed to support the
Raspberry Pi ONLY.

Tudom, a wiringpi-t nem szeretik itt többen. :)

Nem mondtam, hogy kell. Az a gondom, hogy egy userland-ben futó programról semmit sem tudsz mondani az időzítések vonatkozásában. Ahogy nézem a katalóguslapot, 26 µs szélességű jelet fel kell tudnod dolgozni, tehát ha bitközépen veszel mintát, máris 13 µs-nál járunk. Na most, mi van akkor, ha ilyenkor task váltás történik? Vagy becsap egy IT, amelynek a kiszolgálása hosszabb néhány 10 µs-nál? Ilyesmit mikrokontrollerhez szokás illeszteni, amellyel kézben tarthatóak az időzítések, s valami szabványos, hardware támogatott interface-en - pl. i2c - illeszteni a „nagy” géphez, ezúttal ez az R-Pi.

Ahhoz, hogy ilyen keskeny impulzusokat garantáltan, adatvesztés nélkül fel tudj dolgozni, szerintem kernelmodul kell, amelyik a megfelelő élváltást követően garantálni tudja adott időben történő mintavételezését a vonalnak. Már, ha közvetlenül a „nagy” géppel akarod intézni az eszköz kezelését.


tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Most látom, beszélek itt neked a hardware-ről, de ez a program nem csinál semmi érdekeset, csak kész dolgokat használ fel, a dolgok kulcsa a pi_dht_read() függvényben lakozik valahol. Mellesleg debugolj, legalább azt nézd meg, az az i változó mennyi, amikor kilép a ciklusból. Arra tippelek, hogy megpróbálkozik 4-szer, sikertelen lesz 4-szer, így i==4, amikor kilép. Ha ezt tudod, máris közelebb vagy. Ha van digitális tároló szkópod, akkor tudsz mérni, ha nincs, akkor kreatívnak kell lenned.


tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Szerintem megtaláltam, mi a baja, itt van a kód.

A gond az, hogy CPU futásidővel mér időt, s szerintem az R-Pi3 gyorsabb az elődeinél. Ha ez így van, akkor elég gyorsan eléri a timeout időt úgy, hogy még mérnie kellene a bitidőt. Így aztán mindig hibára fut, s mindig timeout-tal tér vissza.

A megoldás az volna - ha már ennyire gány a kód -, hogy vagy nagyobb timeout konstansokat használsz a pi_2_dht_read.c forrásban, de figyelsz a számábrázolásra, s kiszámolod, nehogy túlcsorduljon, vagy a megfelelő helyekre lassító for ciklusokat írsz, ekkor meg arra figyelsz, hogy a ciklusváltozó volatile legyen, különben a fordító optimalizálja, s az egész ciklusodat megszünteti, mint ha le sem írtad volna. :)

Elvileg a DHT_MAXCOUNT értékét meg tudod növelni, mert ha jól látom, a számláló 32 biten van ábrázolva. Így viszont nagyon könnyű javítani. :)


tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

A DHT_MAXCOUNT növelése sajnos nem segített. Most próbálok debuggolni.
Ennyire nem lehet gyors a Pi3... :)

A DHT22 szenzort mivel tudnám tesztelni, hogy jó-e?

update:
A pi_2_dht_read(TYPE, PIN, &rh, &temp) nem DHT_SUCCESS értéket ad vissza.
Ezért ismétel, de azt kidebuggoltam, hogy -4, azaz DHT_ERROR_GPIO.
Kérdés, hogy ez pontosan mit jelent? Nem éri el a GPIO-t?

Akkor ez tér vissza hibával.

Azt kellene megnézni, hogyan hivatkozik a kernel a GPIO-ra, az valami device file-e, ugyanúgy hívják-e, mint a korábbi R-Pi-ben, ha file-ként láttatja a kernel, vajon egyes offsetekkel lehet elérni, mi legyen a bemenet, kimenet, mi az adat, egyáltalán van-e erről valamilyen doksi. Gondolom, hogy van, hiszen a kernel nyílt forrású, és kezeli, csak ezek szerint nem úgy, nem azzal a névvel, mint a korábbi R-Pi-k esetében.

Szerk.: Ha a pi_2_mmio_init() hívása után kiíratod, mivel tér vissza ez a függvény, közelebb leszel a megoldáshoz, hiszen a forrásból látni fogod, hogy hol lépett ki, s miért. De ha minden ötleted elfogyott, a pi_2_mmio_init() függvénybe is tehetsz debugot, csak ne felejtsd el le is fordítani utána. ;)


tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

A pin paraméter még érdekes lehet, hogy itt pontosan mit jelent.
A GPIO lábai (pin), ami 1-40 lehet, vagy a GPIO megnevezése. Pl. pin#11 --> GPIO17

update:
Megvan a hiba pontosabb helye. A pi_2_mmio_init() "-1" hibával tér vissza, azaz MMIO_ERROR_DEVMEM.
Valóban nincs /dev/gpiomem eszköz. :(
Ehhez kellene egy kernel modul(?).

Ezt hogyan tudnám lefordítani kernel modulként? https://github.com/raspberrypi/linux/blob/rpi-4.4.y/drivers/char/broadcom/bcm2835-gpiomem.c

A fedora-arm alatt kellene a bcm2835-gpiomem modul.
Kipróbáltam Raspbian-2016-11-25 alatt és simán működik az alapbeállításokkal. :)

A PIN pedig a GPIO pinje, tehát 11-es láb: GPIO_#17
ezért a kódban a

int PIN = 17;

Van egy rakás GPIO modul a Fedora 25 4.8.14-es kernelében. Lehet, hogy csak más a neve. Létezik például gpio-generic. Ezzel nem oldható meg? Arra már én sem emlékszem, hogyan kell kernel modult hozzá ordítani a kernelhez. Szerintem a kernel-devel és kernel-headers csomagok kellenek hozzá, de a mikéntjéhez doksit kell olvasni.


tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

csak ezek vannak:
gpio-74x164 gpio-charger gpio-da9055 gpio-fan gpio-max7301 gpio-mc33880 gpio-syscon gpio-twl4030 gpio-viperboard gpio-zynq
gpio-beeper gpio-da9052 gpio-dwapb gpio-ir-recv gpio-max730x gpio-pcf857x gpio-tps65912 gpio-twl6040 gpio-wm8994

A gpio-generic modul ott van a kernel-core-4.8.14-300.fc25.armv7hl.rpm file-ban, szerintem a kernel image-ben. Viszont lehet, hogy ez nem segít, mert nem kizárt, hogy kell egy hardware specifikus modul is.

Szerk.:

modinfo gpio-generic

mit mond?


tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE


# modinfo gpio-generic
modinfo: ERROR: Module gpio-generic not found.

# uname -r
4.8.12-300.fc25.armv7hl

4.8.13 verziót ajánlja fel a dnf.

update:
4.8.13: itt is ugyanez: not found

Megvárjam az általad jelzett verziót? Vagy testing repo-ban volt?

A koji build szerveren megtalálod. Viszont ilyen alverzióknál a konfig nem szokott változni, szóval azon túl, hogy friss kerneled lesz, szerintem ez nem fog segíteni.


tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Nem levélben válaszolok, hanem itt.

http://www.thegeekstuff.com/2013/07/write-linux-kernel-module/

http://www.tldp.org/LDP/lkmpg/2.6/html/lkmpg.html

Szerintem szorgalmasan nézegesd a netet. ;)


tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Simán lefordult a modul, de nem működik. :(


# Makefile ----------

obj-m += bcm2835-gpiomem.o

all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

# --------------------

Majd:

~# make

make -C /lib/modules/4.8.13-300.fc25.armv7hl/build M=/home/admin/bcm2835 modules
make[1]: Entering directory '/usr/src/kernels/4.8.13-300.fc25.armv7hl'
CC [M] /home/admin/bcm2835/bcm2835-gpiomem.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/admin/bcm2835/bcm2835-gpiomem.mod.o
LD [M] /home/admin/bcm2835/bcm2835-gpiomem.ko
make[1]: Leaving directory '/usr/src/kernels/4.8.13-300.fc25.armv7hl'

~# sudo insmod bcm2835-gpiomem.ko

~# sudo modinfo bcm2835-gpiomem.ko
filename: /home/admin/bcm2835-gpiomem/bcm2835-gpiomem.ko
author: Luke Wren
description: gpiomem driver for accessing GPIO from userspace
license: GPL
alias: platform:gpiomem-bcm2835
alias: of:N*T*Cbrcm,bcm2835-gpiomemC*
alias: of:N*T*Cbrcm,bcm2835-gpiomem
depends:
vermagic: 4.8.13-300.fc25.armv7hl SMP mod_unload ARMv7 p2v8

A /dev/gpiomem eszköz továbbra sem jött létre. Továbbra is csak /dev/gpiochip0 van. :(
A "gpio readll" ugyanazt a hibát adja.

Szerintem közelebb vagy a megoldáshoz. Lehet, hogy működik az. Próbáld mknod paranccsal létrehozni a device file-t. Illetve az a gyanúm, ahhoz, hogy ez automatizmus legyen, kellhet valami udev rule is.


tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

A dmesg-ben látom:
[ 1080.329930] bcm2835_gpiomem: loading out-of-tree module taints kernel.
[ 1080.330074] bcm2835_gpiomem: module verification failed: signature and/or required key missing - tainting kernel
[ 1081.381594] i2c-bcm2835 3f805000.i2c: i2c transfer failed: 100
[ 1081.381752] i2c-bcm2835 3f805000.i2c: i2c transfer failed: 100

Szerintem ez csak arra utal, hogy ha elszállna a kerneled, s bug reportolnál, a kernel fejlesztői ignorálnák a jelzésed. Annak nem néztem utána, ezen felül van-e ennek jelentősége.


tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Az lsmod-ban ott van a modul, csak a gpiomem eszköz nem jött létre. :(

Hozd létre!

man mknod


tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

mknod régen volt már. :)
milyen major/minor számmal kellene létrehozni?

Nem tudom. Esetleg dmesg nem mond semmit, amikor betöltöd a modult? Egyáltalán mit jelentenek ezek a számok? Kernek doksiból, vagy az általad lefordított modul forrásából ez nem deríthető ki? Esetleg a raspbian-ból nem tudsz puskázni?


tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Meg is néztem már:
mknod /dev/gpiomem c 244 0

Viszont nem változott semmi, "gpiomem hiba". Valami még kell neki... mind1... majd folytatom...

Tisztellek a kitartásodért, s egyben szorítok, hogy sikerüljön. Csak az efféle állhatatosság vezet ebben a szakmában eredményre. A bejegyzéseid alapján úgy érzem, egyre közelebb vagy a célhoz. :)


tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Nem szabad feladni. Egyszerűen érdekel a téma. :)

Nem mellesleg, mi lenne, ha egy pár száz forintos PIC mikrokontrollerrel csinálnál hozzá egy I2C illesztőt? Meglenne az a kellemetessége, hogy nem kellene minden kernel update után kernel modult frissíteni, továbbá valóban korrekt lenne az illesztés, s még tanulnál is belőle.


tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Szép sorban. Ha raspbianon megy gond nélkül, akkor fedora-arm-on is menni fog. Nem? :)

Ha raspbianon megy gond nélkül

Ezt a vitát ne kezdjük elölről. Elvileg nem mehet jól. Az, hogy ritkán hibázik, vagy akár az, hogy eddig sohasem hibázott, nem jelenti azt, hogy jó, ha tudjuk róla, hogy előfordulhat, hogy hibázni fog. A másik, hogy gondolom, abba a kernelbe belefordították ezt a modult. Te is bele tudod tenni a Fedorába, épp most sikerült. Csak az a baj, hogy ha egy hét múlva frissül a Fedora kernele, megint fordíthatod újra forrásból ezt a modult.


tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

ok, tudom.

Szerintem ne eroltesd, ha jol mukodo egyszeru megoldast akarna akkor egy $2-os ESP8266 ESP01-gyel oldana meg. :)

Tuti, kos a horoszkópja! :D


tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Jó nagy kokecolás ez a raspberry pi. beaglebonenon annyira jól működik a hozzávaló kernel module, szépen megírt device treevel, hogy csuda.

https://github.com/torvalds/linux/blob/master/drivers/iio/humidity/dht11.c

iio deviceként szépen látszik, és nem kell ocska adafruitos scripteket futtatgatni.


------------------------
Jézus reset téged

Na, erről már elhiszem, hogy üzembiztosan működik, lévén, kernel space-ben fut. Topicgazda, lehet, ebbe az irányba mennék inkább!


tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

A lent említett driver DHT22 támogatást is tartalmazza:
https://github.com/endian-labs/dht11km

Kipróbálom majd.

A make-nek a "mach/hardware.h" hiányzik (no such file or directory).
Ilyen nincs a /usr/src/kernels/`uname -r` alatt. :(

Kipróbáltam ezt is: https://github.com/torvalds/linux/blob/master/drivers/iio/humidity/dht11.c

# Makefile

obj-m += dht11.o

all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

Lefordul raspbian és fedora-arm alatt is, de minegyik esetén ugyanaz a hiba:

~# insmod dht11.ko
insmod: ERROR: could not insert module dht11.ko: Unknown symbol in module

~# dmesg
[ 593.440545] i2c-bcm2835 3f805000.i2c: i2c transfer failed: 100
[ 599.770289] dht11: Unknown symbol devm_iio_device_alloc (err 0)
[ 599.770360] dht11: Unknown symbol devm_iio_device_register (err 0)

https://github.com/endian-labs/dht11km


------------------------
Jézus reset téged

Akkor nincs iio subsystem az rpin. Ird at a modult hogy sima sysfst adjon.
------------------------
Jézus reset téged

Ami hulyeseg hisz van ahol megy. Hmmm
------------------------
Jézus reset téged

Megpróbálom összefoglalni, mit gondolok erről az egészről:

1) Ez az eszköz úgy adja vissza az infót, hogy egy nyitott kollektoros/drain-es kimeneten a vonalat adott ideig alacsony szintre húzza. Ezt az időt kell mérni.

2) A fentiekből következik, hogy viszonylag pontos mérésre van szükség. Helyesebben szólva dehogy, de az nem megengedhető, hogy valami nem várt esemény történik mérés közben, s így elvétjük a mérést.

3) Ezekből aztán az jön, hogy user space-ben ez nem fog menni. Illetve de, viszont ez nagyon gány, esetleges megoldás, amely többnyire működik, de sohasem tudhatod, mikor nem fog. Az, hogy az elmúlt 5 évben egyszer sem hibázott, semmi garanciát nem jelent arra nézvést, hogy a következő egy percben nem fog akár többször is. Erről itt vitatkoztunk eleget. :) Meg lehet, hogy hibázik az, csak nem veszed észre.

4) Valamelyest normálisabb megoldás ezt kernel space-ben megoldani. Igen ám, de baj van akkor, ha a megoldás nem része a vanilla kernelnek, tudniillik, ha sikerül is összehozni a működést, minden frissítés alkalmával újra kell fordítani a kernel modult. Ez azért elég nyűgös tud lenni.

5) Az igazán korrekt megoldás a mikrokontrollerrel történő illesztés. Egyfelől azért, mert az egész processzor a programozó kezében van, lévén nincs oprendszer. Aztán azért, mert jól számolhatók a futásidők. Továbbá azért, mert egy mikrokontrollerben vannak timer-ek, ha úgy tetszik, számlálók, amelyek hardware-ből képesek időt mérni, így ezeket is fel lehet használni. Az intelligens, operációs rendszert tartalmazó gép felé pedig lehet valamiféle szabványos, vagy legalább is szokásos kommunikációs megoldást választani. Például valamilyen szinkron soros kommunikációt, mint amilyen az SPI vagy I2C, de ez lehet aszinkron kommunikáció is, mint például TTL szintű RS232-szerű adatátvitel. Ezekhez jellemzően van hardware támogatás az operációs rendszert futtató gépben, s szabványosságuk, megszokottságuk miatt biztosan van az operációs rendszerben is támogatás hozzájuk. A jó ebben, hogy nem téved, valamint a „nagy” gép frissítése sem töri el a működést, ezen felül a mikrokontroller is intelligens, olyan formában adod át előfeldolgozva az adatot, amelynek a fogadása a legkényelmesebb. Ez tartalmazhat akár mérési hibák, zajok kidobását, csúszóátlagot, de kétirányú kommunikáció esetén a „nagy” gép akár megmondhatja a mikrokontrollernek, hogy ez utóbbi milyen előfeldolgozást követően adja át a mérési eredményeket.


tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Nagyon türelmes vagy :)
Amúgy egyáltalán nem baj, mert nagyon jó lett az összefoglaló. Annyit még érdemes esetleg megjegyezni, hogy a mikrovezérlő "azonnal" (jó, nem azonnal, mert az éppen végrehajtott utasítást még be kell fejezni) képes reagálni a lefutó élre, ha megszakításkezeléssel dolgozom fel a jelet.