Atommag hozzáférés a pic24 struktúrákhoz
Atomi hozzáférés alatt megértjük egy ilyen hívást (olvashatunk, módosíthatunk, írhatunk vagy azok sorrendjét) egy változóhoz vagy egy perifériás regiszterhez, amely nem fog konfliktusba ütközni, ha a feladat megszakítása vagy prioritása a művelet során RTOS rendszerekben történik. Probléma léphet fel, ha egy megszakítás vagy egy másik feladat ugyanazt az erőforrást használja.
Egyszerű példa: a RA0 vezérlő kimenetének invertálása:
A szintaxis és a logika szempontjából minden helyes, de nézzük meg a kódot, amely a fordításból származik
A fenti példában a LATA-regiszter aktuális értéke betöltésre kerül a kernelregiszterbe, amelyet módosított, majd visszaállít a LATA-regiszterbe. Most képzeljük el, miután befejeztük az utasításokat
egy érték, amely nem veszi figyelembe a bit beállítását a megszakításban, a portra íródik. A grafit rúd nem esett le. Boom!
Ennek eredményeképpen az erőforráshoz való hozzáférés konfliktusai következnek be, és ennek következtében nem hatékony program. Ha úgy gondolja, hogy ez a helyzet messze elterjedt, akkor kattintson a linkre. Ez egy valódi kérdés egy igazi személytől, aki a távoli RTOS TNKernel fejlődésének megkezdése után megbotlott a perifériához való atomos hozzáférés problémájára.
Számos lehetőség van a probléma megoldására. Mindegyiküknek vannak előnyei és hátrányai.
A legegyszerűbb és legnyilvánvalóbb módszer: annak biztosítása érdekében, hogy az utasítások sorrendje nem sérüljön meg, csak ki kell zárnia a konkurens kód futtatásának lehetőségét. Ebben az esetben a bit invertáló művelet atomikusan történik. Ennek a módszernek azonban számos hiányossága van:
Növelje meg a kód mennyiségét olyan utasítások miatt, amelyek tiltják és engedélyezik a megszakításokat.
A kód végrehajtásának sebessége ugyanazon okok miatt csökkenthető.
Ezzel az atommag-hozzáférési módszerrel lehetetlen determinisztikus késleltetést adni az interrupt-jitter bemenet megjelenésének. Egyes rendszerekben ez elfogadhatatlan.
Ez a megoldás nem használható olyan rendszerekben, amelyekben a megelőző RTOS van (vannak saját módszerek).
Ha a célplatform rugalmas megszakításvezérlőt tartalmaz, ennek a módszernek a mellékhatásai meglehetősen erősek lehetnek, mivel több intézkedésre van szükség a megszakítások letiltásához. Például a PIC24 / dsPIC esetében meg kell mentenünk az aktuális rendszermag prioritást az ideiglenes változónál (a veremen), állítsuk be a rendszermag prioritását a maximálisra, és az atomi hozzáférési művelet után állítsuk vissza az elsőbbséget az ideiglenes változóból. Ez az egyetlen helyes módja a megszakítások letiltására a C nyelvű szoftverek fejlesztésekor (a disi utasítás használata nem ajánlott).
Ez a módszer akkor használható, ha egy megelőző RTOS-t használ. A kritikus rész része annak a kódnak, amelyben tiltott a kontextusváltás. Leggyakrabban ez azt jelenti, hogy letiltja a megszakításokat és (esetleg) további lépéseket tesz az ütemező belső változóin.
A kritikus rész ugyanazokkal a hátránnyal jár, mint az előző módszer. Ráadásul a kritikus szakaszok használata nem ösztönözhető, mivel ebben az esetben zavarja az ütemezőt és megsérti az RTOS működésének alapelveit. Ha az erőforráshoz való hozzáférés egy viszonylag nagy kódszámhoz rendelhető, akkor ésszerűbb a mutexeket használni.
A Mutex olyan RTOS-objektum, amely versenyképes hozzáférést biztosít a közös erőforráshoz a feladatokhoz.
Ha nem implementálja a mutex mechanizmust az RTOS-ban, akkor bináris szemaforokat használhat, de ebben az esetben előfordulhat az elsőbbségi inverzió - olyan kellemetlen helyzet, amikor egy magasabb prioritású feladat nem fér hozzá az erőforráshoz.
A mutexek használata a legmegfelelőbb módszer a megosztott erőforrásokhoz való hozzáférés biztosításához. Azonban a perifériák szervizelésekor ez a módszer nagyon költséges lehet a térfogat, és ami a legfontosabb, a kód végrehajtásának sebessége.
Korlátozza a mutexeket a kód viszonylag nagy részére, de nem fér hozzá a struktúra mezőhöz vagy a portbithez.
Az atomos hozzáférést biztosító hardveres módszerekhez a 16 bites Microchip vezérlők disi utasítását is meg lehet adni. Ez az utasítás megtiltja a megszakításokat bizonyos számú parancsciklussal.
Megvizsgáltuk a program erőforrásokhoz való versenyképes hozzáférés általános problémáját. Van azonban egy speciális esete is ennek a problémának - a struktúra bitmezőinek elérése.
Ezen bitmezők elérésekor a fordító atomos utasításokat generálhat:
De a dolgok sokkal rosszabbak lesznek, ha megpróbálunk írni egy változó értékét a szerkezet mezőjében:
Problémák is jelentkezhetnek, ha 1 bitnél nagyobb bitmezőhöz fér hozzá:
A probléma megoldásának módja az xor utasítás használata. amely atomos hozzáférést biztosít minden esetben. még akkor is, ha nagy bitmezőt szeretne változtatni.
Tekintsünk egy példát: a TRISB regiszter alsó négy bitjére írjuk a 0x000A értéket.
az első utasítás betölti a TRISB értéket a W0 regiszterbe;
A második utasítás atomilag és biztonságosan módosítja a W0 regiszter négy legérzékenyebb bitjét;
a harmadik utasítás egy maszkot helyez el a W0 regiszteren, 4 legkevesebb bit felosztásával
az utolsó utasítás atomikusan és biztonságosan (a megmaradt bitek megérintése nélkül) módosítja a TRISB-t; TRISB = 0xFFFA;
Még ha megszakad az első utasítás végrehajtása után is, amely megváltoztatja a TRISB értékét (természetesen nem legalább 4 bit), a művelet megfelelően fog működni. A fenti kód atomi.
Alázatos véleményem szerint ezek a makrók a legmagasabb aerobatika. Számos érdekes megoldást használnak, amelyeket az alábbiakban tárgyalok.
BFAR () makró rögzített
Az egyes bitek szervizelésére vonatkozó utasításokat az összeszerelők helyettesítik, így bizonyos szintű optimalizálásnál a legkevésbé nem optimális kód
Hozzáadott makrók BFAM (). BFAMI (). BFAMD ()
Ugyanazok, mint a BFAR () és a BFAR (). De a művelet által érintett biteket nem egy tartomány, hanem egy maszk tiszteli. A teljes leírás egy kicsit később lesz
Hibajavítás a BFAR makróban ()
Ha a -másár-skalár-összeállítás opciót állítja be (a skalár változók a távolban lévő RAM-területen), akkor hiba történt, amikor a BFAR () makrót tetszőleges változóval (SFR attribútum nélkül) használta.
BFA makró fix ()
A BFA () makró használatakor figyelmeztetést kaptunk arról, hogy egy nagy konstans feltétel nélküli konverziója alá nem írt intre változik
Hozzáadott makró BFARD (). a RAM memóriában lévő bármely skaláris változóhoz való közvetlen hozzáféréshez.
A paraméterátvitel sorrendje megváltozott
Először a makró műveletét jelző paraméter kerül először
Hozzáadott makró BFARI ()
A BFARI () makró hozzáférést biztosít a struktúrához egy mutatóval
Minden művelethez hozzáadtunk új műveleteket: a BFA_SET és a BFA_CLR
Ezeket a műveleteket a bitmezőben a maszk bitek beállítására vagy törlésére használhatja. A maszk átvihető konstansként vagy változóként.
A BFA_IV helyét a BFA_INV váltja fel. Az inverziós művelet az átvitt maszk mentén befordítja a biteket.
Az első verzió. Csak a Microchip C30 fordítóhoz
Az archívum tartalmazza a bfa.h fejlécfájlt. amely négy makrót tartalmaz, amelyek a szerkezeti mezőhöz vagy bármely skalár változóhoz való atomos hozzáférést valósítják meg. Az egyik makrót olyan struktúrákkal való együttműködésre tervezték, amelyek nevei a perifériás regiszterek Microchip C30 szabályainak felelnek meg. A többi makrót bármilyen szerkezettel vagy változó méretű változóval lehet használni, amely nem nagyobb, mint a gépi szó (int).
A makrók használatához elegendő és elégséges a bfa.h fájl csatlakoztatása a modulhoz, és az optimálás nem lehet alacsonyabb, mint -01.
A PIC24 / dsPIC perifériás regiszterek megnevezett mezőihez való atomos hozzáférés
Atomikus hozzáférés a periférikus regiszterek és változók bitmezőihez. A bitmező numerikus tartományként van jelölve. A változónak a NEAR DATA SPACE-ban (az első 8 r<ОЗУ)
Perifériás nyilvántartások és változók bitmezőihez való atomos hozzáférés pointerrel. A bitmező numerikus tartományként van jelölve
Atomikus hozzáférés a periférikus regiszterek és változók bitmezőihez. A bitmező numerikus tartományként van jelölve. A változó bárhol megtalálható a RAM-ban (NEAR vagy FAR DATA SPACE)
A makró atomi hozzáférést biztosít a PIC24 / dsPIC mikrokontrollerek perifériás regiszter struktúráinak elnevezett mezőihez.
inverz biteket a bitmezőben maszkkal
A reg_name a perifériás regiszter neve, amelyhez például elérhetõ a PORTA. TRISB. CMCON és hasonlók. field_name a bitmező neve a regiszter struktúrában (lásd a mikrokontroller dokumentációját és a C30 fejlécfájlt a mikrokontroller számára). Például az IPC0 regiszter esetében ez lehet T1IP. opcionális paraméter csak akkor használható, ha a comm = [BFA_WR, BFA_SET, BFA_CLR, BFA_INV]. Ha a comm = BFA_RD, a paraméter nincs megadva. Ha comm = BFA_WR. a paraméter a bitmezőre írt értéket jelzi. Más esetekben a paraméternek meg kell egyeznie a bitmaszkkal. A paraméter változó lehet.
A makró atomi hozzáférést biztosít bármely olyan struktúra vagy változó bitmezőjéhez, amely a NEAR DATA SPACE területen van (az első 8 KB RAM). A bitmező tartományként szerepel (alacsony rendű bit / nagy megbízhatóságú bit).
Comm hozzáférési típus:
inverz biteket a bitmezőben maszkkal
A reg_name a regisztrált regiszter neve, amelyhez például elérhetõ a PORTA. TRISB. CMCON és hasonlók. Lehetnek olyan programváltozók is, amelyek a közeli adatmemória-területen (az első 8 kB-ban) a szerkezeti mező legkisebb legkisebb bitje 0-tól 15-ig terjedő felső, legfeljebb 0-tól 15-ig terjedő felső mező. opcionális paraméter csak akkor használható, ha a comm = [BFA_WR, BFA_SET, BFA_CLR, BFA_INV]. Ha a comm = BFA_RD, a paraméter nincs megadva. Ha comm = BFA_WR. a paraméter a bitmezőre írt értéket jelzi. Más esetekben a paraméternek meg kell egyeznie a bitmaszkkal. A paraméter változó lehet.
A makró atomos hozzáférést biztosít bármilyen struktúra vagy változó bitmezőjéhez pointerrel. A bitmező tartományként szerepel (alacsony rendű bit / nagy megbízhatóságú bit). A változó lehet mind a NEAR, mind a FAR DATA SPACE.
Comm hozzáférési típus:
inverz biteket a bitmezőben maszkkal
pt mutató a periférikus regiszterhez vagy bármely változóhoz. A makró automatikusan egy mutatót visz be egy int * típusba. a legkisebb, legkevésbé szignifikáns bitet a szerkezeti mezőtől, 0-tól 15-ig a szerkezeti mező felső legjelentősebb bitjét, 0-tól 15-ig, a felső> alacsonyabb értéket. opcionális paraméter csak akkor használható, ha a comm = [BFA_WR, BFA_SET, BFA_CLR, BFA_INV]. Ha a comm = BFA_RD, a paraméter nincs megadva. Ha comm = BFA_WR. a paraméter a bitmezőre írt értéket jelzi. Más esetekben a paraméternek meg kell egyeznie a bitmaszkkal. A paraméter változó lehet.
A makró atomi hozzáférést biztosít bármely olyan struktúra vagy változó bitmezőjéhez, amely a RAM bármelyik területén található (NEAR vagy FAR). A bitmező tartományként szerepel (alacsony rendű bit / nagy megbízhatóságú bit).
Comm hozzáférési típus:
inverz biteket a bitmezőben maszkkal
A val a hozzáférhetõ regiszter neve, például a PORTA. TRISB. CMCON és hasonlók. Lehet bármilyen skaláris programváltozó. a legkisebb, legkevésbé szignifikáns bitet a szerkezeti mezőtől, 0-tól 15-ig a szerkezeti mező felső legjelentősebb bitjét, 0-tól 15-ig, a felső> alacsonyabb értéket. opcionális paraméter csak akkor használható, ha a comm = [BFA_WR, BFA_SET, BFA_CLR, BFA_INV]. Ha a comm = BFA_RD, a paraméter nincs megadva. Ha comm = BFA_WR. a paraméter a bitmezőre írt értéket jelzi. Más esetekben a paraméternek meg kell egyeznie a bitmaszkkal. A paraméter változó lehet.
A fenti makrók ellenőrzik a továbbított paramétereket. jelezve a struktúrákhoz való hozzáférés módját. A fennmaradó paramétereket nem ellenőrzik. A következő megengedett értékek a következőkre vonatkoznak:
A makrók paramétereinek átvitelének ellenőrzése érdekes módon történik: a fejlécek minden egyes paramétertípushoz egyediek:
Ha a makróhoz átadott paraméter eltér a megadott BFA_WR-tól. BFA_RD és BFA_IV. a fordító hibát fog generálni:
Feltételes nyilatkozatok használata. egyetlen makróval végrehajtható a művelet végrehajtása és a visszatérési érték. Ha nem veszi át a végrehajtás részleteit, az összes makró így néz ki:
Ha a comm paraméter (a struktúrához való hozzáférés típusa) megegyezik a BFA_RD értékkel. akkor a makró a következő kifejezést hozza létre:
Így írva
az előfeldolgozó munkája után egy egyszerű feladatot kapunk:
Természetesen a BFA () és a BFAR () makrók közvetlen használata nem egyértelmű. Mindazonáltal ez az egyik módszer:
Ha a regiszter csak az íráshoz használja az alkalmazást, akkor megadhatja a következő makrót:
és ezt már használhatja:
Ha a struktúra mezőt írásra és olvasásra használjuk, a következő makrót definiálhatjuk változó számú paraméterrel:
Használja ezt a makrót az alábbiak szerint:
Gyakran szükség van a be nem jelentett struktúrákhoz való atomos hozzáférés megszerzésére - például egy bizonyos érték beállítására a vezérlő több kimenetén. Ehhez használja a BFAR () makrót.
És még nyilvánvaló:
Az ilyen makrók használata mindenkinek kötelező, aki gyors és biztonságos kódot szeretne írni a PIC24 / dsPIC mikrokontrollerek számára a C30 fordító segítségével.
Ez a megközelítés bármely más architektúrához és más fordítóprogramhoz alkalmazható. Ehhez szükséges, hogy:
a fordítónak rugalmas inline-szerelője volt (például a gcc-ben)
az architektúrának volt mechanizmusa a memória közvetlen elérésére
Ez utóbbi azt jelenti, hogy az alábbi két feltétel valamelyikének teljesülnie kell:
Az utasítások halmazának tartalmaznia kell egy xor utasítást, amely közvetlen hozzáférést biztosít az érdeklődési területhez
Az architektúrának speciális mechanizmusokkal kell rendelkeznie a közvetlen hozzáféréshez. Például a Cortex-M3 vagy a SET / CLR / INV regiszterek bit-sávja a PIC32 teljes perifériájához.
A BFA () és a BFAR () makrók fő előnyei a megosztott erőforrásokhoz való atomos hozzáférés megvalósítása. Természetesen ez nem jelenti azt, hogy a megszakításban és a fő kódban fájdalom nélkül lehet mozgatni a vezérlő ugyanazon lábát. De a port különböző bitjeihez való hozzáférés biztonságos.
A BFA () és a BFAR () makrók használatakor nincs szükség a megszakítások letiltására vagy egy kritikus szakasz végrehajtására. Ez lehetővé teszi, hogy meghatározza a megszakítás idejét, csökkentse a foglalt kód mennyiségét és a műveletek sebességét.
Továbbá, amikor a makrók hozzáférési struktúrákhoz kapcsolódnak, a kód és a végrehajtási idő mennyisége csökken a közvetlen eléréshez képest: