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.
Citace od: dustin kdy 17. 05. 2017, 11:23:19
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.
Citace od: Mirek Prýmek kdy 17. 05. 2017, 11:40:18
Citace od: dustin kdy 17. 05. 2017, 11:23:19
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
Citace od: dustin kdy 17. 05. 2017, 11:53:56
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.
Citace od: lopata kdy 17. 05. 2017, 12:32:38
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
Citace od: lopata kdy 17. 05. 2017, 12:32:38
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.
Citace od: zboj kdy 17. 05. 2017, 12:38:30
Citace od: lopata kdy 17. 05. 2017, 12:32:38
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.
Citace od: lopata kdy 17. 05. 2017, 12:45:30
Citace od: zboj kdy 17. 05. 2017, 12:38:30
Citace od: lopata kdy 17. 05. 2017, 12:32:38
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í...
Citace od: Qeek kdy 17. 05. 2017, 10:16:27
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ší).
Citace od: Sten kdy 17. 05. 2017, 12:35:06
Citace od: lopata kdy 17. 05. 2017, 12:32:38
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.
Citace od: PetrM kdy 23. 05. 2017, 08:54:52
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í.
Citace od: zboj kdy 23. 05. 2017, 09:43:07Naví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í.
Citace od: dustin kdy 23. 05. 2017, 09:56:15
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/
Citace od: dustin kdy 23. 05. 2017, 10:52:55
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.