AVR a multitasking

Čím dál tím víc u mě při psaní programů vzniká potřeba řídit více paralelních procesů.
Má někdo zkušenost s multitaskingem na jádru AVR?
Chtěl bych vědět, co to obnáší, které typy to zvládnou popřípadě by se hodil (jistě nejen mně) nějaký příklad, vysvětlení,jak vůbec multitasking pracuje - kromě toho , že je to paralelní řízení procesů o tom nevím vůbec nic - ani encyklopedie moc informací nedávají.

Multitasking jako takový by byl zřejmě na AVR příliš velké sousto, ale osobně řeším věci ,které mají běžet paralelně, pomocí často se opakující hlavní smyčky, kde postupně volám rutiny obsluhující jednotlivá zařízení a případnou synchronizaci řeším pomocí globálních proměnných. Takto lze řešit i poměrně velké projekty aniž by se v tom člověk ztratil.

Zatím se mi to povětšinou podařilo vyřešit způsobem jak píše Dragst, má to ovšem jednu nevýhodu. Když potřebuješ odezvu do určité doby a program se ti někde na chvíli zadrhne, tak jsi v pytli. Pro tento účel jsou tzv. RTOS (Real Time Operating System). Na stránkách atmelu se o tom dá něco málo zjistit a myslím, že tam jeden z nich mají k dispozici.

Musim nesuhlasit s kolegami z hora. Na ATmega sa da multitasking celkom dobre pouzit. Pravdu povediac si ani neviem predstavit stredne velku aplikaciu s obsluhou tlacitok, displaya senzorov, komunikaciou (> 15kB) bez multitaskingu. Sam pouzivam vlastny system, vycibreny pocas rokov. Da sa pouzit FreeRTOS od ATmega32, ale implementacia nie je na studium jednoducha.

Na stranke avrfreaks.net zadaj do vyhladavaca text RTOS (a potom do druheho okienka este raz) a ziskas linky na iRTOS, SALVO, FreeRTOS, WhatOS. Na nete najdes PicoOs, ATAVR. Alebo nieco je aj na
avrfreaks.net/index.php?modu … tem_id=537

V poslednej dobe ma vsak zaujal tento kod

mikrozone.sk/download.php?view.35

sam vygeneruje kernel i s prazdnymi funciami, ktore sa medzi sebou prepinaju. Pouzitie je tak jednoduche, pouzitie mas nastudovane z kontextu vygenerovaneho zdrojaku za cca 5 minut a vysledok v pomere k tomu tak dobry, ze mi neda tento link neuviest.

Velmi dobre strucne a jasne zalezitost multitaskingu popisal vo svojej utlej, ale o to lepsej knizke pan Vladimir Subrt: Atmel AVR vyvojove prostredi. Okrem multitaskingu je tam na necelych 90 stranach velmi dobre popisany debuging bez potreby JTAG iba cez UART. Vsetko popisane vo WinAVR. Velmi prakticke.

Daj vediet, co si si vybral a preco. :slight_smile:

Martin dík

za prvé nastuduji tu knihu pro pochopení jak to funguje.
Protože ale pracuji v Codevisionu a všechny ty xxOS na které jsem našel odkazy jsou určené pro WinAVR, nebo IAR jsou pro mě nepoužitelné - jediný , který podporuje Codevision je FreeRTOS, ale bohužel jen vnejnovějších verzích, kterou ale nemám. Takže zatím se mi nabízí několik cest:

  1. přejít z CV na WinAVR- zase se učit pracovat v novém ( a myslím, že ne tak komfortním) prostředí

  2. zkusit použít použít kód z odkazu:http://www.mikrozone.sk/download.php?view.35 a upravit ho pro CV- něco mi ale říká, žeto asi nebude fungovat. Mimochodem vřele doporučuji tento prográmek všem, kdo dělají v GCC velmi to ulehčuje vytváření nového projektu - něco podobného má i Codevision.

  3. zkusit napsat něco svého , ne tak univerzálního ale pro mně zatím dostačujíciho.

Zatím mně ale čeká jiná práce, takže ani na jednu z variant zatím není čas.

Martin
Zajímavá věc, určitě si s tím také zkusím pohrát. Menší nevýhodou může být skutečnost, že výsledný projekt obsahuje další cizí kód (z důvodu spolehlivosti) , ale to obvykle nevadí, pokud nejde kritické aplikace. Dobrý tip :exclamation:

Tak jsem se pustil relativně nejjednodušší cestou - úpravou kódu psaného ve WinAVR tak, aby mu rozuměl Codevision. Je to ten co tak zaujal Martina:

a hned první problém:
makra #define PUSH(r) asm volatile(“push r”#r);
#define POP(r) asm volatile(“pop r”#r);
mi cvavr samozřejmě nezchroustá, ale není mi jasné, jak převést asm volatile(“push r”#r);- pravděpodobně zas nějaké makro překladače alespoň do ASM

a ještě by mě zajímalo co je to “SP” - asi stack pointer, ale to SP není nikde definované , ani v žádném include souboru pro konkrétní typy - tam nejsou definované dokonce ani SPH a SPL registry

pozn. ti smajlíci tam být nemají - nevím proč se zobrazují :confused:

V GCC je inline asm totalna beekovina.
popis je napriklad tu:

scienceprog.com/how-to-use-i … ng-winavr/

v inych C-ckach pre AVR je to omnoho zrozumitelnejsie.
To ale nijako nezmensuje ine, omnoho dolezitejsie vyhody GCC. :slight_smile:
Asm subory sa v ramci projektu nastastie integruju omnoho jednoduchsie. Napisat vsak jednu ASM instrukciu do C-cka je zo systemovych dovodov (osoben s nimi moc nesuhlasim) trochu kostrbatejsie. Nastastie to realne v praxi v podstate ani netreba. Tie inline prikazy sa urcite daju prepisat v Codevision podla potrieb.

Podelší době jsem se opět vrátil k tomuto tématu.

Zkusil jsem použít výše uvedený kód a do jednotlivých tasků dal primitivní přepínání portů na vyzkoušení. Ale nedaří se mi. Místo toho,aby se přepínaly jednotlivé úlohy (zkouším to v simulátoru AVR studia) proběhne mi funkce main až na konec a tam se prg zastaví.

když přepnu na disasembler -prg stojí na poslední instrukci cž je RJMP PC-0x0000 - je ten skok něčím podmíněný?

jestli jsem to dobře pochopil, tak fce main jenom vytvoří tasky a přepne na první z nich a povolí přerušení pak skončí a vrací nulu - ale kam? kdo jí volal?

a ještě totéž v souboru .c
gccwiz1.c (4.45 KB)

Nemam casopriestor sledovat Tvoj vytvor, ale skus pouzit toto

mikrozone.eu/download.php?view.35

multitaking je vygenerovany velmi pekne.

Tvorit kod v jednej slucke funguje iba do isteho, zvycajne nedostatocneho, rozsahu aplikacie.

napriklad obsluhovat:

  • UART na 9600 (obsluha do 1,04ms)
  • tlacitka pod 10ms (cas okolo 50us)
  • realizovat hlavny algoritmus s kalibraciou premennych cez realne cisla
    (cca okolo 100ms)
  • zobrazovat udaje na 4x7segment diaply pomocou muxovania bez
    znatelneho blikania (pod 2,5ms)

sa jednoducho v jednej slucke prehladne robi velmi, ale naozaj velmi tazko.

Výtvor není v žádném případě můj - hned v úvodu je:** // generated with AvrWiz (by g@greschenz.de)** :slight_smile:
Je to tedy přesně to co jsi mi doporučil - jen jsem doplnil do hotového kódu pár instrukcí abych mohl otestovat funkčnost. Ale tak jak to vygeneruje ten wizzard mi to nespustí ani první úlohu.
Myslel jsem si tedy, že tomuto jsi svůj časoprostor už někdy obětoval, když ho tu i onde (mikrozone) doporučuješ.

Sorry, dobre som si Tvoj prispevok neprecital. :slight_smile:
Ked uz pisem take veci, dnes alebo zajtra vecer sa na to pozriem a nieco vymyslim, lebo som uz nieco s tym skusal. Inak by som neprisiel na to, ze generovanie UARTu ma nejake muchy. :slight_smile:

Pokud budeš vhodně využívat přerušovací systém a časovače, tak ani věci, které jsi popisoval nejsou problém. Na druhou stranu právě přerušovací systém a časovače jsou základem RTOS, ale je otázka, kdy si to ještě všechno naprogramovat sám nebo využít už nějaký specializovaný systém. Můj názor je takový, že to, co jsi popisoval, se dá ještě lehko zvládnout bez nějakého specializovaného systému…

UART … v přerušení si vyzvedneš příchozí byte, nebo odesílaný byte nahraješ do bufferu

tlačítka … v přerušení spustíš časovač a měříš délku stisknutí, dostatečná doba stisknutí opět může způsobit přerušení…

4x7segment display… opět můžeš reagovat v přerušení od časovače

hlavny algoritmus … může jich být několik a časovačem mu můžeš přidělovat doba jeho konání, v přerušení od časovače je můžeš přepínat… navíc algoritmus můžeš spouštět i v “uměle” vyvolaném přerušení (např. od nějaké nepoužívané jednotky)

Suma sumárum: obsluha UARTu, tlačítek a 7segment displeje ti nespotřebuje skoro žádný čas…a můžeš algorimovat jak zběsilý:)

Ja s Tebou absolutne suhlasim. To uz vsak nie je jednosluckovy program :slight_smile: .
Na napasovavanie RTOS s klasickou koncepciou - samostatna uloha, samostatny zasobnik, samostatna priorita - mam svoj nazor. Podla mna je klasicke pouzitie jednocipakov nie celkom v kontexte pouzitia klasickeho RTOS. Tie boli vyvinute pre oblasti, kde ma bezat niekolko uplne SAMOSTATNYCH uloh. Napriklad Pisem tento prispevok, popri tom sledujem, ci mi neprisla posta no a to cele samozrejme za posluchu mp3 hudby. Taketo aplikacie na jednocipakoch prakticky neexistuju -aj ked uz tie dnes vedia kde co :slight_smile:

Jednocipy su urcene na riesenie uloh v ramci nejakeho celku. Nema zmysel obsluhovat klavesnicu bez toho, aby tato nemala priamy dopad na editaciu/prezeranie hodnot regulacie, ktore su ulozene v pomalej EEPROM, treba ich vediet aj odkomunikovat a pouzit v ramci riadiacich algoritmov.

Preto prva vec, co klasicke RTOS maju a to, ze kazdy proces ma svoj zasobnik vidim pri vacsine aplikacii s jednocipmi ako uplne zbytocne (vzdy su vynimky). Pri jednocipovych aplikaciach zvycajne to co ma bezat casto a s vysokou prioritou, je aj kratke. Absolutne nema zmysel prerusovat nejakym jadrom RTOS vyhodnotenie tlacidiel, ktore trva do 50us a striedat ho s behom hlavneho riadiaceho algoritmu trvajuceho 252ms. Jasne, ze pri pridelovani casu radovo v ms by medzi aplikaciami k takej situacii doslo raz za cas,ale uz by soft na tlacitka potreboval vlastny stack.

Jednoducho 1x za 1ms spustim postupne vsetky aplikacie, ktore musia mat rychlu odozvu a trvaju kratko. Raz za 10ms spustim postupne za sebou vsetky aplikacie s vacsimi casovymi narokmi. Neprepinam medzi nimi, nie je dovod. Jasne, ze tie pod 10ms taktom budu kazdu 1ms prerusovane tymi 1ms aplikaciami. Cele to z casoveho hladiska musim nastavit tak, aby sa vsetko vykonavalo vcas. Ale to predsa i pri RTOS. Pouzitie RTOS automaticky nezaruci, ze sa vsetko vykona nacas. Ak by to tak bolo, bol by to genialny odrb na nepotrebu rychlych procesorov :slight_smile:.
No a este mam aplikacie zbiehajuce do 100ms, 1s no a samozrejme tie v hlavnej slucke, ktore sa robia ak je na ne cas. Divili by ste sa, casu je habadej.

Ak sa maju nejake aplikacie v rovnakej skupine vykonat do 1ms/10ms/100ms/1s, neexistuje najmensi dovod preco by sa mal minat procesorovy cas na prepinanie medzi nimi. Jednoducho sa postupne za sebou spustia a su prerusovane iba kratsimi a castejsie aktivovanymi aplikaciami.

Jednocipove aplikacie pracuju na mnozinou spolocnych dat (samozrejme ze nie vsetky data su spolocne). Ak sa deje presun z/do RAM, musi sa udiat atomicky. Preto treba zabezpecit, aby takyto presun netrval moc dlho (max 20-30us) a nemohol byt preruseny nikym a nicim. No a ak sa presuvaju data na urovni 100ms, tie 1ms aplikacie skratka chvilu pockaju. Kedze su spustane od casovaca, k podtupnemu nabalovaniu sklzu nepride.

Takyto system bohate vystaci s jednym stackom a setri sa tym vela v jednocipoch vzacnej RAM. Je jednoduchy a da sa naprogramovat do 1.5-2kB v zavislosti od mnozstva sluzieb, ktore ma poskytovat.

Uz sa dlhsie chystam napisat na tuto temu clanok, ale uz to trva nejaky ten piatok, tak ako sa poznam a vidim moje casopriestorove moznosti, este to nejaky ten piatok potrva. Ale princip som popisal.

Treba samozrejme osetrit pristup k EEPROM, ktora je pri zapise zufalo pomala, alebo k roznym SPI, UART, I2C zariadeniam. Nie je absolutne pripustne, aby aplikacia beziaca pod 10ms casovou zakladnou zablokovala vseko ostatne len preto, ze milostiva caka na prijem / odvysielanie nejakych par desiatok bajtov. Taky system by bol na ho.no a od takeho co najdalej. Takze tvorca este musi vymysliet, ako “cakat” na hw zdroj. To sa da riesit preemptivnymmultitaskingom. To znamena, ze aplikacia si ochekuje, ci moze zapisat/nacitat dalsi bajt do hw zdroja (UART, AD, SPI, I2C, …) a ked nie tak sa ukonci a da priestor inym. Samozrejme po jej zabvolani musi vediet skocit na miesto testu hw zdroja. Ale to tiez nie je nejaka obrovska veda.