Fórum témák
» Több friss téma |
Fórum » PIC - Miértek, hogyanok haladóknak
Igen, de nekem az nem jó. Fix, meghatározott időközönként kell mintákat vennem (mondjuk 10us-onként). Ha úgy csinálnám ahogy gondolod, akkor olyan gyorsan kapnám az eredményeket ahogy a csövön kifér. Mondjuk 2,3146us-onként, ami nekem itt most nem jó.
A hozzászólás módosítva: Feb 17, 2017
Az ADxCON3-mal be lehet állítani mennyi az Auto Sample ideje és milyen gyors a konverziós órajel most azt nem tudom, hogy ezzel be tudod-e állítani, hogy 10us dobjon megszakítást, de szerintem igen.
Vagy neked az kell, hogy 10 us eltelt mintát vesz utána konvertál és pihen az ADC majd megint 10 us és megint mintát vesz és így tovább?
n időpillanatban belép a megszakításba, törli a flagbitet, az A/D mérési eredményét kimásolja egy tömbbe, majd indítja a következő mintavételt és kilép a megszakításból.
n+10us időpillanatban ismét belép a megszakításba és elvégzi ugyan ezt.
Be lehet allitani, hogy Timer fejezze be a mintavetelezest es inditsa el a konverziot. A mintavetelezest pedig automatikusra kell tenni, hogy amint befejezodott a konverzio kezdje el mintavetelezni. Az eredmenyt vagy DMA segitsegevel egyenesen a RAM-ban viszi at, vagy a sajat pufferet tolti fel (ADCxBUF0-ADCxBUFF).
Nem akarom hogy timer vezérelje az A/D-t, és DMA-t sem szeretnék használni. Csupán csak azt szeretném megvalósítani amit fentebb leírtam. Közben meg is oldottam: Az SSRC biteknek 0b111-nek kell lennie és így úgy működik ahogy kell.
Sziasztok!
Foglalkozott már valaki multitaskinggal? Milyen módszerekkel lehet megoldani?
Igen...
Vaggyis próbálom elsajátítani, mert előtte a delay-t használtam, mindenhova. Most, hogy elkezdtem grafikus alkalmazásokkal foglalkozni most kezdett el be jönni a multitask. Én a microchipnek a GOL sw-jéből indultam el ahol állapotgéppel csinálják a multitaskot. De ők Tick timerhez külön timert használnak én meg a CoreTimert.
Az egyik fő feladatrészt szeretném multitaskinggal csinálni, amiben állapotgép lesz.
Azért nem annyira egyszerű, mert a 3-4 függvénynek 2-3 paramétere van és ezeket is át kell adni.
Nem mondtam, hogy a multitaskban bármi is egyszerű lenne
![]() A Microchip-es example-ben van egy MSG struct amiben van egy param1 (touch x), param2(touch y) és egy állapot mutató pl.: TOUCH_RELEASED, TOUCH_PRESSED (enum-ban definiálva) és ezek alapján tudja a többi fv. hogy mit kell csináljanak. Ez a 2-3 paraméter globális vagy lokális paraméter lenne?
Pfűű pár dolog biza még hiányzik hozzá. Csak a létfontosságúak:
-Cpu user / supervisor mode flag (protected mode) + task state mentés hw támogatással, -task állapot függő verem, -memory manager unit Az csak a cpu maghoz. Van bármelyik is a 32mz-ben? Utána még lesz egy olyan történet, hogy driver szerkezetet építeni a perifériák összeakadását elkerülni. Valójában azt kell hamarabb megcsinálni, és jelenleg ott tart a történet, hogy a srácok szerintem nem tudják gatyába rázni a harmony-t. Az mla is csak azért tudott anno valamennyire kiforrott lenni, mert vagy 10 millió órányi community help benne volt. Amikor azt félre tették, az mla-kat elöntötte a bughalmaz (2012 utáni mla-k úgy kuka ahogy vannak). Szerintem be kellene érni az aszinkron alkalmazás design + interruptok körültekintő felhasználásával, és megtanulni normálisan programozni ![]()
Hát igen! A harmony szerintem is egy játék, arra jó hogy megtanuljon az ember hibát keresni.
![]() Én mindig bare level szinten programozok és nem csak mikrokontrollert, mindent a 0-ról kezdek el írni. A cégnél a sima munkám mellett én írok speckó programokat pár nyelven, amikor épp PHP-ben programoztam kérdezték, hogy hogyhogy Notepad++ban programozom. ![]() ![]() Látni akarom, hogy hogy néz ki leprogramozva egy multitasking, egyrészt mert még nem láttam, másrészt, hogy eldöntsem szükséges-e nekem! Ma ahogy tettem vettem és gondolkoztam rajta én is afelé hajlok, hogy megoldom anélkül.
Ha gondolod, kotorj fel archívumból egy első verziós linux kernelt, és jó szórakozást hozzá
![]() Amíg nem multicore környezetben vagy, a multithread többet árt, mint használ.
En kb. 20 eve multitaskingot hasznalok (68HC11, AVR, ARM), es egyikben sincs MMU. A supervisor mode sem letfontossagu egy olyan sw-ben, ahol mindent magad irsz. Nem kell megvedened az egyik processzt a masiktol. HC11-en, AVR-en, ARM-en es PIC-en is hasznaltam preemptive kernelt. Az egy kicsit bonyolult, es a legtobb esetben nincs ra szukseg, eleg egy sima cooperative kernel is. Az utobbi evekben egy ilyen cooperative kernelt hasznalok ARM-en. A task state mentes az kb. annyi, hogy a cpu regisztereket elmented az adott task stack-jebe es a task tablaba elmented az SP-t. Ezek utan az SP-t atallitod a futtatni kivant task stack-jere es felszeded a regisztereket es beleugrasz a task-ba egy returnnel. Ez maga a context switch. A kozos eroforrasok vedelmere vannak a lock-ok, szemafor-ok.
A Harmony 2.02-vel elég jól haladok, szinte minden működik, amit szeretnék. Az egész eleve multis. Most írogatok hozzá drivereket, az én szintemen, de egész jól használható, ha nem akarok feltétlenül kompatibilis lenni a többi driverrel. Arra kell figyelni, hogy ha pl. az UART4-et használom, és mellette akarom használni az USART drivert is, akkor nem a 4-est használjam. Az ok, amiért sajátot kell írnom, a modbus, mert azt sajnos kifelejtették. Itt nem csak a logikai részekről van szó, sokkal inkáb arról, ahogy a modbus protokoll a csomag végét érzékeli. Az a véleményem, hogy a harmony nem egy kicsi falat, de ha megvan a szál, akkor egész élvezetes. Arról nem is szólva, hogy milyen jól használható utána a sok driver, amit kényszerből megír az ember és rákényszerít egy fajta stílusra, ami nem is olyan szörnyű egy idő után...
A hozzászólás módosítva: Feb 19, 2017
És azt hogyan akadályozod meg tutira, hogy a stack-ek egymásra fussanak? Minden egyes taskot külön tervezel stack mélységre is?
A hozzászólás módosítva: Feb 19, 2017
Ja az a 3 millisec egy kicsit idegesítő, viszont csak modbus rtu esetén kell vele szívni, a modbus ascii egy kicsit kényelmesebb, és nagyon sok helyen van ahhoz is támogatás.
Nem gond, van rá megoldás, csak nem illeszkedik a harmony környezetébe. Így megoldom tőle külön. Nincs megkötve az ember keze, csak vigyázni kell, mit hová teszünk.
Pontosan. Igazabol nem tervezem a stack melyseget, hanem ellenorzom. Adok annyit, amennyit jonak latok, de mukodes kozben megnezem, hogy valoban mennyi kell es ennek fuggvenyeben modositom, ha szukseges. Igazabol szaz byte-os nagysagrendrol van szo. Ha van eleg RAM (mondjuk 32..64k) akkor ez altalaban nem jelet problemat, kap a process 200..800 byte-ot. Itt egy eppen fejlesztes alatt allo kutyu stack usage-e:
Oké, meg lehet éppen csinálni, de annyi pepecseléssel jár, hogy tényleg nem vágom, mi értelme van valójában? Aszinkron állapotgépekkel + interruptokkal nem lenne sokkal egyszerűbb az életed? Vagy olyan a fejlesztési project, hogy jobb lenne ha nem is tudna mások kezébe kerülni, és azért csavartál rajta?
Ha meg tudod oldani, hogy egyetlen állapotba se tudjon beragadni a program, illetve esetleg időkorlátot is teszel, hogy ez ne történhessen meg, akkor az már majdnem multitasking. Ha multitaskingot úgy oldod meg, hogy fix időosztásokkal operálsz, akkor megint inkább állapotgépes lesz. Azt megoldani, hogy mindig az a szál fusson, ami a prioritásokat is figyelni, olyan erőforrásokat igényelhet, ami lassabbá teszi az egészet, mint sima állapotgéppel. Szerinted itt van gyakorlati haszna a multitaskingnak, ki tudtad használni, nem volt egyszerűbb megoldás, ami ugyanoda vezet?
Esetleg az RTOS vagy a freeRTOS? Bővebben: Link
Milyen pepecseles? Ha van kernel, akkor mar csak a kodot kell irni. A state machine az egyik legalapvetobb modszer, amit mind programozasban, mind hardware-ben (!) hasznal az ember, semmi koze a multitaskinghoz. Egy egyszeru UART interrupt rutinban is sokszor hasznal az ember allapotgepet. Nincs ebben semmi csavaras, event driven rendszerek, szeparalt processzekkel. Ezt a masok kezebe kerulest nem ertem. Egy ilyen program sokkal attekinthetobb, mint a "fociklusbol hivogatunk mindent" tipusu iskolai peldaprogramok. Minden process a sajat dolgaval foglalkozik, es signal-ok, message-ek segitsegevel kommunikalnak egymassal.
A gyakorlati haszna az, hogy nem neked kell foglalkozni azzal, hogy az osszes feladathoz tartozo fuggvenyedet ciklukusan meghivd az egyetlen foprogrambol, es az mind vizsgalgasson valami timer allapotot, vagy pollozzon hardware biteket, hogy van-e dolga vagy nincs. Azert, mert ez a tipikus mikrocsip megoldas (sajnos volt szerencsem kinlodni ezekkel), attol ez meg nem jo. Az igazi multitasking lenyege pont az, hogy a kulonbozo feladatokat kulonallo processekben irod meg, es a kernel majd mindig annak adja a CPU-t, akinek kell. Persze egy cooperative kernel eseteben ez csak akkor mukodik jol, ha a processzek nem sokaig foglaljak egyhuzamban a processzort, de ez a fenti fociklusos mindent hivogatos modszernel is igy van. Vannak esetek, amikor egy process megis nagyon sokaig csinal valamit, es ezzel feltartja az osszes tobbi processzt. Erre tobb megoldas is van. Lehet hasznalni preemptive kernelt, de azzal sok egyeb macera van. Lehet olyat csinalni, hogy a hosszan tarto muveletet valahogy feldarabolod tobb reszre, vagy csak beleteszed, hogy x idonkent adja fel a CPU-t. De a legtobb esetben egy-egy esemenyre reagalni nem tart sokbol. Es termeszetesen allapotgepek kellenek, de azok mindenkeppen kellenek. Azok nelkul nem nagyon lehet programozni.
A fix idoosztas egy mas teszta. Meg valamikor 1991-ben kellett ket egymastol fuggetlen z80 gepre irt programot osszeraknom egy joval nagyobb sebessegu, de a z80-nal sw kompatibilis processzorra. Kezenfekvo volt, hogy 2ms-os valtassal hol az egyik, hol a masik kod futott. Ebben az esetben ez jo megoldas volt, de normalis korulmenyek kozott ezzel az a baj, hogyha az egyik programnak semmi dolga nincs, mert var valami bejovo adatra, akkor is lefoglalja a processzort a 2ms idore, mikozben a masiknak szuksege lenne a CPU idore. A multitaskolas lenyege, hogy mindig az a process kapjon idot, akinek szuksege van ra. Ha egy process elmegy varni valamire, akkor o addig nem hasznal el processzor idot, amig be nem kovetkezik az az esemeny, amire var.
Na jó, de ha a process nem kér időt, akkor nem is fordítódik rá a szelete, valamint ha hamarabb végez, akkor visszaadja a szálat.
Abban egyetértek, hogy a későbbiekben már sokkal kevesebb idő a fejlesztés és kényelmesebb, legalább is annak tűnik. De biztosan megmaradnak azok a lehetőségek is, amik speciálisak, hardver közeliek, vagy csak azok, amiket a kernel enged? Nézted, van RTOS a harmony-ben, lehet, hogy kipróbálom! ![]()
Ez megvalositas fuggo. Az en kernelemnel (nem en irtam) minden lehetoseged megmarad. Egy jo cooperativ kernel csak annyit csinal, hogy amikor (az en esetemben) meghivod a BZ_EventWait() fuggvenyt, akkor a kernel megnezi, hogy melyik process READY, es ezek kozul a legnagyobb prioritasunak adja a CPU-t. De valaszthatok round robin schedulingot is, amikor is nincsenek process prioritasok, csak korbe korbe megy a READY processzek kozott. Alapvetoen az egesz 'signal'-okra epeul. A szignal az egy bit egy 32 bites szamban. Minden bit egy szignal. A process csak szignalra tud varni, minden mas (szemafor, lock, message) szignalokra epul. Minden processhez tartozik egy leiro, amiben benne van az, hogy milyen szignalra var eppen, es hogy eddig milyen szignalokat kapott. Namost ha var az 1-re, de csak a 8-at kapta, akkor az a process nem READY. Ha megkapja az 1-et, akkor mar READY-ve valik, es a legkozelebbi BZ_EventWait() kernel hivas latni fogja, hogy a process futokepes, es ha nincs magasabb prioritasu READY process, akkor meg is kapja a CPU-t. De ettol meg ugyanugy vannak megszakitasok, ez minden egyeb. Ez csak a szalak futtatasahoz ad egy nagyon kenyelmes kornyezetet, de nem tilt meg semmit, nem korlatoz semmiben. A signal kuldo fuggvenyeket termeszetesen lehet megszakitasbol is hivni.
Egy preemptiv kernelnel, amikor A process egy signalt kuld B processznek, akkor a kernel megnezi, hogy ettol B process READY-ve valt-e, es ha igen, akkor mar inditja is B-t, ha az magasabb prioritasu, mint A. Namost, mivel signalt megszakitas is tud kuldeni, ezert egy preemtive kornyezetben egy processz futasat ilymodon egy magasabb prioritasu process meg tudja szakitani. Ennek elonye, hogy nem a tobbi process donti el, hogy egy magasabb prioritasu mikor futhat. De hatranya, is van boven. Sokkal jobban kell a kozos eroforrasokra vigyazni, az egyebkent nem javasolt globalis valtozokat volatile-nak kell deklaralni. Meg aztan van a prioritas inverzio nevu problema, ami megintcsak bosszanto.
Ez nagyon "szép", tetszik! A process, ami még nem READY, hogyan kapja meg a szükséges szignálokat? A szignálok vizsgálata a kernel feladata, a kernel dönt, hogy READY-e a process a megfelelő szignálok esetén? Azt, hogy milyen szignálra vár a process, a legutóbbi futásnál adja át a kernelnek? A szignál mögött lévő adatokat hogyan kapja meg a process? (azt hiszem nem kérdezek meg mindent, mert megharagszol!
![]()
Hello!
Megint volt egy kis időm játszani az PIC32MM-el. Összehasonlítottam a kódrészletedet az enyémmel. A konklúzió, hogy dual edge módban megy az SCCP nálam is. Eddig a módokkal nem játszottam. Illetve az MCCP-n igen, de az SCCP-n nem. Mind a két dual edge mód megy, buffered és unbuffered is. A center aligned mód viszont nem megy az SCCP-n és azzal próbáltam, az MCCP-n viszont az is megy. Átnyálaztam az adatlapokat megint, de semmi utalást nem találtam amit kihagyhattam volna. Kihagytam még valamit, vagy ez már tényleg bug? Idézet: Ugy, hogy egy megszakitas vagy egy masik futo process kuld neki signalt: BZ_EventPost(pid, signal);„A process, ami még nem READY, hogyan kapja meg a szükséges szignálokat?” Amikor egy process meghivja a BZ_EventWait(sig) fuggvenyt, akkor a sig parameterben mondja meg, hogy melyik signalokra var. Itt egy nagyon egyszeru pelda, amiben van egy timer megszakitas, ami minden processznek kuldi a SIG_TIMER szignalt, es egy billentyuzet szkennelo process, ami ezt a TIMER signalt hasznalja idozitesre. Ezen felul lehet meg neki kuldeni STOP es START szignalt, csak a pelda kedveert.
Még mielőtt bármiféle állást foglalnék mikrovezérlőkre való kooperatív / preemptív kernel ügyben, egy olyan kérdésem lenne, hogyan tudod biztonságosan meghatározni egyes alkalmazás modulok maximális verem igényét?
A par posttal ezelott emlitett modszer megfelelonek bizonyult. Ha egy processz osszes lehetseges allaoptan atment mar, akkor annal tobb stack nem nagyon kellhet neki. Mivel nem hasznalok nested interrupt-ot, attol sem kell tartanom. Szoval latom, hogy az adott processz mennyi stack-et hasznal, amire rahagyok meg valamennyi biztonsagi tartalekot, es kesz. Nincs MMU, hogy page fault-ot kerjen, ha tulcsordult a stack... Igazabol semmi mas modon nem tudod megoldani, ha nincs HW tamogatasod. Allokalsz annyit, amennyi biztonsaggal elegendo, es remenykedsz, hogy eleg is lesz. Egy C programnal nem lehet elore kiszamolni a stack igenyt. De visszakerdezek. Egy "hagyomanyos" mikrocsipes kornyezetben, ahol azt se nagyon tudja a programozo, hogy egyaltalan hova van beallitva az SP, ott mi garantalja, hogy eleg a stack? Beallitja a RAM vegere, aztan novekszik visszafele, amig ossze nem er a bss-sel vagy a heap-pel (?).
|
Bejelentkezés
Hirdetés |