"Én úgy értelmezem, hogy a call back kilép az ISR -böl..."
Cortex-M -re elég jól definiált, hogyan működik az interrupt exception, illetve, hogy mit jelent az interrupt context. Kicsit berozsdásodtam, de ha jól emlékszem az LR -be kerül speciális érték, és amikor az utolsó return ezt betölti a PC -be, akkor fog a HW kilépni IRQ context -böl.
Tehát alap esetben bármit amit ISR handlerbol hívsz, IRQ context -ben hajtasz végre, így értelem szerűen a call-back -eket is.
Még ha RTOS -od van, akkor is a normál menet az, hogy ISR contex -bol event -et küldesz, ami a fogadó processz ready állapotba teszi. Amikor az IRQ handler -ed kilep, az OS végignézi a ready állapotú processzeket, és a legmagasabb prioritásúra fog visszatérni. Ahhoz, hogy ez működjön "meghamisítja" a stack -re mentett exception frame -et. De ez a működés implementáció specifikus, mert pl. vannak olyan OS -sek amik erőltetik a time sliceing -et, azaz mielőtt egy processz időszelete lejárna, semmiképpen sincs processz váltás.
Az OSE (mondjuk ARM -on sosem használtam) definiál pl interrupt processz típust. Itt mindenképpen az az elvárás, hogy az IRQ handler csak minimális munkát végez, és a speciálisan kezelt interrupt processzt fogja az ütemező elindítani. De ez is kb a fentiekkel megegyező eljárás, csak az OSE sajátosan kezeli ezeket, és saját nevezéktant vezet be emiatt.
Tulajdonképpen arról van szó, hogy van az IRQ handler, ami IRQ exeption context -ben fut. Ezt indítja el a hardware válaszul az IRQ kérésre, és ez a kód fogja tudni megszakítani a processz kontextusban futó kódot. Azaz "ezek ellen" kell(het) re-entrancy védelmet biztosítani, azaz ezek bármilyen normál kódot megszakíthatnak. Van továbbá az IRQ service rutin, ami futhat akar sima processz kontextusban is. Ez végzi a munka nehezét. Az, hogy a 2 -őt egyben implementálod, vagy a 2. -at IRQ contextben futtatva call-back -kent hívod, vagy a processz contexttel komunikalva hajtod valahogy végre a te döntésed (design decision).
Pl1: ha nincs RTOS, és csak egy nagy main loop -pal "ütemezel", akkor az IRQ handler beállít egy globális változót, hogy jelezze az eseményt. A main loop amikor oda ér, ellenőrzi a változót, és ha az állapota eseményt mutat, lefuttatja az IRQ service rutin-t.
Pl2: a kis latency követelmény az adott perifériánál, ezért vagy az IRQ handler egyben az IRQ service is, vagy az IRQ handler call-back -ként hívja az IRQ service rutint.
Pl3: van RTOS, így az IRQ handler call-back -et hiv. A call back RTOS fugvennyel eventet/messaget kuld a processznek ami majd megfelelo utemezes mellett lefuttatja az IRQ service rutint.
A példákból érezhető, hogy a call-back mint megoldás csak a modularizációt/konfigurálhatóságot szolgálja.