class CAN – controller area network kommunikációs busz

A CAN támogatja mind a klasszikus CAN (bxCAN, amelyet az OpenMV Cam M4 és M7 használ), mind a CAN FD (FDCAN, amelyet az OpenMV Cam H7, H7 Plus és Pure Thermal használ) vezérlőket. Fizikai szinten a CAN busz két vezetékből áll: RX és TX. Egy OpenMV Cam CAN buszhoz való csatlakoztatásához CAN transzceiverre van szükség, amely a CAN logikai jeleket az MCU-ról a busz megfelelő feszültségszintjeire alakítja át.

Klasszikus CAN loopback (transzceiver nélküli) módban:

from pyb import CAN

can = CAN(1, CAN.LOOPBACK)

# Accept messages with id 123, 124, 125 or 126.
can.setfilter(0, CAN.LIST16, 0, (123, 124, 125, 126))

can.send("message!", 123)   # send a message with id 123
can.recv(0)                 # receive a message on FIFO 0

CAN FD az összes választható funkció engedélyezésével (FD keret, bitsebesség-kapcsolás, kiterjesztett keret-azonosítók; 500 kbit/s arbitrációs fázis, 1 Mbit/s adatfázis):

from pyb import CAN

can = CAN(
    1,
    CAN.NORMAL,
    baudrate=500_000,
    brs_baudrate=1_000_000,
    sample_point=80,
)

# Accept any id in the range 0xFFF0 .. 0xFFFF.
can.setfilter(0, CAN.RANGE, 0, (0xFFF0, 0xFFFF))

can.send(b"a" * 64, 0xFFFF, fdf=True, brs=True, extframe=True)
can.recv(0)

A következő CAN modulfüggvények és argumentumaik mind a klasszikus, mind az FD CAN vezérlőkhöz elérhetők, hacsak másként nem jelezzük.

Konstruktorok

class pyb.CAN(bus: int | str, *args, **kwargs)

CAN objektum létrehozása az adott bus buszon (egész szám periféria-index, pl. 1 a CAN1 esetén, 2 a CAN2 esetén). További paraméterek nélkül az objektum létrejön, de nem inicializálódik (megtartja a korábbi busz-beállításokat, ha vannak); ha további argumentumokat adunk meg, a busz inicializálódik. Az elérhető paramétereket lásd a CAN.init() metódusnál.

A CAN(2) minden olyan OpenMV Cam ugyanazon fejléclábaira van bekötve, amely felfedi a pyb.CAN perifériát (M4 / M7 / H7 / H7 Plus / Pure Thermal):

Jel

Fejlécláb

Megjegyzések

RX

P3

TX

P2

A CAN periféria csak logikai szintű jeleket biztosít; egy valódi CAN busz meghajtásához külső CAN transzceiver szükséges.

A pyb.CAN nem érhető el az OpenMV Cam N6 modellen.

Metódusok

init(mode: int, prescaler: int = 100, *, sjw: int = 1, bs1: int = 6, bs2: int = 8, auto_restart: bool = False, baudrate: int = 0, sample_point: int = 75, num_filter_banks: int = 14, brs_sjw: int = 1, brs_bs1: int = 8, brs_bs2: int = 3, brs_baudrate: int = 0, brs_sample_point: int = 75) None

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

  • mode a következők egyike: NORMAL, LOOPBACK, SILENT, SILENT_LOOPBACK

  • prescaler az az érték, amellyel a CAN bemeneti órajelet osztjuk a névleges bitidő-kvantumok generálásához. Az előosztó értéke klasszikus CAN esetén 1 és 1024 közötti (beleértve), CAN FD esetén 1 és 512 közötti (beleértve) lehet.

  • sjw az újraszinkronizálási ugrásszélesség a névleges bitek időkvantumainak egységeiben; klasszikus CAN esetén 1 és 4 közötti (beleértve), CAN FD esetén 1 és 128 közötti (beleértve) érték lehet.

  • bs1 meghatározza a mintavételi pont helyét a névleges bitek időkvantumainak egységeiben; klasszikus CAN esetén 1 és 16 közötti (beleértve), CAN FD esetén 2 és 256 közötti (beleértve) érték lehet.

  • bs2 meghatározza az átviteli pont helyét a névleges bitek időkvantumainak egységeiben; klasszikus CAN esetén 1 és 8 közötti (beleértve), CAN FD esetén 2 és 128 közötti (beleértve) érték lehet.

  • auto_restart beállítja, hogy a vezérlő automatikusan megpróbálja-e újraindítani a kommunikációt, miután bus-off állapotba lépett; ha ez le van tiltva, akkor a restart() használható a bus-off állapot elhagyásához

  • baudrate ha 0-tól eltérő átviteli sebességet adunk meg, ez a függvény megpróbálja automatikusan kiszámítani a CAN névleges bitidőt (felülbírálva a prescaler, bs1 és bs2 értékeket), amely kielégíti mind a baudrate értéket (.1%-on belül), mind a kívánt sample_point értéket (a legközelebbi 1%-ig). A CAN időzítés pontosabb szabályozásához állítsa be közvetlenül a prescaler, bs1 és bs2 paramétereket.

  • sample_point megadja a bit mintavételének pozícióját a teljes névleges bitidőhöz viszonyítva, a névleges bitidő egész százalékában kifejezve. Az alapértelmezett sample_point 75%. Ezt a paramétert a rendszer figyelmen kívül hagyja, hacsak nincs beállítva a baudrate.

  • num_filter_banks klasszikus CAN esetén ez a CAN(1)-hez rendelt bankok száma, a 28-ból fennmaradó rész a CAN(2)-höz van rendelve.

A fennmaradó paraméterek csak a CAN FD támogatással rendelkező lapokon vannak jelen, és a választható CAN FD Bit Rate Switch (BRS) funkciót konfigurálják:

  • brs_prescaler az az érték, amellyel a CAN FD bemeneti órajelet osztjuk az adat-bitidő kvantumok generálásához. Az előosztó értéke 1 és 32 közötti (beleértve) lehet.

  • brs_sjw az újraszinkronizálási ugrásszélesség az adatbitek időkvantumainak egységeiben; 1 és 16 közötti (beleértve) érték lehet

  • brs_bs1 meghatározza a mintavételi pont helyét az adatbitek időkvantumainak egységeiben; 1 és 32 közötti (beleértve) érték lehet

  • brs_bs2 meghatározza az átviteli pont helyét az adatbitek időkvantumainak egységeiben; 1 és 16 közötti (beleértve) érték lehet

  • brs_baudrate ha 0-tól eltérő átviteli sebességet adunk meg, ez a függvény megpróbálja automatikusan kiszámítani a CAN adat-bitidőt (felülbírálva a brs_prescaler, brs_bs1 és brs_bs2 értékeket), amely kielégíti mind a brs_baudrate értéket (.1%-on belül), mind a kívánt brs_sample_point értéket (a legközelebbi 1%-ig). A BRS időzítés pontosabb szabályozásához állítsa be közvetlenül a brs_prescaler, brs_bs1 és brs_bs2 paramétereket.

  • brs_sample_point megadja a bit mintavételének pozícióját a teljes névleges bitidőhöz viszonyítva, a névleges bitidő egész százalékában kifejezve. Az alapértelmezett brs_sample_point 75%. Ezt a paramétert a rendszer figyelmen kívül hagyja, hacsak nincs beállítva a brs_baudrate.

Az időkvantum tq a CAN busz alapvető időegysége. A tq a CAN előosztó értékének és a PCLK1-nek (a belső periféria-busz 1 frekvenciájának) a hányadosa; a PCLK1 meghatározásához lásd a pyb.freq() metódust.

Egyetlen bit a szinkronizációs szegmensből áll, amely mindig 1 tq. Ezt követi az 1. bit szegmens, majd a 2. bit szegmens. A mintavételi pont az 1. bit szegmens befejeződése után van. Az átviteli pont a 2. bit szegmens befejeződése után van. Az átviteli sebesség 1/bitidő lesz, ahol a bitidő az 1 + BS1 + BS2 szorozva a tq időkvantummal.

Például az OpenMV Cam H7 modellen (PCLK1 = 100 MHz) a 250 kbps CAN 75%-os mintavételi ponttal a következőképpen konfigurálható: prescaler=25, sjw=1, bs1=11, bs2=4: tq = 25 / 100 MHz = 250 ns, bittime = (1 + 11 + 4) × 250 ns = 4 µs, mintavételi pont = (1 + 11) / 16 = 75%, és az átviteli sebesség 1 / 4 µs = 250 kHz.

További részletekért lásd az STM32 referencia-kézikönyv bxCAN / FDCAN fejezetét az OpenMV Cam MCU-jához.

deinit() None

A CAN busz kikapcsolása.

restart() None

A CAN vezérlő szoftveres újraindításának kikényszerítése a konfigurációjának visszaállítása nélkül.

Ha a vezérlő bus-off állapotba lép, akkor többé nem vesz részt a busz tevékenységében. Ha a vezérlő nincs automatikus újraindításra konfigurálva (lásd init()), akkor ez a metódus használható az újraindítás kiváltására, és a vezérlő a CAN protokollt követve elhagyja a bus-off állapotot, és error active állapotba lép.

state() int

A vezérlő állapotának visszaadása. A visszatérési érték a következők egyike lehet:

  • CAN.STOPPED – a vezérlő teljesen kikapcsolt és visszaállított állapotban van;

  • CAN.ERROR_ACTIVE – a vezérlő be van kapcsolva és Error Active állapotban van (mind a TEC, mind a REC kisebb, mint 96);

  • CAN.ERROR_WARNING – a vezérlő be van kapcsolva és Error Warning állapotban van (a TEC vagy a REC közül legalább az egyik 96 vagy nagyobb);

  • CAN.ERROR_PASSIVE – a vezérlő be van kapcsolva és Error Passive állapotban van (a TEC vagy a REC közül legalább az egyik 128 vagy nagyobb);

  • CAN.BUS_OFF – a vezérlő be van kapcsolva, de nem vesz részt a busz tevékenységében (a TEC túllépte a 255-öt).

info(list: list | None = None) list

Információk lekérése a vezérlő hibaállapotairól, valamint a TX és RX pufferekről. Ha a list meg van adva, akkor annak legalább 8 bejegyzéssel rendelkező lista objektumnak kell lennie, amely az információkkal lesz feltöltve. Egyébként egy új lista jön létre és töltődik fel. Mindkét esetben a metódus visszatérési értéke a feltöltött lista.

A listában lévő értékek:

  • TEC érték

  • REC érték

  • ahány alkalommal a vezérlő Error Warning állapotba lépett (65535 után 0-ra fordul vissza)

  • ahány alkalommal a vezérlő Error Passive állapotba lépett (65535 után 0-ra fordul vissza)

  • ahány alkalommal a vezérlő Bus Off állapotba lépett (65535 után 0-ra fordul vissza)

  • a függőben lévő TX üzenetek száma

  • a 0. fifo-n függőben lévő RX üzenetek száma

  • az 1. fifo-n függőben lévő RX üzenetek száma

setfilter(bank: int, mode: int, fifo: int, params: Tuple[int, ...], *, rtr: Tuple[bool, ...] | None = None, extframe: bool = False) None

Szűrőbank konfigurálása:

  • bank a konfigurálandó klasszikus CAN vezérlő szűrőbank vagy CAN FD szűrőindex.

  • mode az a mód, amelyben a szűrőnek működnie kell, lásd az alábbi táblázatokat.

  • fifo az, hogy melyik fifo-ban (0 vagy 1) tárolódjon egy üzenet, ha azt ez a szűrő elfogadja.

  • params a szűrőt meghatározó értékek tömbje. A tömb tartalma a mode argumentumtól függ.

A params tömb tartalma klasszikus CAN vezérlők esetén (OpenMV Cam M4 / M7):

mode

A params tartalma

CAN.LIST16

Négy 16 bites azonosító, amelyeket elfogad.

CAN.LIST32

Két 32 bites azonosító, amelyeket elfogad.

CAN.MASK16

Két 16 bites azonosító/maszk pár, pl. (1, 3, 4, 4). Az első pár (1, 3) minden olyan azonosítót elfogad, amelynél a 0. bit = 1 és az 1. bit = 0; a második pár (4, 4) minden olyan azonosítót elfogad, amelynél a 2. bit = 1.

CAN.MASK32

Egy 32 bites azonosító/maszk pár (egyébként ugyanaz, mint a CAN.MASK16).

A params tömb tartalma CAN FD vezérlők esetén (OpenMV Cam H7 / H7 Plus / Pure Thermal):

mode

A params tartalma

CAN.RANGE

Két azonosító, amelyek az elfogadott azonosítók tartományát alkotják.

CAN.DUAL

Két azonosító, amelyeket elfogad (pl. (1, 2)).

CAN.MASK

Egy (id, mask) pár (pl. (0x111, 0x7FF)).

  • rtr Klasszikus CAN vezérlők esetén ez logikai értékek tömbje, amely megadja, hogy egy szűrőnek el kell-e fogadnia egy remote transmission request üzenetet. Ha ezt az argumentumot nem adjuk meg, akkor minden bejegyzésnél False az alapértelmezett. A hossz a mode értékétől függ:

    mode

    len(rtr)

    Megjegyzések

    CAN.LIST16

    4

    CAN.LIST32

    2

    CAN.MASK16

    2

    CAN.MASK32

    1

    CAN FD esetén ezt az argumentumot a rendszer figyelmen kívül hagyja.

  • extframe Ha True, a keret kiterjesztett azonosítóval (29 bit) rendelkezik, ellenkező esetben szabványos azonosítót (11 bit) használ.

clearfilter(bank: int, extframe: bool = False) None

Szűrőbank törlése és letiltása:

  • bank a törlendő klasszikus CAN vezérlő szűrőbank vagy CAN FD szűrőindex.

  • extframe CAN FD vezérlők esetén, ha True, kiterjesztett szűrőt töröl (extframe=True beállítással konfigurált), ellenkező esetben szabványos azonosítót töröl (extframe=False beállítással konfigurált).

any(fifo: int) bool

True értéket ad vissza, ha bármilyen üzenet várakozik a FIFO-n, egyébként False értéket.

recv(fifo: int, list: list | None = None, *, timeout: int = 5000) list

Adatok fogadása a buszon:

  • fifo egész szám, amely a fogadáshoz használt FIFO-t jelöli

  • list egy választható lista objektum, amely visszatérési értékként használható

  • timeout az időtúllépés ezredmásodpercben, ameddig a fogadásra várni kell.

Visszatérési érték: Öt értéket tartalmazó lista.

  • Az üzenet azonosítója.

  • Egy logikai érték, amely jelzi, hogy az üzenet azonosítója szabványos vagy kiterjesztett.

  • Egy logikai érték, amely jelzi, hogy az üzenet RTR üzenet-e.

  • Az FMI (Filter Match Index) érték.

  • Az adatokat tartalmazó tömb.

Ha a list None, akkor egy új lista kerül lefoglalásra, valamint egy új bytes objektum az adatok tárolására (a lista ötödik elemeként).

Ha a list nem None, akkor annak legalább öt elemet tartalmazó lista objektumnak kell lennie. Az ötödik elemnek egy memoryview objektumnak kell lennie, amely vagy egy bytearray-ből, vagy egy «B» vagy «b» típusú tömbből jött létre, és ennek a tömbnek legalább 8 bájt számára elegendő helynek kell lennie. A lista objektum ezután feltöltődik a fenti első négy visszatérési értékkel, a memoryview objektum pedig helyben átméreteződik az adatok méretére, és feltöltődik azokkal az adatokkal. Ugyanaz a lista és memoryview objektum újrahasználható a metódus későbbi hívásaiban, így lehetőséget biztosítva az adatok fogadására a heap használata nélkül. Például:

buf = bytearray(8)
lst = [0, 0, 0, 0, memoryview(buf)]
# No heap memory is allocated in the following call
can.recv(0, lst)
send(data: int | bytes | bytearray, id: int, *, timeout: int = 0, rtr: bool = False, extframe: bool = False, fdf: bool = False, brs: bool = False) None

Üzenet küldése a buszon:

  • data a küldendő adat (egy küldendő egész szám vagy egy puffer objektum).

  • id a küldendő üzenet azonosítója.

  • timeout az időtúllépés ezredmásodpercben, ameddig a küldésre várni kell.

  • rtr egy logikai érték, amely megadja, hogy az üzenetet remote transmission request kérésként kell-e elküldeni. Ha az rtr True, akkor csak a data hossza kerül felhasználásra a keret DLC mezőjének kitöltéséhez; a data tényleges bájtjai nincsenek használatban.

  • extframe ha True, a keret kiterjesztett azonosítóval (29 bit) rendelkezik, ellenkező esetben szabványos azonosítót (11 bit) használ.

  • fdf CAN FD vezérlők esetén, ha True értékre van állítva, a keret FD keretformátummal rendelkezik, amely legfeljebb 64 bájtos adathasznos terhelést támogat.

  • brs CAN FD vezérlők esetén, ha True értékre van állítva, a bitsebesség-kapcsolási mód engedélyezett, amelyben az adatfázis eltérő bitsebességgel kerül átvitelre. Az adat-bitidő konfigurációs paramétereit lásd a CAN.init() metódusnál.

Ha a timeout 0, az üzenet a három hardveres puffer egyikébe kerül, és a metódus azonnal visszatér. Ha mindhárom puffer használatban van, kivétel keletkezik. Ha a timeout nem 0, a metódus megvárja, amíg az üzenet átvitelre kerül. Ha az üzenet nem vihető át a megadott időn belül, kivétel keletkezik.

Visszatérési érték: None.

rxcallback(fifo: int, fun: Callable[[CAN, int], None] | None) None

Egy függvény regisztrálása, amely akkor hívódik meg, amikor egy üzenet egy üres FIFO-ba kerül elfogadásra:

  • fifo a fogadó FIFO.

  • fun az a függvény, amely akkor hívódik meg, amikor a FIFO nem üressé válik.

A visszahívási függvény két argumentumot vesz át: az első maga a CAN objektum; a második egy egész szám, amely a visszahívás okát jelzi:

Ok

Jelentés

0

Egy üzenet egy üres FIFO-ba került elfogadásra.

1

A FIFO megtelt.

2

Egy üzenet elveszett egy megtelt FIFO miatt.

Az rxcallback példa használata:

def cb0(bus, reason):
  print('cb0')
  if reason == 0:
      print('pending')
  if reason == 1:
      print('full')
  if reason == 2:
      print('overflow')

can = CAN(1, CAN.LOOPBACK)
can.rxcallback(0, cb0)

Konstansok

Busz-mód konstansok (a init() mode argumentuma):

NORMAL: int

A vezérlő normálisan vesz részt a buszon – elküldi a saját kereteit és nyugtázza az érvényes fogadott kereteket.

LOOPBACK: int

Belső loopback mód: a vezérlő le van választva a lábakról, és az elküldött kereteket közvetlenül visszavezeti a fogadási útvonalra. Hasznos önteszteléshez transzceiver nélkül.

SILENT: int

Csak figyelő (listen-only) mód: a vezérlő fogadja a kereteket, de soha nem hajtja meg a buszt (nincs ACK, nincs átvitel). Hasznos buszforgalom megfigyeléséhez.

SILENT_LOOPBACK: int

A SILENT és a LOOPBACK kombinációja: nincs láb-tevékenység és nincsenek nyugtázások, a TX belső loopback-jével az RX-be.

Vezérlő-állapot konstansok (a state() által visszaadva):

STOPPED: int

A vezérlő teljesen kikapcsolt és visszaállított állapotban van.

ERROR_ACTIVE: int

A vezérlő be van kapcsolva és Error Active állapotban van (mind a TEC, mind a REC kisebb, mint 96).

ERROR_WARNING: int

A vezérlő be van kapcsolva és Error Warning állapotban van (a TEC vagy a REC közül legalább az egyik 96 vagy nagyobb).

ERROR_PASSIVE: int

A vezérlő be van kapcsolva és Error Passive állapotban van (a TEC vagy a REC közül legalább az egyik 128 vagy nagyobb).

BUS_OFF: int

A vezérlő be van kapcsolva, de nem vesz részt a busz tevékenységében (a TEC túllépte a 255-öt).

Klasszikus CAN szűrőmódok (a setfilter() mode argumentuma az OpenMV Cam M4 / M7 modellen):

LIST16: int

A szűrő params tömbje négy 16 bites azonosítót tartalmaz, amelyeket elfogad.

LIST32: int

A szűrő params tömbje két 32 bites azonosítót tartalmaz, amelyeket elfogad.

MASK16: int

A szűrő params tömbje két 16 bites (id, mask) párt tartalmaz.

MASK32: int

A szűrő params tömbje egy 32 bites (id, mask) párt tartalmaz.

CAN FD szűrőmódok (a setfilter() mode argumentuma az OpenMV Cam H7 / H7 Plus / Pure Thermal modellen):

RANGE: int

A szűrő params tömbje két azonosítót tartalmaz, amelyek az elfogadott azonosítók tartományát alkotják.

DUAL: int

A szűrő params tömbje két konkrét elfogadandó azonosítót tartalmaz.

MASK: int

A szűrő params tömbje egy (id, mask) párt tartalmaz.