Fórumok
Sziasztok!
Letre kene hoznom par ilyesmi szimbolumot C preprocessz soran:
#define XYZ_WHAT XYZ_42WHAT
#define XYZ_EVER XYZ_42EVER
#define XYZ_LOLZ XYZ_42LOLZ
Ahol a "42" az egy elore adott konstans, amit 1x szeretnek csak definialni az elejen. Ilyesmivel probalkoztam hogy:
#define __xyz_def(a,b) XYZ_##a##b
#define XYZ_WHAT __xyz_def(42,WHAT)
#define XYZ_EVER __xyz_def(42,EVER)
/* ... */
Ez itten fentebb mar ugye egy fokkal - jobb de a preprocessz alatt nem tudom beleirni azt hogy:
#define NUM 42
#define __xyz_def(a,b) XYZ_##a##b
#define XYZ_WHAT __xyz_def(NUM,WHAT)
/* ... */
Mi is volt erre a trukk? :) Vagy legalabbis ugy remlik hogy volt erre valami, de sehol sem lelem...
Thx, A.
Hozzászólások
Ez elég jó? Még nem jöttem rá, hogyan lehetne a 42-t kiszedni a saját sorába.
(Szerk: az első ## nem is kell.)
Ah, koszi, ez igy most a gyakorlatban tenyleg jo lesz - hogy a NUM/42 erteket csak 1x kelljen leirni ;) Most atirtam erre:
Persze az eredeti kerdesfelvetes az tovabbra is erdekel(ne), de lehet hogy igy ez mar mint elso lepes egeszen jo.
Na, csak meglett. Halványan derengett, hogy valami dupla ugrás kell. Nehéz volt ráguglizni. Az __xyz_def-ben még nem tudsz összefűzni, innen ugrani kell egy másik makróra és ott már igen. Ne kérdezd, nem értem :)
Ízlés szerint az XYZ_-t hardcode-olhatod a CAT3-ba, neki nem kell a dupla ugrás, a NUM-nak kell.
Koszi! Nezem itten, es mar majdnem jo, de... szoval basszus, mar latom mi itten a gond nalam :(
Ha az egyik LULZ mar letezik mint korabbi definicio, akkor baj van:
Ez igy fasza: a NUM 11 ill 42 eseten tenyleg azt csinalja a kod amit varunk - de ha a `#define WHAT` elol kiszedem a kommentet akkor osszeomlik :(
> de ha a `#define WHAT` elol kiszedem a kommentet akkor osszeomlik :(
Sóhaj...
Kábé ez az a pont amikor el szoktam kezdeni kódgenerátort írni, egyszerűbb esetekben (mint itt) sima pythonban, bonyolultabb esetekben jinjával kombinálva.
De várjunk még, hátha van itt valaki okosabb nálam aki tudja a nyers c preproc megoldást.
Igen... kozben reszelgettem itt-ott ezt, es sajnos ez a tobbszoros indirekcio sem segit :( Meg ugye megha az egyik WHAT/LULZ nem is lett volna definialva, akkor sem tulsagosan "future-proof" a megoldas, mert mi van ha kesobb valaki ugy dont hogy definialja...
Mivel a preprocesszor egymenetes feldolgozást végez, szerintem a megoldás nem létezik.
Science for fun...
Igen, ettol felek en is.
Igen, de lehet rekurzívan #include-olni. :)
Nem tudom a megoldást az eredeti kérdésre, csak azt, hogy egyik ismerősöm rekurzív #include-okkal új programnyelvet fejlesztett, amit a preprocesszor interpretál.
Szerk.: a -fmax-include-depth opcióra oda kell figyelni :)
Egyszer a Boost preprocesszorával én is csináltam valami hasonlót, mint amiről az eredeti kérdés szólt, de mivel az egésznek volt egy erőteljes intellektuális önkielégítés jellege, ezért inkább felhagytam vele. (Nem emlékszem rá pontosan, hogy miről szólt a küldetés, de az biztos, hogy volt benne for ciklus. Mármint olyan, amit preprocesszor hajtott végre.)
Science for fun...
... és ha nem akarod minden WHAT és EVER és egyéb sorba kiírni a NUM-ot, akkor még egy indirekció. A lényeg hogy a NUM fölött kell két szint, egy nem elég. Szép, mi? :)
Meg merjem kérdezni, hogy mi az X-probléma ebben a történetben?
Hogyne! Merd :)
Most, hogy az Y probléma megoldódott, kérlek áruld el, mi volt az X probléma.
Most, hogy az Y probléma megoldódott, kérlek áruld el, mi volt az X probléma.
Az a baj hogy annyira nem oldodott meg teljesen (ld. kesobb), de azert ez igy mar hatarozottan
jobb volt mint lettjobb lett mint volt :)Igy cimszavakban a dolog hattere: MSP430FR5xx-es architekturara portolok epp FreeRTOSt. Mindezt olyforman hogy mint preemptive, mind kooperative, mind pedig event+interrupt driven task awakening uzemmodban is szepen menjen, erosen kovetve a "az operacios rendszerhez kotheto dolgokat csak interrupt handler kontextbol csinalunk" elvet. Ehhez szeretnek a Cortex-Mx-es rendszerekhez hasonlatos task yield muveletelt, azaz olyan yieldet amikor a (akar nemprivilegizalt) szoftver altal kivaltott, de relative alacsony prioritasu, hardveresen atfuttatott (azaz nem environment call jellegu) megszakitas inditja be a folyamatot.
No, es mig a Cortex-Mx-re van ilyen hogy PendSV (amit ez a jo ARM is erre teremtett), RISC-V eseten is van (CSR: MIP, MSIP bit), legtobb mas lightweight hardveren nincs. Vagyis, hat, nem nagyon van. Vagyis, hat ugy kell keresni. Szoval ezeknek az MSP430-as mikrokontrollereknek viszont van elvezerelt GPIO bemenetu megszakitasuk (PxIES, PxIE, PxIFG), amihez tartozik X darab (x=1... X) vektor is. Es ezzel kapcsolatban ezt mondja a manual:
Avagy, ha bealdozunk egy Px.y GPIO bemenetet, es egy teljes vektort, akkor azt felhasznalhatjuk az ARM-nal megszokott PendSV-re (vagy hasonlo ugye a RISC-V-n az MSIP-hez tarsithato 3-as mcause). Csak roppantul esznel kell lenni mert a/ a Px.y-t masra nem hasznalhatjuk (se nem input, se nem output) b/ a hozzatartozo PORTx_VECTOR-t sem igazan (vagyhat, maximum esszel) c/ nagyon elo kell kesziteni a GPIO regisztereket a fogadasukra (hardveresen float, legyen input, legyen beepitett pullup-pulldown-valamilyen ellenallas, szoval hogy meg veletlenul se... opcionalisan lehet output is, franc se tudja mi a jobb). Es ha itt barmit elrontunk ebbol, akkor joesetben gyorsan, rosszesetben a leheto legaljsabb helyen ut be a krach (vagy legalabbis lasd meg: unexpected exception failed successfully).
Az altalad kerdezett "X problema" pedig nem mas, mint ennek a megfelelo, portmacro.h-beli elokeszitese, hogy ott te mint felhasznalo csak az x-et meg az y-t kell hogy megadd:
Ezalapjan pedig elkeszul a tobbi regiszter alias:
Meg persze az RTOS porton beluli minden ami ezt felhasznalja, jol:
Mivel sok helyen el tud verezni a dolog ha rosszul allitod be a Px.y-t (es hardverkozeli dolog leven elegge varatlan is lehet), ezert kerestem/keresek erre jo megodlast. Mint a legfelso kodtoredek mutatja, ez meg mindig nem teljesen fasza mert az x-et 2x kell leirni... de igy meg mindig talan jobb mint az eredeti....
Elsőre azt nem értem, hogy ha nincs külön kernel és user mód a CPU-ban, akkor miért nem jó egy
CALL 5
a rendszerhívásnak?Jonak jo de a/ akkor tobb (akar teljesen kulonbozo) kontext handler kell (az eredeti portban kulon van preemptiv timer, a koopperativ yield es kooperativ timer handler is) b/ az interrupt request driven task awakening nem fog menni es/vagy nem lesz hatekony (es raadasul sok stack-et is eszik mert kvazi duplan ment mindent). Konkretan ennel a hardver-osszeallitasnal a rendszerhivas-alapu porthoz kepest ez a megoldas 2x gyorsabb baud rate mellett is lehetove tette az UART interruptok feldolgozasat ugy hogy 0-ra esett le a 10ms jiffy nagysagrendjebol a bejovo adatforgalom kesleltetese is.
Ahogy érteni vélem, a yield rendszerhívás hatására a kernel átadja a vezérlést valamelyik futásra kész processznek. Ebb arra gondolok, hogy van kernel, vannak rendszerhívások, és vannak processzek.
Ha ez stimmel, akkor (felteszem) a többi rendszerhívás is implememtálva van valahogy.
Valojaban ebben a nagyon-nagyon konnyu kis kornyezetben (MMU nelkul: multithreading + IPC + power management) a (sys)tick-en meg a yield-en kivul nincs szukseg mas rendszerhivasra. Persze lehet ugy implementalni a dolgokat hogy az IPC-s adok-kapok is rendszerhivasokon keresztul megy kozvetlenul, de az MMU nelkul nem ad plusz vedelmet (csak lassabb lesz). Ellenben a szinkron multiplexelt es/vagy blocking IPC hivasok (vagy a rokon muveletek, mint szemaforok/mutexek) mar "userspace" szinten hasznalnak rendszerhivasokat amikor varakozara keszteti az adott thread-et. A rendszerhivasokon beluli es/vagy azok kozotti konkret implementacio akkor fontos ha mindezeket meg hatekonyan is szeretned csinalni (lasd: latency, task awakening interrupt handlerbol, ilyesmik).
Meg persze ilyesmibe is belemehetunk hogy a hatekony critical section felepites / lebontas mennyire tekintheto rendszerhivasnak. Ebbe is vannak/lehetnek erdekes trukkok (pl globalis nesting counter amit a kernel hozzacsap a context-hez): egy ilyen RTOS portingnak pont az a lenyege hogy ezeket elrejtse elolunk. Ettol fuggetlenul a critical section felepites / lebontas szerintem egy olyan resz amit RTOS kornyezetben mar nem a vegfelhasznalo dolga. Ott vannak erre a szemaforok vagy (a nagyon-nagyon konnyu kis kornyezet miatt) kommunikalja le kozvetlenul az adott periferiaval ha kell (ez egy kicsit szubjektiv dolog mar, azt elismerem, szoval minden tovabbi nelkul szabad critical section-okat hasznalni, nem lehet belole baj :)).
Fogsz egy tetszoleges scriptnyelvet, amibol webes/parancssori kapcsolos/guis inputbol legeneralod a megfelelo header file-okat. 1. sorba kommenttel: // AUTOGENERATED, DO NOT MODIFY!!!, meg persze az utolso sorban megismetelve. Kommentbe beteheted mi es milyen kapcsolokkal generalta, igy konnyen ujra tudod generalni kicsit mas beallitasokkal
Persze ertem a makros/preprocessoros megoldas sporterteket is. Nem vallalhatja be Teve az osszes hulye projectet. :D
A strange game. The only winning move is not to play. How about a nice game of chess?
Persze, akar a `Makefile`-ba is bele lehet ezt tenni, inline scripttel, nem gond. Nem, sajna annyira nem sport, de kihivas azert van benne :]