STM32F429 以太網MAC濾波應用說明

STM32F429 以太網MAC濾波應用說明

最近在使用MAC濾波,進行流量控制。默認情況下stm32f429系列以太網能夠滿足大部分需求。針對需要進行mac濾波的應用可以從以下幾個方面進行深度發掘。

1 採用4個完美濾波器

MAC 支持多達 4 個用於單播完美過濾的 MAC 地址。如果選擇完美過濾(復位幀過濾寄存器中的 HU 位), MAC 會將接收的單播地址的所有 48 位與編程的 MAC 地址進行比較來確定是否匹配。默認情況下,始終使能 MacAddr0,其它地址 MacAddr1—MacAddr3 則通過單獨的使能位進行選擇。將其它地址 (MacAddr1—MacAddr3) 的各個字節與接收的相應 DA 字節進行比較時,可以將寄存器中相應的屏蔽字節控制位置 1 來屏蔽該字節。這有助於 DA 的組地址過濾。在散列過濾模式( HU 位置 1)下, MAC 將使用 64 位散列表執行對單播地址的不完美過濾。對於散列過濾, MAC 將使用接收的目標地址的 6 個高 CRC位來索引散列表的內容。值爲 000000 時,選取所選寄存器中的位 0;值爲 111111 時,選取散列表寄存器中的位 63。如果相應位(由 6 位 CRC 指示)已置 1,將認爲單播幀已通過散列過濾,否則認爲幀未能通過散列過濾。【STM32F4xx中文參考手冊 P843】

上段中的名詞說明:

(1)完美過濾——值與MacAddr地址的48bit全部匹配,完美此處是指沒有衝突,相較於下面的方式。當然也可以選擇屏蔽字節,即只是部分匹配,類似於CAN接收濾波器。

如下代碼,可以針對MAC:A4-A3-A2-A1-34-12,進行定點接收。

uint32_t data = EthHandle.Instance->MACA1HR;

EthHandle.Instance->MACA1HR = 0x80001234;

EthHandle.Instance->MACA1LR = 0xA1A2A3A4;
 

 2  散列過濾模式(hash)

是指利用hash計算(hash概念請自行百度),此處可以理解爲一種映射,即多對一,因此肯定存在衝突,此種映射方式是通過CRC32計算的6bit來決定的。48bit通過計算映射到6bit,必然存在衝突。因此濾波是“不完美的”。

例如,如果傳入幀的 DA 接收爲 0x1F52 419C B6AF( 0x1F 是 MII 接口上接收的第一個字節),則內部計算出的 6 位散列值爲 0x2C 且爲了過濾要檢查 HTH 寄存器位[12]。如果傳入幀的 DA 接收爲 0xA00A 9800 0045, 則計算出的 6 位散列值爲 0x07 且爲了過濾要檢查HTL 寄存器位[7]。

下面給出hash計算方式(引用自st官網:https://community.st.com/s/question/0D50X00009Xkb6ySAB/calculating-ethernet-multicast-filter-hash-value-),這與手冊上的例子是相對應的:

/ STM32 MACHASH - Copyright (C) 2014-2018 Clive Turvey ([email protected])
//  All Rights Reserved
 
#include <windows.h>
 
#include <stdio.h>
#include <stdlib.h>
 
typedef unsigned char uint8_t;
typedef unsigned long uint32_t;
 
uint32_t Rev32(uint32_t x)
{
  uint32_t y;
  int i;
 
  y = 0;
 
  for(i=0; i<32; i++)
    if (x & (1 << i))
      y |= 1 << (31 - i);
 
  return(y);
}
 
uint32_t MacHash(const uint8_t *Mac) // [email protected]
{
  int i, j;
  uint32_t Crc;
 
  Crc = 0xFFFFFFFF;
 
  for(j=0; j<6; j++)
  {
    Crc = Crc ^ (uint32_t)Mac[j];
 
    for(i=0; i<8; i++)
      if (Crc & 1)
        Crc = (Crc >> 1) ^ 0xEDB88320; // Reversed 0x04C11DB7
      else
        Crc = (Crc >> 1);
  }
 
  return(Rev32(~Crc) >> 26); // Get High order 6-bit in reversed/inverted CRC
}
 
uint32_t MacHashFast(const uint8_t *Mac) // [email protected]
{
  static const uint32_t Rev6Tbl[] = {
    0x00,0x20,0x10,0x30,0x08,0x28,0x18,0x38,
    0x04,0x24,0x14,0x34,0x0C,0x2C,0x1C,0x3C,
    0x02,0x22,0x12,0x32,0x0A,0x2A,0x1A,0x3A,
    0x06,0x26,0x16,0x36,0x0E,0x2E,0x1E,0x3E,
    0x01,0x21,0x11,0x31,0x09,0x29,0x19,0x39,
    0x05,0x25,0x15,0x35,0x0D,0x2D,0x1D,0x3D,
    0x03,0x23,0x13,0x33,0x0B,0x2B,0x1B,0x3B,
    0x07,0x27,0x17,0x37,0x0F,0x2F,0x1F,0x3F };
 
  static const uint32_t Crc32Tbl[] = {
    0x4DBDF21C, 0x500AE278, 0x76D3D2D4, 0x6B64C2B0,
    0x3B61B38C, 0x26D6A3E8, 0x000F9344, 0x1DB88320,
    0xA005713C, 0xBDB26158, 0x9B6B51F4, 0x86DC4190,
    0xD6D930AC, 0xCB6E20C8, 0xEDB71064, 0xF0000000 };
 
  int i;
  uint32_t Crc;
 
  Crc = 0;
 
  for(i=0; i<6; i++)
  {
    Crc = Crc ^ (uint32_t)Mac[i];
 
    Crc = (Crc >> 4) ^ Crc32Tbl[Crc & 0x0F];  /* lower nibble */
    Crc = (Crc >> 4) ^ Crc32Tbl[Crc & 0x0F];  /* upper nibble */
  }
 
  return(Rev6Tbl[Crc & 0x3F]);
}
 
int main(int argc, char **argv)
{
  static const uint8_t Test1[] = { 0x1F, 0x52, 0x41, 0x9C, 0xB6, 0xAF }; // 0x2C
  static const uint8_t Test2[] = { 0xA0, 0x0A, 0x98, 0x00, 0x00, 0x45 }; // 0x07
  static const uint8_t Test3[] = { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x21 }; // 0x24
 
  printf("MacHash %02X\n", MacHash(Test1));
  printf("MacHash %02X\n", MacHash(Test2));
  printf("MacHash %02X\n", MacHash(Test3));
 
  printf("MacHashFast %02X\n", MacHashFast(Test1));
  printf("MacHashFast %02X\n", MacHashFast(Test2));
  printf("MacHashFast %02X\n", MacHashFast(Test3));
 
  return(1);
}

提前計算好MAC地址的分佈情況,針對的設置hash濾波參數,可以大爲減去軟件負荷。

3.接收所有幀

通過如下設置可以接收網絡中的所有mac數據。沒有任何過濾操作。

uint32_t data = EthHandle.Instance->MACFFR;
 EthHandle.Instance->MACFFR = data | 0x80000000;

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章