
前言 网络中传递着各种各样的数据包,当设备连接到网络后,为了减少对接收到的数据进行处理的负荷,就需要对设备接收到的数据包进行过滤。STM32MCU的以太网外设提供多种数据包过滤的模式。可以根据以太网帧的目标MAC 地址,源 MAC地址进行过滤,STM32H7系列还提供对 VLANtag和 IP地址,UDP/TCP端口的过滤。2 P5 i- n& `* t) ~2 d# w $ H$ n- o. d$ K1 _2 R6 a! }# t 拿 MAC地址过滤来说,SM32MCU支持:单播目标地址过滤,多播目标地址过滤,单播源地址过滤和广播地址过滤。单播目标地址过滤和多播目标地址过滤又分为:Perfect地址过滤和 Hash地址过滤。 * v' y, [2 Y. r4 N) e( e5 _: V. l+ E1 ` perfect地址过滤就是把接收到的以太网帧中的目标地址与 MAC地址寄存器中保存的地址进行比较,如果匹配,数据包就被接受,否则就被丢掉。还可以通过设置“反向过滤”,来翻转过滤的结果,接收到的以太网帧中的目标地址与MAC地址寄存器中保存的地址如果不匹配,数据包就被接收,否则就被丢掉。 Hash地址过滤不是直接比较 MAC地址,而是计算目标 MAC地址的 CRC32值,取其高 6位作为索引去查询 Hash表寄存器中对应的值,来判断是否接收该数据帧。Hash地址过滤的方法稍微复杂,本文接下来将基于STM32H743Nucleo板,通过具体的例程介绍如何实现 Hash地址过滤。 MAC 地址Hash 过滤 过滤原理 在 Hash地址过滤模式下,以太网 MAC通过一张 64位的 Hash表来进行过滤。这张表存储在两个 32位的寄存器中。STM32H743的寄存器 ETH_MACHT0R 保存着 Hash表的前 32位,ETH_MACHT1R中保存着 Hash表的后 32位值。- y$ M2 a; a, W' _) z- v: ~ ; X5 C9 ~7 F; T MAC接收到以太网帧后,会自动计算目标 MAC地址的 CRC值,然后用该 CRC值的高 6位,作为索引号去前面提到的 Hash表寄存器中查找对应位,如果该位的值是 1,则收到的以太网帧通过。否则就丢掉。例如,计算出的 CRC高6位是 0,则对应 ETH_MACHT0R的 bit0,如果该位是 1,则通过。 8 G! L/ ~2 t! R9 Y" z0 }% b 在初始化的时候,应该根据想要接收的目标 MAC地址,先设置好 ETH_MACHT0R和 ETH_MACHT1R寄存器的值。Hash地址过滤将 48位的 MAC地址,对应到 6位的 Hash值,肯定会出现多个MAC地址对应到一个 6位 Hash值的情况,所以这种过滤方式也被称作 imperfect过滤模式 Hash值的计算方法& p" t- n' P8 [6 C. f+ f Hash地址过滤模式,最关键的是如何计算6位的Hash值。在RM0433中介绍了 Hash的产生方法,具体如下:) P/ X% g* l* v1 V. w8 y1 C0 p 1. 计算目标 MAC地址的 CRC32值。计算 CRC32的方法参见 IEEE802.3的第 3.2.8章中FCS的说明 。根据IEEE802.3中 CRC值的计算要求,和以太网帧中 MAC地址传输的顺序,MAC地址的 CRC值计算方法如下: 第一个 32位数据进行补码运算 输入的数据都进行按位反转顺序 进行 CRC32计算,多项式为 0x4C11DB7! I/ m; r) J/ H2 }, b. \ 对最终输出数据进行补码运算 2. 对第一步的计算值进行按位反转顺序6 M' a( p, R3 {# E6 Z Q9 k3 ~5 L 3. 取第二步计算值的高 6位 然后就可以根据计算出来的 Hash值,去设置 ETH_MACHT0R和 ETH_MACHT1R寄存器了。" g& W; ~: V; y# R - D9 g2 O0 b2 ] MAC地址过滤的寄存器配置! l) n% r: V3 b. y" n+ W$ Q. J 目标 MAC地址过滤的寄存器配置见下表:1 X$ ^/ T, Z4 X Z ![]() 例程说明, Y# L3 d# d0 i6 j, V& a0 { 下面我们将用一个例子来说明如何配置Hash地址过滤。 在该例程中,我们希望 STM32H743Nucleo板只接收广播,发往自己的单播 MAC地址的消息,以及两个特定多播MAC地址的消息。 单播 MAC地址为:00:80:E1:00:00:00, 多播 MAC地址为:01:0c:0d:01:01:03和 01: 00: 5e: a8: 00: 0a。 例程中,我们需要做以下设置:: I) l2 T4 A5 W3 o 1. 设置数据包过滤寄存器 ETH_MACPFR中相关位设置,使能单播perfect过滤,多播 Hash过滤,不屏蔽广播消息。0 M8 n1 O8 Q5 U$ Q% b/ ~* ^ ![]() 2.将单播地址设置到 ETH_MACA0HR和 ETH_MACA0LR中,并使能该地址。那么所有发往00:80:E1:00:00:00的单播数据包都能被收到,其他的单播数据包将被丢掉。0 J' Z: B' T* { : Y" l/ k: f5 s/ M9 u3 @: u) a/ d* t 3.设置 Hash过滤表寄存器。在初始化以太网外设时,利用 STM32H743的 CRC外设自动计算 MAC地址的 CRC32值,再得到对应的 Hash值,根据该值去初始化ETH_MACHT0R和 ETH_MACHT1R寄存器。H743Nucleo将可以接收发往 01:0c:0d:01:01:03和 01:00: 5e: a8: 00: 0a MAC地址的多播消息,其他的多播消息都被丢掉。6 w. U. S/ E$ r + \; i% f4 C& b; q3 E# L CRC外设初始化代码: ![]() 计算并使能 HashMAC地址过滤的代码:8 f# _% ?, r( x u& Q- b( | ![]() 9 P' N4 ]4 ?) p8 y. { o' { 运行结果将附件的例程烧录到H743Nucleo板,通过 XCAP连续发送下面的 6条消息。 ![]() 两条单播消息,目标MAC地址分别是:00:80:E1:00:00:00和 02:00:00:00:00:00。4 w& _( ?, o; e 三条多播消息,目标 MAC地址分别是:01:0c:0d:01:01:03,01: 00: 5e: a8: 00:0a和 01:0c:0d:01:01:ff。 一条广播消息。" L, e8 e3 x3 ]) }1 h% x 从程序的打印信息里可以看到,H743Nucleo板接收到了其中的 4条消息,MAC地址没有设置的一条单播消息, `$ w i- j* ]) D' H3 u5 N4 N4 w (02:00:00:00:00:00)和一条多播消息(01:0c:0d:01:01:ff)都被过滤掉了。! S7 @/ y( @4 ?) V( u/ O ![]() % F/ h# l% r( ?' r+ ^& Z * x6 y, N' b3 Y |