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

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

[复制链接]
STMCU小助手 发布时间:2021-12-14 10:15
前景描述8 w* K; U  {" M( a; X" }
我司的以太网实现是LAN8720搭配片上MAC层做的,协议栈用LWIP
4 Y& c& y2 Z8 j& g( U4 I! M- V: y0 C# |3 N& s" ?( K
这种做法应该还是蛮常见的,反正不是LAN8720就是DP83864,再不然就是硬件协议栈的W5500了
5 b9 x2 J* M! F. }2 \1 E3 s: m. f. o: n8 s; o  f. Q
想想还是有MAC层过滤比较好,随手翻了翻它的手册,W5500好像是没得MAC层过滤的
$ h" c" l: _/ e2 J$ \  ~7 w! A: X; J# J
假如数据速率比较高,数据量大,而且外面还有乱七八糟无关的数据往板卡送,我也不知道用这个片子到底好不好: T; _& }9 K9 z/ m$ T9 E8 J

# m1 w/ [- ^3 lLAN8720也不好改了,就继续用吧; [  m( s% h9 l$ ^
1 a: t1 N+ Q9 c8 }3 j
好好在,发给板卡的数据的MAC还是有特征的,我只需要过滤发送方MAC地址的前3个字节,也就是特定的厂家那段% o/ P9 c2 h& h; D& W$ r9 R0 X

. ^4 \/ H3 T) B; B7 wMAC地址的科普知识这里就不过多描述了,我们直奔主题$ K) `1 P/ V  w" l

% H7 v) \9 Y% h8 ^9 t( ]怎么用STM32 F7的片上MAC做MAC层过滤: G$ L& {. f2 f* R3 S/ f! z
: g! ]2 |$ ^0 S- x/ ?* w
写这个的目的,就是我搜了搜,没看见有人写这个MAC层过滤功能,具体代码怎么写才能用
1 @! Y7 D& ^  E$ X* s4 B
- @) |" v) `5 L3 B+ x. q" g知识科普-STM32的片上MAC
4 A. t; E. s' CSTM32 F7的MAC层过滤方式有三种(说人话的直白解释,中文手册其实也翻译的不好)
/ ]& b# G3 P1 C0 j精确过滤(手册上叫单播目标/源地址过滤)3 }' O* _/ I$ v3 M, {6 h
粗糙过滤(手册上叫Hash表过滤)7 t+ C  V. E4 Y
特殊过滤(广播,组播过滤等等特殊的过滤)3 c1 T& b7 w# _( c
我这里着重说第1种和第3种
" b. ?" A2 ]) ^( M* H# l+ C- h# b
STM32 F7可以存4个MAC地址
, k, c( q' j7 i: J. ^: y9 i其中MAC地址0是自己的MAC,其他三个可以用来做过滤, P, I4 g. L( e
( Y8 X9 [; L6 [. x) X
网络数据包通过PHY进入STM32的MAC,MAC层是可以对目的地址/源地址检查并过滤掉没得用的数据的,默认的HAL库库函数HAL_ETH_Init中' i4 H1 P4 x+ A$ h1 Y
有一个static的函数
/ k' F% h7 a  l( u. O4 ]! ^static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err)
9 ]+ r5 e- A& |2 y: [会帮你在初始化网络功能时初始化默认的MAC层功能:6 f7 s( g! c' K; k
关闭源地址过滤, U% W3 d# J4 H* n2 Z
不接收所有数据! O9 v# \3 C4 `& `2 L8 D9 R. P
接收广播帧& m9 @4 o: u. |% L* U  e$ ?
打开目的地地址过滤
! ^. \+ d* ?& L4 e单播数据精确过滤( c1 a: l9 g2 I. C
组播数据精确过滤
8 ^+ @' E- b$ j$ \1 C6 m3 {Hash表过滤关闭
' }! }2 {* P! f4 |* V1 J
2 D, f* H/ r4 k: h" X- |% l其他的功能自行研究,我这里捡重要的说
3 {7 K5 }4 [3 X  J
  1. static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err)/ I3 O8 n; ]3 }& u  A: c: A' ]
  2. {6 A- U5 V7 Z: d' t, z8 \% S
  3. ETH_MACInitTypeDef macinit;' q7 ]9 E  Z" X, S0 a5 o  y
  4. ETH_DMAInitTypeDef dmainit;
    " q4 z9 M6 m  T1 ~
  5. uint32_t tmpreg = 0;
    % m5 k: L$ m4 k1 N% ^

  6. 6 y1 p. ?+ I* q" i
  7. if (err != ETH_SUCCESS) /* Auto-negotiation failed */
    ! B) U0 ^4 T- B
  8. {- v" J6 T/ H6 [9 ^- x# l5 i- H
  9. /* Set Ethernet duplex mode to Full-duplex */, j& u' R  L: R& G4 R4 A0 O
  10. (heth->Init).DuplexMode = ETH_MODE_FULLDUPLEX;! k6 Q2 X3 b4 |! K
  11. ; H. w) K4 N& V! l1 L
  12. /* Set Ethernet speed to 100M */
    $ N: b# ^6 T  a1 D. `# p' _2 \
  13. (heth->Init).Speed = ETH_SPEED_100M;& ^! K, r2 f" E
  14. }9 R8 Q; L" m" p/ O- Y3 f) x+ W
  15. : ?& u! x9 A; n4 M; x4 v
  16. /* Ethernet MAC default initialization **************************************/, ?* ]' L  o0 _- @
  17. macinit.Watchdog = ETH_WATCHDOG_ENABLE;( b8 K/ k# x, l" `" ^- L$ v
  18. macinit.Jabber = ETH_JABBER_ENABLE;
    . D. a$ E. z; G. c( X  g( g
  19. macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;/ U9 S( k% Z( U$ w4 m
  20. macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;
    1 U  V7 ?3 N: Y/ q% \* t1 c8 r5 z
  21. macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;& J, P: ]$ B+ s6 ]
  22. macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;
    % o" o2 n; }# E" r( _+ y( G
  23. if(heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)8 Z: U& h$ e2 H2 V& ~
  24. {1 k2 e; A" K& w  F! h6 \
  25. macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;2 ~7 k3 `2 L* z) g2 P
  26. }
    * x; n- a/ R% Z+ R8 J* M: C& W* r( v, l
  27. else( M; g% w: }  J! Z  v
  28. {
    , B, T8 Y. ]* F# {
  29. macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;
    $ C! t; K$ W" n, ?
  30. }
    & g4 `3 H/ c/ T
  31. //这一段是MAC层过滤的设置,下面是DMA的,那个用默认的就可以
    1 D: ]3 P  v3 O' I9 `) x3 E  e
  32. macinit.RetryTransmission = ETH_RETRYTRANSMISSION_DISABLE;
    0 o1 ?  Q1 f, B$ H
  33. macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_DISABLE;
    / }! j/ o+ A* _" M" Y* o$ z
  34. macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;# @" ?( i. {. `7 `. E7 z
  35. macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE;
    6 ^4 w2 M5 R$ p
  36. macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE;
    * u3 M. T' H5 Z9 w
  37. macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_DISABLE;
    6 P3 u8 \# h2 Y  q7 ~/ C  G& F
  38. macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;, z3 a" x% X$ }
  39. macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_ENABLE;
      l4 y, ^2 h) k9 h1 P
  40. macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL;" S& [! }$ a8 ]! E3 \1 I
  41. macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE;& o1 L; ~) v2 ~5 m
  42. macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECT;
      e/ Q! p- \! S  E) l& C" }- T; M
  43. macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT;
    2 l6 ]. v$ n- J3 Z+ P' L8 @9 D
  44. macinit.HashTableHigh = 0x0;3 p, o! i$ k1 E$ V; G
  45. macinit.HashTableLow = 0x0;$ o) M# r/ f  L. V; `
  46. macinit.PauseTime = 0x0;' @' N* L; o9 @1 b0 t
  47. macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;3 L6 B- Z! B4 M) O' ]2 I1 A
  48. macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;4 L5 o- h; J* o0 ?
  49. macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_DISABLE;
    ; Z  x2 O6 b7 i9 D1 X3 a  k
  50. macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE;+ }( r# R1 M. [% P% b0 e
  51. macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE;7 M; d2 i# [. ^. G( M8 U
  52. macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;+ L) @) {  ?7 r  [
  53. macinit.VLANTagIdentifier = 0x0;3 K  W  e+ L, B: d+ z2 y+ G# H
  54. % Q* W, ]0 N& Z/ E5 N
  55. /*------------------------ ETHERNET MACCR Configuration --------------------*/+ X! z: F- V. P  O( p; Y8 m0 Z
  56. /* Get the ETHERNET MACCR value */
    5 }! Q9 s3 g) `2 S9 {( }. Z+ S; v
  57. tmpreg = (heth->Instance)->MACCR;, ^5 j  F/ C1 V# e8 B9 [% @
  58. /* Clear WD, PCE, PS, TE and RE bits */
    ; I: ^$ P1 w) ^3 \8 A
  59. tmpreg &= ETH_MACCR_CLEAR_MASK;" P3 v- Z% K3 t
  60. /* Set the WD bit according to ETH Watchdog value */& k% D9 k/ r* z' G
  61. /* Set the JD: bit according to ETH Jabber value */
    3 t) l# Q# I0 ^6 Y! K
  62. /* Set the IFG bit according to ETH InterFrameGap value */
    : Q4 k3 C# n! b8 A
  63. /* Set the DCRS bit according to ETH CarrierSense value */7 K% o" K0 X! I6 ?1 q! Y- _0 m
  64. /* Set the FES bit according to ETH Speed value */
    * d2 s+ m7 ?. {9 ~& q; `) A
  65. /* Set the DO bit according to ETH ReceiveOwn value */
    . O, q0 }2 v5 x! m6 m  u$ }
  66. /* Set the LM bit according to ETH LoopbackMode value */5 W) X0 [% Y$ O! J' ]
  67. /* Set the DM bit according to ETH Mode value */6 H9 d4 E! _& C, m1 M* e
  68. /* Set the IPCO bit according to ETH ChecksumOffload value */
    . [1 I% {% `0 X1 y2 M
  69. /* Set the DR bit according to ETH RetryTransmission value */$ X0 u, j) B8 h* w
  70. /* Set the ACS bit according to ETH AutomaticPadCRCStrip value */, {) d4 A6 k3 x  U% U
  71. /* Set the BL bit according to ETH BackOffLimit value */2 U% v# S( z3 A& a% Z
  72. /* Set the DC bit according to ETH DeferralCheck value */
    ; Q2 K& ~6 q! L/ n- q. ^
  73. tmpreg |= (uint32_t)(macinit.Watchdog |
    / O- w- B( K! c$ p* p
  74. macinit.Jabber |
    6 M) k. J7 d" m+ `' p: {, ^4 U
  75. macinit.InterFrameGap |7 i  h/ a. {4 m5 {- f
  76. macinit.CarrierSense |5 R; p3 \8 n: l8 P0 Q  i* F
  77. (heth->Init).Speed |2 ]' w7 ?- L; Q4 _) M& e
  78. macinit.ReceiveOwn |, [  [+ H- d' b  N! _5 ~
  79. macinit.LoopbackMode |
    & Y( ?- i8 s4 o) `1 U
  80. (heth->Init).DuplexMode |& v- E7 ?8 a1 P. s) n
  81. macinit.ChecksumOffload |9 s+ x& E" i# t# r/ X9 h6 h
  82. macinit.RetryTransmission |
    % W1 @4 o8 M8 P/ V. o
  83. macinit.AutomaticPadCRCStrip |: E( y. I. @: Y4 ^% ?- X
  84. macinit.BackOffLimit |% @0 t8 Y' L5 C: }9 x' I! e  c
  85. macinit.DeferralCheck);
    " S0 H  J* Q& E

  86. # J0 [5 l4 S! w7 U  q0 Y0 D
  87. /* Write to ETHERNET MACCR */- \5 b) h7 `$ {- ^% N
  88. (heth->Instance)->MACCR = (uint32_t)tmpreg;
    0 c' w7 b: M; ~" {+ K" n8 n+ V
  89. * Y6 @/ L# ]9 f7 T- |
  90. /* Wait until the write operation will be taken into account:# x2 r! m. x) D9 I' ?9 Q, U4 t7 |( K
  91. at least four TX_CLK/RX_CLK clock cycles */
    + x; ~. w' V( M0 r/ T7 J
  92. tmpreg = (heth->Instance)->MACCR;
    8 F. j: p+ l$ ~; x2 W% z+ {4 e+ x" c5 ?
  93. HAL_Delay(ETH_REG_WRITE_DELAY);
    + N- I$ F$ f  S" @
  94. (heth->Instance)->MACCR = tmpreg;  j6 {$ |9 M& k- I6 z
  95. 9 C4 j# Q0 w2 a3 a( k  i+ A
  96. /*----------------------- ETHERNET MACFFR Configuration --------------------*/! `3 r+ I5 d1 k) `% }+ F7 h; N
  97. /* Set the RA bit according to ETH ReceiveAll value */
    , j4 N3 H/ ?" l" B
  98. /* Set the SAF and SAIF bits according to ETH SourceAddrFilter value */. S$ z: |! J# {3 T' j5 V# B: K: F: e
  99. /* Set the PCF bit according to ETH PassControlFrames value */" p5 l- V; `8 I
  100. /* Set the DBF bit according to ETH BroadcastFramesReception value */6 q+ w$ G+ v5 x* B+ x
  101. /* Set the DAIF bit according to ETH DestinationAddrFilter value */1 u" ^$ q8 C- I0 I
  102. /* Set the PR bit according to ETH PromiscuousMode value */
    - M, h0 ?0 N1 s7 M
  103. /* Set the PM, HMC and HPF bits according to ETH MulticastFramesFilter value */
    , q; a: g2 J3 O  X# C9 v! F
  104. /* Set the HUC and HPF bits according to ETH UnicastFramesFilter value */
    0 `4 }- V% k$ m5 V, [! l& G
  105. /* Write to ETHERNET MACFFR */
    . D$ w0 U" r: i6 z: I* t: M
  106. (heth->Instance)->MACFFR = (uint32_t)(macinit.ReceiveAll |" M; m! j$ ?5 ~, W! ~& t; [
  107. macinit.SourceAddrFilter |( L( x! t: J: `0 X" w9 M& L; R9 N
  108. macinit.PassControlFrames |+ ?( c; H: n! j5 q3 s
  109. macinit.BroadcastFramesReception |8 k0 \+ [/ N  z: y0 v2 {1 y8 i# z
  110. macinit.DestinationAddrFilter |: q* i5 H2 b/ l. H) Z
  111. macinit.PromiscuousMode |5 t4 b8 X4 G% Z" j# t4 g) r- T8 P* P
  112. macinit.MulticastFramesFilter |
    ( r* \: ?, e' C
  113. macinit.UnicastFramesFilter);
    7 [' x. R% |$ U! S/ d

  114. 6 G. C) Z. f% N
  115. /* Wait until the write operation will be taken into account:
    . I, y+ z6 x+ h% X+ s8 Q
  116. at least four TX_CLK/RX_CLK clock cycles */0 a! p2 U! z2 a5 T5 b
  117. tmpreg = (heth->Instance)->MACFFR;. t- \% ^9 r; M) d/ _2 z! z
  118. HAL_Delay(ETH_REG_WRITE_DELAY);! K4 k# n9 ]6 Q" l8 D9 ?
  119. (heth->Instance)->MACFFR = tmpreg;
    ' Q) J, f0 ]0 \$ @4 D* K( W
  120. $ S5 G  D1 `1 |% U
  121. /*--------------- ETHERNET MACHTHR and MACHTLR Configuration --------------*/
    % N" U5 E5 B( a/ J8 [
  122. /* Write to ETHERNET MACHTHR */" Z) Z8 j/ `+ |# Y+ U$ p; X
  123. (heth->Instance)->MACHTHR = (uint32_t)macinit.HashTableHigh;
    4 O) P; P3 V( L! E4 K+ V' I

  124. 1 m  R, D6 v1 j" F
  125. /* Write to ETHERNET MACHTLR */( S7 e0 W- `% z( W
  126. (heth->Instance)->MACHTLR = (uint32_t)macinit.HashTableLow;" |- k/ q2 V/ e! H- ^) z, v
  127. /*----------------------- ETHERNET MACFCR Configuration -------------------*/
    5 w3 l: \9 ]/ m  @) f( `) C

  128. ( g% O& s# o8 q& o% Y9 R
  129. /* Get the ETHERNET MACFCR value */8 q1 d* D& G! D2 r2 G
  130. tmpreg = (heth->Instance)->MACFCR;
    ' ]' r- b& s! z6 q( P
  131. /* Clear xx bits */
    ' e" c8 ]* P% X8 L& a, s0 z
  132. tmpreg &= ETH_MACFCR_CLEAR_MASK;
    ! q* P3 m1 s6 j, n* E, Q8 Q

  133. 4 \3 G& W( T2 K! @4 A
  134. /* Set the PT bit according to ETH PauseTime value */
    $ t' P# d  t$ w% j2 K: g
  135. /* Set the DZPQ bit according to ETH ZeroQuantaPause value */9 x* H; f" Q5 K4 ]8 m  |/ v, Z
  136. /* Set the PLT bit according to ETH PauseLowThreshold value */
    . n1 j: Z3 e! F
  137. /* Set the UP bit according to ETH UnicastPauseFrameDetect value */* N8 F6 k0 K0 ]) j8 F; b
  138. /* Set the RFE bit according to ETH ReceiveFlowControl value */
    ( d) e, p3 {) {# g  X: {) [
  139. /* Set the TFE bit according to ETH TransmitFlowControl value */& C$ I7 |- q( Q6 v% P
  140. tmpreg |= (uint32_t)((macinit.PauseTime Instance)->MACFCR = (uint32_t)tmpreg;# q9 G& w; }0 Z$ A3 a4 Y3 o
  141. 5 r# c: Q( p& ?  f/ \1 Q- B! @4 D* x
  142. /* Wait until the write operation will be taken into account:2 Q7 K" [! o% o1 r* [/ g% }7 z
  143. at least four TX_CLK/RX_CLK clock cycles */
    / \+ X0 B8 h7 _$ M& Q: P
  144. tmpreg = (heth->Instance)->MACFCR;* t; O' W! c( [
  145. HAL_Delay(ETH_REG_WRITE_DELAY);
    % a, W2 ~, j0 m. R' i
  146. (heth->Instance)->MACFCR = tmpreg;
    ) P& P2 s& t: x* |9 B6 Q; c
  147. ( X/ i- I4 D7 s5 D, K* T1 y# v! L
  148. /*----------------------- ETHERNET MACVLANTR Configuration ----------------*/+ t, w% [6 p9 v+ M0 T
  149. /* Set the ETV bit according to ETH VLANTagComparison value */! L% u! H7 z2 y& ]: O- e
  150. /* Set the VL bit according to ETH VLANTagIdentifier value */
    : T+ b8 u$ F7 C7 c
  151. (heth->Instance)->MACVLANTR = (uint32_t)(macinit.VLANTagComparison |
    $ G% [2 P2 Y3 N# @
  152. macinit.VLANTagIdentifier);
    - o, j$ j/ {, r8 G2 w, U
  153. 7 |/ k( X% D4 q0 T
  154. /* Wait until the write operation will be taken into account:4 \4 W1 Y" B8 F) \% b4 T+ t2 l/ }1 l
  155.    at least four TX_CLK/RX_CLK clock cycles */
    0 Q9 }4 p' G$ k
  156. tmpreg = (heth->Instance)->MACVLANTR;- x: m$ x( f  T9 y2 P* ?+ t
  157. HAL_Delay(ETH_REG_WRITE_DELAY);
    $ _1 b/ M. z1 Y4 Q/ K
  158. (heth->Instance)->MACVLANTR = tmpreg;
    * f( p' b4 U6 j2 z
  159. 7 l6 m, ~0 c- H% Q
  160. /* Ethernet DMA default initialization ************************************/
    2 N( f' b6 {  o7 N
  161. dmainit.DropTCPIPChecksumErrorFrame = ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE;
    1 P: N, H( E" v4 T/ I
  162. dmainit.ReceiveStoreForward = ETH_RECEIVESTOREFORWARD_ENABLE;8 d% D  S6 G- G( ~6 n
  163. dmainit.FlushReceivedFrame = ETH_FLUSHRECEIVEDFRAME_ENABLE;
    - b  Z2 g3 A, g0 W5 ^. i& k# ^
  164. dmainit.TransmitStoreForward = ETH_TRANSMITSTOREFORWARD_ENABLE;  H$ _, T4 s2 X' a0 [2 P6 i
  165. dmainit.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES;9 l0 Z: }3 G% d! R4 M, U
  166. dmainit.ForwardErrorFrames = ETH_FORWARDERRORFRAMES_DISABLE;$ V( {. C5 a6 P' U$ i3 M$ _
  167. dmainit.ForwardUndersizedGoodFrames = ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE;, e8 l2 t8 B  B; n6 T# A1 Y
  168. dmainit.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES;
    : l8 A* R& [, A% ^3 t. I2 ^
  169. dmainit.SecondFrameOperate = ETH_SECONDFRAMEOPERARTE_ENABLE;
    ( w0 ^9 \4 t5 P
  170. dmainit.AddressAlignedBeats = ETH_ADDRESSALIGNEDBEATS_ENABLE;
    ( @. C( S& y5 @, e# S8 H5 O
  171. dmainit.FixedBurst = ETH_FIXEDBURST_ENABLE;
    5 G8 e! F- g, C1 |# @" p
  172. dmainit.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;) N( a5 v9 C% P2 o
  173. dmainit.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;
    * S7 r4 k: J6 j
  174. dmainit.EnhancedDescriptorFormat = ETH_DMAENHANCEDDESCRIPTOR_ENABLE;1 G1 I7 d1 N) i8 `$ ~" @4 [
  175. dmainit.DescriptorSkipLength = 0x0;
    1 {' q  h3 J8 e- Y  Q$ q9 k. `9 f
  176. dmainit.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1;! P$ c& v( [! E( T

  177. $ q: g3 k8 z$ X- K8 U7 {) x* I. [
  178. /* Get the ETHERNET DMAOMR value */
    ' I% b7 Y$ x  e/ N
  179. tmpreg = (heth->Instance)->DMAOMR;' q1 Y( m4 V; S8 I
  180. /* Clear xx bits *// ?8 O; f& |9 c6 @3 g2 F; h1 `- R+ _. k
  181. tmpreg &= ETH_DMAOMR_CLEAR_MASK;
    - n% N  t& v8 B% o1 U
  182. ! q* R2 x8 ]! b9 k2 B
  183. /* Set the DT bit according to ETH DropTCPIPChecksumErrorFrame value */
    ! t& F- o6 W  w( }5 C: `, }/ Y4 o
  184. /* Set the RSF bit according to ETH ReceiveStoreForward value */
    * e4 h! {0 _0 Z1 ^# T( P
  185. /* Set the DFF bit according to ETH FlushReceivedFrame value */1 ?) N- D' a. i: O
  186. /* Set the TSF bit according to ETH TransmitStoreForward value */# ]& e* ]. d) @
  187. /* Set the TTC bit according to ETH TransmitThresholdControl value */
    " I! J" K5 E- ]5 y2 m1 o" }5 v% d, F
  188. /* Set the FEF bit according to ETH ForwardErrorFrames value */2 S, F6 l! h9 Q
  189. /* Set the FUF bit according to ETH ForwardUndersizedGoodFrames value */( ]7 P" C+ Y5 r) f! B/ p0 z
  190. /* Set the RTC bit according to ETH ReceiveThresholdControl value */% ^$ Y3 d& z3 B
  191. /* Set the OSF bit according to ETH SecondFrameOperate value */; J2 }+ b8 S2 {% X  ?' d4 I
  192. tmpreg |= (uint32_t)(dmainit.DropTCPIPChecksumErrorFrame |: W2 {" s2 c" n
  193.                      dmainit.ReceiveStoreForward |/ B! ]# l! ?) p
  194.                      dmainit.FlushReceivedFrame |
    ! {6 n2 r8 ]) l
  195.                      dmainit.TransmitStoreForward |8 p4 U: Y! U# E
  196.                      dmainit.TransmitThresholdControl |
    + r5 f' P6 o0 T
  197.                      dmainit.ForwardErrorFrames |+ A1 F6 f  V& P0 e6 ^" L
  198.                      dmainit.ForwardUndersizedGoodFrames |* P" f& b6 N7 z* t$ d, _5 n+ j/ S
  199.                      dmainit.ReceiveThresholdControl |3 Q3 c( b  i' |, d3 b5 `$ u) I
  200.                      dmainit.SecondFrameOperate);
    ) M* ~+ `$ P5 B

  201.   A$ c# C9 ~. t1 G; S. J
  202. /* Write to ETHERNET DMAOMR */
    0 @7 g$ A% o. @: Z+ N. A0 z
  203. (heth->Instance)->DMAOMR = (uint32_t)tmpreg;+ D; f4 R6 Y& B) Z' |4 H+ q
  204. / Q/ x' j4 j3 q7 o* G
  205. /* Wait until the write operation will be taken into account:
    1 V2 i6 {' M9 [; x- P- [& n
  206.    at least four TX_CLK/RX_CLK clock cycles */( `' @/ j; h" p
  207. tmpreg = (heth->Instance)->DMAOMR;
    5 f9 l2 P# i/ x# ]" V+ {4 y
  208. HAL_Delay(ETH_REG_WRITE_DELAY);! T% j: _* Z' g
  209. (heth->Instance)->DMAOMR = tmpreg;
    6 D4 p- o' y* |3 p

  210. ) V" I1 I1 g" P" r# [. g
  211. /*----------------------- ETHERNET DMABMR Configuration ------------------*/8 }5 ~" i* _' [$ m
  212. /* Set the AAL bit according to ETH AddressAlignedBeats value */' P# R2 S& D( g# N) K: ]
  213. /* Set the FB bit according to ETH FixedBurst value */( a5 Z5 ]7 J2 u! v% b
  214. /* Set the RPBL and 4*PBL bits according to ETH RxDMABurstLength value */
    ; n" j( ^& F* P3 x
  215. /* Set the PBL and 4*PBL bits according to ETH TxDMABurstLength value */( O8 Z4 [: n7 T8 W4 g( |
  216. /* Set the Enhanced DMA descriptors bit according to ETH EnhancedDescriptorFormat value*/
    / U# g( t, W* c5 M( W
  217. /* Set the DSL bit according to ETH DesciptorSkipLength value */2 p' e& h1 R. K4 |8 y( S7 d8 z4 s
  218. /* Set the PR and DA bits according to ETH DMAArbitration value */5 [2 f) q% q8 D: V/ o. P1 ?
  219. (heth->Instance)->DMABMR = (uint32_t)(dmainit.AddressAlignedBeats |
    % x+ j$ r4 T- d3 r# T
  220.                                       dmainit.FixedBurst |4 o! O0 ^% U+ i* k% U; X" |
  221.                                       dmainit.RxDMABurstLength |    /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */' v3 I+ B5 i; U9 B
  222.                                       dmainit.TxDMABurstLength |0 c6 E" ]! A9 g4 q/ z) f( q
  223.                                       dmainit.EnhancedDescriptorFormat |
    8 S1 R* I% S. `3 ?/ a1 L
  224.                                       (dmainit.DescriptorSkipLength Instance)->DMABMR;, \* C& `# y0 X0 k% \7 K; B
  225. HAL_Delay(ETH_REG_WRITE_DELAY);
    & ?+ r1 q; y& p% @9 }
  226. (heth->Instance)->DMABMR = tmpreg;
    : m7 E" Z) b6 q

  227. - O" ]) S2 V+ A  `
  228. if((heth->Init).RxMode == ETH_RXINTERRUPT_MODE)
    4 d! i& {  l; P- Y
  229. {0 K' ~8 S$ J9 y3 B+ a% t3 m! U
  230.    /* Enable the Ethernet Rx Interrupt */6 c# J6 Z7 k5 C1 \
  231.    __HAL_ETH_DMA_ENABLE_IT((heth), ETH_DMA_IT_NIS | ETH_DMA_IT_R);
    3 O9 P/ A1 }* I! S3 N" F3 f
  232. }
    , d8 s; d2 W, ?' l1 z& h

  233. # |, d( U* d" q* A7 R
  234. /* Initialize MAC address in ethernet MAC */, J8 f4 ~4 E4 \+ H6 h- o( @: a
  235. ETH_MACAddressConfig(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);
    . C- X- _" ?% o) [
  236. }
复制代码

  y( _: V- Y0 O这里我就要稍微吐槽一下HAL库了
2 }2 W' Z! c. D+ w) @" i! c3 HMAC层过滤的设置没有预留接口出来,有设置MAC地址的函数
& D/ {5 V% C( Z" e  Y1 t3 B( T2 L; x" z# Y7 y
static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr): T% I* {8 M& i! I1 h
2 e3 u; d( V, N( a% n2 d' B8 ?
就不多做一个设置MAC层过滤的函数嘛,连后面用到的宏定义都有~~7 b  L( k; H; u1 R5 }' ?& }8 b

% O5 `3 g( }' O. R木有办法,自己编一个初始化MAC层过滤的函数吧3 ], F( s+ Z" o
4 M! ?& b) d) B  _; A+ y
其实也就是把上面这个ETH_MACDMAConfig函数分离成两个单独的设置函数,再编一个设置MAC层过滤的函数" O: t7 W2 J: `3 @: \' O
3 M4 s& L. X5 E
开启MAC层过滤的初始化代码
, \( I% O1 o- ]" K5 |" d" p# L* F
  1. uint8_t ETH_MAC_Setting(ETH_HandleTypeDef *heth). N$ {! d" V( Z4 S& V
  2. {- a6 S; m* t) m. [
  3. ETH_MACInitTypeDef macinit;
    / M9 m* p7 R+ |" o9 Y  p2 h
  4. /* Ethernet MAC default initialization **************************************/8 t/ s4 c1 j! A- F/ }+ j9 p
  5. macinit.Watchdog = ETH_WATCHDOG_ENABLE;
    . D7 j. C; t9 `! I; c& ]- e" P
  6. macinit.Jabber = ETH_JABBER_ENABLE;0 C8 f1 g7 e$ C+ A$ }. Y/ m, L1 C
  7. macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;- Y5 l; x9 @7 G7 @
  8. macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;8 d+ N$ D0 X; s; d# p
  9. macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;& _! q7 b4 ]- ]; }- x1 X
  10. macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;& o: B, c5 y! y$ z2 b6 K8 j
  11. if (heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)
    5 b- H9 u2 V& t1 X8 ^
  12. {
    7 c( m2 h' z, T* t& F: K2 n
  13. macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;
    ! K7 i/ _; F- ?: u% e. A
  14. }
    * a; u3 h3 [, ?6 _. j- Q9 M$ }7 G" j
  15. else7 T' b5 }4 j4 k1 x: }# j% r' l+ \8 l
  16. {
    7 N; [8 X9 B, l) D, [) z3 C
  17. macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;; }+ V1 h( r: d% g& c, |: C
  18. }
    9 g' C* r- O5 J0 [' ?6 \1 R9 [
  19. macinit.RetryTransmission = ETH_RETRYTRANSMISSION_ENABLE;          //使能重传2 N4 Y4 f8 [& i1 x
  20. macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_ENABLE;          //使能自动去除
    + V; ]. z! L1 J' I0 a8 X2 Z
  21. macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;4 N% s8 d- m: }2 n+ b; Q* b
  22. macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE;# j: h3 v3 |$ r+ ^  s
  23. macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE; ///不接收所有包
    " e# V# c$ ^! B
  24. macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_NORMAL_ENABLE; //源地址过滤
    4 R3 N5 @* O6 M3 X
  25. macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;- |4 L$ I8 G: U7 X
  26. macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_DISABLE; //广播不接收' P$ k& A* t6 p& ~  u( |
  27. macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL; //目的地址过滤
    7 D. o6 m2 {, W3 B/ R2 V+ W
  28. macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE; //混乱模式9 K/ c: B  K$ `
  29. macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECT; //多播过滤
    $ g# g/ O  r3 x4 l9 M( B
  30. macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT; //单播过滤5 `/ A6 X$ j6 n" U: U8 t. k% r
  31. macinit.HashTableHigh = 0x0; //Hash表高位/ E3 ~* J4 ?8 g8 c
  32. macinit.HashTableLow = 0x0; //Hash表低位! q; N; N. m& A. I3 S: ]* o
  33. macinit.PauseTime = 0x0;8 P' e$ W0 F  k: k: G* \# s$ D  f
  34. macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;5 b+ o# c2 }* ^7 O, F
  35. macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;
    ! u! X3 D  B' |# U- r- N; K
  36. macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_ENABLE;* g8 {/ e  |8 u' w9 C( D
  37. macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE; //接收流控
    9 S, [$ E8 C% ^- Y# I; I9 _
  38. macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE; //发送流控
    - b) z  x9 x( t) u5 f
  39. macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;7 O% j# i- E+ z. z5 t
  40. macinit.VLANTagIdentifier = 0x0;# S! K4 ?! x/ m( X, C$ H; X
  41. 3 N# J3 w/ r  _3 F
  42. return HAL_ETH_ConfigMAC(heth, &macinit);! L' a- a% B# Q  H4 s' [- K3 W' ?
  43. }
复制代码
8 I# h  l0 F0 p  X
默认的MAC层 DMA初始化函数+ y0 B& a% f6 e% A
  1. uint8_t ETH_DMA_Setting(ETH_HandleTypeDef *heth)! W6 e4 ^1 M4 v& m6 K5 ?; e) v( }
  2. {, g  x- |$ F' e
  3. ETH_DMAInitTypeDef dmainit;
    ) Z( H, I3 Q$ k/ Y
  4. /* Ethernet DMA default initialization ************************************/- E; O- {2 L, B; ?& n& C5 W+ e
  5. dmainit.DropTCPIPChecksumErrorFrame = ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE;! E0 G( u7 G7 ^5 B3 x  _) c, J
  6. dmainit.ReceiveStoreForward = ETH_RECEIVESTOREFORWARD_ENABLE;
    / J6 c' `# n; p) W% A; `) ]
  7. dmainit.FlushReceivedFrame = ETH_FLUSHRECEIVEDFRAME_ENABLE;8 S9 k' `/ G& k7 H9 p: {
  8. dmainit.TransmitStoreForward = ETH_TRANSMITSTOREFORWARD_ENABLE;
    7 t  D( T6 g& M7 j) f' i5 E
  9. dmainit.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES;
    3 f7 @* [8 K8 E! F7 q
  10. dmainit.ForwardErrorFrames = ETH_FORWARDERRORFRAMES_DISABLE;
    ) }) q  m* n/ E' i  Z6 @- w, b3 {" l
  11. dmainit.ForwardUndersizedGoodFrames = ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE;! `1 Z. t, ?0 o* A4 O% L
  12. dmainit.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES;
    ( A$ n* W$ E' k: Q3 T" V
  13. dmainit.SecondFrameOperate = ETH_SECONDFRAMEOPERARTE_ENABLE;
    , t( v, o. R; s5 y* f/ X. f& _1 N0 l1 H
  14. dmainit.AddressAlignedBeats = ETH_ADDRESSALIGNEDBEATS_ENABLE;$ g! G6 m# L* c; b
  15. dmainit.FixedBurst = ETH_FIXEDBURST_ENABLE;6 M) e+ H, ~. [# f. R! |
  16. dmainit.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;
    5 h- {+ p5 U* y' J6 a5 ?
  17. dmainit.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;$ E9 h2 \# x0 M- A+ a/ T2 q
  18. dmainit.EnhancedDescriptorFormat = ETH_DMAENHANCEDDESCRIPTOR_ENABLE;
    . Y9 G9 L% @( b! k) w
  19. dmainit.DescriptorSkipLength = 0x0;
    ! N$ d3 U- D- \5 c5 g
  20. dmainit.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1;+ B5 U  t2 a0 l3 t
  21. uint8_t res =  HAL_ETH_ConfigDMA(heth, &dmainit);7 U/ F5 ?" s9 K7 E9 B
  22. if ((heth->Init).RxMode == ETH_RXINTERRUPT_MODE)
    / F' m; O$ I1 U* E0 _& l
  23. {+ R# ?2 J; k6 K1 V# n- ?* ?$ c
  24. /* Enable the Ethernet Rx Interrupt */
    / |9 {9 ^* Q. v& @% @
  25. __HAL_ETH_DMA_ENABLE_IT((heth), ETH_DMA_IT_NIS | ETH_DMA_IT_R);5 f6 @+ T: [& }% w4 `0 _
  26. }' N  c2 D. \+ b$ h3 ^# e5 |
  27. return res;
    3 o1 N, T/ D0 x; _/ X" _2 x
  28. }
复制代码
% l6 W9 J' [, I
用来设置MAC地址的函数(其实就是把库函数的static函数取出来直接用了)
  1. <blockquote>//heth: HAL句柄
复制代码
+ h  v0 f% i9 {
然后到最最重要的MAC层过滤设置

9 \; c7 v$ q  ~0 U4 ^$ Y; Y以MAC1为例
9 ?  K$ @4 W4 L+ s, S
. Q+ q' [- W$ o0 t, M$ M. X' _  G
20191124093921254.png
: H4 Q& Z. P% O3 x

3 u  [$ ~3 \& B. S% l6 K- k+ t
20191124094439199.png

0 V3 P4 {9 I0 y
8 v) c2 Z' k4 W7 H' g6 P注意看红框的描述
0 [7 P& e! F1 d2 \
功能很好用,可以过滤源地址/目的地址,还可以做掩码功能4 m$ i6 B% U1 N0 |/ T( P
设置MAC层过滤的代码' }+ `, e( w0 i
  1. static void ETH_MAC_Filter_Setting(ETH_HandleTypeDef *heth,ST_ETH_PAR * para), }% W; A" a' S7 n, o
  2. {2 K$ B1 _0 x! J( [' Y
  3.     //设置本机MAC地址
    ; N: J1 d+ d! V7 e  N: N
  4.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);
    # B) x: v- n# [; K4 {# h: N3 M
  5.     //设置UDP-A的对方MAC地址/ p/ L: W4 ^$ _2 \9 j7 Z
  6.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS1,para->UDP_A_MAC);" ]9 e8 o( z1 G3 R7 M- l
  7.     (heth->Instance)->MACA1HR|=0xC0000000;//需要完全匹配UDP-A的对方MAC才接收  K& R& s, a8 {7 S4 X
  8.     //设置UDP-B的对方MAC地址- f, Y: X# A+ i5 |7 ^& _# |/ H
  9.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS2,para->UDP_B_MAC);
    , i3 w6 Y5 ~  D' m5 ]2 ]
  10.     (heth->Instance)->MACA2HR|=0xC0000000;//需要完全匹配UDP-A的对方MAC才接收+ R' y& ~0 \2 V, c# V$ v" t
  11. }
复制代码

+ B, q- _6 n* B' k我这里是希望为我的两个UDP精确过滤接收到的源地址0 x5 Q9 X+ S& p
所以AE位设置为1,SA设置为1,MBC全部为0(MAC地址全部检查)
- T( `. z4 [2 a( c: `1 f: q6 v4 f" p- W$ t0 ^: _! _' G4 ^
假如我希望过滤MAC中特定的厂家字段8 e$ B" u+ \3 n6 h) l8 x
例如某个MAC地址
' l5 ?0 v0 k8 X+ V- c$ o3 O
01-02-03-04-05-06
5 t4 A' E9 [. N; y其中01-02-03就是厂家字段- ^& ~$ F+ h- Q8 O0 ]

9 Q6 y$ Z' h0 Y# J2 P1 {. p) p那么代码要这样修改(MBC的第29位,28位,27位置1)/ B  d" {2 S  M! W2 f
这样MAC层就不会检查MAC地址里后3个字节(04-05-06)
* f; l- N2 t  o8 p7 V/ i9 H但是会检查前3个字节,也就是厂家字段
7 {# U( a1 ^& m8 ~% V- H" Q' c- D3 U这里需要注意MAC地址的字节序
) E# u" @- P$ e# e0 S/ U6 N0 H
  1. static void ETH_MAC_Filter_Setting(ETH_HandleTypeDef *heth,ST_ETH_PAR * para)! m+ a5 i( _" U0 g5 i* X! h
  2. {& B7 @$ @( }0 K1 G0 Q5 q( \
  3.     //设置本机MAC地址1 [+ @- f# @/ @. Z9 h
  4.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);2 c  c$ g9 r  e! r0 y
  5.     //设置UDP-A的对方MAC地址
    1 l, A0 T& T. I' P4 c$ C
  6.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS1,para->UDP_A_MAC);2 a% J1 e5 a9 d; t- {
  7.     (heth->Instance)->MACA1HR|=0xF8000000;//需要匹配厂家字段
    + o$ D5 O( q+ d6 V" N* }
  8.     //设置UDP-B的对方MAC地址
    1 z1 r  c" ^. ]4 f0 R' b- [8 [
  9.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS2,para->UDP_B_MAC);' u- D7 I# y' ^' s8 d
  10.     (heth->Instance)->MACA2HR|=0xF8000000;//需要匹配厂家字段
    + Y: U$ O0 h5 X) c# a" G8 x( V* |
  11. }
复制代码

# ^3 Q$ o' m7 a8 `8 b3 k9 E然后这些函数的调用顺序按:
  W# s1 ]6 V% i1. HAL_ETH_Init5 a1 p) d2 k% p; @5 D
2. ETH_MAC_Setting
0 u% v% G. H0 X1 ?. b$ W/ ^+ t; a3. ETH_DMA_Setting
! c1 X$ o1 \0 t& _4. ETH_MAC_Filter_Setting1 G3 ]6 n3 q7 B* g) H
. m, b. {( t; o8 J
用你希望过滤的MAC传递到一个Hash计算函数里,得到一个值,通过这个值产生“映射”关系来过滤MAC地址,所以这个并不是精确的,因为可能会重复~~
+ ?' r% D+ H1 h0 P
# O% m$ U, p/ I# Q+ Z9 p
HASH函数) M8 I3 O/ l' C% N
函数3 f- J5 O; ]* D; ?, U
  1. / STM32 MACHASH - Copyright (C) 2014-2018 Clive Turvey (<a href="mailto:sourcer32@gmail.com">sourcer32@gmail.com</a>)8 U+ [9 }- B* s) `
  2. //  All Rights Reserved
    $ J. u; f7 u/ ?# ^/ F

  3. 9 X+ U0 M/ |# a, B: O) q, B  S5 K
  4. #include <windows.h>2 Q) {( n7 c: m; U

  5. 5 x2 `% m3 s+ h! X  ^; A
  6. #include <stdio.h>- l. N+ O& L4 z3 b
  7. #include <stdlib.h>
    3 i% ?; `" x# r/ |3 V. B+ m
  8. " g$ P  ?4 @5 b( E8 E+ {$ c
  9. typedef unsigned char uint8_t;
    : \5 Z: D6 D4 O
  10. typedef unsigned long uint32_t;% m6 U1 u0 K8 D: ]2 t

  11. . |) n; Y4 A% b2 q" S: z& R9 N
  12. uint32_t Rev32(uint32_t x)
    - y; Y5 ^) D' K5 L) _+ _# Z
  13. {2 S4 F* ]9 P' p( a& h+ r4 ]; N" h
  14.   uint32_t y;# ]* E* e: G3 @  v; ^- n
  15.   int i;
    4 g6 E/ {) p: r
  16. 9 N6 \* T4 v/ p- G& |8 |3 z1 G4 T( _
  17.   y = 0;
    + v. g& i+ @! i1 ?

  18. 3 E) ?) i1 A+ T+ ], e. q
  19.   for(i=0; i<32; i++)
    3 z% [; ~' h( M
  20.     if (x & (1 << i))2 K' a1 K/ h1 c5 l* K8 Y
  21.       y |= 1 << (31 - i);
    0 w. i' K' p8 R% q
  22. 4 \% _7 o& [7 d
  23.   return(y);
    + h2 t( v" Q# l' m) b
  24. }
    . f  a1 I/ @+ o3 a2 w5 q- b- v. z

  25. 0 V2 ~+ M! Q; F9 q2 L
  26. uint32_t MacHash(const uint8_t *Mac) // <a href="mailto:sourcer32@gmail.com">sourcer32@gmail.com</a>
    ' l% k$ c7 U5 d, N; E6 X7 W6 a8 e
  27. {* X& V. \1 X3 }2 k
  28.   int i, j;
    1 Z2 A' l7 O# M+ p) m$ C8 A) z
  29.   uint32_t Crc;
    - A2 H  N/ U9 i5 V" t: {# Y

  30. ' t* x2 b; C3 {9 p8 m+ H) |2 y
  31.   Crc = 0xFFFFFFFF;) q5 L- j3 j& H

  32. 4 b* |" \4 j) _. ^: v' [' [
  33.   for(j=0; j<6; j++)1 z# E6 B, o& z
  34.   {
    $ Y" K/ Z+ ~. Z* A9 q, d5 l
  35.     Crc = Crc ^ (uint32_t)Mac[j];
    & v, `! d; C0 j) Y1 \5 w: p1 `2 \, K

  36. 3 e8 O, K) `+ A' _4 d9 y0 J
  37.     for(i=0; i<8; i++)3 @" P+ T* k) L  l8 N& a
  38.       if (Crc & 1)
    , f& k, I, M  l8 c, R3 v6 l* T
  39.         Crc = (Crc >> 1) ^ 0xEDB88320; // Reversed 0x04C11DB7/ ^4 o" S- x: W( D) n3 I# I" p
  40.       else6 @$ e$ K7 I+ R* ^- ~" n+ E
  41.         Crc = (Crc >> 1);3 t3 Z* L- x" m! i* X6 S4 j
  42.   }1 n; ?: v9 }* x8 z) y) N
  43. . d& d% A! ~! U% P/ w/ J4 A
  44.   return(Rev32(~Crc) >> 26); // Get High order 6-bit in reversed/inverted CRC
    ) R# q1 w" B0 n2 j+ v. U
  45. }
    8 @2 K* O6 P  e+ h; E2 s

  46. " A; p1 b& U- f+ D& S  E
  47. uint32_t MacHashFast(const uint8_t *Mac) // <a href="mailto:sourcer32@gmail.com">sourcer32@gmail.com</a>
    9 \$ Z3 J% u! `6 D. ?4 W
  48. {+ S+ G1 l4 X6 _: c$ T
  49.   static const uint32_t Rev6Tbl[] = {
    : N5 C# e+ L# x5 ?+ N  C
  50.     0x00,0x20,0x10,0x30,0x08,0x28,0x18,0x38,/ ]+ z$ p  i9 @; J
  51.     0x04,0x24,0x14,0x34,0x0C,0x2C,0x1C,0x3C,4 o+ M" G; ~# A/ z) X3 p3 F& O6 c
  52.     0x02,0x22,0x12,0x32,0x0A,0x2A,0x1A,0x3A,3 n. d9 U- V+ _2 W% [+ z& f
  53.     0x06,0x26,0x16,0x36,0x0E,0x2E,0x1E,0x3E,
    ! P0 k6 L; k/ \3 r! F
  54.     0x01,0x21,0x11,0x31,0x09,0x29,0x19,0x39,
    9 |- K$ o" \! p
  55.     0x05,0x25,0x15,0x35,0x0D,0x2D,0x1D,0x3D,
    ' l2 j2 K, f! \, f$ ?+ y$ S
  56.     0x03,0x23,0x13,0x33,0x0B,0x2B,0x1B,0x3B,
    8 C( _% P. O9 Z- U
  57.     0x07,0x27,0x17,0x37,0x0F,0x2F,0x1F,0x3F };8 a, L. x9 z  c6 r4 n) b3 A
  58. / v- Y2 t$ T' a
  59.   static const uint32_t Crc32Tbl[] = {
    . n& W  k( r) D) Z+ }
  60.     0x4DBDF21C, 0x500AE278, 0x76D3D2D4, 0x6B64C2B0,: A6 p9 ^) n4 ]0 r" C- C7 q, X/ u
  61.     0x3B61B38C, 0x26D6A3E8, 0x000F9344, 0x1DB88320,- t% a$ K. @$ N6 y
  62.     0xA005713C, 0xBDB26158, 0x9B6B51F4, 0x86DC4190," S; F# q* J3 I4 U/ v( \- m
  63.     0xD6D930AC, 0xCB6E20C8, 0xEDB71064, 0xF0000000 };
    5 X  C+ x8 h  m7 }& a
  64. / g; z* u# e9 o4 a5 n) C( z
  65.   int i;
    2 n8 d: E) X" D+ ^+ P( l
  66.   uint32_t Crc;
    ( Z% H0 H% f# m3 @" ^

  67. ' M* {+ K# b, O  T! [9 _0 d) c' |, U
  68.   Crc = 0;: c& q% k4 z9 ?* k# m! B

  69. $ I$ s! V, ?2 M
  70.   for(i=0; i<6; i++)
    ) g' O5 D. y" O: j
  71.   {
    # O+ V9 [. U2 D; z
  72.     Crc = Crc ^ (uint32_t)Mac<i>;
    ( T  ?/ ?1 y0 j4 P6 g" _

  73. 9 `  q( E( T; I
  74. </i>   Crc = (Crc >> 4) ^ Crc32Tbl[Crc & 0x0F];  /* lower nibble */; f4 K4 a; L3 z5 H" {6 Y7 Y/ I
  75.     Crc = (Crc >> 4) ^ Crc32Tbl[Crc & 0x0F];  /* upper nibble */. }$ s" l  \% b( N% G# u& I
  76.   }
    ; c% D& R4 M' ?2 W6 ^9 h9 P: z; O9 |

  77. % ?8 X+ {0 J; @- @
  78.   return(Rev6Tbl[Crc & 0x3F]);0 M4 S: W, g) ?1 N5 n& f
  79. }: M$ L- C" b+ L5 S* ^' I
  80. * v8 \+ ^7 x* w, H  i$ T
  81. int main(int argc, char **argv). Q; _- i" G8 k, `3 Y
  82. {
    3 u" _6 K$ c. e* [
  83.   static const uint8_t Test1[] = { 0x1F, 0x52, 0x41, 0x9C, 0xB6, 0xAF }; // 0x2C' u9 h1 @0 w7 v  q% v
  84.   static const uint8_t Test2[] = { 0xA0, 0x0A, 0x98, 0x00, 0x00, 0x45 }; // 0x079 V) |% j4 F. g9 A+ N
  85.   static const uint8_t Test3[] = { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x21 }; // 0x24
    3 {, F* V; h. ]" C4 @2 h0 l6 e

  86. 0 G9 ~# x9 B3 _2 R& n5 s# t
  87.   printf("MacHash %02X\n", MacHash(Test1));/ ~! ]% O( w4 _
  88.   printf("MacHash %02X\n", MacHash(Test2));
    - f5 Z! J4 J6 Z
  89.   printf("MacHash %02X\n", MacHash(Test3));
      ~* Y+ J/ `5 |7 y4 a7 u( ]* d
  90. 4 R7 n) \8 @8 y8 v% `: G/ l) N
  91.   printf("MacHashFast %02X\n", MacHashFast(Test1));
    8 L, G  P2 Q8 q( v" E; u
  92.   printf("MacHashFast %02X\n", MacHashFast(Test2));2 M+ b# g/ k9 F$ L  f' j
  93.   printf("MacHashFast %02X\n", MacHashFast(Test3));8 O: w6 u7 B) M5 p# @; I* r/ k
  94. # G1 p; a! u# {
  95.   return(1);
    / w6 k& z5 [" ?; N" v$ s4 P
  96. }
复制代码

- u3 {  c5 L7 j# V  f6 }+ T0 }: R3 z" ^/ i1 i0 J
回到手册" }' c& \; s! Y, F* L# X4 ~; `

, y; @) T- J. m! h5 ^; w  Q
20191124100604140.png

  L7 F8 Y' x. m) ~: I2 a7 Q  A- U' C& r1 i; A
20191124100636882.png

. H8 }/ A. h8 ]/ v, ^9 W, F% x0 B4 d4 W1 r: }0 D2 {

) E- f' `7 X8 O. A9 G* ]9 M/ d上面的函数算出来一个数,假如是手册上的那个0x2c,二进制为101100B
: o: w9 X# N  N( T* N  x换句看得懂的人话···就是:/ Y9 n) g, R9 d  x4 P9 Q  N4 P
算出来的数先看第6位
9 A/ Z/ r9 {4 X0 R是1的话说明用到的是HASH表高位寄存器
+ o+ U8 F* H  q7 V否则用到的是HASH表低位寄存器
. `8 t1 W$ |3 O( z* Q8 A) d然后剩下的5位,转成十进制不是12嘛% K9 V: `& b7 ]" p4 ~4 p
如果你希望过滤这个MAC. V1 o8 S, V3 ^
那么你就把对应的HASH表高/低位寄存器的对应位置1,否则置02 q; S8 d2 s2 H' t; c
这里的0x2c就是要把9 |* l7 [2 G' K# ~1 b4 J% ~; e
HASH表高位寄存器的第12位置10 n* [2 e# C& X- B
就可以过滤这条MAC了$ ~4 E1 _7 ?- r1 r5 }- s
然后把你希望的MAC地址都按照上面说的方法弄完$ q+ b& k5 O( W( O1 x

7 C6 |7 a: ]. W, j4 W0 J回到这个函数稍微改一下5 t. @6 G8 E7 l) U8 M# W7 P* L' K
  1. uint8_t ETH_MAC_Setting(ETH_HandleTypeDef *heth)
    + C/ p# @2 S3 Q! `0 {  ~# S
  2. {; s3 p# l& X9 n
  3.     ETH_MACInitTypeDef macinit;% h& E! _( E: b
  4.     /* Ethernet MAC default initialization **************************************/3 O5 C% K3 @9 g
  5.     macinit.Watchdog = ETH_WATCHDOG_ENABLE;
    ' c* Y9 k1 T' [. T
  6.     macinit.Jabber = ETH_JABBER_ENABLE;
    ; ?- `4 B: ]/ `5 r# @
  7.     macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;
    ' _0 d% C- c& T* j  O
  8.     macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;3 t! Q6 x/ ?; C) O
  9.     macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;/ B' p' R" d6 J, T
  10.     macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;4 k* ]1 _: g, k! U  q. S
  11.     if (heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)
    3 h1 l; i+ D9 w+ J7 r
  12.     {
    9 B# l- m+ @0 r/ Z# N- e" n
  13.         macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;
    / c) o! M% ]# T: [7 v& V
  14.     }
    , Z$ Z& @7 Z" {& H# z
  15.     else
    . V' E: [5 [" E7 T% E# u0 n
  16.     {) J: x/ F6 L7 i! W5 W7 H
  17.         macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;8 F/ |" u3 `+ X7 r  a" h3 e
  18.     }
    . k8 ~% H: M# t% x; o
  19.     macinit.RetryTransmission = ETH_RETRYTRANSMISSION_ENABLE;          //使能重传! Y0 }, s* e9 l) c
  20.     macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_ENABLE;          //使能自动去除3 b' w. k9 t% v4 X, f
  21.     macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;
    8 ^4 R3 C8 x+ I, E  K6 e# E( A
  22.     macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE;  F8 T0 U8 L+ W* P' V6 Q  ~
  23.     macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE; ///不接收所有包5 \9 [9 \  s' N# y6 p$ T" P  C! O
  24.     macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_NORMAL_ENABLE; //源地址过滤, r* U. ?$ R4 i0 x
  25.     macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;' y9 o% p2 \5 W6 A
  26.     macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_DISABLE; //广播不接收
    , E9 ~1 K! H: W1 q: v( h+ \
  27.     macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL; //目的地址过滤
    7 G% N; Y4 r: }5 ^$ M# X- f& S
  28.     macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE; //混乱模式
    2 _8 j1 b. }% ^# ~
  29.     macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECTHASHTABLE; //!!多播HASH完美过滤
    ! m3 m, S. E7 i8 Z
  30.     macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECTHASHTABLE; //!!单播HASH完美过滤
      ~  j3 s, |! `2 E# K) i3 I0 f) e) [
  31.     macinit.HashTableHigh = 0x0; //!!填你最后算完的Hash表高位
    ! F: f$ Z' a% {; R  L- r
  32.     macinit.HashTableLow = 0x0; //!!填你最后算完的Hash表低位) r+ S' T) Q; \' q6 {: W5 O+ N4 l
  33.     macinit.PauseTime = 0x0;
    # X+ E$ t' o! G( n/ R2 E
  34.     macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;
    ! W  f$ N$ z' W; g/ y
  35.     macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;
    & A# R. n+ T# c1 @& W
  36.     macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_ENABLE;
    ' m% x: k0 ]2 ?- G
  37.     macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE; //接收流控5 C! ^# b7 G3 k) v
  38.     macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE; //发送流控
    ( I; X8 Z- v# R1 y7 y0 J/ S$ d
  39.     macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;
    - M- b4 y# A% B! g, H
  40.     macinit.VLANTagIdentifier = 0x0;+ u7 ~% X' r1 K, a* ^& `
  41. ) K- q: h# u) l$ }+ \
  42.     return HAL_ETH_ConfigMAC(heth, &macinit);7 d9 p9 g* l1 N0 @0 p" X9 I- k, _
  43. }
复制代码
1 ^& x' _- N5 ?) W
大概MAC层过滤就这些东西了7 H6 X# [9 M$ Q) C7 t$ s; h
如果有条件弄MAC层过滤真的强烈建议开启,可以大幅减轻协议栈的处理负担,板卡不会因为处理大量无用的数据而白白浪费处理性能。; [/ |. A$ ^8 l  R1 z7 p  E* W
4 |/ C# h  o/ w1 r+ P% }

6 i" x0 p8 @! g0 ^
( Z, S  s& Q; J2 G! P, h0 g, U  y
8 r& v$ X5 z% o. |# m* g
赞 收藏 评论0 发布时间:2021-12-14 10:15

举报

0个回答

所属标签

相似技术帖

官网相关资源

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