[ Megoldva ] Raspberry Pi microseconds

Még csak ismerkedem a Raspberry Pi-vel, de sehogyan sem tudom C-ben megmérni két programpont között eltelt időt minél nagyobb pontossággal.

Azokat a példákat, amiket találtam, nem sikerült valós működésre bírnom.

Tudna valaki mondjuk arra egy példakódot adni, hogy hogyan kaphatom meg az aktuális timestamp-et micro- vagy nanosec pontossággal? Nem kell a valós idő, nekem elég csak egy relatív idő - nem tudom, itt a real time clock hogyan van.

Hozzászólások

Szerkesztve: 2022. 11. 15., k – 21:43

gettimeofday() 

Szerk: kicsit komplexebb pelda:

#include <sys/time.h>

static double timeval_diff(struct timeval *t1,struct timeval *t2)
{
 struct timeval td;
 double         diff;
 td.tv_sec =t2->tv_sec -t1->tv_sec;
 td.tv_usec=t2->tv_usec-t1->tv_usec;
 while ( td.tv_usec<0 )         td.tv_usec+=1000000,td.tv_sec-=1;
 while ( 1000000<=td.tv_usec )  td.tv_usec-=1000000,td.tv_sec+=1;
 diff=(double)td.tv_sec+(double)td.tv_usec/1000000.0;
 return(diff);
}

/* ... */

struct timeval t0,t1;
double diff_seconds;

gettimeofday(&t0,NULL);
do_something_lengthy();
gettimeofday(&t1,NULL);

diff_seconds=timeval_diff(&t0,&t1);

/* ... */

Minek a while, miért nem elég az if? A vessző operátor meg azért van, mert elfogyott a boltban a kapcsos zárójel? :)

Amúgy az egész marha bonyolult így. Át kell számolni mindent µs-ra - vagy akár s-ra -, aztán csak ki kell vonni őket.

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

Azert volt/lett igy abban a projektben amibol kimasoltam mert nem feltetlen volt ott garantalva a rendes normalizalasa a timeval-nak. Lehet hogy ket timeval osszegekent all elo, vagy ilyesmi. Ha garantalva lenne akkor eleg egy if() az elso helyett es a masodik nem is kell. 

Nem, sajnos numerikusan igy stabilabb (double-ba meg ne probald atkonvertalni :]) es megsporolsz relative sok muveletet ami beagyazott rendszereknel feletlenul elonyos lehet (nem lenne elonyos ha pl uint64_t-be konvertalnad at), illetve tudod egyszerusiteni az eletet ha csak arra vagy kivancsi hogy eltelt-e egy (vagy n egesz) masodperc de tort-ido felbontassal kezeled a problemat. De barhogyis, persze, az nem elonyos hogy 10 (es nem 8 vagy 16) ujjal teremtettek minket, az itt is latszik, dehat ez van :)

Nem látok túl sok különbséget a struktúrában tárolt két darab uint32_t vagy az egy darab uint64_t között. 32 bites architektúrán egyik sem lesz atomikus. A double mantisszája tényleg rövid hozzá, meg ugye ott már a 0.1 is végtelen kettedes tört emlékeim szerint, tehát pontatlan lesz.

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

Nem látok túl sok különbséget a struktúrában tárolt két darab uint32_t vagy az egy darab uint64_t között.

Valojaban ez akkor erdekes es/vagy kerdeses hogyha az a kerdes hogy szukseged van-e ott helyben (a beagyazott rendszerbe) valodi masodpercekre. Ha nem, akkor jo az uint64_t is. Ha igen, akkor akkor szamitasban (pl egy RTC-szeru ora jaratasaban) ugyanannyi effort a 2x uint32_t mint az uint64_t, cserebe ezelobbi esetben ott lesz keznel mindig a masodperc, barmilyen orajel-generatorod is legyen. Persze megherkentheto (szinten nem nagy faradsaggal) a kettohatvany alapu masodpercezes is, de itt inkabb a flexibilitast az adja hogy akkor kisebb hetkoznapi alegysegekben (mint pl millisec) is jol tudsz szamolni. Itt ugye az osszes korlatot az adja hogy ne kelljen szoroznod... de ha meg kell is szorozni akkor osztani es/vagy maradekozni ne kelljen. 

A szorzás is kellemetlen, bár kevésbé. Ezt most papíron elkezdtem levezetni, s az jött ki, kőkeményen kihasználja a túlcsordulásban rejlő lehetőségeket.

Tehát x / n = x * c / (2 ^ b) (ez itt nyilván nem xor), ahol n = 1000000. Ebből c * n = 2 ^ b, de n prímtényezői között van 5, konkrétan 5 ^ 6, így ennek klasszikus megoldása nincs. Egy dolgot el tudok képzelni, az a túlcsordulás által történő spontán maszkolás.

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

Nem értem. Kiolvasod a két gettimeofday() hívással az időpontokat.

Levonod a későbbi tv_sec-jéből a korábbiét. Összehasonlítod a tv_usec komponenseket, ha a későbbi >= , akkor levonod belőle a korábbit, és készen is vagy, ha nem, akkor hozzáadsz 1 milliót, és úgy vonod le, a tv_sec-et pedig pedig csökkented eggyel.

t2->tv_sec -= t1->tv_sec;
​​​​​​​if (t2->tv_usec < t1->tv_usec) { t2->tv_usec += 1000000; t2->tv_sec--; }
t2->tv_usec -= t1->tv_usec;

Az eredmény egy struct timeval lesz, és nem kell floating pontokkal baszakodni.

Ez inkabb a topicnyito kolleganak volt gyors valasz, ld: két programpont között eltelt időt minél nagyobb pontossággal. Demonak jo ez. Elesben, mission critical helyeken en sem igy csinalom :) Na, ez kb ennyi akart lenni. Igen, a 2x while vs. 1x if kerdest mar fentebb is koruljartuk :]

Lenne még a clock_gettime-ból a CLOCK_MONOTONIC, annak az elméleti felbontása nanosecundum.

Java alatt kivonunk egymásból két long-ot, oszt csókolom, lehet máris foglalkozni magával a feladattal.

Tudsz csinalni a fentiek alapjan relative egyszeruen:

#include <stdio.h>
#include <sys/time.h>
#include <stdint.h>
#include <inttypes.h>

uint64_t getmicroseconds(void)
{
 struct timeval tv;
 uint64_t       r;
 gettimeofday(&tv,NULL);
 r=(uint64_t)tv.tv_sec*(uint64_t)1000000+(uint64_t)tv.tv_usec;
 return(r);
}

/* ... */

uint64_t t0,t1;
t0=getmicroseconds();
do_something_lengthy();
t1=getmicroseconds();
printf("Elapsed time: %" PRIu64 "\n",t1-t0);

Olyat tudok csinálni, ami így néz ki, csak mint ahogy fentebb mások is írták, elég drága művelet.

Nekem konkrétan nagy sebességgel (8MHz) kellene olvasnom a GPIO-n elérhető adatokat, egy adott feltétel után.

Tehát olvasom a GPIO értékeket, megnézem, hogy teljesül-e a feltétel, és ha igen, elkezdem tárolni a kiolvasott adatokat. Itt kellene rögzítenem a kezdés időpontját. Lényeges különbség, hogy csak le kelle-e kérnem egy tick számláló egész értékét, vagy egy ilyen összetett kódot lefuttatnom. Míg ez lefut, elveszítek pár beérkező adatot.

ESP-ken például van olyan számláló, ami a bekapcsolástól kezdve mér a legkisebb időegységben, és csak egy egész szám. Gyorsan, könnyen, hatékonyan kezelhető. Tényleg fura, hogy Raspberry-n nincs.

Sajnos a linuxot sem ismerem olyan mélyen, hogy tudjam, abban van-e?

Nem figyeltél! Zahy azért nem apalnak válaszolt, hogy tudja javítani a hibás kódot. Most már nem tudja. :(

Az nem megy, ha a timestamp-et elteszed valahova, aztán akkor dolgozol vele, ha már van időd? Amúgy műszer firmware-ét írtam, írom, szintén valós idejű feldolgozással, futásidőben kifeszített részekkel, ismerem az érzést. :) PIC32 200 MHz-ről.

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

Mamrint jol ertem hogy RPin szeretnel 8MSPS-sel mintavetelezni igy barmit? Szerintem ez nem igazan fog osszejonni egy linux felett (egyszeruen elkapcsol az operendszer a taszkod alol ami ezt csinalja). Meg bare metal modon is relative nehez ilyen nagy SPS mellett mintavetelezni digitalis jelet egy sima mikrokontrolleren vagy processzoron vagy barmin. 

Ha ilyesmit szeretnel csinalni, amit irsz, akkor viszont erdemesebb valami regiszter-szeruseget kozvetlenul kiolvasnod. Nem ismerem az RPi architekturajat, de pl Cortex-M alatt vannak ezek a SysTick timerek meg (SoC-tol fuggoen kulonfele) periferialis timerek meg hasonlo josagok, azokkal egy elemi memoriaolvasassal meg tudod kapni az idot. Siman lehet hogy elerheto valami ilyesmi is ott. Egy ilyen rendszerhivas (syscall) ami ezen gettimeofday()-k mogott van az tenyleg eleg draga lehet - de nem is a matek miatt hanem a syscall-ok lelkivilaga miatt.

DMA-zni kell az inputot, utána elég lóhalálában feldolgozni átlagosan 8 MS/s sebességgel, tehát gyorsabban, hogy maradjon IT-kre, miegymásra idő. De ez a 8 MS/s elég feszesnek tűnik. GHz-es processzorok világában talán nem lehetetlen.

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

Én csak egy cikket olvastam róla futólag cirka pár éve. És lehet, hogy nem is a Pi-ről szólt a cikk :-) Tőlem lehet jól dokumentált is, akkor sem tudnám. Egyébként meg ott kezdődik a kérdés, hogy _melyik_ Raspberry Pi, mert már talán négy változat is van különböző processzorokkal.

Szerk.: Kicsit utána olvastam, és valamivel kevertem, mert az RPI-nek nincs ilyen funkciója. Viszont talán lehetne olyat hegeszteni rá, hogy a Linux csak 3 magot használjon a 4-ből (RPI4 esetén), és egyet pedig ütemező nélkül mint egy MCU-t felprogramozva használunk. Tuti nem volna egyszerű, de izgalmas projekt volna.

Szerk.2: Itt van egy beszélgetés szál, ahol éppen ilyet akar megcsinálni egy beválallós/álmodozó valaki: https://forums.raspberrypi.com/viewtopic.php?t=113423

De, sokkal egyszerűbb. A linkelt szálban írnak róla, hogy mit és hogyan lehet csinálni vele. Elvileg el lehet érni real-time garanciát is, de nagyon mélyen bele kell mászni, be kell konfigurálgatni odáig, hogy hogyan használja a cache-t. Én sem állnék neki. Bár az is lehet, hogy ha csak annyit megcsinál, hogy egy kernel modult ír, ami egy magon dedikáltan megállás nélkül fut és tolja az adatot egy ringbufferbe, az még működne is gond nélkül. Mert a 8MHz az sok, de a cache találat problémákhoz képest nem annyira sok.

Alapvetoen erre van a virtualizacio. De az se fog feltetlenul mindent megoldani rendes HW tamogatas nelkul.

Egyebkent, ha a csak a mag dedikalasa gond, akkor isolcpu es CPU affinity syscall. Persze nem lesz tokeletes, mert a kernelhivasokra ez nem biztos, hogy hat. De legalabb a tobbi processz nem zajong ott...

Nem hiszem - bár nem tudom -, hogy a virtualizált gépben minden valós idejű lesz, miközben a host egy oprendszert futtat. Ráadásul a virtuális gépben olyan kódot kellene futtatni, ami nem oprendszer, tulajdonképpen amit a boot loader húz be a memóriába, mintha az lenne a kernel. Olyannyira nem hiszem, hogy ha így meg lehetne kerülni a host kernelét, az egy óriási virtualizációs security hole lenne.

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

Ebben a real time-ban nem tudok őszintén hinni, ha oprendszer van azon a gépen. Mi van a DMA-val? Mi van az IT rutinokkal? Amíg hozzám kerül a vezérlés IT-ből, hány vektoros vezérlésátadáson keresztül burjánzott az egész, s növelte meg az interrupt latency-t? Mi van az interrupt priority order-rel? És a DMA csatornák prioritásával? Mi az, ami cache-en keresztül érődik el, s mi az, ami direktben? Mennyi timer-t vehetek el és melyeket úgy, hogy a rendszer ne dőljön össze, jogosultságom legyen használni kedvemre? Szóval a valósidejűség egy MCU-n is olyan fogalom, ami valamelyest értelmezésfüggő, s igény szerint kell a hardware-t felprogramozni, doksit hosszú órákig nézegetni, regisztereket megfelelően inicializálni. Ez egy oprendszer alatt nálam már nagyjából a mocsárban szügyig gázolás élménye lenne, kezemben a fejem fölé tartott géppisztollyal.

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

Szerk-re válasz:

de nagyon egyszerű, erre szolgál a CPU-izoláció nevű ficsor, amit egy isolcpu=X kernelparaméterrel lehet előidézni, ahol X annak a processzormagnak a száma, amit ki akarsz vonni a scheduler fennhatósága alól. És ha van ilyen processzorod, akkor a taskset paranccsal tudod ehhez a processzorhoz ragasztani a speciális parancsod futását, az un. CPU-affinitás funkció segítségével. Itt egy leírás róla:

https://www.linkedin.com/pulse/cpu-isolation-affinity-linux-vinit-tirna…

Szerk: most olvastam tovább, pont ezt írja le a szerk2-beli linked mögött.

Nem vagyok arról meggyőződve, hogy 8 MS/s-ot software-esen kell feldolgozni. Különösképpen nem úgy, hogy azon a gépen oprendszer fut, hálózati kiszolgálás, filerendszer támogatás, talán gafikus user interface is, meg toronyóra lánccal. Szerintem ez így egy nagyon rosszul tervezett rendszer.

Erre célhardware-t kell tervezni. Lehet valami CPLD vagy FPGA szerű dolog, DMA, aztán utólag RAM-ból kényelmesen feldolgozni a regisztrátumot, elküldeni SPI-n vagy USB-n már oprendszer felé az előfeldolgozott stream-et.

Egy MCU lehet, hogy tud olyat, hogy 125 ns-os timer tick-re DMA-t triggerel, s adott GPIO port címről az adatot memóriába ír. Ha megtelt a buffer, feldolgozod.

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

Mar kezd erdekelni a dolog. A vegen meg nekiugrok a fiokban porosodo odroid c2-nek :)

Ezt lattad?

https://iosoft.blog/2020/05/25/raspberry-pi-dma-programming/

Ha ESP-t lattal mar (es nem csak arduiono projekten keresztul), akkor nem lesz nehez...

Esp-t annyiban már láttam, hogy írtam is rá egy logikai analizátort FreeRtos-ban, ahol az egyik CPU csak a GPIO-kat olvassa.

Jobb híján egyelőre ezzel próbálok nekimenni a 8MHz.es órajelnek, ami a hivatalos dokumentáció szerint 7.88MHz pontosabban.

Ha szkóppal mérem, 7.4 és 8.1MHz közötti ugráló értéket kapok.

A logikai analizátorom ezt méri az órajel lábon. Egészen eddig azt hittem, a mérésem hibája, hogy foghíjas, de kezdek elbizonytalanodni ... A 7.88MHz-nek nem kellene fixnek lennie?

Bár a szkópom belépő szintű, de a 17Mhz-es color clockot is stabilan méri. Ennél meg ugrál, tehát lehet, ez tényleg nem fix órajel. De sehol nem találok referenciát erről, hogy ennek stabil órajelnek kell-e lennie, vagy valóban vannak kimaradó részei ...

Amúgy szerintem 8MHz-es mintát venni Raspberry-n csak DMA-val lehet. Nem is ezzel van a baj, hanem azzal, hogy a kernel nem hagyja egyfolytában futni a taszkomat, emiatt mégsem tudok így mintát venni.

Abban az órajelben nem lehet valami wait state?

Ha a kernel hagyja futni a DMA interrupt callback függvényedet, akkor nyertél. Nem hiszem, hogy pending interrupt-ot hosszú ideig nem hagyna érvényre jutni. Az, hogy a taskodhoz nem jut a vezérlés, a kutyát nem érdekli, a DMA IT rutin futása elég, de jobban belegondolva, annak sem lenne szinte semmi dolga. A DMA tegye memóriába, ami jött, ennyi a feladat. Feldolgozni ráérsz, ha megkaptad az időszeletkédet.

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

Köszönöm, teljesen igazad van, ezt nagyon elrontottam! Rossz mintakódból dolgoztam.

Most azonban egy működő mintakód alapján már úgy tűnik, tényleg jól olvasom be az adatokat, ami jó hír. Az is jó hír, hogy ezzel megoldódott a timestamp problémám is, mivel a mintavételező callback függvényem megkapja paraméterben a mintavétel timestamp idejét is. Sajnos a dokumentáció csak annyit mond, hogy ez egy timestamp érték, azt nem mondja meg, hogy miben számolva. (Biztos illene tudnom.) De a lényeg az, hogy kapok időbélyeget minden élváltáshoz. Szomorú azonban az, hogy a 0 utáni 1-ek 20 egységre vannak, míg az 1 utáni 0-ák 5 egységre. És minden kapott timestamp érték 5 többszörösével tér el egymástól, így úgy tűnik, az 5 a legkisebb időköz, ami eltelhet két mintavételezés között. Vagyis a minta frekvenciája még mindig >= mint a mintavételezés frekvenciája. Tehát még ez sem elég gyors.

Nem teljesen ertem.

DMA-t hasznalsz, igaz? Hogyan?

Ez pl. eleg rossz eredmenyeket mert: https://github.com/hzeller/rpi-gpio-dma-demo . De nem vagyok rola meggyozodve, hogy jol hasznalja. Kizartnak tartom, hogy egy rendesen felprogramozott DMA csatorna ne tudna memoriat irni vagy olvasni normalis sebesseggel...

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree…

#define BCM2835_DMA_MAX_DMA_CHAN_SUPPORTED 14

// normál esetben
#define MAX_DMA_LEN SZ_1G

// ha végzett a másolással
#define BCM2835_DMA_INT_EN   BIT(0)

Hmm. 1 GB DMA-zására alkalmas (30 bites a számlálója). Régen úgy emlékszem, 64 kByte volt még az x86 8257-es kontrollerének határa. Hova fejlődtünk. :)
 

Egyébként jól látom, hogy az iménti tesztkódban az alkotó apró blokkot másolt csak DMA-val és tulajdonképpen a saját szoftvere (ami időosztásban kapja a futást) korlátozta a jó eredményben? Esetleg ha sok MB-os blokkokat küldene DMA kontrollerrel, akkor jobban látható lenne a valós DMA képesség.

A mintakódok kapaszkodónak jók, de ha valami jót akarsz, magadnak kell kitaposni az utat. A mintakód arra jó, hogy legyen bátorságod önállóan gondolkodni, hozzányúlni. Fogalmam sincs, milyen felületet biztosít a Linux kernel a DMA-hoz, de attól tartok, meg kell ismerned. Szükséged lesz még harware timer-re, ami triggereli a DMA kontrollert.

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

Hogy mik vannak... en sem hallottam errol... de siman lehet hogy van ilyesmi... Remlik hogy vannak olyan SoC-ok amikben van Cortex-A es Cortex-M mag is, de lehet hogy keverem valamivel.

Igen, mint ahogy egy MCU-ba is jol jonne egy kisebb adag offload CPLD vagy FPGA-szeru logika, ugy egy CPU/SoC-on belul is jobb ha van egy kisebb offload MCU, ilyen esetekre... 

Ha nem is Cortex-M, de nézd meg a Beaglebone PRU-ját
https://elinux.org/BeagleBone_PRU_Notes

Itt az ARM Cortex A8 (vagy a másik modellnél dual A15) futtatja a Linuxot és az összes realtime funkció le lesz delegálva 2 darab, egyenként 200 MHz órajelű I/O mikrovezérlőnek.
Ezek a CPU-val közös tokban vannak és prioritással férnek hozzá a RAM-hoz + I/O-hoz.

Ezzel csinálnak mindenféle barkács ügyességet, például 100 MHz 14 bit logikai analizátort. :D
Illetve ezzel valósítanak meg max. 50..66 MHz-ig intelligens buszprotokollokat is.
 

FPGA-ra pedig ott van a Zynq 7000 család. ARM Cortex A9 + FPGA közös tokban.
Ez komplett lapkán SBC méretben is van: https://www.digikey.hu/-/media/Images/Product%20Highlights/T/Trenz/TE07…
Rádióamatőr kísérletekre kiegészítették 122 Msps duál ADC-vel és DAC-kal, így a rövidhullámot közvetlen lehet feldolgozni: https://redpitaya.com/red-pitaya-for-radio-amateurs-sdr/

Van sokkal nagyobb és drágább Zynq, ahol közös tokban tartalmaz
   - ARM alkalmazásprocesszort (Linuxhoz)
   - ARM mikrovezérlőt is
   - FPGA blokkot
   - gyors interfészeket
https://www.xilinx.com/content/xilinx/en/products/silicon-devices/soc/z…

A 8MHz egy szabályos órajel, ehhez akarom szinkronizálni a többi GPIO-n érkező adatot.

Mivel időt nem tudok elég gyorsan mérni mintavétel közben, ezért azt számolom, hányszor olvasok azonos értéket ezen a 8MHz-es órajel kapun. Azt reméltem, hogy ez mindig egy 1-nél, de inkább 2-nél vagy 3-nál is nagyobb szám lesz. Akkor tudnám, hogy gyorsabb vagyok, mint a forrás adat.

Sajnos azonban van, hogy ez az érték 1. :(

Persze, így, hogy számolok, lassabban tudok mintákat venni, tehát lehet, hogy számlálás nélkül még pont beleférnék a 8MHz-be. A több magot sem használom még ki.

ESP-n azt meg lehetett csinálni, hogy a 2 magból az egyiket csak az én privilegizált kódom használta, minden más a másik magon futott. Ha RPi alatt is ki lehetne venni az OS kezéből az egyik magot, akkor szerintem biztos beleférne.

Sajnos azonban van, hogy ez az érték 1. :(

Es sajnos siman lehet az is hogy ugy olvasol ki ket db 0-t egymas utan hogy kozte volt meg egy atmenet is... vagy akar tobb... szoval igen, tenyleg az lenne a biztos hogyha 0000111100011110001111 formaban olvasnad ki, bar meg ott is siman lehet hogy osszelebeg az egesz (pl kepzeld el hogy 8MHz-n jon az orajel de te pont stabilan 2.1 MHz-vel olvasod ki valami miatt... akkor is kb ilyesmit fogsz merni/latni).

ki lehetne venni az OS kezéből az egyik magot

Minek? Futtathatod a kódot a kernelben (kernel modul, kernel thread), és akkor simán monopolizálhatod az egyik magot. Igaz, ennek az égadta világon semmi értelme nincsen, mert ezzel csak azt fogod elérni, hogy az egyik core az idő 100%-ában pörög (megdobja a fogyasztást és a hőtermelést a Pi-n, rossz esetben le is olvad majd a 'csába), és közben meg alig végez hasznos munkát.

Az egyik jó opció, hogy találsz egy olyan beépített modult a Pi-n, ami pont olyan kommunikációt tud hardverből, amit szeretnél, és akkor játszi könnyedséggel tudod a kommunikációt azzal a hardverrel lekezelni, közül zéró terhelés mellett. Ha ez nem megy, akkor meg rá kell dobni egy 500 Ft-os mikrokontrollert a Pi hátára, és azzal kell szépen a kommunikációt lebonyolítani (a Pi meg beszélhet mondjuk egy UART-on keresztül a miktrokontrollerrel).

Az egyik jó opció, hogy találsz egy olyan beépített modult a Pi-n,  [...]

Pontosan. Raadasul a 8MSPS mintavetelezes meg egy MCU-nak is erdekes problema, persze attol fuggoen hogy ez szinkron, aszinkron vagy milyen mintavetelezes kene hogy legyen (ezt nem tudjuk, legalabbis nekem nem egyertelmu). Szoval meg az is lehet hogy ez inkabb egy FPGA-nak valo feladat lenne eleve ;)

Az oprendszertől én is tartok, de maga a Pi 3 több mint 60MHz-cel tudja írni a GPIO-kat direkt hozzáféréssel. Ezért reméltem, hogy 8MHz-es olvasás még bele fog férni. Legfeljebb single user módba menekülök. De mindehhez jó lett volna tudni, milyen valós idők alatt zajlanak le az események. És persze az is lehet, hogy csak RPi 4 alatt működne még így is.

Nem megy Raspberry-n az RTOS valamelyik valtozata? Esetleg egy real-time linux, ha fontos az oprendszer...

Tuti nem allnek neki sima kernellel es desktop disztribucioval.

Igen, ezen én is gondolkodtam régebben.
De arra jutottam, hogy ezeket meg kell hagyni számítási magnak, hiszen erősek és kár elpazarolni.
Ellenben realtime-célora:
  1. PRU - lásd fentebb általam írtakat
  2. ha nincs PRU, akkor meg öcsiNYÁK-ra (akár próbaNYÁK-ra) egy mikrovezérlőt éa rádugni az RPi tüskesorára.

Mikrovezérlők közül
  - AVR-nek Raspberry SPI-jén keresztül beletolható a programja, kipróbáltam megy.
  - STM32-nek pedig Raspberry UART-on keresztül tolható bele a programja, szintén kipróbáltam, megy.
Utóbbi képes legalább 15 Mbps tempóval SPI-n adatot cserélni a Raspberryvel, miközben az időkritikus folyamatokat nagyon finom időbeli precizitással interruptból ellátja.

És nem csak mikrovezérlőre. Ennek a 10. oldalára kukkants rá: http://kiwisdr.com/docs/KiwiSDR/KiwiSDR.design.review.pdf
Itt egy 65 millió 14 bites minta / másodperces A/D van. Digitális oldalon az FPGA-ban keverő és decimálás (mintaredukálás) van, majd a redukált mintát az FPGA szintén SPI-n keresztül tolja át 48 Mbps tempóval a Beaglebone SBC-nek utófeldolgozásra, kiértékelésre.