こんにちは、
L2 ルックアップ テーブルを動的に構成したいのですが、どのように CAN 構成すればよいでしょうか?
ECT ツールを使用せずに、L2 ルックアップ テーブルをどのように構成できますか?
例はありますか?
敬具
アトキンソン
こんにちは@PavelL
「あなたのコードでは、エントリ[3]のシフト値が欠落しており、エントリ[3]、エントリ[4]、エントリ[5]の括弧が欠落しているか、位置が間違っています。」
私はこれを Python コードと同じように実装しましたが、括弧とシフト値がどこに欠けているかわかりません。もっとわかりやすいように、揃えたコードを教えていただけますか?括弧とシフトが抜けていてすみません。
正確なエントリ[3]、エントリ[4]、エントリ[5]を提供していただければ、より役立ち、明確になります。
こんにちは@Atkinson 、
コードでは、エントリ[3]のシフト値が欠落しており、エントリ[3]、エントリ[4]、エントリ[5]の括弧が欠落しているか、位置が間違っています。
L2 ルックアップ構成を確認するには、エントリを動的ではなく静的に設定することを検討してください。これにより、問題がエントリ形式にあるのか、動的更新メカニズムにあるのかを切り分けるCAN。
また、Python スクリプト内の「きれいなテーブル」は、コマンド ウィンドウの出力をフォーマットするためにのみ使用され、機能やレジスタ構成には影響しないことに注意してください。
よろしくお願いいたします。
パベル
こんにちは@PavelL
int WriteL2LookupEntry(int cs)
{
const uint32_t DESTPORTS = 0x004;
const uint32_t インデックス = 2;
定数 uint64_t MACADDR = 0x112233445566;
const uint64_t MACADDR_MASK = 0xffffffffffff;
const uint32_t VLANID = 0;
定数 uint32_t VLANID_MASK = 0x0;
const uint32_t IOTAG = 0;
定数 uint32_t IOTAG_MASK = 0;
const uint32_t SRCPORT = 0x6;
const uint32_t SRCPORT_MASK = 0xF;
const uint32_t ENFPORT = 0;
const uint32_t RETAG = 0;
const uint32_t ミラー = 0;
const uint32_t テイク = 0;
const uint32_t MIRR_VLAN = 0xFFF;
const uint32_t TRAPTOHOST = 0;
const uint32_t CBSIDIN = 0x3F;
const uint32_t CBENONDA = 0;
定数 uint32_t VLIDX = 0xFFF;
定数 uint32_t SA_POLICE = 0;
定数 uint32_t DA_POLICE = 0;
uint32_t L2_OFFSET = 0x23;
uint32_t L2CTRL_OFFSET = 0x29;
定数 uint32_t SWREG_BASE = 0x00000000;
const uint32_t VALID = 1U;
const uint32_t RDWRSET = 1U;
const uint32_t 有効 = 1U;
const uint32_t HOSTCMD = 3U;
const uint32_t MGMTROUTE = 0U;
const uint32_t ロック = 1U;
const uint32_t ERROR = 0U;
uint32_t L2_ADDRESS = SWREG_BASE + L2_OFFSET;
uint32_t L2_ADDRESS_CTL = SWREG_BASE + L2CTRL_OFFSET;
uint32_t l2Entry[ADDRESS_RANGE] = {0};
l2Entry[0] = (((INDEX & 0x03ff) << (1 % 32)) + ((ENFPORT & 1) << (11 % 32))
+ ((宛先ポート & 0x7FF) << (12 % 32)) + ((送信元ポート & 0xF) << (23 % 32))
+ ((MACADDR & 0x1F) << (27 % 32)));
l2Entry[1] = (((MACADDR >> 5) & 0xFFFFFFFF));
l2Entry[2] = ((((MACADDR >> 37) & 0x7FF) << (64 % 32)) + ((VLANID & 0xFFF) << (75 % 32))
+ ((IOTAG & 1) << (87 % 32)) + ((MACADDR_MASK & 0xFF) << (88 % 32)));
l2Entry[3] = (((MACADDR_MASK >>
l2Entry[4] = (((MACADDR_MASK >> 40) & 0xFF << (128 % 32)) + ((VLANID_MASK & 0xfff) << (136 % 32))
+ ((IOTAG_MASK & 1) << (148 % 32)) + ((SRCPORT_MASK & 0xF) << (149 % 32))
+ ((RETAG & 0x1) << (153 % 32)) + ((MIRROR & 0x1) << (154 % 32))
+ ((TAKETS & 0x1) << (155 % 32)) + ((MIRR_VLAN & 0xF) << (156 % 32)));
l2Entry[5] = (((MIRR_VLAN >> 4) & 0xFF << (160 % 32)) + ((TRAPTOHOST & 0x1) << (168 % 32))
+ ((CBSIDIN & 0x3F) << (169 % 32)) + ((CBENONDA & 0x1) << (175 % 32))
+ ((VLIDX & 0xFFF) << (177 % 32)) + ((SA_POLICE & 0x1) << (189 % 32))
+ ((DA_POLICE & 0x1) << (190 % 32)));
uint32_t ステータス = 0;
する {
Std_ReturnType ret = spi_read_reg(L2_ADDRESS_CTL、&status);
if (ret != E_OK) {
-1 を返します。
}
} while ((ステータス >> VALID_BIT_SHIFT) & 1U);
(int i = 0; i < ADDRESS_RANGE; i++) の場合 {
Std_ReturnType ret = spi_write_reg(L2_ADDRESS + i, l2Entry[i]);
if (ret != E_OK) {
-2 を返します。
}
uint32_t 読み取りバック = 0;
ret = spi_read_reg(L2_ADDRESS + i, &readBack);
if (ret != E_OK || readBack != l2Entry[i]) {
-3 を返します。
}
}
uint32_t コントロールL2エントリ = 0;
controlL2Entry = ((有効 << 31) + (RDWRSET << 30) + (エラー << 29) + (ロック済み << 28) + (有効 << 27) +
(MGMTROUTE << 26) + (HOSTCMD << 23));
Std_ReturnType ret = spi_write_reg(L2_ADDRESS_CTL、controlL2Entry);
if (ret != E_OK) {
-4 を返します。
}
する {
ret = spi_read_reg(L2_ADDRESS_CTL、&ステータス);
if (ret != E_OK) {
-5 を返します。
}
} while ((ステータス >> VALID_BIT_SHIFT) & 1U);
0を返します。
}
Python スクリプトに似た実装に変更しました。何か間違いを見つけたら、変更したものを送ってください。
Pythonスクリプト
「書き込み後、エントリのMAC/VLAN/ポート基準に一致するフレームを送信し、DESTPORTSフィールドに従って転送されるかどうかを確認します。」
あなたが言ったように、この方法で送信しようとしていますが、この反射は見られません
自分のエントリーが反映されているのが分かりません。
他に設定する必要があるものはありますか?
Pythonスクリプトで、controll2entryのレジスタ値をL2_ADDRESS_CTLに書き込んだ後
「prettytable」にエントリを追加するコードは数行しかありませんでした。
これも同様に行う必要がありますか? また、これを行うための規定はありますか?
こんにちは@Atkinson 、
エントリ[3]、エントリ[4]、およびエントリ[5]には、シフト値が欠落しており、式が不完全です。これにより、レジスタ値が不正確になる可能性があります。L2 エントリを正しく構築する Python リファレンス スクリプトとロジックを比較することをお勧めします。
書き込み後、エントリの MAC/VLAN/ポート基準に一致するフレームを送信し、DESTPORTS フィールドに従って転送されるかどうかを確認します。
よろしくお願いいたします。
パベル
こんにちは@PavelL
int WriteL2LookupEntry(int cs)
{
const uint32_t DESTPORTS = 0x002;
const uint32_t インデックス = 8;
定数 uint64_t MACADDR = 0x661122334455;
const uint64_t MACADDR_MASK = 0xffffffffffff;
const uint32_t VLANID = 0;
const uint32_t VLANID_MASK = 0xfff;
const uint32_t IOTAG = 0;
const uint32_t IOTAG_MASK = 0;
const uint32_t SRCPORT = 0x5;
const uint32_t SRCPORT_MASK = 0xF;
const uint32_t ENFPORT = 0;
const uint32_t RETAG = 0;
const uint32_t ミラー = 0;
const uint32_t テイク = 0;
const uint32_t MIRR_VLAN = 0xFFF;
const uint32_t TRAPTOHOST = 0;
const uint32_t CBSIDIN = 0x3F;
const uint32_t CBENONDA = 0;
定数 uint32_t VLIDX = 0xFFF;
定数 uint32_t SA_POLICE = 0;
定数 uint32_t DA_POLICE = 0;
uint32_t L2_OFFSET = 0x23;
uint32_t L2CTRL_OFFSET = 0x29;
定数 uint32_t SWREG_BASE = 0x00000000;
const uint32_t VALID = 1U;
const uint32_t RDWRSET = 1U;
const uint32_t 有効 = 1U;
const uint32_t HOSTCMD = 3U;
const uint32_t MGMTROUTE = 0U;
const uint32_t ロック = 1U;
const uint32_t ERROR = 0U;
uint32_t L2_ADDRESS = SWREG_BASE + L2_OFFSET;
uint32_t L2_ADDRESS_CTL = SWREG_BASE + L2CTRL_OFFSET;
uint32_t l2Entry[ADDRESS_RANGE] = {0};
l2Entry[0] = ((インデックス & 0x03FF) << 1)
| ((ENFPORT & 0x1) << 11)
| ((宛先ポート & 0x7FF) << 12)
| ((SRCPORT & 0xF) << 23)
| ((uint32_t)(MACADDR & 0x1F) << 27);
l2Entry[1] = (uint32_t)((MACADDR >> 5) & 0xFFFFFFFF);
l2Entry[2] = (uint32_t)(((MACADDR >> 37) & 0x7FF) << 0)
| ((VLANID & 0xFFF) << 11)
| ((IOTAG & 0x1) << 23)
| ((uint32_t)(MACADDR_MASK & 0xFF) << 24);
l2Entry[3] = (uint32_t)((MACADDR_MASK >>
l2Entry[4] = ((uint32_t)((MACADDR_MASK >> 40) & 0xFF) << 0)
| ((VLANID_MASK & 0xFFF) <<
| ((IOTAG_MASK & 0x1) << 20)
| ((SRCPORT_MASK & 0xF) << 21)
| ((再タグ & 0x1) << 25)
| ((ミラー & 0x1) << 26)
| ((テイク& 0x1) << 27)
| ((MIRR_VLAN & 0xF) << 28);
l2Entry[5] = (((MIRR_VLAN >> 4) & 0xFF) << 0)
| ((TRAPTOHOST & 0x1) <<
| ((CBSIDIN & 0x3F) << 9)
| ((CBENONDA & 0x1) << 15)
| ((VLIDX & 0xFFF) << 17)
| ((SA_POLICE & 0x1) << 29)
| ((DA_POLICE & 0x1) << 30);
uint32_t ステータス = 0;
する {
Std_ReturnType ret = spi_read_reg(L2_ADDRESS_CTL、&status);
if (ret != E_OK) {
-1 を返します。
}
} while ((ステータス >> VALID_BIT_SHIFT) & 1U);
(int i = 0; i < ADDRESS_RANGE; i++) の場合 {
Std_ReturnType ret = spi_write_reg(L2_ADDRESS + i, l2Entry[i]);
if (ret != E_OK) {
-2 を返します。
}
uint32_t 読み取りバック = 0;
ret = spi_read_reg(L2_ADDRESS + i, &readBack);
if (ret != E_OK || readBack != l2Entry[i]) {
-3 を返します。
}
}
uint32_t コントロールL2エントリ = 0;
controlL2Entry |= (有効 << VALID_BIT_SHIFT);
controlL2Entry |= (RDWRSET << RDWRSET_BIT_SHIFT);
controlL2Entry |= (エラー << ERROR_BIT_SHIFT);
controlL2Entry |= (ロック済み << ロック済み_ビットシフト);
controlL2Entry |= (VALIDENT << VALIDENT_BIT_SHIFT);
controlL2Entry |= (MGMTROUTE << MGMTROUTE_BIT_SHIFT);
controlL2Entry |= (HOSTCMD << HOSTCMD_BIT_SHIFT);
Std_ReturnType ret = spi_write_reg(L2_ADDRESS_CTL、controlL2Entry);
if (ret != E_OK) {
-4 を返します。
}
する {
ret = spi_read_reg(L2_ADDRESS_CTL、&ステータス);
if (ret != E_OK) {
-5 を返します。
}
} while ((ステータス >> VALID_BIT_SHIFT) & 1U);
0を返します。
}
これは私が修正したコード実装です
この実装によって動的エントリが導入されるかCAN確認できますか。SO、レジスタ値を読み戻して、値がレジスタに書き込まれているかどうかを調べてデバッグしてみましたが、値がレジスタに書き込まれていることは確認できましたが、エントリが作成されたかどうかはわかりません。
また、L2 ルックアップ テーブルの動的エントリの反映も反映されませんか?
SO、L2 ルックアップ テーブル エントリが作成されたかどうかをどのように確認すればよいでしょうか?
こんにちは@Atkinson 、
1. ビットシフト構文 (<<, >>)
コード内のビット シフト演算子の一部が << や >> などの HTML エンティティに置き換えられたようです。これは通常、コードが Web ベースのプラットフォームにコピーされたときに発生します。とにかく、コード内で直接確認してください。
#define L2_CTRL_VALID_BIT (1U << 31)
次のようにする必要があります。
#L2_CTRL_VALID_BIT を定義します (1U << 31)
2. 入国審査
CreateL2Entry()関数、特にentry[3]、entry[4]、entry[5]に、いくつかの構文エラーとシフト値の欠落があります。これにより、レジスタ書き込みが不完全または無効になる可能性があります。
例えば
L2 エントリの 6 つの 32 ビット ワードすべてを正しく構築する Python リファレンス スクリプトと実装を比較することをお勧めします。
よろしくお願いいたします。
パベル
こんにちは@PavelL
3.)レジスタアドレスを#define L2_ENTRY0_ADDR 0x00000023に変更しました。
しかし、メッセージを送信するときに反映される追加しようとしているテーブルをまだ識別できません
「私の理解が正しければ、UM11107の表1182に記載されているL2ルックアップテーブルについて言及されていると思います。このテーブルは、エントリごとに6つの32ビットレジスタで構成されています。この構造は、Pythonスクリプトのデバッグ出力に反映されています。 」
SO、L2ルックアップテーブルに動的エントリを作成する必要があるアドレスにデータを書き込もうとしているのですが、動的エントリが作成されないという問題に直面しています。
#L2_ENTRY0_ADDR 0x00000023 を定義します
#L2_ENTRY1_ADDR 0x00000024 を定義します
#L2_ENTRY2_ADDR 0x00000025 を定義します
#L2_ENTRY3_ADDR 0x00000026 を定義します
#L2_ENTRY4_ADDR 0x00000027 を定義します
#L2_ENTRY5_ADDR 0x00000028 を定義します
#L2_CTRL_ADDR 0x00000029 を定義します
#L2_CTRL_VALID_BIT を定義します (1U << 31)
#L2_CTRL_WR_RDB_BIT を定義します (1U << 30)
#L2_CTRL_VALIDENTRY_BIT を定義します (1U << 28)
#define L2_CTRL_HOSTCMD_SHIFT 23
#define L2_CTRL_HOSTCMD_WRITE (0b011U << L2_CTRL_HOSTCMD_SHIFT)
Std_ReturnType CreateL2Entry(uint32_t エントリ[6])
{
uint16_t インデックス = 11;
uint64_t MACADDDR = 0x661122334455;
uint64_t MACADDR_MASK = 0xFFFFFFFFFFFF;
uint16_t VLANID = 3;
uint16_t VLANID_MASK = 0xFFF;
uint8_t IOTAG = 0;
uint8_t IOTAG_MASK = 0;
uint8_t SRCPORT = 5;
uint8_t SRCPORT_MASK = 0xF;
uint8_t 宛先ポート = 0x02;
uint8_t ENFPORT = 1;
uint8_t RETAG = 0;
uint8_t ミラー = 0;
uint8_t テイク = 0;
uint16_t MIRR_VLAN = 0xFFF;
uint8_t トラップホスト = 0;
uint8_t CBSIDIN = 0x3F;
uint8_t CBENONDA = 0;
uint16_t VLIDX = 0xFFF;
uint8_t SA_POLICE = 0;
uint8_t DA_POLICE = 0;
エントリ[0] = ((インデックス & 0x03FF) << 1) |
((ENFPORT & 0x1) << 11) |
((DESTPORTS & 0x7FF) << 12) |
((SRCPORT & 0xF) << 23) |
((MACADDR & 0x1F) << 27);
エントリ[1] = (uint32_t)((MACADDR >> 5) & 0xFFFFFFFF);
エントリ[2] = (((MACADDR >> 37) & 0x7FF) << 0) |
((VLANID & 0xFFF) << 11) |
((IOTAG & 0x1) << 23) |
((MACADDR_MASK & 0xFF) << 24);
エントリ[3] = (uint32_t)((MACADDR_MASK >>
エントリ[4] = (((MACADDR_MASK >> 40) & 0xFF) << 0) |
((VLANID_MASK & 0xFFF) <<
((IOTAG_MASK & 0x1) << 20) |
((SRCPORT_MASK & 0xF) << 21) |
((RETAG & 0x1) << 25) |
((ミラー & 0x1) << 26) |
((テイク& 0x1) << 27) |
((MIRR_VLAN & 0xF) << 28);
エントリ[5] = (((MIRR_VLAN >> 4) & 0xFF) << 0) |
((TRAPTOHOST & 0x1) <<
((CBSIDIN & 0x3F) << 9) |
((CBENONDA & 0x1) << 15) |
((VLIDX & 0xFFF) << 17) |
((SA_POLICE & 0x1) << 29) |
((DA_POLICE & 0x1) << 30);
E_OK を返します。
}
Std_ReturnType WriteL2LookupEntry(uint8_t swt)
{
swt > 0 の場合、E_NOT_OK を返します。
Std_ReturnType ret;
uint32_t ctrlReg = 0;
uint32_t エントリ[6];
// ステップ1: エントリを作成する
ret = CreateL2Entry(エントリ);
if (ret != E_OK) ret を返します。
// ステップ2: VALIDビットがクリアされるのを待つ
する {
ret = spi_read_reg(L2_CTRL_ADDR, &ctrlReg);
if (ret != E_OK) ret を返します。
} while (ctrlReg & L2_CTRL_VALID_BIT);
// ステップ3: エントリデータをレジスタに書き込む
ret = spi_write_reg(L2_ENTRY0_ADDR, entry[0]); if (ret != E_OK) return ret;
ret = spi_write_reg(L2_ENTRY1_ADDR, entry[1]); if (ret != E_OK) return ret;
ret = spi_write_reg(L2_ENTRY2_ADDR, entry[2]); if (ret != E_OK) return ret;
ret = spi_write_reg(L2_ENTRY3_ADDR, entry[3]); if (ret != E_OK) return ret;
ret = spi_write_reg(L2_ENTRY4_ADDR, entry[4]); if (ret != E_OK) return ret;
ret = spi_write_reg(L2_ENTRY5_ADDR, entry[5]); if (ret != E_OK) return ret;
// ステップ4: 書き込みをトリガーするように制御レジスタを設定する
uint32_t ctrlValue = (1U << 31) |
(1U << 30) |
(1U << 28) |
(1U << 27) |
(3U << 23);
ret = spi_write_reg(L2_CTRL_ADDR、ctrlValue);
if (ret != E_OK) ret を返します。
する {
ret = spi_read_reg(L2_CTRL_ADDR, &ctrlReg);
if (ret != E_OK) ret を返します。
} while (ctrlReg & L2_CTRL_VALID_BIT);
E_OK を返します。
}
L2 ルックアップ テーブルに動的エントリが作成されないため、問題が発生しているかどうかを一度確認できますか?
こんにちは@Atkinson 、
1. はい、ホスト ツールはもともと SJA1110-EVM ボード用に開発されました。私は個人的に、レジスタ アクセスの理解を確認するために、デバッグ プリントでこれらのスクリプトを使用しています。S32G-VNP-RDB2 プラットフォーム上で直接実行することはできませんが、S32G は SPI 経由で SJA1110 にアクセスするため、基礎となるロジックを適応させることができます。
2. S32G プラットフォーム用の SPI 読み取り/書き込み実装を探している場合、主に 2 つの選択肢があります。
3. 私の理解が正しければ、UM11107 の表 1182 に記載されている L2 ルックアップ テーブルを参照していることになります。このテーブルは、エントリごとに 6 つの 32 ビット レジスタで構成されます。この構造は、Python スクリプトのデバッグ出力に反映されています。
よろしくお願いいたします。
パベル
こんにちは@PavelL
いくつか質問があります
1.)この l2_write_lookup_table.py のデバッグ出力は SJA1110 EVM ボード実装から取得されましたが、S32G-VNP RDB ボードからのものではないのでしょうか? また、S32G-VNP-RDB32 ボードに l2_write_lookup_table.py を直接実装することはできません。
2.) 上記のコードと統合するための SPI_read と Spi_write のコードを提供していただけますか?
S32Gの実装ではSPI_ReadとSPI_write経由で書き込み操作は行われているが、動的エントリが追加されるのを見ることができないため
Std_ReturnType spi_read_reg(uint32_t regAddress, uint32_t* regValue)
{
Std_ReturnType ret;
uint32_t TxChBuf[65] = {0};
uint32_t RxChBuf[65] = {0};
uint16_t regCount = 1;
Siul2_Dio_Ip_WritePin(SPI_MCU_ES1_CS_AP_PORT、SPI_MCU_ES1_CS_AP_PIN、0U);
ret = getSpiAPCommand(false, regAddress, regCount, TxChBuf, regValue);
if (ret != E_OK) {
Siul2_Dio_Ip_WritePin(SPI_MCU_ES1_CS_AP_PORT、SPI_MCU_ES1_CS_AP_PIN、1U);
ret を返します。
}
ret=Spi_SetupEB(5u, (uint8_t*)TxChBuf, (uint8_t*)RxChBuf, 8u);
if (ret == E_OK) {
ret=Spi_SyncTransmit(SpiConf_SpiSequence_SpiSequence_sja);
if (ret == E_OK) {
*regValue = RxChBuf[1];
}
}
Siul2_Dio_Ip_WritePin(SPI_MCU_ES1_CS_AP_PORT、SPI_MCU_ES1_CS_AP_PIN、1U);
ret を返します。
}
Std_ReturnType spi_write_reg(uint32_t regAddress, uint32_t regValue)
{
Std_ReturnType ret;
uint32_t TxChBuf[65] = {0};
uint32_t RxChBuf[65] = {0};
uint16_t regCount = 1;
uint32_t regValArray[1] = { regValue };
// チップセレクトをLOWにする
Siul2_Dio_Ip_WritePin(SPI_MCU_ES1_CS_AP_PORT、SPI_MCU_ES1_CS_AP_PIN、0U);
ret = getSpiAPCommand(true, regAddress, regCount, TxChBuf, regValArray);
if (ret != E_OK) {
Siul2_Dio_Ip_WritePin(SPI_MCU_ES1_CS_AP_PORT、SPI_MCU_ES1_CS_AP_PIN、1U);
ret を返します。
}
ret=Spi_SetupEB(5u, (uint8_t*)TxChBuf, (uint8_t*)RxChBuf, 8u);
if (ret == E_OK) {
ret=Spi_SyncTransmit(SpiConf_SpiSequence_SpiSequence_sja);
}
Siul2_Dio_Ip_WritePin(SPI_MCU_ES1_CS_AP_PORT、SPI_MCU_ES1_CS_AP_PIN、1U);
ret を返します。
}
間違っていたら訂正してください!!
3.)レジスタアドレスを#define L2_ENTRY0_ADDR 0x00000023に変更しました。
しかし、メッセージを送信するときに反映される追加しようとしているテーブルをまだ識別できません
こんにちは@Atkinson 、
あなたのコードは良さそうです。ただし、SPI で動的テーブルにアクセスする場合、エントリ アドレスは FF なしで、2 だけ右にシフトされます。これは、以前の投稿のいくつかで既に述べたとおりです。
SO、 #define L2_ENTRY0_ADDR 0xFF00008cは #define L2_ENTRY0_ADDR 0x00000023にする必要があります。
ただし、ルーチンspi_write_reg が実際に何を行うかによって異なります。
以下は write_l2_lookup_table.py の出力です。私のデバッグ出力(tx/rx は、オシロスコープまたはロジック アナライザによって SPI ワイヤ上に表示されるデータを指します):
DBG spi_tx: ['0x02000290', '0xAABBCCDD']
DBG spi_rx: ['0x02000290', '0x00000000']
DBG spi_read 0x0029 -> 0x00000000
DBG spi_write 0x0023 <- 0x37FFFA00
DBG spi_tx: ['0x80000230', '0x37FFFA00']
DBG spi_write 0x0024 <- 0x119A22AB
DBG spi_tx: ['0x80000240', '0x119A22AB']
DBG spi_write 0x0025 <- 0xFF807089
DBG spi_tx: ['0x80000250', '0xFF807089']
DBG spi_write 0x0026 <- 0xFFFFFFFF
DBG spi_tx: ['0x80000260', '0xFFFFFFFF']
DBG spi_write 0x0027 <- 0xF1FFFFFF
DBG spi_tx: ['0x80000270', '0xF1FFFFFF']
DBG spi_write 0x0028 <- 0x1FFE7EFF
DBG spi_tx: ['0x80000280', '0x1FFE7EFF']
DBG spi_write 0x0029 <- 0xD9800000
DBG spi_tx: ['0x80000290', '0xD9800000']
+-------+-------------+-------------------+---------+--------+--------+
|インデックス |デスポート |マカドル |ヴラニド |エンポート | IOタグ |
+-------+-------------+-------------------+---------+--------+--------+
| 256 | 11111111111 | 11:22:33:44:55:66 | 14 | 1 | 1 |
+-------+-------------+-------------------+---------+--------+--------+
L2ルックアップテーブルエントリ書き込み(SW1)
FAE リクエストに関しては、FAE は私のエスカレーション パスに含まれていません。NXPについてでは FAE が割り当てられている、SO FAE に直接お問い合わせすることができます。
よろしくお願いいたします。
パベル
こんにちは@PavelL
#L2_ENTRY0_ADDR 0xFF00008c を定義します
#L2_ENTRY1_ADDR 0xFF000090 を定義します
#L2_ENTRY2_ADDR 0xFF000094 を定義します
#L2_ENTRY3_ADDR 0xFF000098 を定義します
#L2_ENTRY4_ADDR 0xFF00009C を定義します
#L2_ENTRY5_ADDR 0xFF0000A0 を定義します
#L2_CTRL_ADDR 0xFF0000A4 を定義します
Std_ReturnType CreateL2Entry(uint32_t エントリ[6])
{
uint16_t インデックス = 11;
uint64_t MACADDDR = 0x661122334455;
uint64_t MACADDR_MASK = 0xFFFFFFFFFFFF;
uint16_t VLANID = 3;
uint16_t VLANID_MASK = 0xFFF;
uint8_t IOTAG = 0;
uint8_t IOTAG_MASK = 0;
uint8_t SRCPORT = 5;
uint8_t SRCPORT_MASK = 0xF;
uint8_t 宛先ポート = 0x02;
uint8_t ENFPORT = 1;
uint8_t RETAG = 0;
uint8_t ミラー = 0;
uint8_t テイク = 0;
uint16_t MIRR_VLAN = 0xFFF;
uint8_t トラップホスト = 0;
uint8_t CBSIDIN = 0x3F;
uint8_t CBENONDA = 0;
uint16_t VLIDX = 0xFFF;
uint8_t SA_POLICE = 0;
uint8_t DA_POLICE = 0;
エントリ[0] = ((インデックス & 0x03FF) << 1) |
((ENFPORT & 0x1) << 11) |
((DESTPORTS & 0x7FF) << 12) |
((SRCPORT & 0xF) << 23) |
((MACADDR & 0x1F) << 27);
エントリ[1] = (uint32_t)((MACADDR >> 5) & 0xFFFFFFFF);
エントリ[2] = (((MACADDR >> 37) & 0x7FF) << 0) |
((VLANID & 0xFFF) << 11) |
((IOTAG & 0x1) << 23) |
((MACADDR_MASK & 0xFF) << 24);
エントリ[3] = (uint32_t)((MACADDR_MASK >>
エントリ[4] = (((MACADDR_MASK >> 40) & 0xFF) << 0) |
((VLANID_MASK & 0xFFF) <<
((IOTAG_MASK & 0x1) << 20) |
((SRCPORT_MASK & 0xF) << 21) |
((RETAG & 0x1) << 25) |
((ミラー & 0x1) << 26) |
((テイク& 0x1) << 27) |
((MIRR_VLAN & 0xF) << 28);
エントリ[5] = (((MIRR_VLAN >> 4) & 0xFF) << 0) |
((TRAPTOHOST & 0x1) <<
((CBSIDIN & 0x3F) << 9) |
((CBENONDA & 0x1) << 15) |
((VLIDX & 0xFFF) << 17) |
((SA_POLICE & 0x1) << 29) |
((DA_POLICE & 0x1) << 30);
E_OK を返します。
}
Std_ReturnType WriteL2LookupEntry(uint8_t swt)
{
swt > 0 の場合、E_NOT_OK を返します。
Std_ReturnType ret;
uint32_t ctrlReg = 0;
uint32_t エントリ[6];
ret = CreateL2Entry(エントリ);
if (ret != E_OK) ret を返します。
する {
ret = spi_read_reg(L2_CTRL_ADDR, &ctrlReg);
if (ret != E_OK) ret を返します。
} while (ctrlReg & (1U << 31));
ret = spi_write_reg(L2_ENTRY0_ADDR, entry[0]); if (ret != E_OK) return ret;
ret = spi_write_reg(L2_ENTRY1_ADDR, entry[1]); if (ret != E_OK) return ret;
ret = spi_write_reg(L2_ENTRY2_ADDR, entry[2]); if (ret != E_OK) return ret;
ret = spi_write_reg(L2_ENTRY3_ADDR, entry[3]); if (ret != E_OK) return ret;
ret = spi_write_reg(L2_ENTRY4_ADDR, entry[4]); if (ret != E_OK) return ret;
ret = spi_write_reg(L2_ENTRY5_ADDR, entry[5]); if (ret != E_OK) return ret;
uint32_t ctrlValue = (1U << 31) | (1U << 30) | (1U << 28) | (1U << 27) | (3U << 23);
ret = spi_write_reg(L2_CTRL_ADDR、ctrlValue);
if (ret != E_OK) ret を返します。
する {
ret = spi_read_reg(L2_CTRL_ADDR, &ctrlReg);
if (ret != E_OK) ret を返します。
} while (ctrlReg & (1U << 31));
E_OK を返します。
}
これは、動的エントリを作成するための現在の実装です。この実装が正しいかどうかを FAE とクロス検証できますか。
その他の変更が必要な場合は
こんにちは@Atkinson 、
質問への回答は、アプリケーションの利用CASEに関連しています。
S32G でも SJA1110 でも、どこにでも動的エントリを作成できます。
SJA1110 のスイッチコアに動的エントリを書き込む方法の例を次に示します。
よろしくお願いいたします、
パベル
こんにちは@PavelL
1.)SO、動的構成のレジスタへのアクセスに関するこの変更は、S32G または SJA1110 スイッチで行う必要がありますか?
2.) SJA1110 スイッチ経由の場合、SPI によるレジスタの読み取りと書き込みを実行する必要があるかどうか、またこの実装は SWITCH_DRV 間でどこに実行する必要があるか?
3.) スイッチで追加されるSO動的エントリを作成できます
さらに詳しい説明があると助かります!!
こんにちは@Atkinson 、
現在仕事が忙しくて返信が遅れたことをお詫び申し上げます。
最初は簡単ではないと思われるかもしれませんが、コンセプトは実際には非常にシンプルです。
最終的なレジスタ アドレスは、アクセス方法 (AHB 経由の M7 コア経由で内部的にアクセスしているか、SPI_AP インターフェース経由で外部的にアクセスしているか) によって異なります。ベース アドレスはアクセス ポイントによって異なります。
レジスタ アドレスは、UM11107 の表 2 に示されているベース アドレスを使用して計算されます。たとえば、スイッチ サブシステムの場合、ベース アドレスは SPI_AP アクセスの場合は0x00000000 、AHB アクセスの場合は0xFF000000です。
あなたのCASE、レジスタ0x8C (DYN_BE_LKP_ENTRY0) は、AHB 経由でアクセスすると0xFF00008Cになります。
ここで混乱が生じる可能性があります。SDK ドライバは次のように定義します。
こんにちは@PavelL
読み書きの完全な住所を教えていただけますか?
住所 名前 アクセス リセット 説明
8Ch DYN_BE_LKP_
エントリー0
読み取り/書き込み 0h
(FFFFFFFEh)
8chより前のベースアドレスは何でしたか?
例えば0x3fc0008cになりますので、この動的エントリテーブルには完全なアドレスがあります。完全なアドレスを教えていただけますか?
8Ch DYN_BE_LKP_
エントリー0
読み取り/書き込み 0h
(FFFFFFFEh)
90時間 DYN_BE_LKP_
エントリー1
読み取り/書き込み 0h
94時間 DYN_BE_LKP_
エントリー2
読み取り/書き込み 0h
98時間 DYN_BE_LKP_
エントリー3
読み取り/書き込み 0h
9Ch DYN_BE_LKP_
エントリー4
読み取り/書き込み 0h
A0h DYN_BE_LKP_
エントリー5
読み取り/書き込み 0h
A4h DYN_BE_LKP_CTRL 読み取り/書き込み 0h
(FF800000h)
こんにちは@Atkinson 、
裏付けとなる文書は知りません。これは一般的な知識であり、デバイスに依存しません。このトピックについて Copilot に相談したところ、FTDI の代わりに DSPI5 を使用するように sja11xx_ftdi4232.py を変更できるはずです。
よろしくお願いいたします。
パベル
こんにちは@PavelL
このスクリプトを S32G-VNP-RDB2 または RDB3 ボードで使用するには、S32G プロセッサ上の DSPI5 を介して通信するように FTDI レイヤーを変更する必要があります。
どうすればいいですか? 裏付けとなる書類はありますか?
こんにちは@Atkinson 、
Q1: 「Linux BSP が SD カードにプリインストールされているので、動的構成が自動的に有効になりますか?」
A1: いいえ、BSP には動的構成をサポートする DSA ドライバが含まれていますが、すべてのユースケースで自動的に有効になるわけではありません。
Q2: write_l2_lookup.py (python evm ホストツール) を使用して動的に L2 ルックアップエントリを構成する場合、そのプロセスは同じままですか?S32G-VNP-RDBボードの場合は変更されます。
A2: 動的エントリを作成してアップロードするための一般的なフローは、UM11107 および AN12925 で説明されているとおりです。
ただし、write_l2_lookup_table.py スクリプトは FTDI ドライバを使用して USB 経由で SJA1110-EVM にアクセスします。
このスクリプトを S32G-VNP-RDB2 または RDB3 ボードで使用するには、S32G プロセッサ上の DSPI5 を介して通信するように FTDI レイヤーを変更する必要があります。
Q3: 「ノートPCと S32G-VNP_RDB32 ボードをインターフェースして動的エントリを作成することは可能ですか?」
A3: はい、可能です。Linux 上で実行されるカスタム ソフトウェアを自由に開発し、SPI または イーサネット 経由で独自のプロトコルを処理して動的なエントリを構成できます。
Q4: 「もう1つ、SJA1110_SDK_1.0.2はRTM1.0.0の実装に必要な主なものであるかどうかは問題ありませんか?」
A4: いいえ、互換性と安定性のために、最新バージョンの SJA1110 SDK 1.0.2 を使用することをお勧めします。
さらにサポートが必要な場合は、FAE にお問い合わせいただくか、 https://support.nxp.com/s/?language =en_US からチケットを送信してください。
ご理解のほどよろしくお願いいたします。
よろしくお願いいたします。
パベル
こんにちは@PavelL
SO、SD カードを S32G-VNP-RDB ボードに挿入する場合、Linux BSP は SD カードにプリインストールされます。SDカードに存在するBSPが動的構成を自動的に有効にするSO
write_l2_lookup.py (python evm ホスト ツール) を使用して動的に L2 ルックアップ エントリを構成する場合、そのプロセスは同じままですか?S32G-VNP-RDBボードの場合は変更されます
プロセスが同じままであれば、ノートPCと RDB32 ボードをインターフェースする方法は、ノートPCと SJA1110 EVM ボードを介してインターフェースする場合、USBインターフェースを使用して接続され、動的エントリを構成するのに役立ちます。では、S32G-VNP-RDB32 ボードのCASE、インターフェースはどのようになるのでしょうか。
動的エントリを作成してノートPCと S32G-VNP_RDB32 ボードをインターフェースすることは可能ですか?
もう 1 つ、SJA1110_SDK_1.0.2 が RTM1.0.0 を実装するために必要な主なものであるかどうかは問題ありませんか?
こんにちは@Atkinson 、
Linux BSP は、S32G-VNP-RDB3 ボードに付属の SD カードにすでにプリインストールされているSO、この点に関しては追加の操作は必要ありません。
ボードを正常に起動できたと思います (以前のメッセージで既に言及していた場合は申し訳ありません)。
BSP には、動的な L2 ルックアップ テーブル構成のサポートを含む、さまざまな便利な機能を提供する SJA1110 DSA ドライバが含まれています。
DSA ドライバはデフォルトで有効になっています。
このCASEは複数の分野にまたがるトピックに発展したため、今後の進め方について FAE と協議しました。
よろしくお願いいたします。
パベル
こんにちは@PavelL
現在、S32G-VNP-RDB32 -- SJA1110スイッチに実装しようとしています。
現在、私は独自のファームウェアを持っていません
どのLinux BSPを利用する必要があるか
どのような変更が必要か
こんにちは@Atkinson 、
S32G-VNP-RDB3 ボードからこれを実行する予定の場合、状況は大きく変わります。ボード上で Linux BSP を実行しますか、それとも独自のファームウェアを使用する予定ですか?
よろしくお願いいたします。
パベル
こんにちは@PavelL
3. SPI_HAP(ホストアクセスプロトコル)
ホストツールのwrite_l2_lookup_table.pyスクリプトは、SPI経由でL2テーブルを動的に設定する方法を示しています。このアプローチは、任意の外部MCUまたはホストプロセッサで使用できます。このスクリプトのロジックは、必要に応じてM7コア内部で直接実行できるように移植することもできます。
write_l2_lookup_table.py 経由でエントリを設定したいと考えています
write_l2_lookup_table.pyファイルに記述した設定がRDB32ボードにどのように移行されるか
ノートPCから RDB32Board にどのようなインターフェースが必要ですか?
L2ルックアップエントリをデバイス(RDB32ボード)に渡すための通信メカニズムは何ですか?
手順を教えていただけますか、または実装手順はどこで確認できますか
こんにちは@Atkinson 、
はい、その通りです。システムが起動すると、静的構成が外部フラッシュから自動的に読み込まれます。
動的構成の概念をもう少し詳しく説明します。
動的構成のタスクは、次の 2 つの部分に CAN 分けられます。
これに使用できるインターフェースは 3 つあります。
よろしくお願いいたします。
パベル
こんにちは@PavelL
3. SPI_HAP(ホストアクセスプロトコル)
ホストツールのwrite_l2_lookup_table.pyスクリプトは、SPI経由でL2テーブルを動的に設定する方法を示しています。このアプローチは任意の外部MCUまたはホストプロセッサで使用できます。このスクリプトのロジックは、必要に応じて内部M7コアで直接実行できるように移植することもできます。
write_l2_lookup_table.py 経由でエントリを設定したいと考えています
write_l2_lookup_table.pyファイルに記述した設定がRDB32ボードにどのように移行されるか
ノートPCから RDB32Board にどのようなインターフェースが必要ですか?
L2ルックアップエントリをデバイス(RDB32ボード)に渡すための通信メカニズムは何ですか?
手順を教えていただけますか、または実装手順はどこで確認できますか
こんにちは@PavelL
おっしゃるとおり、switch_coreの設定を動的に行いたいのですが
システムが起動すると、ペリフェラルで設定した静的構成がロードされます。
静的に設定されているテーブル エントリを動的に構成する方法を探しています。
どちらのCASEでも、スイッチ構成を動的に更新する方法は通常 3 つあります。
これらが唯一可能な方法である場合、私が提供したコードとして設定すると、機能しますか、それとも機能しませんか?
また、ここで言及されている 3 つのプロセスは、ECT および write_l2_lookup_table.py と同じですか? それとも異なるものですか?
こんにちは@Atkinson 、
動的 L2 ルックアップ テーブルを使用するCASEを明確にしていただけますか?
個人的には、次の 2 つの典型的なシナリオで動的エントリの使用を検討します。
どちらのCASEでも、スイッチ構成を動的に更新する方法は通常 3 つあります。
あなたのユースCASEはこれらのカテゴリのいずれかに該当しますか、それとも何か違うものを目指していますか?
よろしくお願いいたします。
パベル
こんにちは@PavelL
あなたが言ったように、コードを組み込んでみました
エントリの作成に役立つコードをどこに配置すればよいか教えていただけますか?
以前のメッセージでは、ECT(イーサネット構成ツール)とSPI_HAPを使用する2つの方法があると述べていました。
したがって、これらのツールとファイルは実行時 ryt で処理する必要がありますか?
私が共有したコードは、これらのツールなしで実装しようとしているものです
動的 L2 ルックアップ エントリを作成したいと考えていますが、これは問題ないでしょうか?
よろしく
アトキンソン
こんにちは@Atkinson 、
祝日のため返信が遅れましたことをお詫び申し上げます。
コードを共有していただきありがとうございます。ざっと見たところ、一見すると、AN12925の5.1.3.2章に概説されている原則と一致しているように見えます。L2 ルックアップ テーブル エントリを書き込みます。また、#define ステートメントが SJA1110.h から再利用されているように見えることにも気付きました。これは標準的な方法です。
ただし、徹底的なカスタム コード レビューは、弊社の無料オンライン サポートの範囲外となることにご注意ください。さらに、この関数を呼び出すタイミングとコンテキストはアプリケーションに大きく依存し、システムのアーキテクチャと要件によって異なる場合があります。
よろしくお願いいたします。
パベル
こんにちは@PavelL
静的 status_t wait_for_valid_clear(uint8_t swt) {
status_t ステータス;
uint32_t ctrl = 0;
する {
ステータス = SWITCH_DRV_Read(swt, 1, DYN_BE_LKP_CTRL, &ctrl);
if (status != STATUS_SUCCESS) ステータスを返します。
} while (ctrl & DYN_BE_LKP_CTRL_VALID_MASK);
if (ctrl & DYN_BE_LKP_CTRL_ERROR_MASK) STATUS_ERROR を返します。
STATUS_SUCCESS を返します。
}
status_t SJA1110_AddL2LookupEntry_Dynamic(uint8_t swt) {
status_t ステータス;
// MAC = 66:11:22:33:44:55
uint8_t mac[6] = {0x66, 0x11, 0x22, 0x33, 0x44, 0x55};
uint64_t mac64 = ((uint64_t)mac[0] << 40) | ((uint64_t)mac[1] << 32) | ((uint64_t)mac[2] << 24) |
((uint64_t)mac[3] << 16) | ((uint64_t)mac[4] <<
// L2ルックアップ入力フィールドを準備する
uint32_t エントリ[WORD_COUNT] = {0};
entry[0] = ((5 & 0xF) << 24) | (1 << 11); // SrcPort、DestPorts 1 & 2
エントリ[1] = (uint32_t)(mac64 & 0xFFFFFFFF);
エントリ[2] = (uint32_t)((mac64 >> 32) & 0xFFFF);
エントリ[2] |= (3 << 16); // VLAN ID = 3
entry[3] = 0; // オプションのマスク
エントリ[4] = 0;
エントリ[5] = (8 << 4) | (1 << 10); // CB_SID_IN = 8, CB_ON_DA = 1
// 前の操作が完了するまで待機します
ステータス = wait_for_valid_clear(swt);
if (status != STATUS_SUCCESS) ステータスを返します。
// L2エントリデータをレジスタに書き込む
ステータス = SWITCH_DRV_Write(swt, WORD_COUNT, DYN_BE_LKP_ENTRY0, エントリ);
if (status != STATUS_SUCCESS) ステータスを返します。
// 制御レジスタ値を構築する
uint32_t ctrl = DYN_BE_LKP_CTRL_VALID_MASK |
DYN_BE_LKP_CTRL_RDWRSET_MASK |
(HOSTCMD_WRITE << DYN_BE_LKP_CTRL_HOSTCMD_SHIFT);
// トリガー書き込み
ステータス = SWITCH_DRV_Write(swt, 1, DYN_BE_LKP_CTRL, &ctrl);
if (status != STATUS_SUCCESS) ステータスを返します。
// 操作が完了するまで待機します
wait_for_valid_clear(swt) を返します。
}
このコードは動的エントリの生成に利用CANますか?
このコードが正しい場合、関数をどこで呼び出す必要がありますか?
よろしく
アトキンソン
こんにちは@PavelL
#include
#include
// SoCマッピングに従ってレジスタアドレスを定義します
#define DYN_BE_LKP_ENTRY0 0x000 // 実際のアドレスに置き換えます
#定義 DYN_BE_LKP_ENTRY1 0x004
#DYN_BE_LKP_ENTRY2 0x008 を定義します
#定義 DYN_BE_LKP_ENTRY3 0x00C
#define DYN_BE_LKP_ENTRY4 0x010
#define DYN_BE_LKP_ENTRY5 0x014
#DYN_BE_LKP_CTRL 0x018 を定義します
void insert_l2_unicast_entry(void)
{
// === 入力 ===
uint64_t mac = 0x021122334455ULL; // MACアドレス
uint16_t vlan_id = 3;
uint8_t dest_port = 3; // ポート3
uint16_t dest_ports_mask = (1 << dest_port);
uint16_t インデックス = 5;
// === ステップ 1: 前の操作が完了するまで待機します ===
read_register(DYN_BE_LKP_CTRL) と ETHSW_DYN_BE_LKP_CTRL_bValid_MASK が有効な間、
// === ステップ 2: 入力フィールドを準備する ===
uint32_t mac_lo = (uint32_t)(mac & 0xFFFFFFFF); // 下位32ビット
uint32_t mac_hi = (uint32_t)((mac >> 32) & 0xFFFF); // 上位16ビット
uint32_t エントリ0 = ETHSW_DYN_BE_LKP_ENTRY0_uvEntry_30__0_(0x00000000);
uint32_t エントリ1 = ETHSW_DYN_BE_LKP_ENTRY1_uvEntry_62__31_(mac_lo);
uint32_t エントリ 2 = ETHSW_DYN_BE_LKP_ENTRY2_uvEntry_94__63_(mac_hi);
uint32_t エントリ3 = ETHSW_DYN_BE_LKP_ENTRY3_uvEntry_126__95_(
((vlan_id & 0xFFF) << 16) | (dest_ports_mask & 0xFFFF));
uint32_t entry4 = ETHSW_DYN_BE_LKP_ENTRY4_uvEntry_158__127_(0x00000000); // オプションフラグ/予約済み
uint32_t エントリ5 = ETHSW_DYN_BE_LKP_ENTRY5_uvEntry_190__159_(インデックス);
// === ステップ3: DYNレジスタにエントリを書き込む ===
write_register(DYN_BE_LKP_ENTRY0、エントリ0);
write_register(DYN_BE_LKP_ENTRY1、エントリ1);
write_register(DYN_BE_LKP_ENTRY2、エントリ2);
write_register(DYN_BE_LKP_ENTRY3、エントリ3);
write_register(DYN_BE_LKP_ENTRY4、エントリ4);
write_register(DYN_BE_LKP_ENTRY5、エントリ5);
// === ステップ 4: 制御レジスタを介して書き込みをトリガーする ===
uint32_t ctrl_val = 0;
ctrl_val |= ETHSW_DYN_BE_LKP_CTRL_b有効(1);
ctrl_val |= ETHSW_DYN_BE_LKP_CTRL_bWrRdB(1); // 書き込み操作
ctrl_val |= ETHSW_DYN_BE_LKP_CTRL_uvHostCommand(0b011); // ホスト書き込み
ctrl_val |= ETHSW_DYN_BE_LKP_CTRL_bValidEntry(1); // 有効なエントリ
write_register(DYN_BE_LKP_CTRL、ctrl_val);
// === ステップ 5: 操作が完了するまで待機します ===
read_register(DYN_BE_LKP_CTRL) と ETHSW_DYN_BE_LKP_CTRL_bValid_MASK を読み取りながら実行します。
// === ステップ 6: エラーの確認 ===
uint32_t ステータス = read_register(DYN_BE_LKP_CTRL);
if (ステータス & ETHSW_DYN_BE_LKP_CTRL_bError_MASK) {
// エラーを処理する
// 必要に応じてこれを印刷またはログに記録できます
}
}
L2ルックアップテーブルにデータを動的に書き込むためのコードをCAN挿入できるかどうか
テストするにはこのコードをどこに挿入すればよいですか?
ご返信をお待ちしております
よろしく
アトキンソン
こんにちは@PavelL
SPI_HAP経由で設定する方法
write_l2_lookup_table.py はどこにありますか?
これを SPI_HAP 経由でどのように通信する必要がありますか?デバイスの起動後
以前の静的構成では、各インデックスを介して各データを構成しましたか?
SO、最初に静的に構成されたデータは問題ないか、または静的構成のいずれもコネクテッドすべきではないということですか?
この write_l2_lookup_table.py を CAN 共有できますか?
このスクリプトをどこから実行すると (データを渡すためにどのポートにコネクテッドする必要があるか)、スクリプトはデータをポーリングしますか?
よろしく
アトキンソン
こんにちは@Atkinson 、
動的構成の**方法**はユース**CASE**によって異なり、内部の M7 コアによって実行することも、SPI を介して外部で実行することも**CAN**。以下に考えられる解決策のリストを示します。
1. ECT(イーサネット制御ツール)
外部イーサネット (UDP) フレームを介した動的構成。M7 コア上で実行されている内部ファームウェアは構成を受信し、それをスイッチ コアに適用します。
2. 修正ECT
ECT ソース コードは、あらゆる イーサネット フレーム形式 (UDP だけでなく) を受け入れるように適応できます。これにより、カスタム プロトコルまたはシステムへの統合が可能になります。内部ロジックは同じままで、実際のレジスタの更新は M7 コアが実行します。
3. SPI_HAP(ホストアクセスプロトコル)
ホスト ツールの write_l2_lookup_table.py スクリプトは、SPI を介して L2 テーブルを動的に構成する方法を示しています。このアプローチは、任意の外部MCUまたはホスト プロセッサで使用できます。必要に応じて、このスクリプトのロジックを移植して内部 M7 コア上で直接実行することもCAN。
上記の方法はすべて、AN12925 のセクション 5.1.3.2 で説明されているのと同じ原則に従います。レジスタ レベルのフローは同一であり、制御レジスタのポーリング、エントリ レジスタへの書き込み、および制御レジスタを介した更新のトリガーが含まれます。
よろしくお願いいたします。
パベル