你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32 F7的MAC层过滤使用+实例代码

[复制链接]
STMCU小助手 发布时间:2021-12-14 10:15
前景描述
$ x  A% V$ n& W+ m4 w- Q我司的以太网实现是LAN8720搭配片上MAC层做的,协议栈用LWIP
$ a6 T2 ?  `" k8 y
1 r8 [: O, ]8 @这种做法应该还是蛮常见的,反正不是LAN8720就是DP83864,再不然就是硬件协议栈的W5500了
7 Z" i" m* D! D' u$ Z# u# A: E; D# U! T% {" f
想想还是有MAC层过滤比较好,随手翻了翻它的手册,W5500好像是没得MAC层过滤的
0 t: I3 v9 A; K. @3 y- [) ?; @# K( W6 ]0 O; n9 i7 Y
假如数据速率比较高,数据量大,而且外面还有乱七八糟无关的数据往板卡送,我也不知道用这个片子到底好不好
, {; t# Y! }; K. I3 d; {  |6 O( A9 `. g1 J+ O4 N7 ]) D
LAN8720也不好改了,就继续用吧
, e( S2 U+ v; C# K, ~3 G5 x5 o9 }+ r& s" L
好好在,发给板卡的数据的MAC还是有特征的,我只需要过滤发送方MAC地址的前3个字节,也就是特定的厂家那段5 Z& l( J+ Z; J2 y$ {: p* |
. B9 _9 e4 X- ?  J8 v# K  j
MAC地址的科普知识这里就不过多描述了,我们直奔主题
, Z7 U$ M# P8 V" X% {. i6 l
; A/ D# O2 m! i) }$ i2 C1 ]" x怎么用STM32 F7的片上MAC做MAC层过滤
' `' K7 p8 g9 A- S7 b
) N" C+ P2 p$ O" |写这个的目的,就是我搜了搜,没看见有人写这个MAC层过滤功能,具体代码怎么写才能用0 p: k+ d' R% N5 I2 t& N0 @

9 k! w  \  |- C  C. S, g知识科普-STM32的片上MAC* _- k" W4 Q/ B$ F9 D
STM32 F7的MAC层过滤方式有三种(说人话的直白解释,中文手册其实也翻译的不好)
) d2 G# i) R+ ^3 q. d. f7 I精确过滤(手册上叫单播目标/源地址过滤)& T6 A1 O# q3 }; i( V) @
粗糙过滤(手册上叫Hash表过滤)' ]( ?* g+ x* ]9 q4 L
特殊过滤(广播,组播过滤等等特殊的过滤)
" k, s- j# n9 f' W6 B我这里着重说第1种和第3种0 S2 C) U; i1 l; r

+ P& W6 {+ y6 Q( V1 V! Y& N& OSTM32 F7可以存4个MAC地址
# J  s/ z& r2 b其中MAC地址0是自己的MAC,其他三个可以用来做过滤: x/ M9 H5 i& ]; H  Z, r

; o" z) _' O/ T+ n4 Z7 t: u网络数据包通过PHY进入STM32的MAC,MAC层是可以对目的地址/源地址检查并过滤掉没得用的数据的,默认的HAL库库函数HAL_ETH_Init中, U, x" E+ Z) ~. A5 @4 J) f
有一个static的函数
& q. ^' i/ _4 g+ gstatic void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err); r" j  H7 v; j" h* o) n& X3 b
会帮你在初始化网络功能时初始化默认的MAC层功能:  y: H; H2 c0 V4 t& M! G  E
关闭源地址过滤
- C2 p9 N) |. m$ R% F0 H不接收所有数据
0 n8 S# ^$ j1 J3 f- i  f/ h/ i接收广播帧6 v  R1 N8 t: ]+ M# _/ N- ]
打开目的地地址过滤1 @8 i, C8 |! ]# c& @
单播数据精确过滤
9 ~: k2 u' U( g9 ]2 l% a7 `: S4 p组播数据精确过滤  D  O2 t4 s, m- A. X% ]
Hash表过滤关闭
) I. C3 [" K9 }
7 z0 k: a+ j/ M其他的功能自行研究,我这里捡重要的说; D+ {0 ]# y& Q/ w+ x  X! P: I5 K! T
  1. static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err)
    ! l) V8 {( k, C
  2. {' V2 c/ w" [* ?; z! e5 B
  3. ETH_MACInitTypeDef macinit;3 `- s: n1 `$ o: h# d+ e6 M5 B; H9 L
  4. ETH_DMAInitTypeDef dmainit;
    0 Z# T2 V: X6 O( K; `( @' e
  5. uint32_t tmpreg = 0;
    0 E4 e% _  ?, R( a9 R

  6. 6 u8 e+ u5 Z4 \6 C. G9 [
  7. if (err != ETH_SUCCESS) /* Auto-negotiation failed */6 Z( C  M6 x0 }9 c# _* Y
  8. {; ^4 d  V% ]7 R
  9. /* Set Ethernet duplex mode to Full-duplex */
    & E9 f! M" _5 c
  10. (heth->Init).DuplexMode = ETH_MODE_FULLDUPLEX;5 m  i$ H) a1 ]! p
  11. ' H' _6 t1 S0 |$ `! Y5 ^
  12. /* Set Ethernet speed to 100M */
    ; I% B5 J9 `% B) K- R2 t. m$ n
  13. (heth->Init).Speed = ETH_SPEED_100M;
      @1 Q; N3 k! [5 p/ Q# _
  14. }7 W# g. |6 P$ J! a8 Z3 Z. X+ ^# d
  15. & h9 s: C8 k% |* g- w' L
  16. /* Ethernet MAC default initialization **************************************/
    9 u" e% W5 O2 H; Y9 w
  17. macinit.Watchdog = ETH_WATCHDOG_ENABLE;3 u, m% c$ x6 C' B1 R
  18. macinit.Jabber = ETH_JABBER_ENABLE;! \/ n+ c4 p4 p- L
  19. macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;5 S* M# [0 v, d: q& o  Z5 P
  20. macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;( v5 h5 I9 b% |  ?9 `3 T# l
  21. macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;
    " ^, S. V' }3 Y5 B8 A6 J+ T, b9 T9 m
  22. macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;* e0 ?1 @* J2 @  q$ G6 J
  23. if(heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)) ]+ i7 R' r! z7 o: C
  24. {
    0 g8 p3 D) V# N) O0 ]
  25. macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;
    & A7 W  y& }1 m! C& f" J- V; D( }
  26. }2 Q. V  w# I" e0 T2 @1 V
  27. else
    # u+ k& n( U6 d" A  M9 l: |
  28. {  J; n+ \! q  j: X
  29. macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;5 C/ c$ S3 f; P* s2 s* Y( d: K' H) M
  30. }
    9 `! u( x" r% [: \, z5 I
  31. //这一段是MAC层过滤的设置,下面是DMA的,那个用默认的就可以
    ) ]  ]/ W% m/ M3 \% Q# u  P
  32. macinit.RetryTransmission = ETH_RETRYTRANSMISSION_DISABLE;: n5 j3 Q) E) p9 _
  33. macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_DISABLE;
    ; \0 h6 ^+ P# Q1 ?9 q5 ~9 a0 M/ E2 W
  34. macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;
    0 [: y0 P3 h( ?+ ^  D$ G) O% N4 X
  35. macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE;
    - S$ U: c! X6 G* k1 c5 a( P2 `
  36. macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE;1 N, W, I4 z2 g& M, w, `
  37. macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_DISABLE;' c3 V/ O, k; M& O, b* ^
  38. macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;3 Q+ Z* S/ z+ I  N- Y4 G
  39. macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_ENABLE;
    3 |9 s# N1 L% G6 f! q1 {2 e- w
  40. macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL;% K( {+ N( _1 J/ M* P9 [% h" G
  41. macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE;
    8 y$ ?1 p! n# _6 i, r% ?# `9 G
  42. macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECT;
    1 E6 G- F: _! S  Z4 R' ?+ D/ h- p5 B
  43. macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT;
    - r! k# Q. a# J. `
  44. macinit.HashTableHigh = 0x0;' s  I) v' u9 C: E! {
  45. macinit.HashTableLow = 0x0;
    4 q' N# E- y* t7 T
  46. macinit.PauseTime = 0x0;
    ; U' ^1 P( n- z0 b
  47. macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;
    & Y" Z8 c8 ^* e- W2 `2 D) Q( o
  48. macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;
    6 V/ x& \. E9 C
  49. macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_DISABLE;% F9 Y/ }/ d$ ]3 s. Q' ~3 ^$ h
  50. macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE;
    $ `0 Z; c( K2 c. D" A* P/ L* I( e
  51. macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE;
    3 B0 }! L$ t% H* Z& r
  52. macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;2 Z" Q8 u( I$ X0 j
  53. macinit.VLANTagIdentifier = 0x0;+ H8 e* i* _( y( g/ p( h

  54. . W) _6 E. y. o' O; D% o  X
  55. /*------------------------ ETHERNET MACCR Configuration --------------------*/; L' t9 ~  ^; i) Z& l! }
  56. /* Get the ETHERNET MACCR value */0 Y. }$ k2 j" m; H* O4 P
  57. tmpreg = (heth->Instance)->MACCR;
    9 e5 A3 F& I! G! k' ?
  58. /* Clear WD, PCE, PS, TE and RE bits */
    7 l5 |3 p' m) s0 I0 B# A
  59. tmpreg &= ETH_MACCR_CLEAR_MASK;2 K% ]; N$ B2 y4 N& z' p& U
  60. /* Set the WD bit according to ETH Watchdog value */
    7 i. Z6 G+ `  j  g* T
  61. /* Set the JD: bit according to ETH Jabber value */
    / g* w6 ~; O7 O- E3 ~; J
  62. /* Set the IFG bit according to ETH InterFrameGap value */
    9 ?$ a+ v+ h0 Y
  63. /* Set the DCRS bit according to ETH CarrierSense value */
    / p" D* Y: }7 U
  64. /* Set the FES bit according to ETH Speed value */
    * ]( k4 i% H: i3 O, W* o: ]* V
  65. /* Set the DO bit according to ETH ReceiveOwn value */' A- o4 t( o1 ?- p' }. Y' q
  66. /* Set the LM bit according to ETH LoopbackMode value */
    : P. L4 j/ {- q# ~2 Q2 e$ J
  67. /* Set the DM bit according to ETH Mode value */. a2 f! z9 e/ [' ^5 s. z  {5 g
  68. /* Set the IPCO bit according to ETH ChecksumOffload value */
    + {4 J6 t+ D' W
  69. /* Set the DR bit according to ETH RetryTransmission value */$ N) o* z3 O  ^- t6 K! @
  70. /* Set the ACS bit according to ETH AutomaticPadCRCStrip value */
    . c3 [8 o. d' ^! f0 n$ n
  71. /* Set the BL bit according to ETH BackOffLimit value */4 P6 E$ ~7 w  A* V3 c& b
  72. /* Set the DC bit according to ETH DeferralCheck value */" ^- P1 `) q8 n# B$ T1 [
  73. tmpreg |= (uint32_t)(macinit.Watchdog |- ^) M7 F( A& u
  74. macinit.Jabber |
    : B4 d0 M4 d1 C3 ]7 r  z
  75. macinit.InterFrameGap |' T$ @  x1 \9 q( j
  76. macinit.CarrierSense |
    : `( w% X" i  W( ]2 X7 k6 ]
  77. (heth->Init).Speed |
    6 G7 M) W  W0 [7 @  e  H
  78. macinit.ReceiveOwn |7 x6 Z1 p6 X2 P) Q
  79. macinit.LoopbackMode |2 ]! m% x; p1 `1 o  |% y
  80. (heth->Init).DuplexMode |
    : E4 H& ~  l2 ~6 m% [
  81. macinit.ChecksumOffload |. K9 W, v' Y3 F2 K! v
  82. macinit.RetryTransmission |
    ; [- S' d. T$ D  [
  83. macinit.AutomaticPadCRCStrip |# ?6 B3 M! p% l1 B$ ^) q
  84. macinit.BackOffLimit |
    / e- @2 \, q& {) I4 ]3 q* w7 a
  85. macinit.DeferralCheck);9 B; M4 |( k" J; V5 U

  86. 1 C; r' K6 C+ w  U" {, [+ [/ \
  87. /* Write to ETHERNET MACCR */
    3 c; Z% }. H5 D) k( E
  88. (heth->Instance)->MACCR = (uint32_t)tmpreg;: g9 n+ q5 A% ?8 ~% ?
  89. ; `5 W+ }6 `9 b" f3 o1 s0 T
  90. /* Wait until the write operation will be taken into account:1 U) V' ]* D" C# H: S" |) T
  91. at least four TX_CLK/RX_CLK clock cycles */0 \) Y# m1 j, s5 ^' a
  92. tmpreg = (heth->Instance)->MACCR;
    3 `7 B% h8 S  `9 l+ Y% x7 D
  93. HAL_Delay(ETH_REG_WRITE_DELAY);
    ( F7 J* ?9 u- l  d5 q) c% z
  94. (heth->Instance)->MACCR = tmpreg;) d0 T2 T# Q/ {4 O+ ^' L- r+ g& o
  95. 4 l1 s; k& R, ^5 I5 P
  96. /*----------------------- ETHERNET MACFFR Configuration --------------------*/
    1 A( p6 O' A* x+ s0 n) v* [
  97. /* Set the RA bit according to ETH ReceiveAll value */6 k. i. A0 s# w" {& F" [( g
  98. /* Set the SAF and SAIF bits according to ETH SourceAddrFilter value */' L6 T  B8 `2 e% b
  99. /* Set the PCF bit according to ETH PassControlFrames value */
    8 f) q# |4 x+ I2 B- M5 U3 G
  100. /* Set the DBF bit according to ETH BroadcastFramesReception value */" m5 C4 r+ g& f
  101. /* Set the DAIF bit according to ETH DestinationAddrFilter value */
    . B% h) e+ o: _5 _" }
  102. /* Set the PR bit according to ETH PromiscuousMode value */
    ; l5 t8 N) w1 O( ^! B" V
  103. /* Set the PM, HMC and HPF bits according to ETH MulticastFramesFilter value */
      p) F& [0 _9 Q
  104. /* Set the HUC and HPF bits according to ETH UnicastFramesFilter value */+ ~( ~# s; @2 h9 ~' s* F3 X  P
  105. /* Write to ETHERNET MACFFR */
    - q& V, P% ~5 u& U/ e+ V7 v
  106. (heth->Instance)->MACFFR = (uint32_t)(macinit.ReceiveAll |
    ; H: Y# b+ o/ y' N. B7 ^  z3 k: u
  107. macinit.SourceAddrFilter |
    " o- l1 u+ U2 ^8 c6 M7 @# K3 K
  108. macinit.PassControlFrames |/ W( U( U, u$ S# a
  109. macinit.BroadcastFramesReception |6 N/ n& e+ S6 a9 t% O8 ^8 ~5 S
  110. macinit.DestinationAddrFilter |6 K6 O: L3 Q4 c5 l) r- h! a
  111. macinit.PromiscuousMode |4 o# R* ^* L" l, b. N$ a+ ?
  112. macinit.MulticastFramesFilter |
    7 M: j, J1 V: D4 ]4 v! l
  113. macinit.UnicastFramesFilter);
    " D/ k3 y& t. E$ m0 M

  114. ) n  c& W; Z, \; @
  115. /* Wait until the write operation will be taken into account:% m" B" k6 p( i  f+ D3 M. g/ J* D2 X
  116. at least four TX_CLK/RX_CLK clock cycles */
    " \* B0 h$ q+ m: i& h5 v
  117. tmpreg = (heth->Instance)->MACFFR;
    # _) }# U$ s* d! E3 ^3 L3 z
  118. HAL_Delay(ETH_REG_WRITE_DELAY);
    7 n- M' Z  r" Q" D$ n
  119. (heth->Instance)->MACFFR = tmpreg;
    ) n, r1 Y+ i: \( x
  120. $ n* h; F# S: _9 K3 y- C
  121. /*--------------- ETHERNET MACHTHR and MACHTLR Configuration --------------*/
    % S9 }3 h$ }% w9 v4 {6 L9 C; ~
  122. /* Write to ETHERNET MACHTHR */
    ' t9 [0 X5 I  B3 d
  123. (heth->Instance)->MACHTHR = (uint32_t)macinit.HashTableHigh;
    0 y% P5 F3 I6 g; x4 t$ M, v2 t5 f
  124. ) F" j) @# p6 J
  125. /* Write to ETHERNET MACHTLR */
    $ Y9 d( a% e; B% Z0 @1 l4 f/ k
  126. (heth->Instance)->MACHTLR = (uint32_t)macinit.HashTableLow;$ A4 g8 ^) q% u
  127. /*----------------------- ETHERNET MACFCR Configuration -------------------*/8 y- h' u8 |* A$ t6 r/ f1 Y1 q  j

  128. ; ?: d; u- X& O; C! I0 i& \1 ?1 ]# B5 C
  129. /* Get the ETHERNET MACFCR value */' t  H5 G' F( g0 \; P; Q
  130. tmpreg = (heth->Instance)->MACFCR;
    : _3 R% T8 z' ^. L9 ^* L& H
  131. /* Clear xx bits */! L2 q8 Q) z: z7 ?9 W
  132. tmpreg &= ETH_MACFCR_CLEAR_MASK;
    9 k+ m6 i5 Q4 A! K) Q
  133. 9 G' ^3 k, Z9 g/ ~' g4 {2 d* @
  134. /* Set the PT bit according to ETH PauseTime value */9 y* h& [3 Q7 A3 C5 L
  135. /* Set the DZPQ bit according to ETH ZeroQuantaPause value */' n( m" m( O2 u
  136. /* Set the PLT bit according to ETH PauseLowThreshold value */
    8 N8 N+ E/ J. G6 `
  137. /* Set the UP bit according to ETH UnicastPauseFrameDetect value */0 B# [, b& ?2 _1 c+ W
  138. /* Set the RFE bit according to ETH ReceiveFlowControl value */
    1 b. b% m. j% y3 a/ H) [! O
  139. /* Set the TFE bit according to ETH TransmitFlowControl value */
    / _& z$ h& _% \7 {6 @6 w
  140. tmpreg |= (uint32_t)((macinit.PauseTime Instance)->MACFCR = (uint32_t)tmpreg;
    7 r. s7 i  l5 t  X/ c, M& s

  141. & M  F( O5 B4 ^' w; s1 V
  142. /* Wait until the write operation will be taken into account:
      [# M, P$ m8 s1 b
  143. at least four TX_CLK/RX_CLK clock cycles */* C% [. U/ S& z) S
  144. tmpreg = (heth->Instance)->MACFCR;
    3 K9 W4 ~. i8 N2 }" i+ U0 ~! h
  145. HAL_Delay(ETH_REG_WRITE_DELAY);; Z/ U8 m8 t5 F2 u! c2 k6 Z! V  \
  146. (heth->Instance)->MACFCR = tmpreg;
    9 s% L' ]3 d1 D5 Z' E, i; G* f. B

  147. / a) a# w) T8 S
  148. /*----------------------- ETHERNET MACVLANTR Configuration ----------------*/
    ( B4 p0 I' k# h0 C, n) R
  149. /* Set the ETV bit according to ETH VLANTagComparison value */
    * x+ v* e7 o6 R& w) y
  150. /* Set the VL bit according to ETH VLANTagIdentifier value */
    # d% J4 \& Y$ j- K0 `! _
  151. (heth->Instance)->MACVLANTR = (uint32_t)(macinit.VLANTagComparison |
    ! x: ^1 {$ s8 m! m! L
  152. macinit.VLANTagIdentifier);4 e" g6 _$ O! v$ x' ]& W4 f4 I
  153. " o) c5 K% D3 L( B* V' m
  154. /* Wait until the write operation will be taken into account:( i; t& f. w& |
  155.    at least four TX_CLK/RX_CLK clock cycles */% c" z% [5 a4 K5 g7 d1 [% l
  156. tmpreg = (heth->Instance)->MACVLANTR;
    1 P! x/ O( d% U; v3 v" ^1 [
  157. HAL_Delay(ETH_REG_WRITE_DELAY);
    $ u" n# |/ p+ K% M9 k
  158. (heth->Instance)->MACVLANTR = tmpreg;: Y1 o3 H7 |. h
  159. 1 W+ G2 h* z, F7 o: v* L! ?
  160. /* Ethernet DMA default initialization ************************************/& J; |4 [9 N% j5 r, {: k. \
  161. dmainit.DropTCPIPChecksumErrorFrame = ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE;
    - r3 Y3 A9 ^* t/ {, C9 `
  162. dmainit.ReceiveStoreForward = ETH_RECEIVESTOREFORWARD_ENABLE;
    # R/ V/ q5 Z2 F  U$ f
  163. dmainit.FlushReceivedFrame = ETH_FLUSHRECEIVEDFRAME_ENABLE;
    6 V% R# {2 q" C9 x) m
  164. dmainit.TransmitStoreForward = ETH_TRANSMITSTOREFORWARD_ENABLE;/ J: ]% ~  P9 \! A2 g) U
  165. dmainit.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES;5 ]# [. B7 j* [, O. {  }
  166. dmainit.ForwardErrorFrames = ETH_FORWARDERRORFRAMES_DISABLE;
    ; M0 U  K  V9 @3 U
  167. dmainit.ForwardUndersizedGoodFrames = ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE;2 @' y0 f; s4 M( \1 P7 E, c
  168. dmainit.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES;
    # ^# Q& Z2 m5 K4 G) m' x7 C
  169. dmainit.SecondFrameOperate = ETH_SECONDFRAMEOPERARTE_ENABLE;
    . H' x: R* s5 G* C1 X+ P9 ]) w; O
  170. dmainit.AddressAlignedBeats = ETH_ADDRESSALIGNEDBEATS_ENABLE;
    0 A3 O+ h- O, o% L8 |% c7 U, k
  171. dmainit.FixedBurst = ETH_FIXEDBURST_ENABLE;
    . ^$ D7 K7 s  c# h: k" S- p
  172. dmainit.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;
      j: _( D  J  [8 U
  173. dmainit.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;0 V9 p' a" j5 P4 W, _
  174. dmainit.EnhancedDescriptorFormat = ETH_DMAENHANCEDDESCRIPTOR_ENABLE;8 v# s$ j+ e# L: h$ L; j
  175. dmainit.DescriptorSkipLength = 0x0;2 O' {3 M8 U0 ~+ z! s
  176. dmainit.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1;. P) S1 y# Y8 C  Z$ ?5 j6 b+ \: C

  177. 7 V+ \+ a1 X7 w3 [. I" m
  178. /* Get the ETHERNET DMAOMR value */* d$ A0 s  J' l2 D! n
  179. tmpreg = (heth->Instance)->DMAOMR;0 i7 R& t  F8 S) O* H
  180. /* Clear xx bits */- O( S( Z, o% Z9 p" L* y6 S
  181. tmpreg &= ETH_DMAOMR_CLEAR_MASK;- t4 n- x. r' G2 U6 w) X8 ]

  182. ; A4 l9 o7 S# y: v6 g. _1 j
  183. /* Set the DT bit according to ETH DropTCPIPChecksumErrorFrame value */' U% c# _! I" l- z3 u
  184. /* Set the RSF bit according to ETH ReceiveStoreForward value */7 h9 N2 \1 x! T4 }
  185. /* Set the DFF bit according to ETH FlushReceivedFrame value */
    8 l; s* Q1 z- N7 Y! Z* j5 G
  186. /* Set the TSF bit according to ETH TransmitStoreForward value */
    # @  B( A' u! y2 R
  187. /* Set the TTC bit according to ETH TransmitThresholdControl value */" T: u. V3 T/ |( a  q
  188. /* Set the FEF bit according to ETH ForwardErrorFrames value */- V+ }1 T2 I2 Q1 [  p
  189. /* Set the FUF bit according to ETH ForwardUndersizedGoodFrames value */1 u& I7 s- t( ^! R4 v7 \
  190. /* Set the RTC bit according to ETH ReceiveThresholdControl value */& ^7 K' `- u- Y& r9 k& d$ p
  191. /* Set the OSF bit according to ETH SecondFrameOperate value */
    6 `1 w; f# r- m1 u& Q
  192. tmpreg |= (uint32_t)(dmainit.DropTCPIPChecksumErrorFrame |2 K( C% {4 ~2 a
  193.                      dmainit.ReceiveStoreForward |
    $ l# j" }& K7 A7 t" h5 R
  194.                      dmainit.FlushReceivedFrame |2 w9 z1 Y# k/ q- ^
  195.                      dmainit.TransmitStoreForward |
    " \) r; o3 Z2 F5 x/ c
  196.                      dmainit.TransmitThresholdControl |
    9 j7 P$ {  E0 Q, E( N9 t1 M& @. w
  197.                      dmainit.ForwardErrorFrames |" E9 t3 \8 w$ J1 h7 Y& j
  198.                      dmainit.ForwardUndersizedGoodFrames |
    ' F6 S, ?6 W" b8 W( J! ?
  199.                      dmainit.ReceiveThresholdControl |
    : H0 e: E' L: ^' G
  200.                      dmainit.SecondFrameOperate);
    : ?" k% h/ O$ {6 ^
  201. / Q1 s1 X; z! n8 T3 C* y
  202. /* Write to ETHERNET DMAOMR */
    . j7 M( @, c" }6 ]2 j7 @* j9 `# v
  203. (heth->Instance)->DMAOMR = (uint32_t)tmpreg;
    9 {+ @/ P+ ]; k/ T4 |) }$ M- p
  204. 3 U: R+ |5 i# T
  205. /* Wait until the write operation will be taken into account:9 y8 b2 n: g' F9 U
  206.    at least four TX_CLK/RX_CLK clock cycles */, F) t8 T6 y9 S3 d
  207. tmpreg = (heth->Instance)->DMAOMR;
    0 T9 ^0 P, W$ e
  208. HAL_Delay(ETH_REG_WRITE_DELAY);
    4 F% e% ?5 C  q: r$ s5 F  F- X
  209. (heth->Instance)->DMAOMR = tmpreg;
    0 G1 S( u% [4 i. ?
  210.   a# \8 l. p! g! D7 d3 o
  211. /*----------------------- ETHERNET DMABMR Configuration ------------------*/3 B3 F: C# q) Q( p
  212. /* Set the AAL bit according to ETH AddressAlignedBeats value */. ~: G( r" R$ l) S2 {
  213. /* Set the FB bit according to ETH FixedBurst value */
    ( {6 x: g( o) A5 J/ Z' x! S
  214. /* Set the RPBL and 4*PBL bits according to ETH RxDMABurstLength value */; m$ W) G% b% E- y2 |. F
  215. /* Set the PBL and 4*PBL bits according to ETH TxDMABurstLength value */# G% E* O! X8 y) G
  216. /* Set the Enhanced DMA descriptors bit according to ETH EnhancedDescriptorFormat value*/7 z( S/ t# o  C% z+ [* T
  217. /* Set the DSL bit according to ETH DesciptorSkipLength value */
    , A( z8 p! s+ a* ?* w
  218. /* Set the PR and DA bits according to ETH DMAArbitration value */+ a' z' v% i6 O2 K; L5 u
  219. (heth->Instance)->DMABMR = (uint32_t)(dmainit.AddressAlignedBeats |
    2 N! _* J! t! j/ _( s; z, {
  220.                                       dmainit.FixedBurst |
    7 i% q% V5 _& h- ?, l0 R
  221.                                       dmainit.RxDMABurstLength |    /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */
    . G/ J! e/ _5 {
  222.                                       dmainit.TxDMABurstLength |
    % @2 |! G# D1 ~3 b) c1 K
  223.                                       dmainit.EnhancedDescriptorFormat |
    ; h7 B) y7 F* B6 D) A1 M: U2 u
  224.                                       (dmainit.DescriptorSkipLength Instance)->DMABMR;  c7 `% Y% Y9 `9 Q+ N2 ]$ [
  225. HAL_Delay(ETH_REG_WRITE_DELAY);7 {( ]' D3 Z0 j) D
  226. (heth->Instance)->DMABMR = tmpreg;
    , K  L$ {7 q7 [3 k0 h
  227. 1 ?8 u5 e9 }5 q3 A
  228. if((heth->Init).RxMode == ETH_RXINTERRUPT_MODE)- i+ e0 F8 }2 c3 j2 }
  229. {  _# Z& w' i* k; E+ N
  230.    /* Enable the Ethernet Rx Interrupt */
    " I$ {; Z% Z* N  W) }
  231.    __HAL_ETH_DMA_ENABLE_IT((heth), ETH_DMA_IT_NIS | ETH_DMA_IT_R);
    % `( a0 v/ u. V, z( m' u
  232. }
    ( e1 i* j3 G2 h

  233. " x6 h5 S' `3 y) n1 a& t
  234. /* Initialize MAC address in ethernet MAC */
    ; \/ D% h& Q+ F4 y
  235. ETH_MACAddressConfig(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);
    / V( k. ]: E" u" v+ K& M
  236. }
复制代码
1 E1 i* O( C$ z1 o; R
这里我就要稍微吐槽一下HAL库了" G; c- z$ D. a$ T6 \6 T" i
MAC层过滤的设置没有预留接口出来,有设置MAC地址的函数8 q$ c9 d6 ^! @9 F+ x# p1 n
8 V9 T+ A! ]* s- }& v- I! A; k
static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr)
" u; Q1 `( j' B, ?5 u0 b* B- g7 ~5 y+ `4 A6 F# w4 H2 t
就不多做一个设置MAC层过滤的函数嘛,连后面用到的宏定义都有~~" r: B* ?# k- _' i% Q

8 f& C# C& P6 r& C5 B& x+ i2 F8 d木有办法,自己编一个初始化MAC层过滤的函数吧
$ ?, a. A5 m3 M  c3 j# `& R7 |& U, T- [! w  T+ A- d3 o
其实也就是把上面这个ETH_MACDMAConfig函数分离成两个单独的设置函数,再编一个设置MAC层过滤的函数( Y+ L0 x, P3 h% {- [
) G7 }1 `7 k8 b+ J. H) W
开启MAC层过滤的初始化代码

" A  ?6 u# j7 M0 W1 D
  1. uint8_t ETH_MAC_Setting(ETH_HandleTypeDef *heth), a/ \& p2 R, q% F, A
  2. {$ Y' e, t8 @, J7 T" x
  3. ETH_MACInitTypeDef macinit;3 Z9 R" x/ l+ n0 ?* w+ \6 H' r
  4. /* Ethernet MAC default initialization **************************************/
    / n2 s4 L! V" Z
  5. macinit.Watchdog = ETH_WATCHDOG_ENABLE;! t% g$ q6 `+ F
  6. macinit.Jabber = ETH_JABBER_ENABLE;
    $ \( @% }1 \, t& i3 [* e$ l0 i
  7. macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;& a. t7 q) n& ]  W) S8 F+ k% M
  8. macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;
    , n$ N0 |: @& T* f
  9. macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;
    - g6 A- x+ e- Y" A& g8 \/ A
  10. macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;
    1 [  c8 W* I% |  N4 F/ q8 b5 V
  11. if (heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)6 T5 U* R( m8 q. P
  12. {$ }" L: \# R9 l. a& y  h
  13. macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;
    1 g# z1 n. [- \( X9 A5 w/ L$ \6 |" s
  14. }5 |, R# D) |2 W. O; r# {4 w
  15. else" |! |4 s$ ~9 J
  16. {
    2 v& ^2 L- W. _* F- w9 ]
  17. macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;
    1 N& y5 Z2 }) J; t+ V) a/ f$ V
  18. }
    0 X2 X0 p' e( [0 J( I& @8 j; l
  19. macinit.RetryTransmission = ETH_RETRYTRANSMISSION_ENABLE;          //使能重传! t" r7 v  R% r+ Q$ `9 R1 ?# b
  20. macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_ENABLE;          //使能自动去除
    $ u* n& B+ z7 r
  21. macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;
    3 L4 p- H) d1 \5 Y4 j* W! o
  22. macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE;
    3 `3 }% X' [; i. |$ M
  23. macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE; ///不接收所有包, K7 O2 \& ~1 X  ]: K
  24. macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_NORMAL_ENABLE; //源地址过滤
    4 q# F' ]* t1 U8 ~9 ]0 w
  25. macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;
    ) R3 n2 V1 ?! D3 G! [6 K
  26. macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_DISABLE; //广播不接收
    ; G4 S. C/ ^3 R5 j
  27. macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL; //目的地址过滤5 {2 e) ?, |# m) ^; s% i+ k
  28. macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE; //混乱模式& G2 |9 `. I' Q
  29. macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECT; //多播过滤- [, ]7 N* c4 ^( a2 ]. X
  30. macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT; //单播过滤$ ~" i, A0 I, ]
  31. macinit.HashTableHigh = 0x0; //Hash表高位
    * \5 ?4 K8 y1 g2 C  T' z
  32. macinit.HashTableLow = 0x0; //Hash表低位
    , O+ r# Y! v$ I8 l6 j
  33. macinit.PauseTime = 0x0;
    6 I9 e9 x( G* P' h
  34. macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;
    . F0 L0 }/ ?3 s2 e1 T
  35. macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;, x1 u- Q1 W' t+ z+ G
  36. macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_ENABLE;' M8 e$ u! _4 E6 S; ], _1 s
  37. macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE; //接收流控
    ' |# q& i% e  f, h. H" J
  38. macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE; //发送流控% F8 y$ {3 Z  F5 S/ M1 m+ m- P
  39. macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;, A  U: r- V3 |
  40. macinit.VLANTagIdentifier = 0x0;
    ) V3 h3 S; o4 z7 R. y
  41. " R" |# i6 W7 f: b
  42. return HAL_ETH_ConfigMAC(heth, &macinit);$ g: ?/ e0 |" O- U- Z
  43. }
复制代码
; w- ~4 Y2 C$ I7 r8 d; g4 o( G
默认的MAC层 DMA初始化函数
; Q" p; ?9 _$ N: j+ A1 k  w
  1. uint8_t ETH_DMA_Setting(ETH_HandleTypeDef *heth)& J) i& a3 T" M+ [
  2. {0 W4 L! g8 [+ r2 s9 _
  3. ETH_DMAInitTypeDef dmainit;
    " K" b5 {* E/ l! N1 @0 L
  4. /* Ethernet DMA default initialization ************************************/& k) T6 B' Z: d6 J- r) K: ?
  5. dmainit.DropTCPIPChecksumErrorFrame = ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE;
    6 U/ T7 `5 Q. F0 R$ M
  6. dmainit.ReceiveStoreForward = ETH_RECEIVESTOREFORWARD_ENABLE;, Z  P; A+ }/ I8 D
  7. dmainit.FlushReceivedFrame = ETH_FLUSHRECEIVEDFRAME_ENABLE;: I' Q7 _# Q3 }3 A6 O
  8. dmainit.TransmitStoreForward = ETH_TRANSMITSTOREFORWARD_ENABLE;2 h. o" B7 p( J
  9. dmainit.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES;
    ; D5 C  b5 v" L. B
  10. dmainit.ForwardErrorFrames = ETH_FORWARDERRORFRAMES_DISABLE;
    9 |  t  b$ r0 q" j
  11. dmainit.ForwardUndersizedGoodFrames = ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE;
    6 \; p: l1 S: ]; A' |
  12. dmainit.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES;+ p* q& W, N# C; \6 Z5 e- ?0 t
  13. dmainit.SecondFrameOperate = ETH_SECONDFRAMEOPERARTE_ENABLE;7 }5 ?: |' @" j8 ?0 Q
  14. dmainit.AddressAlignedBeats = ETH_ADDRESSALIGNEDBEATS_ENABLE;
    ( C" O" o. \. ?
  15. dmainit.FixedBurst = ETH_FIXEDBURST_ENABLE;9 r9 v3 E( [5 ^9 ]6 S0 Y0 U- S, N
  16. dmainit.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;
    6 g% y5 P' H* H
  17. dmainit.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;
    ' R! W, s" J, }
  18. dmainit.EnhancedDescriptorFormat = ETH_DMAENHANCEDDESCRIPTOR_ENABLE;
    7 w7 z. P) V8 @
  19. dmainit.DescriptorSkipLength = 0x0;
    & F# S; F: E+ m6 S9 E+ ]
  20. dmainit.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1;2 o. g8 `* n2 q5 f* r% ?( {
  21. uint8_t res =  HAL_ETH_ConfigDMA(heth, &dmainit);
    ! B: n% W" v! n0 m* o
  22. if ((heth->Init).RxMode == ETH_RXINTERRUPT_MODE)
    / m- R' f. e) A) V
  23. {
    7 ]7 C1 H4 Z" ]3 ?
  24. /* Enable the Ethernet Rx Interrupt */: n7 m7 H' M9 n! N. ?
  25. __HAL_ETH_DMA_ENABLE_IT((heth), ETH_DMA_IT_NIS | ETH_DMA_IT_R);6 E+ O  B$ p  Y% p2 l
  26. }
    % V" O: A. w) A, B  |4 v
  27. return res;. Z: r$ J4 \& ?) @- m
  28. }
复制代码
/ I8 ^; z4 F1 b- k: {. K
用来设置MAC地址的函数(其实就是把库函数的static函数取出来直接用了)
  1. <blockquote>//heth: HAL句柄
复制代码
& g0 c# ]  m& t  q
然后到最最重要的MAC层过滤设置
4 ]" O6 R: r6 w7 k* [3 y
以MAC1为例
: q0 L+ E$ U" U- `& t4 I. |/ a0 w

* E+ m( P$ K6 Z' `; D/ J
20191124093921254.png

, R& K: g) V- R3 G
/ _8 l6 L# G" j- K( T- f, l  \: e# G$ d
20191124094439199.png
5 u6 e$ K& T$ P; c; n

- K" j; C5 f- M" p3 |" K+ j2 f" u注意看红框的描述

1 p- M" ?% U1 d; H$ u功能很好用,可以过滤源地址/目的地址,还可以做掩码功能
2 K) Y1 o4 [" a  E2 {设置MAC层过滤的代码
- x/ X; [: o$ d3 M
  1. static void ETH_MAC_Filter_Setting(ETH_HandleTypeDef *heth,ST_ETH_PAR * para): @0 m6 H/ I4 }4 {/ Z/ B' G: n3 W
  2. {. n+ ]  g: C7 L; \% x
  3.     //设置本机MAC地址
    ' s- X& Y& I/ g4 M% S
  4.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);
    ( z$ }( \) p( w* i# A# L2 |: g, h
  5.     //设置UDP-A的对方MAC地址1 N. ^9 V6 B$ f5 F% t; f
  6.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS1,para->UDP_A_MAC);
    ) L! S: T% A- o! R% B. i, R' ~2 ]8 @
  7.     (heth->Instance)->MACA1HR|=0xC0000000;//需要完全匹配UDP-A的对方MAC才接收
    ' c4 s" c9 @# P7 A
  8.     //设置UDP-B的对方MAC地址
    # L- c6 h" W8 A, {3 ^3 x4 i
  9.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS2,para->UDP_B_MAC);* o8 D8 e, C2 p% h4 E) Q
  10.     (heth->Instance)->MACA2HR|=0xC0000000;//需要完全匹配UDP-A的对方MAC才接收
    $ E; s9 G' e5 u' b$ N4 t
  11. }
复制代码

) o, n1 O! E; b' q我这里是希望为我的两个UDP精确过滤接收到的源地址, x# X* o/ a7 Q' r
所以AE位设置为1,SA设置为1,MBC全部为0(MAC地址全部检查)
" k8 A2 Y6 K* n$ }2 e! v5 c/ E* l; |# E& _# ]+ k6 b7 R8 R
假如我希望过滤MAC中特定的厂家字段- ]; p- t3 P8 v, G3 n
例如某个MAC地址
/ ^6 B7 e5 i' G& z' G
01-02-03-04-05-06
; Z1 {, J( j% r( I2 k/ `8 |& z. ]其中01-02-03就是厂家字段
5 j' ~! c, `# m  Z8 S( z$ S
4 k( _1 H1 r: U, |  a4 H& S. ]那么代码要这样修改(MBC的第29位,28位,27位置1)
  @  ^; T! N2 \" O7 I) z这样MAC层就不会检查MAC地址里后3个字节(04-05-06)
; \3 R7 ^  c; V& R; Z$ @但是会检查前3个字节,也就是厂家字段3 P' f; E0 C+ V/ x, ~! f
这里需要注意MAC地址的字节序
$ t$ ^& d+ O$ S( T" a, N
  1. static void ETH_MAC_Filter_Setting(ETH_HandleTypeDef *heth,ST_ETH_PAR * para)" O+ ^( x. u& A; ?1 H
  2. {8 y: f3 l& P, S+ E9 k  E4 t
  3.     //设置本机MAC地址
    9 V% [6 b% k, c. b0 B) M
  4.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);2 s7 q# ?' [* z
  5.     //设置UDP-A的对方MAC地址( v8 r# C3 @5 I1 k% W9 U% t
  6.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS1,para->UDP_A_MAC);
    $ v0 }: r% W1 I" q- R3 X
  7.     (heth->Instance)->MACA1HR|=0xF8000000;//需要匹配厂家字段
    7 k$ n' F" D5 F. }: {
  8.     //设置UDP-B的对方MAC地址
    0 D5 U1 O0 A0 b! c+ r% _0 R: K
  9.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS2,para->UDP_B_MAC);# w3 I3 M" w6 v  F
  10.     (heth->Instance)->MACA2HR|=0xF8000000;//需要匹配厂家字段/ h# x& B) n( U
  11. }
复制代码

* u- H+ L% U! l( s$ M) |; [然后这些函数的调用顺序按:7 P+ `! a9 T: s8 Z7 X
1. HAL_ETH_Init0 J) {& z  u% \/ J- T
2. ETH_MAC_Setting  q) j2 f, t& s; U& l3 y2 y
3. ETH_DMA_Setting
" g3 d+ v9 S' Z5 e# q3 y4. ETH_MAC_Filter_Setting0 K* U, J  {2 E' K3 e
2 @+ l9 l/ q( Y: o4 V/ R
用你希望过滤的MAC传递到一个Hash计算函数里,得到一个值,通过这个值产生“映射”关系来过滤MAC地址,所以这个并不是精确的,因为可能会重复~~  c% S6 Y/ D" O3 Q

* w3 Q5 Z; K) E; R
HASH函数
2 F7 g. u1 b. ^, `: z函数  M2 q( U9 Z* c" }. |6 U
  1. / STM32 MACHASH - Copyright (C) 2014-2018 Clive Turvey (<a href="mailto:sourcer32@gmail.com">sourcer32@gmail.com</a>)
      z& P% f5 r4 g- z! w: T
  2. //  All Rights Reserved
    ) [8 d0 W( ]$ n2 p& M( Z0 k( a8 f7 h

  3. * |. x3 x! ~! T8 j
  4. #include <windows.h>$ {/ Z: I: a8 j: r
  5. ( h. m; y$ g6 p3 H7 j
  6. #include <stdio.h>6 A5 x" Z" J4 B3 {& b% `) ^
  7. #include <stdlib.h>  Y7 x8 ^4 F( ?. q: Q5 Y
  8. / c1 u9 n. h% {+ \
  9. typedef unsigned char uint8_t;
    & {5 S5 A# ~* Z- |4 w
  10. typedef unsigned long uint32_t;! X0 m3 B- s4 H7 c; R$ X+ C

  11. ( m6 v: i" ?# y/ R
  12. uint32_t Rev32(uint32_t x)
    ) L3 o( Y! @7 W1 p
  13. {" }* e! a  ~: e% R: p; l: V
  14.   uint32_t y;+ v( }4 ^4 n/ r1 y' z/ E/ C( `
  15.   int i;
    ! M% L8 i# R9 v- B

  16. 7 \& ~5 Q. K; W2 L( {/ A$ [
  17.   y = 0;
    3 C% M0 B" b' a; y( E

  18. & J7 G( e2 ~# g
  19.   for(i=0; i<32; i++)
    + y: z  a* Q6 k+ W: Y
  20.     if (x & (1 << i))7 X# z9 s, B6 V7 Z  {" L
  21.       y |= 1 << (31 - i);2 r/ O% R9 S* [' x

  22. ; N* V! l; O& \. {
  23.   return(y);
    ( C! ^1 M( u$ {/ D# _% {1 P  S
  24. }0 R  s% u2 d% w  g2 P

  25. ( a9 X# Y- G/ K) Q/ ]& ~& D
  26. uint32_t MacHash(const uint8_t *Mac) // <a href="mailto:sourcer32@gmail.com">sourcer32@gmail.com</a>
    5 B. d+ A0 J" x' O( ^/ r$ ?3 ~
  27. {; f$ x1 ]" g& G5 b
  28.   int i, j;
    8 C. k, l& v3 a! c
  29.   uint32_t Crc;5 g  B( Q9 r2 F  P; r
  30. ( ?9 p' q: j% w6 S' I' u
  31.   Crc = 0xFFFFFFFF;6 ~6 S! k/ q6 F' I

  32. 4 s. j: O( ^1 l+ r: z% U
  33.   for(j=0; j<6; j++)
    ( {9 ?% }# `: @9 B" x: B: B6 ^/ b6 b
  34.   {
    ; s' t" u% h- [+ j
  35.     Crc = Crc ^ (uint32_t)Mac[j];
    - |( l/ f( S2 `( d- N: A

  36.   i2 U( f% W8 W' k
  37.     for(i=0; i<8; i++)& w: ~+ x  M" o3 b
  38.       if (Crc & 1)3 e4 G% L* i# ?; U% g- Q
  39.         Crc = (Crc >> 1) ^ 0xEDB88320; // Reversed 0x04C11DB7% g( d/ @3 Y. z* e; l: C% d
  40.       else
    + v) m( X1 k3 Q
  41.         Crc = (Crc >> 1);
    : [2 [, ?" ?- _  n1 K: U+ e! f# m6 t; e
  42.   }
    2 j- P7 |. ]. K+ @! j/ n

  43. $ B: w: u4 v( h4 e
  44.   return(Rev32(~Crc) >> 26); // Get High order 6-bit in reversed/inverted CRC( A1 o8 N7 s% {! I, E
  45. }) @& s1 Q$ V( Y. G3 z2 \% ~
  46. 4 A; l; h5 r4 g$ L# V
  47. uint32_t MacHashFast(const uint8_t *Mac) // <a href="mailto:sourcer32@gmail.com">sourcer32@gmail.com</a>% h6 r+ l+ a3 a9 _5 P
  48. {2 w5 T: S/ s' e3 t! P, E* c! C
  49.   static const uint32_t Rev6Tbl[] = {
    ( h/ w6 n) u6 Y! N7 V0 R' ^( O; F
  50.     0x00,0x20,0x10,0x30,0x08,0x28,0x18,0x38,
    # [: y2 {( f& `: H4 N$ L; A
  51.     0x04,0x24,0x14,0x34,0x0C,0x2C,0x1C,0x3C,
    8 K1 T  O  h' C) P
  52.     0x02,0x22,0x12,0x32,0x0A,0x2A,0x1A,0x3A,& P/ i/ K* G5 g/ A
  53.     0x06,0x26,0x16,0x36,0x0E,0x2E,0x1E,0x3E,
    ( ?* q+ ]2 G) b8 O% H
  54.     0x01,0x21,0x11,0x31,0x09,0x29,0x19,0x39,0 y0 @) }# i$ R3 w- r. a
  55.     0x05,0x25,0x15,0x35,0x0D,0x2D,0x1D,0x3D,
    / h$ n" h3 N7 ?6 Z) ?5 e9 X, N
  56.     0x03,0x23,0x13,0x33,0x0B,0x2B,0x1B,0x3B,
    $ Q; z; v( D" k! M1 s
  57.     0x07,0x27,0x17,0x37,0x0F,0x2F,0x1F,0x3F };6 b; T: E6 `1 T2 O. C5 {3 Q

  58. , y* ?/ X% G) t# s, f2 q8 s4 T! W
  59.   static const uint32_t Crc32Tbl[] = {0 w! S8 M" N* o
  60.     0x4DBDF21C, 0x500AE278, 0x76D3D2D4, 0x6B64C2B0,
    % W8 a+ ?( j. m; q* Z+ K7 k
  61.     0x3B61B38C, 0x26D6A3E8, 0x000F9344, 0x1DB88320,5 ^- q9 m* a+ Y# E
  62.     0xA005713C, 0xBDB26158, 0x9B6B51F4, 0x86DC4190,
    ( h1 j: K+ e7 ~& c3 M+ p% b
  63.     0xD6D930AC, 0xCB6E20C8, 0xEDB71064, 0xF0000000 };
    ! @% h8 r" A3 f0 N) C( E

  64. / I4 v( H3 W% x8 o+ s' \
  65.   int i;
    ; X+ r3 O' ]7 x4 D  S
  66.   uint32_t Crc;
    $ h7 y: X' X5 z; J" C* {

  67. / q" P( l8 a2 L: \# m0 P: F
  68.   Crc = 0;
    : U& @) X& Z, y: I! {
  69. + Y- U* h  ~/ b
  70.   for(i=0; i<6; i++)
    9 G3 `8 M8 h* N2 u& U8 d0 e) |
  71.   {2 F0 k6 k& e* V
  72.     Crc = Crc ^ (uint32_t)Mac<i>;
    2 c$ ?: W% `9 Z) M
  73. ; C' u3 }8 A+ Y+ ]/ j
  74. </i>   Crc = (Crc >> 4) ^ Crc32Tbl[Crc & 0x0F];  /* lower nibble */
    " i  Q! [6 E& Q' u" g
  75.     Crc = (Crc >> 4) ^ Crc32Tbl[Crc & 0x0F];  /* upper nibble */
    5 l7 C$ ]/ D6 L5 r
  76.   }
    & f" L( _! y$ j1 p; b- f
  77. % o- x; u- Q6 g
  78.   return(Rev6Tbl[Crc & 0x3F]);
    1 s& b0 l: `8 b" H, @
  79. }
    9 T7 f/ q# F+ m- j$ ]

  80. 9 c8 R& Z) g3 k% e4 p. D! s
  81. int main(int argc, char **argv)" y: x( \; E* n  o6 W- z* U
  82. {/ }' f, ^5 k) f9 U/ t  O& X
  83.   static const uint8_t Test1[] = { 0x1F, 0x52, 0x41, 0x9C, 0xB6, 0xAF }; // 0x2C
    ; g4 ~& N: J' I+ l9 [9 M4 U6 }
  84.   static const uint8_t Test2[] = { 0xA0, 0x0A, 0x98, 0x00, 0x00, 0x45 }; // 0x07
    ; A/ p! e6 g" A7 b+ R1 y
  85.   static const uint8_t Test3[] = { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x21 }; // 0x24
    " W+ o6 @& U0 l: v# @
  86. 8 D8 M$ I" o  c6 `6 h
  87.   printf("MacHash %02X\n", MacHash(Test1));
    $ X# m# d8 x& _& }0 [- A
  88.   printf("MacHash %02X\n", MacHash(Test2));
    $ [; i6 O9 \" k( O( x
  89.   printf("MacHash %02X\n", MacHash(Test3));, V& a9 E2 o- W3 c5 B8 L; f1 o+ _
  90. / d2 L2 ]. a. |1 ^$ S
  91.   printf("MacHashFast %02X\n", MacHashFast(Test1));
    - D7 s/ S; P! F0 t& C
  92.   printf("MacHashFast %02X\n", MacHashFast(Test2));
    ! Y* ?) L& z- a7 v, M
  93.   printf("MacHashFast %02X\n", MacHashFast(Test3));/ I  H* N( k4 W1 b6 A/ C: d

  94. # ^. _# R8 P5 `% K! a
  95.   return(1);
    4 Q* b! }, \$ s, q2 J
  96. }
复制代码

8 \2 K, h: ]$ b1 y% M0 O7 k( ]/ f0 D- W2 m- ], t" o
回到手册$ X+ p6 I1 {0 Q& z/ x- z" [1 P

! s9 x% o/ h5 D! }
20191124100604140.png
8 X$ E& ]+ T& g* i

6 K7 i: `+ |% F- S: A8 o# Z
20191124100636882.png

1 l% h+ C  w" y
; K/ w/ [! y% P. {) |# V: z. W5 D9 |
上面的函数算出来一个数,假如是手册上的那个0x2c,二进制为101100B
7 z- C* s; r* Z5 k/ G3 t换句看得懂的人话···就是:2 j- G7 M  q) G% |) z2 }' ?+ W0 p, x
算出来的数先看第6位+ S3 z/ G# t. Y1 |0 j
是1的话说明用到的是HASH表高位寄存器
3 y, {1 n2 ]- W0 |: k& [" g( a6 X否则用到的是HASH表低位寄存器3 F" q' u& {& }% U
然后剩下的5位,转成十进制不是12嘛1 v5 K" J9 [( n9 }
如果你希望过滤这个MAC
# g! J' O: O8 {1 \% a3 Z  J9 \那么你就把对应的HASH表高/低位寄存器的对应位置1,否则置08 m8 ~( i3 I* B3 [  U. ]
这里的0x2c就是要把
4 t7 R7 B( y" r; P$ C/ j0 L4 CHASH表高位寄存器的第12位置1# f$ N$ H. P' z" r
就可以过滤这条MAC了9 M6 t7 \0 l5 B/ h. j' h- n
然后把你希望的MAC地址都按照上面说的方法弄完
' {. \) U6 [: e, M4 U- a3 J  s* l" @$ a( C; i; W) E$ _# V
回到这个函数稍微改一下; l8 O5 \& n3 i# k6 m* f- c% c
  1. uint8_t ETH_MAC_Setting(ETH_HandleTypeDef *heth)1 p' W4 }* m! s4 r& _
  2. {
    ( C) A, T, U! d3 K$ N
  3.     ETH_MACInitTypeDef macinit;
    * b( B& H$ O  c
  4.     /* Ethernet MAC default initialization **************************************/
    $ e5 t5 N) L! Q3 L
  5.     macinit.Watchdog = ETH_WATCHDOG_ENABLE;( l: x( r( Y5 J: D) t0 P. U
  6.     macinit.Jabber = ETH_JABBER_ENABLE;8 M) {1 m- O1 S
  7.     macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;/ x. b3 C- k0 h1 K1 d
  8.     macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;  c- R4 X) ~2 |9 \' X9 U! |
  9.     macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;
    , U8 F# Y# T$ f
  10.     macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;* ^' {2 V8 i9 C& F+ K# i- {
  11.     if (heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE), V( F3 H- @$ o% l3 U! q
  12.     {
    : M! h. k; h" ~6 t2 }; h% y3 d
  13.         macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;2 d6 Q4 L+ k0 ~3 m$ ]' ~8 a
  14.     }
    4 K! D2 @6 n7 `. r/ @: t4 K
  15.     else/ k1 r: y6 H! N# A+ V# c% m. G8 {! v
  16.     {
    , T9 Z: D/ b6 }+ y7 H
  17.         macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;9 [" K2 @# F& @
  18.     }
    ( [7 G0 d6 V7 A% F+ U/ b. O
  19.     macinit.RetryTransmission = ETH_RETRYTRANSMISSION_ENABLE;          //使能重传
    4 _: M( F6 ^; I: A% H3 S- h
  20.     macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_ENABLE;          //使能自动去除% U3 c0 B2 t) N: h' M$ X
  21.     macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;: @  H$ ^; v8 `+ b
  22.     macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE;
    ) X/ H. a: o. `
  23.     macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE; ///不接收所有包" s8 h' P4 P3 H
  24.     macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_NORMAL_ENABLE; //源地址过滤
    . s" O6 N8 Q6 R6 ]+ k7 S
  25.     macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;
    4 x  _: B3 [! [1 O: h* f3 ~
  26.     macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_DISABLE; //广播不接收
    " n2 Q* O! G( `2 a3 g6 O
  27.     macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL; //目的地址过滤
    " [) w6 ^3 @# C! A+ J$ g: ]& T; _; l
  28.     macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE; //混乱模式2 j$ E  p* F: }& H5 h
  29.     macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECTHASHTABLE; //!!多播HASH完美过滤3 |& q) z, B! ]1 H5 W
  30.     macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECTHASHTABLE; //!!单播HASH完美过滤5 U- T  q3 z# Z9 e) i
  31.     macinit.HashTableHigh = 0x0; //!!填你最后算完的Hash表高位1 Y# `7 A  Z5 v. g8 d2 t% U
  32.     macinit.HashTableLow = 0x0; //!!填你最后算完的Hash表低位9 v3 v' z2 g) D% H* B
  33.     macinit.PauseTime = 0x0;! `, R  T* a) y2 s2 ~7 I( x
  34.     macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;; }7 k  _6 p4 h
  35.     macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;. x) y) Z" z$ f1 w) W
  36.     macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_ENABLE;
    1 t) g8 r2 a1 C, K: q3 x
  37.     macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE; //接收流控* a! E7 C) {& g4 n. _* z
  38.     macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE; //发送流控
    1 \) j9 S1 S' y5 m' H& h7 Y# |  R
  39.     macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;
    6 r9 Z5 v3 `2 x  Y
  40.     macinit.VLANTagIdentifier = 0x0;2 W6 Q1 J- E( V& \# w, I! J
  41. 9 ^! v1 U6 ?3 K. ^! r+ @" A" s" I
  42.     return HAL_ETH_ConfigMAC(heth, &macinit);9 _1 c2 D" _1 d$ y, d
  43. }
复制代码
3 g. z! |5 h9 J( ?; {
大概MAC层过滤就这些东西了; d5 F, j9 Q" S0 Q3 p0 I3 _! p
如果有条件弄MAC层过滤真的强烈建议开启,可以大幅减轻协议栈的处理负担,板卡不会因为处理大量无用的数据而白白浪费处理性能。/ v" I0 S& K+ }6 S4 d! K
- H" Z6 ?- ~9 c* |& l- g  O) l

2 o6 q) ?  B: l" m6 o
& V% D/ R0 a1 q; w$ f
, ^2 p$ E' j. I7 @4 K
赞 收藏 评论0 发布时间:2021-12-14 10:15

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版