class CAN – Controller Area Network protokoll

A CAN egy kétvezetékes soros protokoll, amelyet megbízható, valós idejű üzenetküldésre használnak egy közös buszra csatlakoztatott egy vagy több csomópont között. A CAN 2.0 szabványosítása az ISO-11898-ban történt, és ma CAN Classic néven is ismert.

Létezik egy újabb, visszafelé kompatibilis protokoll is, melynek neve CAN FD (CAN with Flexible Data-Rate, azaz CAN rugalmas adatsebességgel). A machine.CAN meghajtó jelenleg nem támogatja a CAN FD funkcióit; ha CAN FD-re van szükséged, használd a pyb.CAN osztályt STM32-n.

A CAN támogatáshoz szükség van egy vezérlőre (gyakran egy belső mikrokontroller periféria) és egy külső adó-vevőre, amely a jeleket szintillesztve a CAN buszra helyezi.

Elérhető az STM32 alapú OpenMV kamerákon (M4 / M7 / H7 / H7 Plus / Pure Thermal / N6, valamint az Arduino-márkájú változatokon, amelyek tartalmaznak adó-vevőt). Egyelőre nem támogatott az OpenMV Cam RT1062 (mimxrt port) és az OpenMV Cam AE3 (alif port) eszközökön.

A machine.CAN interfész egy alacsony szintű, alapszintű CAN üzenetküldő interfész, amely a CAN vezérlőt egy kimenő prioritásos sorként (üzenetek küldéséhez), egy bejövő sorként (üzenetek fogadásához) és hibajelentési mechanizmusokként absztrahálja.

Megjegyzés

A tervezett can és aiocan micropython-lib modulok lesznek a CAN MicroPythonnal való használatának ajánlott módja.

Konstruktor

class machine.CAN(id: int, *args, **kwargs)

Egy adott id-jű CAN vezérlő objektum létrehozása:

  • Az id egy adott CAN vezérlő objektumot azonosít; ez kártya- és port-specifikus.

  • Az összes többi argumentum a CAN.init() függvénynek kerül átadásra. Legalább egy argumentumot (bitrate) meg kell adni.

Ennek az osztálynak a jövőbeli verziói itt port-specifikus kulcsszavas argumentumokat is elfogadhatnak, amelyek a hardvert konfigurálják. Jelenleg ilyen kulcsszavas argumentumok nincsenek implementálva.

Példa

A 1-es CAN vezérlő létrehozása és inicializálása 500 kbps átviteli sebességgel:

from machine import CAN
can = CAN(1, 500_000)

Metódusok

init(bitrate: int, mode: int = CAN.MODE_NORMAL, sample_point: int = 75, sjw: int = 1, tseg1: int | None = None, tseg2: int | None = None) None

A CAN busz inicializálása a megadott paraméterekkel:

  • A bitrate a kívánt busz bitsebesség bit/másodpercben.

  • A mode a Módok alatt felsorolt értékek egyike, amely a kívánt működési módot jelzi. Az alapértelmezett a „normal” működés a buszon.

A következő paraméterek opcionálisak, és a CAN bit időzítésekhez kapcsolódnak. A legtöbb esetben ezeket a paramétereket az alapértelmezett értékeken hagyhatod:

  • A sample_point az adatbit idejének egész százalékos értéke. Megadja a bitminta pozícióját a teljes névleges bitidőhöz viszonyítva. A CAN meghajtó ennek megfelelően számítja ki a paramétereket. Ezt a paramétert figyelmen kívül hagyja, ha a tseg1 és tseg2 be van állítva.

  • Az sjw az újraszinkronizálási ugrásszélesség időkvantum egységekben a névleges bitekhez; klasszikus CAN esetén 1 és 4 közötti érték lehet (mindkettő beleértve).

  • A tseg1 a mintavételi pont helyét határozza meg időkvantum egységekben a névleges bitekhez; klasszikus CAN esetén 1 és 16 közötti érték lehet (mindkettő beleértve). Ez az ISO-11898 szabványban definiált Prop_Seg és Phase_Seg1 fázisok összege. Ha ez az érték be van állítva, akkor a tseg2 értéket is be kell állítani, és a sample_point figyelmen kívül marad.

  • A tseg2 az átviteli pont helyét határozza meg időkvantum egységekben a névleges bitekhez; klasszikus CAN esetén 1 és 8 közötti érték lehet (mindkettő beleértve). Ez az ISO-11898 szabványban szereplő Phase_Seg2 fázisnak felel meg. Ha ez az érték be van állítva, akkor a tseg1 értéket is be kell állítani.

Ha ezek az argumentumok meg vannak adva, akkor a CAN vezérlő helyesen lesz konfigurálva a kívánt bitrate értékhez és a megadott összes bitenkénti időkvantum-számhoz. A tseg1 és tseg2 értékek felülírják a sample_point argumentumot, ha mindegyik meg van adva.

Megjegyzés

Az egyes vezérlő-hardverekre további korlátozások vonatkozhatnak ezeknek a paramétereknek az érvényes értékeit illetően, és ValueError kivételt vetnek, ha egy adott érték nem támogatott.

Megjegyzés

Bizonyos vezérlő-hardverek további opcionális kulcsszavas paramétereket fogadhatnak el hardver-specifikus funkciókhoz, mint például a túlmintavételezés.

set_filters(filters: list | tuple | None) None

Vételi szűrők beállítása a CAN vezérlőben. A filters lehet:

  • None az összes bejövő üzenet elfogadásához, vagy

  • [] vagy () az összes üzenetfogadás letiltásához, vagy

  • Egy iterálható objektum, amely egy vagy több, a szűrési feltételeket meghatározó elemet tartalmaz. Minden elem egy három elemű tuple vagy lista legyen:

    • Az identifier egy CAN azonosító (int).

    • A bit_mask egy bitmaszk a CAN azonosító mező bitjeihez (int).

    • A flags egy egész szám, amelyben a Üzenet-flag-ek által definiált bitek közül nulla vagy több van beállítva. Ez megadja azokat a tulajdonságokat, amelyeknek a bejövő üzenetnek meg kell felelnie. Nem minden vezérlő támogatja az összes flag szerinti szűrést, ValueError keletkezik, ha nem támogatott flag-et kérünk.

A bejövő üzenetek akkor kerülnek elfogadásra, ha a bit_mask által maszkolt bitek egyeznek az üzenet azonosítója és a szűrő identifier értéke között, és a szűrőben beállított flag-ek megfelelnek a bejövő üzenetnek.

Ha a CAN.FLAG_EXT_ID bit be van állítva a flag-ekben, a szűrő csak a kiterjesztett (Extended) CAN azonosítókra illeszkedik. Ha a CAN.FLAG_EXT_ID bit nincs beállítva, a szűrő csak a szabványos (Standard) CAN azonosítókra illeszkedik.

Az összes szűrő VAGY (OR) kapcsolatba kerül a vezérlőben. Ha a filters argumentumnak üres listát vagy tuple-t adunk át, az azt jelenti, hogy semmilyen üzenet nem kerül fogadásra.

Egyes CAN vezérlők megkövetelik, hogy minden szűrő csak egyetlen vételi FIFO-hoz legyen társítva. Ezekben az esetekben az argumentumban szereplő szűrőelemek körforgásos (round-robin) módon kerülnek elosztásra a rendelkezésre álló FIFO-k között. Ez a meghajtó nem tesz különbséget a FIFO-k között a vételi IRQ-ban.

Megjegyzés

Ha a hívó több elemet tartalmazó iterálható objektumot ad át, mint a CAN.FILTERS_MAX, akkor ValueError keletkezik.

Megjegyzés

Ha akár az identifier, akár a bit_mask a megadott azonosítótípushoz tartozó tartományon kívül esik, akkor „invalid id” okkal ValueError keletkezik.

Példák

Az összes bejövő üzenet fogadása:

can.set_filters(None)

Csak a 0x301 és 0x700 szabványos azonosítóértékű üzenetek fogadása:

can.set_filters(((0x301, 0x7FF, 0),
                 (0x700, 0x7FF, 0)))

A 0x300-0x3FF tartományba eső szabványos azonosítóértékű üzenetek, valamint csak a 0x50700 kiterjesztett azonosítóértékű üzenet fogadása:

can.set_filters(((0x300, 0x700, 0),
                 (0x50700, 0x1FFF_FFFF, CAN.FLAG_EXT_ID)))
FILTERS_MAX: int

Konstans érték, amely beolvassa az ehhez a hardveres vezérlőhöz támogatott vételi szűrők maximális számát.

Vedd figyelembe, hogy egyes vezérlőkre összetettebb hardveres korlátozások vonatkozhatnak a használatban lévő szűrők számát illetően (például a szabványos és kiterjesztett azonosítószűrők független számolásával). Ezekben az esetekben a CAN.set_filters akkor is ValueError kivételt vethet, ha a FILTERS_MAX korlát nincs túllépve.

send(id: int, data: bytes, flags: int = 0) int | None

Egy új CAN üzenet bemásolása a vezérlő hardveres átviteli sorába, hogy elküldésre kerüljön a buszra. Az átviteli sor egy prioritásos sor, amely CAN azonosító prioritás szerint van rendezve (az alacsonyabb numerikus azonosítók magasabb prioritásúak).

  • Az id egy egész szám CAN azonosító érték.

  • A data egy bytes objektum (vagy hasonló), amely a CAN üzenet adatait tartalmazza, vagy egy Remote Transmission Request (távoli átvitelkérés) leírását adja (lásd alább).

  • A flags egy egész szám, amelyben a Üzenet-flag-ek által definiált bitek közül nulla vagy több van beállítva, megadva a kimenő CAN üzenet tulajdonságait (Extended ID, Remote Transmission Request stb.)

Ha az üzenet sikeresen beállításra került a buszra való átvitelre, a függvény egy egész számot ad vissza a 0 és CAN.TX_QUEUE_LEN (kizárólag) közötti tartományban. Ez az érték az az átviteli puffer index, ahova az üzenet küldésre be lett sorolva, és a CAN.cancel_send függvény, valamint a CAN.IRQ_TX események használhatják.

Ha a sor megtelt, akkor a küldés sikertelen lesz, és None kerül visszaadásra.

A küldés akkor is sikertelen lehet, és None értéket adhat vissza, ha a megadott id érték prioritása megegyezik az átviteli sorban már szereplő üzenetével, és a CAN vezérlő hardver nem tudja garantálni, hogy az azonos azonosítójú üzenetek ugyanabban a sorrendben kerülnek a buszra, mint amilyenben a sorba kerültek. Ha az üzenetet mindenképp be szeretnéd sorolni, add át a CAN.FLAG_UNORDERED flag-et a flags argumentumban. Ez a flag azt jelzi, hogy elfogadható az azonos CAN azonosítójú üzeneteket tetszőleges sorrendben küldeni a buszra.

Ha a vezérlő „Bus Off” hibaállapotban van, vagy le van tiltva, akkor ennek a függvénynek a hívása OSError kivételt vet.

Megjegyzés

Ez a szándékosan alacsony szintű implementáció úgy lett megtervezve, hogy a hívó egy szoftveres sort hozhasson létre a kimenő üzenetekből.

Fontos

A CAN „átviteli sor” nem FIFO sor, hanem prioritás szerint rendezett, és bár akár CAN.TX_QUEUE_LEN elemet is tárolhat, az egy időben sorba állítható üzenetekre egyéb hardveres korlátozások is vonatkozhatnak.

Remote Transmission Request (távoli átvitelkérés)

Ha a CAN.FLAG_RTR bit be van állítva a flags argumentumban, akkor a vezérlő üzenet helyett egy Remote Transmission Request kérést küld. Ebben az esetben a data argumentum tartalma figyelmen kívül marad. A vezérlő olyan kérést küld, amelyben a DLC hosszmező megegyezik a data argumentum hosszával.

Példák

Kísérlet egy három byte-os 0a0b0c adattartalmú, 0x200 szabványos azonosítójú üzenet küldésére:

can.send(0x200, b"\x0a\x0b\x0c", 0)

Kísérlet egy üres adattartalmú, 0x180008 kiterjesztett azonosítójú üzenet küldésére. Jelezd, hogy a vezérlő tetszőleges sorrendben küldhet ezzel az azonosítóval üzeneteket, arra az esetre, ha már vannak sorba állítva más, azonos azonosítójú üzenetek küldésre:

can.send(0x180008, b"", can.FLAG_EXT_ID | can.FLAG_UNORDERED)

Kísérlet egy 8 byte hosszúságú, 0x555 szabványos azonosítójú Remote Transmission Request küldésére:

can.send(0x555, b" " * 8, can.FLAG_RTR)
recv(arg: list | None = None) list | None

Egy olyan CAN üzenet visszaadása, amelyet a vezérlő a CAN.set_filters() által beállított szűrőknek megfelelően fogadott.

Ez a függvény egyetlen opcionális argumentumot fogad; ha meg van adva, akkor egy legalább 4 elemű lista kell legyen, amelyben a második elem egy memoryview objektum, amely egy bytearray vagy hasonló objektumra hivatkozik, amelynek elegendő kapacitása van bármely fogadott CAN üzenet tárolásához (8 byte CAN Classic, 64 byte CAN FD esetén). A megadott lista kerül visszaadásra sikeres eredményként, és így elkerülhető a memóriafoglalás a függvényen belül.

Ha a CAN vezérlő nem fogadott üzenetet, akkor ez a függvény None értéket ad vissza.

Megjegyzés

A CAN.set_filters függvényt meg kell hívni, mielőtt a vezérlő bármilyen üzenetet fogadhatna. Az összes üzenet fogadásához hívd meg a set_filters(None) függvényt.

Ha a CAN vezérlő fogadott egy üzenetet, akkor ez a függvény egy 4 elemű listát ad vissza:

  • A 0. index a fogadott üzenet CAN azonosítója, egész számként.

  • Az 1. index egy memoryview, amely hozzáférést biztosít a fogadott üzenet adataihoz.

    • Ha az arg nincs megadva, akkor ez egy memoryview, amely a fogadott byte-okat tartalmazza. Ezt a memoryview objektumot egy újonnan lefoglalt bytearray támogatja, amely elég nagy bármely fogadott CAN üzenet tárolásához. Ez lehetővé teszi, hogy az eredmény biztonságosan újra felhasználható legyen jövőbeli arg argumentumként, így memóriafoglalások takaríthatók meg.

    • Ha az arg meg van adva, akkor a megadott memoryview átméretezésre kerül, hogy pontosan a fogadott byte-okat tárolja. A hívó felelőssége gondoskodni arról, hogy a memoryview mögötti objektum bármilyen hosszúságú CAN üzenetet képes legyen tárolni.

  • A 2. index egy egész szám, amelyben a Üzenet-flag-ek által definiált bitek közül nulla vagy több van beállítva. Ez a fogadott üzenettel kapcsolatos metaadatokat jelzi.

  • A 3. index egy egész szám, amelyben a Vételi hiba-flag-ek által definiált bitek közül nulla vagy több van beállítva. Bármely nem nulla érték a CAN üzenetek fogadásakor felmerülő lehetséges problémákat jelzi. Ezek a flag-ek minden alkalommal nullázódnak a vezérlőben, amikor ez a függvény visszatér.

Remote Transmission Request (távoli átvitelkérés)

Ha egy Remote Transmission Request kérés érkezik, akkor a CAN.FLAG_RTR bit lesz beállítva a 2. indexben, és az 1. indexnél lévő memoryview csupa nullát fog tartalmazni, a fogadott kérés DLC mezőjével megegyező hosszúsággal.

Példa
can.set_filters(None)   # receive all
while True:
    res = can.recv()
    if res:
        can_id, data, flags, errs = res
        print("Received", hex(can_id), data.hex(), hex(flags), hex(errs))
    else:
        time.sleep_ms(1)  # not a good pattern, use the irq instead!
irq(handler: Callable[[CAN], None] | None = None, trigger: int = 0, hard: bool = False) None

Beállít egy megszakítás-kezelő (handler) függvényt, amely akkor hívódik meg, ha a trigger-ben megjelölt események közül egy vagy több bekövetkezett.

  • A handler egy függvény, amely akkor hívódik meg, amikor a megszakítási esemény bekövetkezik. A kezelőnek pontosan egy argumentumot kell fogadnia, amely a CAN példány.

  • A trigger konfigurálja azt az esemény(eke)t, amely(ek) megszakítást generálhat(nak). A lehetséges értékek a következők közül egy vagy több maszkja:

    • A CAN.IRQ_RX esemény akkor következik be, miután a CAN vezérlő legalább egy üzenetet fogadott az RX FIFO-jába (ami azt jelenti, hogy a CAN.recv() sikeresen visszatér).

    • A CAN.IRQ_TX esemény akkor következik be, miután a CAN vezérlő vagy sikeresen elküldött egy üzenetet a CAN buszra, vagy nem sikerült elküldenie egy üzenetet. Ennek a triggernek a kezelőre vonatkozóan további követelményei vannak, a részletekért lásd: IRQ flag-ek.

    • A CAN.IRQ_STATE esemény akkor következik be, amikor a CAN vezérlő egy súlyosabb hibaállapotba lépett. Hívd meg a CAN.state() függvényt a frissített állapot lekéréséhez.

  • A hard ha True, akkor hardveres megszakítás kerül használatra. Ez csökkenti a késleltetést a CAN vezérlő eseménye és a kezelő meghívása között. A hardveres megszakítás-kezelők nem foglalhatnak memóriát; lásd: Megszakításkezelők írása.

Egy irq objektumot ad vissza. Ha argumentumok nélkül hívjuk, akkor egy korábban konfigurált irq objektum kerül visszaadásra.

Példát lásd: IRQ flag-ek.

cancel_send(index: int) bool

Felkéri a CAN vezérlőt, hogy szakítsa meg egy üzenet buszra való küldését.

Az index argumentum egyetlen átviteli puffert azonosít. Egy egész számnak kell lennie a 0 és CAN.TX_QUEUE_LEN (kizárólag) közötti tartományban. Általában ez egy korábban a CAN.send() által visszaadott érték lesz.

Az eredmény True, ha ebben a pufferben átvitelre váró üzenet volt, és az átvitel megszakításra került.

Az eredmény egyébként False (vagy nem volt átvitelre váró üzenet ebben a pufferben, vagy az átvitel már sikeres volt).

A CAN.IRQ_TX IRQ eseményt kell használni annak megállapítására, hogy egy üzenet biztosan elküldésre került-e vagy sem, de vedd figyelembe, hogy versenyhelyzetek (race condition) léphetnek fel, ha egy átvitelt megszakítanak, majd ugyanazt a puffert egy másik üzenet küldésére használják (különösen, ha a CAN vezérlő IRQ nem „hard”).

state() int

Egy egész értéket ad vissza, amely a vezérlő aktuális állapotát jelzi. Az érték a Állapotok alatt definiált értékek egyike lesz.

Az alacsonyabb súlyosságú hibaállapotok automatikusan törlődhetnek, ha a busz helyreáll, de a CAN.STATE_BUS_OFF állapot csak a CAN.restart() függvény meghívásával állítható helyre.

get_counters(list: list | None = None, /) list

Visszaadja a vezérlő hibaszámláló értékeit. Az eredmény egy nyolc értékből álló lista. Ha az opcionális list paraméter meg van adva, akkor a megadott lista objektum frissítésre és eredményként visszaadásra kerül, a memóriafoglalás elkerülése érdekében.

A lista elemei a következők:

  • TEC (Transmit Error Counter, átviteli hibaszámláló) érték

  • REC (Receive Error Counter, vételi hibaszámláló) érték

  • Ahányszor a vezérlő az Active állapotból a Warning állapotba lépett.

  • Ahányszor a vezérlő a Warning állapotból az Error Passive állapotba lépett.

  • Ahányszor a vezérlő az Error Passive állapotból a Bus Off állapotba lépett.

  • A hardveres sorban függőben lévő TX üzenetek teljes száma.

  • A hardveres sorban függőben lévő RX üzenetek teljes száma.

  • Ahányszor RX túlcsordulás (overrun) történt.

Megjegyzés

A vezérlőtől függően ezek az értékek egy bizonyos érték után visszacsordulhatnak 0-ra.

Megjegyzés

Ha egy vezérlő nem támogat egy adott számlálót, akkor ahhoz a listaelemhez None értéket ad vissza.

get_timings(list: list | None = None, /) list

Visszaad egy elemekből álló listát, amely a CAN vezérlőben jelenleg konfigurált időzítéseket jelzi. Ez hibakeresési célból az időzítések ellenőrzésére használható. Az eredmény egy hat értékből álló lista. Ha az opcionális list paraméter meg van adva, akkor a megadott lista objektum frissítésre és eredményként visszaadásra kerül, a memóriafoglalás elkerülése érdekében.

A lista elemei a következők:

  • A vezérlő által használt pontos átviteli sebesség. A CAN.init() függvénynek átadott bitrate argumentumtól eltérhet a hardveres korlátok teljesítéséhez szükséges kvantálás miatt.

  • Újraszinkronizálási ugrásszélesség (SJW) időkvantum egységekben a névleges bitekhez. Ugyanaz a jelentése, mint a CAN.init() sjw paraméterének.

  • A mintavételi pont helye időkvantum egységekben a névleges bitekhez. Ugyanaz a jelentése, mint a CAN.init() tseg1 paraméterének.

  • Az átviteli pont helye időkvantum egységekben a névleges bitekhez. Ugyanaz a jelentése, mint a CAN.init() tseg2 paraméterének.

  • CAN FD időzítési információ. None azoknál a vezérlőknél, amelyek nem támogatják a CAN FD-t, vagy ha a CAN FD nincs inicializálva. Egyébként egy négy elemből álló beágyazott lista, amely a fenti elemeknek felel meg, de a CAN FD BRS funkcióra alkalmazandó.

  • Opcionális vezérlő-specifikus időzítési információ. A vezérlőtől függően ez vagy None, ha a vezérlő nem jelent ilyet, vagy egy állandó hosszúságú lista, amelynek elemei egy adott hardveres vezérlőre jellemzőek.

Megjegyzés

Ha a CAN.init() függvény nem lett meghívva, akkor ez a függvény még mindig ad vissza eredményt, de az eredmény a vezérlő belső állapotától függ, és lehet, hogy nem pontos.

restart() None

Hatására a vezérlő kilép a STATE_BUS_OFF állapotból anélkül, hogy bármilyen más belső állapotot törölne. Emellett töröl néhány hibaszámlálót is (mindig az egyes hibaállapotokba való belépések számát, esetleg a TEC és REC értékeket is, a vezérlőtől függően).

Ennek a függvénynek a meghívása emellett megszakít minden küldésre váró üzenetet is. Ezekhez az üzenetekhez nem kerül IRQ_TX megszakítás kézbesítésre.

Vedd figyelembe, hogy ez a függvény a vezérlőtől függően kiléptetheti vagy sem a vezérlőt az „Error Passive” állapotból, attól függően, hogy a vezérlő hardvere nullázza-e a TEC és REC értékeket vagy sem.

deinit() None

Deinicializál egy korábban aktív CAN példányt. Az összes függőben lévő üzenet (átviteli és vételi) eldobásra kerül, és a vezérlő abbahagyja a buszon való kommunikációt. A példány újbóli használatához hívd meg a CAN.init() függvényt.

Ennek a függvénynek a meghívására válaszul nem hívódik meg IRQ_TX vagy IRQ_RX megszakítás.

Lásd még: CAN.restart().

Konstansok

TX_QUEUE_LEN: int

A CAN üzenetek maximális száma, amelyek a vezérlő kimenő hardveres üzenetsorában sorba állíthatók. A CAN.send(), CAN.cancel_send() és IRQ flag-ek által használt „átviteli puffer indexek” ebben a tartományban lesznek.

Módok

Ezek az értékek a vezérlő működési módjait jelölik, ahogyan azokat a CAN.init() függvénynek átadjuk. Nem minden vezérlő támogatja az összes módot.

Egy futó vezérlő módjának megváltoztatásához meg kell hívni a CAN.deinit() függvényt, majd újra meghívni a CAN.init() függvényt az új móddal.

MODE_NORMAL: int

A vezérlő szabványos CAN hálózati csomópontként aktív (nyugtázza az érvényes üzeneteket, és az aktuális State állapotától függően hibákat is továbbíthat).

MODE_SLEEP: int

A CAN vezérlő alvó állapotban van, alacsony fogyasztású módban. A vezérlőtől függően ez támogathatja a vezérlő felébresztését és a CAN.MODE_NORMAL állapotba való átmenetet, ha CAN forgalom érkezik.

MODE_LOOPBACK: int

Egy tesztelési mód. A CAN vezérlő továbbra is csatlakozik a külső buszhoz, de a saját elküldött üzeneteit is fogadja, és figyelmen kívül hagy minden ACK hibát.

MODE_SILENT: int

A CAN vezérlő üzeneteket fogad, de nem kommunikál a CAN buszon (beleértve az ACK-k, hibák stb. küldését).

MODE_SILENT_LOOPBACK: int

Egy tesztelési mód, amelyhez egyáltalán nem szükséges CAN adó-vevő csatlakoztatása. A CAN vezérlő fogadja a saját elküldött üzeneteit anélkül, hogy egyáltalán kommunikálna a CAN buszon. A CAN TX és RX lábak tétlenek maradnak.

Állapotok

Ezeket az értékeket a CAN.state() adja vissza, és a CAN vezérlő hibaállapotát tükrözik:

STATE_STOPPED: int

A vezérlő nem lett inicializálva.

STATE_ACTIVE: int

A vezérlő aktív, és mind a TEC, mind a REC hibaszámláló a 96-os figyelmeztetési küszöbérték alatt van. Lásd: CAN.get_counters().

STATE_WARNING: int

A vezérlő aktív, de a TEC és REC hibaszámlálók közül legalább az egyik 96 és 127 között van. Lásd: CAN.get_counters().

STATE_PASSIVE: int

A vezérlő az „Error Passive” állapotban van, ami azt jelenti, hogy már nem továbbít aktív hibákat a buszra, de egyébként működőképes. Ez az állapot akkor következik be, amikor a TEC és REC hibaszámlálók közül legalább az egyik 128 vagy nagyobb, de a TEC 255-nél kisebb. Lásd: CAN.get_counters().

STATE_BUS_OFF: int

A vezérlő a Bus-Off állapotban van, ami azt jelenti, hogy a TEC hibaszámláló nagyobb, mint 255. A CAN vezérlő ebben az állapotban nem kommunikál a buszon, és a folytatáshoz a CAN.restart() függvényen keresztül újra kell indítani.

Üzenet-flag-ek

Ezek az értékek egy CAN üzenettel kapcsolatos metaadatokat jelölnek. A CAN.send(), CAN.recv() és CAN.set_filters() függvények egy olyan egész értéket fogadnak el vagy adnak vissza, amely ezeknek a flag-eknek a bitenkénti VAGY (OR) kapcsolatából áll össze.

FLAG_RTR: int

Azt jelzi, hogy egy üzenet egy remote transmission request (távoli átvitelkérés).

FLAG_EXT_ID: int

Ha be van állítva, azt jelzi, hogy egy üzenetazonosító kiterjesztett (Extended, 29 bites). Ha nincs beállítva, azt jelzi, hogy egy üzenetazonosító szabványos (Standard, 11 bites).

FLAG_UNORDERED: int

Ha be van állítva a CAN.send() flags argumentumában, azt jelzi, hogy elfogadható, ha az azonos CAN azonosítójú üzenetek tetszőleges sorrendben kerülnek a buszra.

Egyébként több azonos azonosítójú üzenet sorba állításának kísérlete a CAN.send() sikertelenségét eredményezheti, ha a vezérlő hardver nem tudja kikényszeríteni a sorrendet.

Ez a flag soha nincs beállítva a fogadott üzeneteknél, és a CAN.set_filters() figyelmen kívül hagyja.

Vételi hiba-flag-ek

A CAN.recv() eredménye tartalmaz egy olyan egész értéket, amely ezeknek a flag-eknek a bitenkénti VAGY (OR) kapcsolatából áll össze. Ha be vannak állítva, ezek a flag-ek a CAN üzenetek fogadásával kapcsolatos lehetséges általános problémákat jeleznek.

RECV_ERR_FULL: int

Az a hardveres FIFO, ahova ezt az üzenetet fogadták, megtelt, és további bejövő üzenetek elveszhetnek.

RECV_ERR_OVERRUN: int

Az a hardveres FIFO, ahova ezt az üzenetet fogadták, megtelt, és egy vagy több bejövő üzenet elveszett.

IRQ értékek

IRQ_RX: int

Add át az irq() trigger argumentumának, hogy a kezelő minden alkalommal elsüljön, amikor a CAN vezérlő egy teljes üzenetet fogadott az RX FIFO-ba. A kezelőn belül olvasd be az üzenetet a recv() függvénnyel.

IRQ_TX: int

Add át az irq() trigger argumentumának, hogy a kezelő minden alkalommal elsüljön, amikor a CAN vezérlő befejez egy átviteli kísérletet (sikeres vagy sikertelen). A kezelőn belül használd az alábbi további biteket annak megállapításához, hogy melyik mailbox fejeződött be, és hogy sikertelen volt-e – lásd: IRQ flag-ek.

IRQ_STATE: int

Add át az irq() trigger argumentumának, hogy a kezelő minden alkalommal elsüljön, amikor a vezérlő a STATE_* értékek között vált (active / warning / passive / bus-off). Használd a state() függvényt a kezelőn belül az új állapot beolvasásához.

IRQ_TX_FAILED: int

Állapot-flag, amely az irq().flags() értékben lehet beállítva, amikor egy IRQ_TX esemény elsül. Azt jelzi, hogy az átviteli kísérlet sikertelen volt (jellemzően azért, mert a cancel_send() meghívásra került, vagy a vezérlő hibaállapotba lépett).

IRQ_TX_IDX_SHIFT: int

Az átviteli-mailbox-index mező bitpozíciója az irq().flags() értéken belül egy IRQ_TX esemény során. A mailbox index (flags >> IRQ_TX_IDX_SHIFT) & IRQ_TX_IDX_MASK formában nyerhető ki.

IRQ_TX_IDX_MASK: int

Az átviteli-mailbox-index mező bitmaszkja az irq().flags() értéken belül egy IRQ_TX esemény során. A kinyert index megegyezik a megfelelő send() hívás által visszaadott egész számmal (egy int a 0 és TX_QUEUE_LEN közötti tartományban).

IRQ flag-ek

A CAN.irq() meghívása regisztrál egy megszakítás-kezelőt a CAN.IRQ_RX, CAN.IRQ_TX és CAN.IRQ_STATE triggerek közül egy vagy többel.

A függvény egy IRQ objektumot ad vissza, és a flags() függvény meghívása ezen az objektumon egy olyan egész számot ad vissza, amely azt jelzi, hogy mely trigger esemény(ek) váltották ki a megszakítást. Egy CAN IRQ kezelőnek ismételten meg kell hívnia a flags() függvényt, amíg az 0 értéket nem ad vissza.

Amikor a flags() függvény beállított CAN.IRQ_TX bittel tér vissza, a kezelő az eredményben az alábbi flag-biteket is ellenőrizheti a TX eseménnyel kapcsolatos további információkért:

  • A CAN.IRQ_TX_FAILED bit akkor van beállítva, ha az átvitel sikertelen volt. Általában ez csak akkor fordul elő, ha a CAN.cancel_send() meghívásra került, bár előfordulhat akkor is, ha a vezérlő hibaállapotba lép.

  • A CAN.IRQ_TX_IDX_MASK << CAN.IRQ_TX_IDX_SHIFT a flags érték egy bitmaszkolt régiója, amely az eseményt generáló átviteli puffer indexét tartalmazza. Ez egy egész szám lesz a 0 és CAN.TX_QUEUE_LEN (kizárólag) közötti tartományban, és megegyezik egy korábbi CAN.send() hívás eredményével.

IRQ_TX példa

from machine import CAN

def irq_send(can):
    while flags := can.irq().flags():
        if flags & can.IRQ_TX:
            idx = (flags >> can.IRQ_TX_IDX_SHIFT) & can.IRQ_TX_IDX_MASK
            success = not (flags & can.IRQ_TX_FAILED)
            print("irq_send", idx, success)

can = CAN(1, 500_000)
can.irq(irq_send, trigger=can.IRQ_TX, hard=True)

Fontos

Ha a CAN.IRQ_TX trigger be van állítva, akkor a kezelőnek kötelező ismételten meghívnia a flags() függvényt, amíg az 0 értéket nem ad vissza, ahogyan ebben a példában látható. Ellenkező esetben a CAN megszakítások nem biztos, hogy helyesen engedélyeződnek újra.