Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: knuths_daemon 17. 05. 2017, 09:37:46
-
Zdravím, mám prototyp aplikace v C využívající polling, kterýžto podle události volá callbacky. Kód je ale vzhledem k těm callbackům dost špagetový, proto bych rád využil spíše ve všech ohledech lepší korutiny. Problém ale je, že ucontext už je zlikvidovaný a aplikace je pro MCU, nejspíš tam bude FreeRTOS nebo něco podobného, takže běžné knihovny pro Linux použít nejde. Nějaké typy, jak přepínat mezi fibry? Předpokládám, že v pollingu prostě stačí místo callbacků volat příslušnou čekající korutinu, jen se trochu bojím přepínání kontextu. Stačí prostě uložit registry a přehodit zásobník?
-
Jestliže tam poběží nějaký RTOS, není lepší použít přímo jeho korutiny, které přepínání kontextu vesměs řeší za tebe?
-
Nejsem žádný embedded odborník, ale teď potřebuji vyřešit trochu složitější úkol pro STM32 a docela se mi zalíbil chibiOS s pěkně udělanými preemptivními vlákny. Možná bys ty korutiny vůbec nepotřeboval.
-
docela se mi zalíbil chibiOS s pěkně udělanými preemptivními vlákny. Možná bys ty korutiny vůbec nepotřeboval.
Souhlas, s Chibiosem jsem si taky trochu hrál a moc se mi líbil.
-
docela se mi zalíbil chibiOS s pěkně udělanými preemptivními vlákny. Možná bys ty korutiny vůbec nepotřeboval.
Souhlas, s Chibiosem jsem si taky trochu hrál a moc se mi líbil.
Preemptivní přepínání kontextů ale neřeší dotaz.
-
Preemptivní přepínání kontextů to přímo neřeší, ale třeba probouzení vláken událostmi, čekání vlákna na signál, mailboxy/fronty mezi vlákny atd. - možná by ten polling vůbec nebyl potřeba, kdyby se využily možnosti embedded OS. Samozřejmě ve finále to na tom jednojádře poběží stejně, ale vývoj může být trochu méně bolestný a bližší programování v normálním OS. Leč nechť každý koná dle svých potřeb.
-
http://www.abclinuxu.cz/blog/enlightenment/2017/3/nove-octaforge-cile-octastd-coroutines-a-dalsi-zmeny
-
Preemptivní přepínání kontextů to přímo neřeší, ale třeba probouzení vláken událostmi, čekání vlákna na signál, mailboxy/fronty mezi vlákny atd. - možná by ten polling vůbec nebyl potřeba, kdyby se využily možnosti embedded OS. Samozřejmě ve finále to na tom jednojádře poběží stejně, ale vývoj může být trochu méně bolestný a bližší programování v normálním OS. Leč nechť každý koná dle svých potřeb.
On ten polling (vlastní smyčka) je alternativou, to ano, ovšem využití služeb OS zní jako overkill, když můžu přepínat kontexty v userspacu. Třeba na Arduinu je vlastní implementace jediná možnost.
-
Ten chibiOS je odladěná docela rozsáhlá (volitelně přikompilovatelná) implementace "vlastní smyčky", samozřejmě nerozlišuje mezi user-space a kernel-space. Mimochodem funguje i pro AVR arduino, ale samozřejmě to má krutě málo RAM. Naposledy jsem pro arduino řešil přesně takovou smyčku ručně + matlal se s prioritami obsluh (např. příjem zprávy přes sériák větší priorita, aby nic nezmeškal, zatímco výpis na grafický TFT počká). V dalším projektu jsem si už připlatil a místo Arduino mini pro za 35 Kč používám STM32 maple mini za 75Kč + vývoj v chibios v eclipse. Jde to i HW krokovat, ale tam jsem se zatím ještě nedostal.
-
setjmp a longjmp je možné použít k userspace implementaci korutin.
-
setjmp a longjmp je možné použít k userspace implementaci korutin.
To už radši getcontext/setcontext, tam nedochází k problémům se sdíleným stackem
-
setjmp a longjmp je možné použít k userspace implementaci korutin.
To není pravda. longjmp likviduje zásobník, takže něco jako kooperativní
sleep_dont_block(1000);
go_on();
s tím udělat nejde. Na to je potřeba již zmíněný ucontext, což je ovšem (zastaralá) záležitost POSIXu.
-
setjmp a longjmp je možné použít k userspace implementaci korutin.
To není pravda. longjmp likviduje zásobník, takže něco jako kooperativní
sleep_dont_block(1000);
go_on();
s tím udělat nejde. Na to je potřeba již zmíněný ucontext, což je ovšem (zastaralá) záležitost POSIXu.
Stack jde hacknout nějak takhle: http://fanf.livejournal.com/105413.html
Hezké to není, ale fungovat by to mělo, pro mikrokontrolér myslím dobré, relativně nenáročné na zdroje a všechno je pod kontrolou v userspace.
-
setjmp a longjmp je možné použít k userspace implementaci korutin.
To není pravda. longjmp likviduje zásobník, takže něco jako kooperativní
sleep_dont_block(1000);
go_on();
s tím udělat nejde. Na to je potřeba již zmíněný ucontext, což je ovšem (zastaralá) záležitost POSIXu.
Stack jde hacknout nějak takhle: http://fanf.livejournal.com/105413.html
Hezké to není, ale fungovat by to mělo, pro mikrokontrolér myslím dobré, relativně nenáročné na zdroje a všechno je pod kontrolou v userspace.
Tady akorát záleží, na čem to poběží, aby to zbytečně nebrzdily syscally. Jinak ano, osobně sice preferuju čistší switch zásobníku, ale pokud se někomu ten kód líbí...
-
Jestliže tam poběží nějaký RTOS, není lepší použít přímo jeho korutiny, které přepínání kontextu vesměs řeší za tebe?
Kooperativní konkurentní běh se vesměs řeší v userspacu (je to levnější) a ani OS nepotřebuje (minimalistické MPU). Obecně vyjma inicializace stačí pro přepnutí sekvence 1. push registrů, 2. přehození zásobníku, 3. pop registrů. Některé jazyky ani s registry nic nedělají, protože mají jiné vhodnější ABI, ale i tak je to operace velmi levná. Vlákna jsou zbytečně drahá, když je stejně k dispozici jen jedno vlákno a veškeré operace jen čekají (buď na senzor nebo data z jiné korutiny). Preemptivní přepínání je ve většinu případů kontraproduktivní (navíc vyžaduje přerušení, čímž se to celé ještě zhorší).
-
setjmp a longjmp je možné použít k userspace implementaci korutin.
To už radši getcontext/setcontext, tam nedochází k problémům se sdíleným stackem
To je deprecated a většinou to už je vyřazené z knihovny. Navíc na unixoidních systémech to je pomalé (používají se syscally).
-
A nestačí tam prostě portnout FreeRTOS, hlavní vlákno s pollingem a semaforem (bez parametrů) / frontou (s parametry) / eventem (flagy) odblokovat vlákno, co to zpracuje? Proč se furt musí vymýšlet rovnáky na ohybáky?
-
Přesně to samé jsme před pár dny navrhovali s chibios. Stejně jako FreeRTOS jde jen o sadu maker, funkcí a datových struktur. Žádné přepínání user-space/kernel space se tam samozřejmě neřeší, přesto i na osmibitovém jednočipu nabízí kooperativní či preemptivní vlákna, jednoduchý scheduler (dokonce i tickless pro snížení spotřeby), blokované fronty, kritické sekce, semafory atd. atd. Pro složitější projekt je takový otestovaný "framework" dost velké usnadnění, protože umožňuje snáz modelovat dle reality a vyhýbat se některým hackům.
-
A nestačí tam prostě portnout FreeRTOS, hlavní vlákno s pollingem a semaforem (bez parametrů) / frontou (s parametry) / eventem (flagy) odblokovat vlákno, co to zpracuje? Proč se furt musí vymýšlet rovnáky na ohybáky?
Správa vláken je drahá a semafory dtto. Není-li potřeba preempce, jsou mnohem lepší korutiny. Navíc některé MCU ani podporu vláken nemají.
-
Navíc některé MCU ani podporu vláken nemají.
Co konkrétně je potřeba v MCU pro správu "vláken", jaká se používají v tenkých "OS" typu FreeRTOS či ChibiOS? Běží to i na AVR v arduinu http://www.chibios.org/dokuwiki/doku.php?id=chibios:product:nil:features
Pro složitější projekty se tenká vrstva takového "OS" hodí.
-
Co konkrétně je potřeba v MCU pro správu "vláken", jaká se používají v tenkých "OS" typu FreeRTOS či ChibiOS? Běží to i na AVR v arduinu http://www.chibios.org/dokuwiki/doku.php?id=chibios:product:nil:features
Pro složitější projekty se tenká vrstva takového "OS" hodí.
Myslim, ze je potreba odlisit vlakna a tasky (abysme vedeli, o cem se vlastne bavime). Neznam vnitrnosti ChibiOSu pro AVR, ale mam podezreni, ze bude fungovat jenom na principu casovace - tj. zadam si, ze za dve sekundy chci spustit nejaky task a on se mi za dve sekundy spusti, pokud v tu dobu nebezi jiny task.
Docela pochybuju o tom, ze by se na AVR dal udelat "plnotucny" hard realtime system s preempci, ale mozna se mylim.
-
ChibiOS má dvě verze - RT a NIL srovnání http://www.chibios.org/dokuwiki/doku.php?id=chibios:articles:rt_vs_nil
NIL je vhodná i pro AVR a neumí round-robin preemption vláken stejné priority (tj. sledování spotřebovaného time slicu a přepnutí při zjištění jeho vypršení). Umí preemption vláken různých priorit. Tj. když se probudí vlákno vyšší priority interruptem od časovače nebo periférie, uloží stav stávajícího vlákna a přepne na jiné s vyšší prioritou. Samozřejmě se musí hlídat paměť. NIL neumí dynamicky vytvářená vlákna.
Verze RT běží výborně např. na STM32 (používám čínský klon maple mini STM32F103 za 3 dolary) a umí vše z toho.
Pěkný popis scheduleru verze RT je např. http://www.playembedded.org/blog/en/2016/10/29/explanation-multithreading-chibios/
-
NIL je vhodná i pro AVR a neumí round-robin preemption vláken stejné priority (tj. sledování spotřebovaného time slicu a přepnutí při zjištění jeho vypršení). Umí preemption vláken různých priorit. Tj. když se probudí vlákno vyšší priority interruptem od časovače nebo periférie, uloží stav stávajícího vlákna a přepne na jiné s vyšší prioritou. Samozřejmě se musí hlídat paměť. NIL neumí dynamicky vytvářená vlákna.
Aha, tak to je lepsi, nez jsem myslel - omezeni jsou tam porad velky, ale na AVR je to super vysledek.
Diky moc za doplneni a linky!
-
Na AVR je NIL verze údajně plně funknční (netestoval jsem), ale pokud stojí deska s 32bitem na 72MHz se 128kB flešky a 20kB RAM 3 dolary, nemyslím si, že by pro složitější projekt dávala kombinace ořezané NIL + slaboučké AVR smysl. Programuje se obojí přes vestavěné USB bez potřeby dalšího hardware.
Jen pro debugging v eclipse je potřeba USB STLink za 2 dolary, ale to jsem zatím ještě nezkoušel.
Samozřejmě pro jednoduchý projekt je daleko rychlejší apt-get install arduino a za pár minut ledka bliká. Prvotní rozchození chibios v eclipse + naučit se nahrávat na desku mi trvalo pěkných pár večerů.
-
Jinak to arduino IDE s nahranou knihovnou STM32 desek (projekt stm32duino) jde pro to maple mini použít úplně v pohodě včetně uploadu na desku, samozřejmě je to klasické tupé arduino setup + loop + chudé IDE.