class CAN -- コントローラエリアネットワーク通信バス¶
CAN はクラシック CAN(bxCAN、OpenMV Cam M4 および M7 で使用)と CAN FD(FDCAN、OpenMV Cam H7、H7 Plus、Pure Thermal で使用)の両方のコントローラをサポートします。物理レベルでは、CAN バスは RX と TX の 2 本の線で構成されます。OpenMV Cam を CAN バスに接続するには、CAN トランシーバを使用して MCU からの CAN 論理信号をバス上の適切な電圧レベルに変換する必要があります。
ループバック(トランシーバなし)モードのクラシック CAN:
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(FD フレーム、ビットレート切り替え、拡張フレーム ID、500 kbit/s のアービトレーションフェーズ、1 Mbit/s のデータフェーズ):
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)
以下の CAN モジュール関数とその引数は、特に明記されていない限り、クラシックおよび FD CAN コントローラの両方で利用できます。
コンストラクタ¶
- class pyb.CAN(bus: int | str, *args, **kwargs)¶
指定した
bus(整数のペリフェラルインデックス。例えばCAN1なら1、CAN2なら2)上に CAN オブジェクトを構築します。追加のパラメータを指定しない場合、オブジェクトは作成されますが初期化されません(以前のバス設定があればそれを保持します)。追加の引数が指定された場合はバスが初期化されます。利用可能なパラメータについてはCAN.init()を参照してください。CAN(2)は、pyb.CANを公開しているすべての OpenMV Cam(M4 / M7 / H7 / H7 Plus / Pure Thermal)で同じヘッダピンに配線されています。信号
ヘッダピン
備考
RXP3TXP2CAN ペリフェラルは論理レベルの信号のみを提供します。実際の CAN バスを駆動するには外部の CAN トランシーバが必要です。
pyb.CANは OpenMV Cam N6 では利用できません。メソッド¶
- 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¶
指定したパラメータで CAN バスを初期化します:
mode は次のいずれかです: NORMAL、LOOPBACK、SILENT、SILENT_LOOPBACK
prescaler は、公称ビットタイムクォンタを生成するために CAN 入力クロックを分周する値です。プリスケーラは、クラシック CAN では 1 から 1024 まで、CAN FD では 1 から 512 まで(いずれも両端を含む)の値を取れます。
sjw は、公称ビットの時間クォンタ単位での再同期ジャンプ幅です。クラシック CAN では 1 から 4 まで、CAN FD では 1 から 128 まで(いずれも両端を含む)の値を取れます。
bs1 は、公称ビットの時間クォンタ単位でサンプルポイントの位置を定義します。クラシック CAN では 1 から 16 まで、CAN FD では 2 から 256 まで(いずれも両端を含む)の値を取れます。
bs2 は、公称ビットの時間クォンタ単位で送信ポイントの位置を定義します。クラシック CAN では 1 から 8 まで、CAN FD では 2 から 128 まで(いずれも両端を含む)の値を取れます。
auto_restart は、コントローラがバスオフ状態に入った後、自動的に通信の再開を試みるかどうかを設定します。これが無効の場合、
restart()を使用してバスオフ状態から抜け出すことができますbaudrate に 0 以外のボーレートを指定すると、この関数は baudrate(誤差 .1% 以内)と希望する sample_point(最も近い 1% 単位)の両方を満たす CAN の公称ビットタイムを自動的に計算しようとします(prescaler、bs1、bs2 を上書きします)。CAN タイミングをより精密に制御するには、prescaler、bs1、bs2 パラメータを直接設定してください。
sample_point は、公称ビットタイム全体に対するビットサンプルの位置を、公称ビットタイムに対する整数のパーセンテージで指定します。sample_point のデフォルトは 75% です。このパラメータは baudrate が設定されていない限り無視されます。
num_filter_banks は、クラシック CAN において CAN(1) に割り当てられるバンクの数です。残りの 28 個のうちの残余は CAN(2) に割り当てられます。
残りのパラメータは、CAN FD をサポートするボードにのみ存在し、オプションの CAN FD ビットレート切り替え(BRS)機能を構成します:
brs_prescaler は、データビットタイムクォンタを生成するために CAN FD 入力クロックを分周する値です。プリスケーラは 1 から 32 まで(両端を含む)の値を取れます。
brs_sjw は、データビットの時間クォンタ単位での再同期ジャンプ幅です。1 から 16 まで(両端を含む)の値を取れます
brs_bs1 は、データビットの時間クォンタ単位でサンプルポイントの位置を定義します。1 から 32 まで(両端を含む)の値を取れます
brs_bs2 は、データビットの時間クォンタ単位で送信ポイントの位置を定義します。1 から 16 まで(両端を含む)の値を取れます
brs_baudrate に 0 以外のボーレートを指定すると、この関数は brs_baudrate(誤差 .1% 以内)と希望する brs_sample_point(最も近い 1% 単位)の両方を満たす CAN データビットタイムを自動的に計算しようとします(brs_prescaler、brs_bs1、brs_bs2 を上書きします)。BRS タイミングをより精密に制御するには、brs_prescaler、brs_bs1、brs_bs2 パラメータを直接設定してください。
brs_sample_point は、公称ビットタイム全体に対するビットサンプルの位置を、公称ビットタイムに対する整数のパーセンテージで指定します。brs_sample_point のデフォルトは 75% です。このパラメータは brs_baudrate が設定されていない限り無視されます。
時間クォンタ tq は CAN バスの基本的な時間単位です。tq は CAN プリスケーラ値を PCLK1(内部ペリフェラルバス 1 の周波数)で割ったものです。PCLK1 を確認するには
pyb.freq()を参照してください。1 つのビットは、同期セグメント(常に 1 tq)で構成されます。続いてビットセグメント 1、その後ビットセグメント 2 が続きます。サンプルポイントはビットセグメント 1 が終了した後です。送信ポイントはビットセグメント 2 が終了した後です。ボーレートは 1/bittime となり、bittime は 1 + BS1 + BS2 に時間クォンタ tq を乗じたものです。
例えば、OpenMV Cam H7(PCLK1 = 100 MHz)では、サンプルポイント 75% の 250 kbps CAN は
prescaler=25, sjw=1, bs1=11, bs2=4として構成できます:tq = 25 / 100 MHz = 250 ns、bittime = (1 + 11 + 4) × 250 ns = 4 µs、サンプルポイント =(1 + 11) / 16 = 75%、ボーレートは1 / 4 µs = 250 kHzとなります。詳細については、OpenMV Cam の MCU 用の STM32 リファレンスマニュアルの bxCAN / FDCAN セクションを参照してください。
- restart() None¶
設定をリセットせずに CAN コントローラのソフトウェア再起動を強制します。
コントローラがバスオフ状態に入ると、バス活動に参加しなくなります。コントローラが自動再起動するよう設定されていない場合(
init()を参照)、このメソッドを使用して再起動をトリガーできます。コントローラは CAN プロトコルに従ってバスオフ状態から抜け出し、エラーアクティブ状態に入ります。
- state() int¶
コントローラの状態を返します。戻り値は次のいずれかです:
CAN.STOPPED-- コントローラは完全にオフでリセットされています。CAN.ERROR_ACTIVE-- コントローラはオンでエラーアクティブ状態です(TEC と REC の両方が 96 未満)。CAN.ERROR_WARNING-- コントローラはオンでエラーワーニング状態です(TEC または REC の少なくとも一方が 96 以上)。CAN.ERROR_PASSIVE-- コントローラはオンでエラーパッシブ状態です(TEC または REC の少なくとも一方が 128 以上)。CAN.BUS_OFF-- コントローラはオンですがバス活動に参加していません(TEC が 255 を超えてオーバーフローした)。
- info(list: list | None = None) list¶
コントローラのエラー状態と TX および RX バッファに関する情報を取得します。list が指定された場合、それは少なくとも 8 個のエントリを持つリストオブジェクトであるべきで、その情報で埋められます。指定されない場合は新しいリストが作成されて埋められます。どちらの場合も、メソッドの戻り値は内容が埋められたリストです。
リスト内の値は次のとおりです:
TEC 値
REC 値
コントローラがエラーワーニング状態に入った回数(65535 を超えると 0 に巻き戻る)
コントローラがエラーパッシブ状態に入った回数(65535 を超えると 0 に巻き戻る)
コントローラがバスオフ状態に入った回数(65535 を超えると 0 に巻き戻る)
保留中の TX メッセージ数
fifo 0 上の保留中の RX メッセージ数
fifo 1 上の保留中の RX メッセージ数
- setfilter(bank: int, mode: int, fifo: int, params: Tuple[int, ...], *, rtr: Tuple[bool, ...] | None = None, extframe: bool = False) None¶
フィルタバンクを構成します:
bank は、構成するクラシック CAN コントローラのフィルタバンク、または CAN FD フィルタインデックスです。
mode はフィルタが動作するモードです。下記の表を参照してください。
fifo は、このフィルタによってメッセージが受け入れられた場合に、メッセージを格納する fifo(0 または 1)です。
params はフィルタを定義する値の配列です。配列の内容は mode 引数に依存します。
クラシック CAN コントローラ(OpenMV Cam M4 / M7)における params 配列の内容:
mode
params の内容
CAN.LIST16受け入れられる 4 つの 16 ビット ID。
CAN.LIST32受け入れられる 2 つの 32 ビット ID。
CAN.MASK162 組の 16 ビット ID/マスクペア。例えば
(1, 3, 4, 4)。最初のペア(1, 3)はビット 0 = 1 かつビット 1 = 0 のすべての ID を受け入れます。2 番目のペア(4, 4)はビット 2 = 1 のすべての ID を受け入れます。CAN.MASK321 組の 32 ビット ID/マスクペア(それ以外は
CAN.MASK16と同じ)。CAN FD コントローラ(OpenMV Cam H7 / H7 Plus / Pure Thermal)における params 配列の内容:
mode
params の内容
CAN.RANGE受け入れられる ID の範囲を形成する 2 つの ID。
CAN.DUAL受け入れられる 2 つの ID(例:
(1, 2))。CAN.MASK1 組の
(id, mask)ペア(例:(0x111, 0x7FF))。rtr クラシック CAN コントローラの場合、これはフィルタがリモート送信要求メッセージを受け入れるべきかどうかを示すブール値の配列です。この引数が指定されない場合、すべてのエントリは
Falseがデフォルトになります。長さは mode に依存します:mode
len(rtr)備考
CAN.LIST164
CAN.LIST322
CAN.MASK162
CAN.MASK321
CAN FD の場合、この引数は無視されます。
extframe True の場合、フレームは拡張識別子(29 ビット)を持ちます。そうでない場合は標準識別子(11 ビット)が使用されます。
- clearfilter(bank: int, extframe: bool = False) None¶
フィルタバンクをクリアして無効にします:
bank は、クリアするクラシック CAN コントローラのフィルタバンク、または CAN FD フィルタインデックスです。
extframe CAN FD コントローラの場合、True なら拡張フィルタ(extframe=True で構成されたもの)をクリアし、そうでなければ標準識別子(extframe=False で構成されたもの)をクリアします。
- recv(fifo: int, list: list | None = None, *, timeout: int = 5000) list¶
バス上でデータを受信します:
fifo は受信する FIFO を表す整数です
list は戻り値として使用されるオプションのリストオブジェクトです
timeout は受信を待機するミリ秒単位のタイムアウトです。
戻り値: 5 つの値を含むリスト。
メッセージの id。
メッセージ ID が標準か拡張かを示すブール値。
メッセージが RTR メッセージかどうかを示すブール値。
FMI(フィルタマッチインデックス)値。
データを含む配列。
list が
Noneの場合、新しいリストが割り当てられ、データを含む新しい bytes オブジェクト(リストの 5 番目の要素として)も割り当てられます。list が
Noneでない場合、それは少なくとも 5 つの要素を持つリストオブジェクトであるべきです。5 番目の要素は、bytearray または型 'B' もしくは 'b' の配列から作成された memoryview オブジェクトであるべきで、この配列は少なくとも 8 バイトを収められる十分な空きがなければなりません。リストオブジェクトには上記の最初の 4 つの戻り値が埋め込まれ、memoryview オブジェクトはデータのサイズにインプレースでリサイズされてそのデータで埋められます。同じリストおよび memoryview オブジェクトはこのメソッドの後続の呼び出しで再利用でき、ヒープを使わずにデータを受信する方法を提供します。例えば: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¶
バス上でメッセージを送信します:
data は送信するデータ(送信する整数、またはバッファオブジェクト)です。
id は送信するメッセージの id です。
timeout は送信を待機するミリ秒単位のタイムアウトです。
rtr は、メッセージをリモート送信要求として送信すべきかどうかを指定するブール値です。rtr が True の場合、data の長さのみがフレームの DLC スロットを埋めるために使用されます。data 内の実際のバイトは使用されません。
extframe True の場合、フレームは拡張識別子(29 ビット)を持ちます。そうでない場合は標準識別子(11 ビット)が使用されます。
fdf CAN FD コントローラの場合、True に設定すると、フレームは最大 64 バイトのデータペイロードをサポートする FD フレーム形式を持ちます。
brs CAN FD コントローラの場合、True に設定するとビットレート切り替えモードが有効になり、データフェーズが異なるビットレートで送信されます。データビットタイミングの構成パラメータについては
CAN.init()を参照してください。
timeout が 0 の場合、メッセージは 3 つのハードウェアバッファのいずれかのバッファに置かれ、メソッドはただちに戻ります。3 つのバッファすべてが使用中の場合は例外がスローされます。timeout が 0 でない場合、メソッドはメッセージが送信されるまで待機します。指定された時間内にメッセージを送信できない場合は例外がスローされます。
戻り値:
None。
- rxcallback(fifo: int, fun: Callable[[CAN, int], None] | None) None¶
空の FIFO にメッセージが受け入れられたときに呼び出される関数を登録します:
fifo は受信側の FIFO です。
fun は FIFO が空でなくなったときに呼び出される関数です。
コールバック関数は 2 つの引数を取ります。1 つ目は CAN オブジェクト自体です。2 つ目はコールバックの理由を示す整数です:
理由
意味
0空の FIFO にメッセージが受け入れられました。
1FIFO が満杯です。
2FIFO が満杯のためメッセージが失われました。
rxcallback の使用例:
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)
定数¶
バスモード定数(
init()のmode引数):コントローラ状態定数(
state()が返す):クラシック CAN フィルタモード(OpenMV Cam M4 / M7 における
setfilter()のmode引数):CAN FD フィルタモード(OpenMV Cam H7 / H7 Plus / Pure Thermal における
setfilter()のmode引数):