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

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

[复制链接]
STMCU小助手 发布时间:2021-12-14 10:15
前景描述
+ z- ]/ k& C' l我司的以太网实现是LAN8720搭配片上MAC层做的,协议栈用LWIP
) J* K- y4 @, ?% O9 @$ A6 X6 p3 `( F4 i% j' C: z! V
这种做法应该还是蛮常见的,反正不是LAN8720就是DP83864,再不然就是硬件协议栈的W5500了
- V* W: o: K' y7 ]7 n
! x' e2 f! l6 c6 C8 `想想还是有MAC层过滤比较好,随手翻了翻它的手册,W5500好像是没得MAC层过滤的' G3 w+ d% _2 u/ \

' Y4 |) y: H; x4 l0 i. D( u: g, L假如数据速率比较高,数据量大,而且外面还有乱七八糟无关的数据往板卡送,我也不知道用这个片子到底好不好- M& P: k& d' }( L  E
4 J1 V2 M8 j& t
LAN8720也不好改了,就继续用吧
2 v# c% C- Y; r- ^( }6 C' s/ t2 I# t- s: O% m) D; {, Q* y
好好在,发给板卡的数据的MAC还是有特征的,我只需要过滤发送方MAC地址的前3个字节,也就是特定的厂家那段# H) w, g$ G6 z/ K, t& t
7 O' P7 r# ]( e1 X: d2 J
MAC地址的科普知识这里就不过多描述了,我们直奔主题1 T4 W0 k! D: b8 s

7 `3 z6 O- ~- r  ?( Q怎么用STM32 F7的片上MAC做MAC层过滤
  e. e$ ]6 t0 u, Q' p. ~. e# i, Y% `3 E8 T; c
写这个的目的,就是我搜了搜,没看见有人写这个MAC层过滤功能,具体代码怎么写才能用
. b7 B6 _% f3 F  @( @+ J
" ~0 j# t$ o) ~9 x知识科普-STM32的片上MAC
1 s, G, _9 e) }# B% e! V( OSTM32 F7的MAC层过滤方式有三种(说人话的直白解释,中文手册其实也翻译的不好)
1 T4 s9 l. m' E3 _精确过滤(手册上叫单播目标/源地址过滤)
0 R5 p- B0 A$ ~0 T# S粗糙过滤(手册上叫Hash表过滤). V9 H' l4 c) |% y% @' a, S) O
特殊过滤(广播,组播过滤等等特殊的过滤)/ Z; E/ B$ ^5 n1 C
我这里着重说第1种和第3种
8 V0 Z/ ~2 s+ f/ h% X( r& s  N3 l9 s
STM32 F7可以存4个MAC地址
1 k" H: Y( m& p+ d' X其中MAC地址0是自己的MAC,其他三个可以用来做过滤
- P/ N- ^5 h, M. T4 [! I, F) F0 y' m3 Y( o
网络数据包通过PHY进入STM32的MAC,MAC层是可以对目的地址/源地址检查并过滤掉没得用的数据的,默认的HAL库库函数HAL_ETH_Init中
, h% L( ^& i# H; u3 d有一个static的函数* g7 a# ]( B0 E
static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err)3 C; f6 z' _$ G0 x3 ]1 G. R
会帮你在初始化网络功能时初始化默认的MAC层功能:
  y9 o5 Y$ n1 r, _/ g" v% t  b" [关闭源地址过滤6 l6 N( n3 A. l
不接收所有数据4 W+ T  a* X% C* o3 {% W
接收广播帧
/ e/ x: p/ a0 U) t打开目的地地址过滤
4 E. J5 k) m9 K6 ^# z" K, U单播数据精确过滤6 c8 E, {7 C6 h" [* s: Z
组播数据精确过滤
1 a' L% b- b  O$ Z' Y; t4 \. m6 U1 c* tHash表过滤关闭
) Q9 [) n3 r- g% H% ]- G; B6 ?( B! o/ d
其他的功能自行研究,我这里捡重要的说! g8 V6 ]* w. |' _. l
  1. static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err)
    8 t6 _) Q+ C2 i; |+ r* F5 |9 @
  2. {
    " y+ e2 P, w3 _! o& h- C6 q
  3. ETH_MACInitTypeDef macinit;- \) O0 q" `) X3 ]! I# Z9 Q: \
  4. ETH_DMAInitTypeDef dmainit;& `$ i$ A( s9 V: J& t4 i
  5. uint32_t tmpreg = 0;
      ^3 k( }$ I7 [" ^7 O
  6. ) x% }+ T5 D1 q
  7. if (err != ETH_SUCCESS) /* Auto-negotiation failed */
    % q1 r( S& }( L$ W* s9 U
  8. {. C, E& S' l! C5 E
  9. /* Set Ethernet duplex mode to Full-duplex */
    + y- O; h/ Z! `( `  ]9 w
  10. (heth->Init).DuplexMode = ETH_MODE_FULLDUPLEX;" d) n! r0 L) v5 T5 q. e! m& v) W
  11. & j: j2 \: r% [! }. `8 g
  12. /* Set Ethernet speed to 100M */* }5 {3 M, {5 D5 {" [2 ]
  13. (heth->Init).Speed = ETH_SPEED_100M;1 i) L$ \( F  V# ~9 `
  14. }
    3 b; o0 K4 F+ O2 Y3 `1 n8 _  V1 |

  15. * ]& z1 z# G" |( X3 C. g
  16. /* Ethernet MAC default initialization **************************************/' s4 W7 \! O+ C$ Z" s3 @
  17. macinit.Watchdog = ETH_WATCHDOG_ENABLE;
    , b& k) O5 p; V& F+ k- R$ J9 h+ Z; e0 t
  18. macinit.Jabber = ETH_JABBER_ENABLE;2 L& b& ]! z6 R7 _
  19. macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;
    4 c: x: Z0 K* ^! K' a; i8 R, U, E: N
  20. macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;
    # l& x' b" d+ y5 F# R5 y+ o
  21. macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;+ S) r$ R* G/ T! [! w# ?
  22. macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;6 s6 [, c3 k' n6 a
  23. if(heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)
    ! J! a: i) @7 d) c: i
  24. {
    4 m! @+ W, Z% T/ |3 H+ J' |6 r
  25. macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;
    4 Q, v0 n9 i1 j8 m$ D
  26. }3 U) B6 m; C# y+ C* i
  27. else
    % ]6 k" C! {9 R9 L3 y
  28. {
    8 E: n  S1 W. k
  29. macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;1 o; B, U1 ^' U* b* H% @$ L* r
  30. }: u  u5 G1 I! W# R% v8 J, M
  31. //这一段是MAC层过滤的设置,下面是DMA的,那个用默认的就可以
    & ?2 \: e3 H! d- M; J- {4 `- G: q
  32. macinit.RetryTransmission = ETH_RETRYTRANSMISSION_DISABLE;
    ( K; U/ t* z: V6 t/ `, r% T
  33. macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_DISABLE;
    " b' Y0 h& e5 T/ Q
  34. macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;
    . b0 N. J! G6 J7 q1 \
  35. macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE;
    : x* i% c0 Y- ^7 q8 \$ j+ q. r
  36. macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE;
      l, d' X5 W" D
  37. macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_DISABLE;
    / s: x% J/ J) e/ `
  38. macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;7 w7 O  U( c* ^& @* V8 _7 a
  39. macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_ENABLE;+ j% Q; {5 t4 Q5 o  |$ L
  40. macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL;
    + _6 I: y- J! R% _6 |" Q4 I8 J
  41. macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE;# a8 t" ?- ?' d/ I
  42. macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECT;
    1 T# }" F5 J1 B4 N0 f& @
  43. macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT;( l5 ^: K  q+ i/ r
  44. macinit.HashTableHigh = 0x0;" t) _) t8 U7 {) L6 _
  45. macinit.HashTableLow = 0x0;
    , _; O1 K$ z/ N: k: k7 y
  46. macinit.PauseTime = 0x0;
    8 U8 ?0 \' ^8 r! Y# F( X( F
  47. macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;6 x6 t. Q4 [& n+ ~; q
  48. macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;
    ) a7 D" Q# K) d' ?# D6 B
  49. macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_DISABLE;
    7 N$ h, D% o3 F8 `! _9 Y9 A7 y
  50. macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE;
    & m& ?! m7 w: J5 m5 E; \  }# o
  51. macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE;
    ' o. C$ d: u+ r  g
  52. macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;
      {+ ]$ ~* H! b: Y9 k
  53. macinit.VLANTagIdentifier = 0x0;' w( |4 N3 P1 E( r1 ]# A
  54. 1 {7 U  G; H" B# h1 U
  55. /*------------------------ ETHERNET MACCR Configuration --------------------*/
    / b1 L7 `# R1 O% N. s1 K) c
  56. /* Get the ETHERNET MACCR value */, D% P# M, Y* O3 ^  U- _
  57. tmpreg = (heth->Instance)->MACCR;
    9 N" W. H& a/ S7 ]7 u
  58. /* Clear WD, PCE, PS, TE and RE bits */1 J( ^& x; K6 v. o
  59. tmpreg &= ETH_MACCR_CLEAR_MASK;5 t: S: I9 F4 ~/ Y
  60. /* Set the WD bit according to ETH Watchdog value */
    6 n7 s/ m8 a- f/ c) F
  61. /* Set the JD: bit according to ETH Jabber value */
    ( n. s+ Y* f+ b8 @) W. _  |
  62. /* Set the IFG bit according to ETH InterFrameGap value */
    3 [' ]9 N' o; p; {
  63. /* Set the DCRS bit according to ETH CarrierSense value */8 z! y7 w5 `+ a8 p  ~+ G
  64. /* Set the FES bit according to ETH Speed value */6 b7 F' C. _" u; S4 F& {
  65. /* Set the DO bit according to ETH ReceiveOwn value */
    ) `2 J. U8 _) M: c  K4 `6 v. d7 R  G
  66. /* Set the LM bit according to ETH LoopbackMode value */
      _! X6 ~# O( l% N% d5 O1 U( N
  67. /* Set the DM bit according to ETH Mode value */
    $ x' T. x$ ^, k, W% B0 c7 S! c0 a+ b
  68. /* Set the IPCO bit according to ETH ChecksumOffload value */+ u  |/ x. H( t& P: [
  69. /* Set the DR bit according to ETH RetryTransmission value */4 M2 v& I9 V# _& g) I' R1 T% H" z
  70. /* Set the ACS bit according to ETH AutomaticPadCRCStrip value */# G5 ^4 Z( p# O7 _4 V6 q# N
  71. /* Set the BL bit according to ETH BackOffLimit value */
    9 }4 O/ v1 v3 M5 P) k
  72. /* Set the DC bit according to ETH DeferralCheck value */, X& f- F& L5 m  _4 [9 L2 |
  73. tmpreg |= (uint32_t)(macinit.Watchdog |
    9 E# r; A9 U7 D) w
  74. macinit.Jabber |" a% W2 U: p5 m  J5 k
  75. macinit.InterFrameGap |
    , t/ l' V( P' G. ^8 r
  76. macinit.CarrierSense |% z0 }, F2 H/ o7 `; j
  77. (heth->Init).Speed |- O! {: g* @, r; P+ [" n
  78. macinit.ReceiveOwn |
    9 u9 P  D/ D: C3 _
  79. macinit.LoopbackMode |
    8 A+ p: v; e  u, K
  80. (heth->Init).DuplexMode |3 Q( L& m9 L( H/ V7 R& R! M
  81. macinit.ChecksumOffload |1 S7 a% s3 o. [1 Z
  82. macinit.RetryTransmission |
    % b: [0 G& I; E  ~" }
  83. macinit.AutomaticPadCRCStrip |
    . P  \7 S9 f7 J( l# q
  84. macinit.BackOffLimit |
    , ]% U# c/ D; O% _) X, |* X
  85. macinit.DeferralCheck);$ N" ~, n, W& Q, @' D# E  i
  86. 6 `# d& R% i! u- r) O2 C- ?
  87. /* Write to ETHERNET MACCR */
    4 [$ Q& N9 }, E/ x# O
  88. (heth->Instance)->MACCR = (uint32_t)tmpreg;4 o7 C3 ]; B) F5 f* T
  89. 0 C: F0 N( {& t
  90. /* Wait until the write operation will be taken into account:
    # Z3 t# O/ _/ m3 H* A" `5 j
  91. at least four TX_CLK/RX_CLK clock cycles */( j9 r6 F4 Q; _9 y
  92. tmpreg = (heth->Instance)->MACCR;
    , A# j1 ^& M: j7 A$ ~
  93. HAL_Delay(ETH_REG_WRITE_DELAY);
    1 G, ~: j4 |4 o% Q3 |$ r/ B; q
  94. (heth->Instance)->MACCR = tmpreg;
    / C; X- s7 m- \% k% C9 L

  95. # O! I# z2 r/ l
  96. /*----------------------- ETHERNET MACFFR Configuration --------------------*/
    * l4 _: N! U0 Z
  97. /* Set the RA bit according to ETH ReceiveAll value */
    5 p* W0 S& X  h6 e# @, F6 I+ ?
  98. /* Set the SAF and SAIF bits according to ETH SourceAddrFilter value */  o7 X9 \- W) ~9 @6 b
  99. /* Set the PCF bit according to ETH PassControlFrames value */
    ( q7 a1 M# A1 G4 ]5 ^
  100. /* Set the DBF bit according to ETH BroadcastFramesReception value */
    ! i: `) s' a8 E0 W+ W# W# j; s9 w: M' W
  101. /* Set the DAIF bit according to ETH DestinationAddrFilter value */" @; B" U2 q, o& t( g
  102. /* Set the PR bit according to ETH PromiscuousMode value */
    , ^2 |& f( z" M# Y, _
  103. /* Set the PM, HMC and HPF bits according to ETH MulticastFramesFilter value */9 P- B3 x3 b, |
  104. /* Set the HUC and HPF bits according to ETH UnicastFramesFilter value */
    - x; e) r- t  Y: l2 l8 e3 L; U
  105. /* Write to ETHERNET MACFFR */. l! j" p8 z  G
  106. (heth->Instance)->MACFFR = (uint32_t)(macinit.ReceiveAll |
    # n7 Z  p6 M7 V2 Q1 Y
  107. macinit.SourceAddrFilter |
    ) w% J% Q9 a; ~
  108. macinit.PassControlFrames |! E6 C4 M) D/ V1 c8 Z
  109. macinit.BroadcastFramesReception |1 D1 K5 }0 F0 j; j
  110. macinit.DestinationAddrFilter |
    . P$ L2 p6 [$ [) p
  111. macinit.PromiscuousMode |8 \- L0 w7 s5 {4 y
  112. macinit.MulticastFramesFilter |- }) c/ \& r" R- a
  113. macinit.UnicastFramesFilter);. S" [- u# T5 q
  114. . U- q* \" Q: v: A; ?
  115. /* Wait until the write operation will be taken into account:3 t- ?- F; \2 q' U
  116. at least four TX_CLK/RX_CLK clock cycles */
    1 o% |: F8 n& @0 d
  117. tmpreg = (heth->Instance)->MACFFR;
    9 T5 ?- ~" N, ?  G  n
  118. HAL_Delay(ETH_REG_WRITE_DELAY);5 o2 [" c' S) C( R2 V7 o  D' D
  119. (heth->Instance)->MACFFR = tmpreg;
    5 U% y" H' y- u/ e* ^7 }
  120. 5 D7 ?0 b6 V# ]: Z% D5 V% ?9 p
  121. /*--------------- ETHERNET MACHTHR and MACHTLR Configuration --------------*/
    7 a7 f$ ~% v6 W1 H, f
  122. /* Write to ETHERNET MACHTHR */+ W; b4 x2 {" Z$ K
  123. (heth->Instance)->MACHTHR = (uint32_t)macinit.HashTableHigh;
    : d1 w/ E+ C; l

  124. , B/ L# ^+ h; J/ D1 J, K6 j0 e! _, {
  125. /* Write to ETHERNET MACHTLR */+ i- W9 P2 D& i: g
  126. (heth->Instance)->MACHTLR = (uint32_t)macinit.HashTableLow;' L1 A/ {) L. K5 F$ J5 u( A
  127. /*----------------------- ETHERNET MACFCR Configuration -------------------*/7 u# D$ g0 ~" `9 S

  128. # t' K6 b( v( W; n) B
  129. /* Get the ETHERNET MACFCR value */
    + U2 l& l- R) {! z
  130. tmpreg = (heth->Instance)->MACFCR;+ F  \: p( G# u' e$ ?/ y) z
  131. /* Clear xx bits */
    , A: d. W$ ^2 S3 O. Z" t$ ^" h
  132. tmpreg &= ETH_MACFCR_CLEAR_MASK;
    ( E& ]1 g- l# w; S: Q% s$ \

  133. 7 g. R3 C* d4 F( J
  134. /* Set the PT bit according to ETH PauseTime value */) U! S; Q+ y. `3 p
  135. /* Set the DZPQ bit according to ETH ZeroQuantaPause value */* _. s1 Z% @' [% |, L" G/ f
  136. /* Set the PLT bit according to ETH PauseLowThreshold value */
    ) H) t3 o9 r7 }! f
  137. /* Set the UP bit according to ETH UnicastPauseFrameDetect value */6 u% M; O1 C  _6 y# ?
  138. /* Set the RFE bit according to ETH ReceiveFlowControl value */" x- D8 |; N" c% Q7 ^
  139. /* Set the TFE bit according to ETH TransmitFlowControl value */
    - e; y% b* t. F2 u2 X. {. y% A6 [
  140. tmpreg |= (uint32_t)((macinit.PauseTime Instance)->MACFCR = (uint32_t)tmpreg;
    1 _# c7 s/ B6 i
  141.   V) ?" W4 ^* v* X
  142. /* Wait until the write operation will be taken into account:
    6 O/ E1 V2 m9 u2 |- g$ k
  143. at least four TX_CLK/RX_CLK clock cycles */
    " Y& g+ r2 P. g4 n3 \( f) [7 I
  144. tmpreg = (heth->Instance)->MACFCR;2 _7 @) q: g0 W; K5 h& H
  145. HAL_Delay(ETH_REG_WRITE_DELAY);4 n- t/ i  @) \+ N7 M. n
  146. (heth->Instance)->MACFCR = tmpreg;
    ( F. Z% k- k0 M* w! S

  147. 4 |& j8 [( `& r, P9 `
  148. /*----------------------- ETHERNET MACVLANTR Configuration ----------------*/7 z3 z6 t% i7 t
  149. /* Set the ETV bit according to ETH VLANTagComparison value */
    * |& K: ]* z- E7 s
  150. /* Set the VL bit according to ETH VLANTagIdentifier value */
    1 r8 M: j8 ]7 L  }8 j( e
  151. (heth->Instance)->MACVLANTR = (uint32_t)(macinit.VLANTagComparison |' U" I/ k) S+ M, q3 }  Z( t* n
  152. macinit.VLANTagIdentifier);
    9 U% u4 z. v& h; V" p
  153. 2 `  L+ }6 w5 J4 Y& [/ v; |
  154. /* Wait until the write operation will be taken into account:
    3 `: s. I3 q2 x
  155.    at least four TX_CLK/RX_CLK clock cycles */1 }" h( k9 a* M( i% I9 N! p5 W- g
  156. tmpreg = (heth->Instance)->MACVLANTR;+ A* T' L: u9 \+ f8 @" ]* p/ Z
  157. HAL_Delay(ETH_REG_WRITE_DELAY);
    * M, \+ [; _! y$ m) L4 A
  158. (heth->Instance)->MACVLANTR = tmpreg;
    4 b4 \3 `7 t- y9 w

  159. - r2 w7 G) D+ A: D6 l' C2 R
  160. /* Ethernet DMA default initialization ************************************/
    - ]! H' @( I# H0 M0 Q. @) p
  161. dmainit.DropTCPIPChecksumErrorFrame = ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE;. ]* g- o6 h4 k; \" u. G5 I
  162. dmainit.ReceiveStoreForward = ETH_RECEIVESTOREFORWARD_ENABLE;
    ( J* F2 R5 _& w% A" j
  163. dmainit.FlushReceivedFrame = ETH_FLUSHRECEIVEDFRAME_ENABLE;* Y2 K, t* a7 |' Y) i8 G  F
  164. dmainit.TransmitStoreForward = ETH_TRANSMITSTOREFORWARD_ENABLE;
    ! W* L# B" T! t. u( b
  165. dmainit.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES;
    5 X0 n3 {$ c5 w  ?& M' A" v  W
  166. dmainit.ForwardErrorFrames = ETH_FORWARDERRORFRAMES_DISABLE;
    + D; _! w) s3 {2 s
  167. dmainit.ForwardUndersizedGoodFrames = ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE;
    ( z+ K& v7 d6 w# G5 v& F4 j
  168. dmainit.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES;
    . H! E6 B3 @  `( s" B8 ?: c& w! ^. A
  169. dmainit.SecondFrameOperate = ETH_SECONDFRAMEOPERARTE_ENABLE;
    & ~' t- {4 o7 _( h( ?1 l) Y/ H
  170. dmainit.AddressAlignedBeats = ETH_ADDRESSALIGNEDBEATS_ENABLE;6 T) ]+ {* S; G+ I. B1 n
  171. dmainit.FixedBurst = ETH_FIXEDBURST_ENABLE;
    4 m- [+ ]" s5 Z0 Q# L
  172. dmainit.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;
    1 h& _+ ]! |+ m% M2 t0 y) |; e7 P
  173. dmainit.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;
    ; q, K# v9 B$ _* c+ e: Q
  174. dmainit.EnhancedDescriptorFormat = ETH_DMAENHANCEDDESCRIPTOR_ENABLE;0 F% Y8 N% s/ S2 P
  175. dmainit.DescriptorSkipLength = 0x0;
    " f- I% V" j3 |
  176. dmainit.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1;
    8 e4 Q. ?8 G2 J# }/ r

  177. ) P2 F9 j1 x7 {, b0 |3 d5 u7 ]
  178. /* Get the ETHERNET DMAOMR value */- f& @- `6 A& [, H/ Y! N
  179. tmpreg = (heth->Instance)->DMAOMR;
    6 k' C, v. F/ i! h& h$ V9 m
  180. /* Clear xx bits */, N( n. ~, w+ \) ~& K9 _4 k& ^0 z
  181. tmpreg &= ETH_DMAOMR_CLEAR_MASK;4 A) L$ U. ?, A
  182. : ^  N! _. @0 H$ a
  183. /* Set the DT bit according to ETH DropTCPIPChecksumErrorFrame value */
    7 b2 a# s# P* j. \5 @
  184. /* Set the RSF bit according to ETH ReceiveStoreForward value */
    1 Y. N8 l6 E8 x; e3 ~
  185. /* Set the DFF bit according to ETH FlushReceivedFrame value */
    7 p7 P9 P0 D: v" q6 @
  186. /* Set the TSF bit according to ETH TransmitStoreForward value */
      L' q7 y/ @1 b; C3 f- t9 |
  187. /* Set the TTC bit according to ETH TransmitThresholdControl value */
    1 k+ O, Q; f$ e
  188. /* Set the FEF bit according to ETH ForwardErrorFrames value */
    2 ~6 m9 u5 x: l6 W; D% r3 s1 Y% D
  189. /* Set the FUF bit according to ETH ForwardUndersizedGoodFrames value */6 [2 [4 F  i! Q% M: E! C
  190. /* Set the RTC bit according to ETH ReceiveThresholdControl value */, ?2 V0 }: j! S$ `3 ~
  191. /* Set the OSF bit according to ETH SecondFrameOperate value */3 }" k! m5 L1 [; W: P9 q: V
  192. tmpreg |= (uint32_t)(dmainit.DropTCPIPChecksumErrorFrame |
    ' l" B1 |7 C1 C+ x6 y7 O! z: [5 d8 ]
  193.                      dmainit.ReceiveStoreForward |
    # K$ u4 @* i# `8 K& I  J
  194.                      dmainit.FlushReceivedFrame |
    " B- e# n) V) ^
  195.                      dmainit.TransmitStoreForward |: C/ R; f( Q9 V; a
  196.                      dmainit.TransmitThresholdControl |& G& g0 I' `$ W9 V6 t
  197.                      dmainit.ForwardErrorFrames |1 F$ W7 v$ g; M! N* J& t! Y/ m
  198.                      dmainit.ForwardUndersizedGoodFrames |
    0 i. y# k/ G3 y7 y6 A
  199.                      dmainit.ReceiveThresholdControl |
      ?0 w+ L2 s5 ~9 B1 X7 z6 g
  200.                      dmainit.SecondFrameOperate);
    ) p3 t. B2 u; W8 Q
  201. 6 r: F9 r) D; |% r: {8 d
  202. /* Write to ETHERNET DMAOMR */
    . ]7 t1 z- k, v5 _
  203. (heth->Instance)->DMAOMR = (uint32_t)tmpreg;- n) i( f/ n( R6 Q) B+ g" g( D, W9 \9 {

  204. 1 u3 p! b( g( s' ~) ]% I
  205. /* Wait until the write operation will be taken into account:
    0 Z2 H0 G. u* x
  206.    at least four TX_CLK/RX_CLK clock cycles */
    " w& |2 F( L, Y; m: a
  207. tmpreg = (heth->Instance)->DMAOMR;0 x& c, V: q" \* @0 c/ O5 ]
  208. HAL_Delay(ETH_REG_WRITE_DELAY);/ ^* O4 ~. |: M/ {! z
  209. (heth->Instance)->DMAOMR = tmpreg;" K4 p4 D" W% \- J; D5 ?; J
  210. ( z4 J  Y3 ^5 g7 s5 M+ u6 l
  211. /*----------------------- ETHERNET DMABMR Configuration ------------------*/& l3 F! V1 J% _% Y3 A
  212. /* Set the AAL bit according to ETH AddressAlignedBeats value */
    3 [+ O6 m8 ]& \* R$ p2 A
  213. /* Set the FB bit according to ETH FixedBurst value */3 A& ^+ ^4 C6 M: j3 `- A4 u
  214. /* Set the RPBL and 4*PBL bits according to ETH RxDMABurstLength value */
    " X; A! Q+ R7 C  K' B8 u
  215. /* Set the PBL and 4*PBL bits according to ETH TxDMABurstLength value */4 U" V' {# X3 W" A3 [( M
  216. /* Set the Enhanced DMA descriptors bit according to ETH EnhancedDescriptorFormat value*/
    / A5 d  Y# Q4 A( p
  217. /* Set the DSL bit according to ETH DesciptorSkipLength value */
    6 i8 t) O5 k$ e) H$ e3 j5 ?
  218. /* Set the PR and DA bits according to ETH DMAArbitration value */  C( m9 [8 X9 Z$ @
  219. (heth->Instance)->DMABMR = (uint32_t)(dmainit.AddressAlignedBeats |
    4 o0 L0 ~& c( j8 P9 A. Q7 y$ k
  220.                                       dmainit.FixedBurst |1 F/ Q, \& M1 }# P: H3 _6 e$ o
  221.                                       dmainit.RxDMABurstLength |    /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */6 `9 {; E: }* G8 o$ O  c
  222.                                       dmainit.TxDMABurstLength |6 m: P% Q. g1 Q8 l" o
  223.                                       dmainit.EnhancedDescriptorFormat |; F" B; l, ^( \' N! {
  224.                                       (dmainit.DescriptorSkipLength Instance)->DMABMR;
    : P7 G& g- B2 E" x, {1 d& L
  225. HAL_Delay(ETH_REG_WRITE_DELAY);5 G' J/ Z9 j! B! p, `
  226. (heth->Instance)->DMABMR = tmpreg;
    5 g8 `: m0 Z2 S- t: Q3 B
  227. $ K9 j% P& I9 w  l5 \) V! j
  228. if((heth->Init).RxMode == ETH_RXINTERRUPT_MODE)
    ; P% Q  r0 z. `, k# {
  229. {
    " e3 m0 F# R1 M  M
  230.    /* Enable the Ethernet Rx Interrupt */
    . B, [  P1 K3 M6 P
  231.    __HAL_ETH_DMA_ENABLE_IT((heth), ETH_DMA_IT_NIS | ETH_DMA_IT_R);
    ' i8 J9 b2 d3 ]2 E! P8 x
  232. }
    ' e  a! W: `5 o. j) e+ I  `
  233. & I& ~$ ^* `; ~2 y
  234. /* Initialize MAC address in ethernet MAC */
    & s2 h& u& L3 {; K
  235. ETH_MACAddressConfig(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);4 C* |5 P- Z4 N( ~' H/ E
  236. }
复制代码
" N; r+ P8 P# P2 ~3 |
这里我就要稍微吐槽一下HAL库了
. j1 \& E1 t& X9 eMAC层过滤的设置没有预留接口出来,有设置MAC地址的函数
; _: [' r' `% c4 T9 h& m  k, W3 V2 V* y. v9 F* e0 i
static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr)
* x$ N  B/ x8 k; Z4 |9 v- O
; x* |# T5 s& V就不多做一个设置MAC层过滤的函数嘛,连后面用到的宏定义都有~~  k  U% Q, z- ]  }" A' D

' O$ H# x" E; v1 x. D木有办法,自己编一个初始化MAC层过滤的函数吧6 }% g# S" j: ]

$ a" H1 l# Z8 w9 `6 I- i& d0 d其实也就是把上面这个ETH_MACDMAConfig函数分离成两个单独的设置函数,再编一个设置MAC层过滤的函数/ v6 p0 f* X, I1 B. V9 B
3 g, |' \0 S$ i
开启MAC层过滤的初始化代码
! e) b& }5 n+ K: N
  1. uint8_t ETH_MAC_Setting(ETH_HandleTypeDef *heth), ?) N! J8 J1 n( J0 I
  2. {
    ; J1 a7 l. c* n7 B5 L- Y; B4 v
  3. ETH_MACInitTypeDef macinit;; d6 o3 N3 |' w/ N! M8 y
  4. /* Ethernet MAC default initialization **************************************/
    3 L, j0 B7 `; K/ h& ~2 m2 C
  5. macinit.Watchdog = ETH_WATCHDOG_ENABLE;: l0 E1 z, S  x5 ?6 K' f
  6. macinit.Jabber = ETH_JABBER_ENABLE;& R8 ?) h, Z0 U& z4 W+ [8 w
  7. macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;
    8 Q- p& F( I1 H& T5 A$ `; V( t5 Y
  8. macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;
    + M! t9 W, d# y9 \, @
  9. macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;: T* Q& Q" @) F$ H# U/ ^5 W
  10. macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;! q1 a! D$ x( i; Y4 \, h
  11. if (heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)
    6 l6 ?. M+ ?* W$ ?7 t/ s% i: n9 H
  12. {( I9 s9 W8 Z! u3 N, j3 w
  13. macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;
    , f4 j' @) |. x. N' j; W) }
  14. }
    1 X6 r- U# f0 L% ]
  15. else
    & _& K& L2 J$ n0 W, I5 f, w- E
  16. {5 ?8 Y8 r2 j; u: A* d2 d8 i! o. T
  17. macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;
    8 t: p2 J' f% }8 I' D8 p; p. ?4 z
  18. }
    6 I! C) b: W; U/ m
  19. macinit.RetryTransmission = ETH_RETRYTRANSMISSION_ENABLE;          //使能重传( K" K' C- R) t/ S1 U
  20. macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_ENABLE;          //使能自动去除9 ]0 U6 j2 f" |2 k
  21. macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;
    5 l" |6 {( @# }$ i2 S
  22. macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE;
    1 \2 @! }1 y! H% {/ l( W# {( k
  23. macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE; ///不接收所有包
    ' A& ?1 B* h4 n# m0 Q
  24. macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_NORMAL_ENABLE; //源地址过滤1 m- t: R0 t8 a. q/ u7 j) e
  25. macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;# L% p+ t0 e$ A# s
  26. macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_DISABLE; //广播不接收
      C9 H3 R; S* h) w8 x
  27. macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL; //目的地址过滤
    ( ]' U) G2 s7 @) [
  28. macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE; //混乱模式
    ) n- k8 J4 i# y. h# C2 R5 r
  29. macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECT; //多播过滤3 P/ d  ]) j% s: m1 i. |/ D- F
  30. macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT; //单播过滤
    7 m. @# C% A# l2 t7 X/ W: m) b
  31. macinit.HashTableHigh = 0x0; //Hash表高位
    % T& J( t. \( V+ _5 {: ]4 z
  32. macinit.HashTableLow = 0x0; //Hash表低位
    3 S5 C% d2 m" V% t8 N
  33. macinit.PauseTime = 0x0;0 M4 Q+ v/ D: O5 [% c; }
  34. macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;4 T5 a# y' Q) z6 |* g. f
  35. macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;& y. i; P! x9 o/ V" w
  36. macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_ENABLE;
    0 ?1 b$ c4 {7 E" _" B
  37. macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE; //接收流控. A6 W5 g# F. a" o) ]
  38. macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE; //发送流控
    , T. A# q" I9 q" v
  39. macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;
    + n. ^! g0 ^9 ~! X2 _
  40. macinit.VLANTagIdentifier = 0x0;
    5 ~( M# r  i  @! e  n

  41. * d' f9 M, w: k; |1 C& {0 e( P
  42. return HAL_ETH_ConfigMAC(heth, &macinit);# C* Y) Y! e8 G7 {6 O
  43. }
复制代码
( I* U# V2 N: i
默认的MAC层 DMA初始化函数9 l" {. K* k& T  m
  1. uint8_t ETH_DMA_Setting(ETH_HandleTypeDef *heth)
      |* r* G. ^5 B+ u
  2. {: j7 T) W) ^" p3 x8 z% C3 V
  3. ETH_DMAInitTypeDef dmainit;
    # K( b2 i0 Q+ p) a4 u
  4. /* Ethernet DMA default initialization ************************************/
    - _) n2 x5 Y1 ~
  5. dmainit.DropTCPIPChecksumErrorFrame = ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE;
    4 j. h, A* y" v+ o* \& d6 j
  6. dmainit.ReceiveStoreForward = ETH_RECEIVESTOREFORWARD_ENABLE;
    ' D9 N, P: m) c6 C$ b, K
  7. dmainit.FlushReceivedFrame = ETH_FLUSHRECEIVEDFRAME_ENABLE;  K+ a# ~4 ?- w7 p1 H" ]% I4 e7 J3 D
  8. dmainit.TransmitStoreForward = ETH_TRANSMITSTOREFORWARD_ENABLE;
    + L# w9 P0 U8 j# q2 k+ w/ m0 m
  9. dmainit.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES;: r/ J# C/ N5 X$ |$ j: u4 z
  10. dmainit.ForwardErrorFrames = ETH_FORWARDERRORFRAMES_DISABLE;! s2 I) J8 x0 o1 r- }" F
  11. dmainit.ForwardUndersizedGoodFrames = ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE;
    " u1 x$ p* k' l& [% k2 X2 L4 O
  12. dmainit.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES;
    ) }$ s+ S7 ^, ~" @; `. |  y% L
  13. dmainit.SecondFrameOperate = ETH_SECONDFRAMEOPERARTE_ENABLE;
    2 \) }- u$ M6 n4 e- Z4 V2 I
  14. dmainit.AddressAlignedBeats = ETH_ADDRESSALIGNEDBEATS_ENABLE;
    ! Q3 R# M- b) B0 A2 u
  15. dmainit.FixedBurst = ETH_FIXEDBURST_ENABLE;3 y( |: w" @" o5 a" N
  16. dmainit.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;
    " g( c+ ]% U& f% o. G5 f; M
  17. dmainit.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;
    - ]5 k3 a* j5 p
  18. dmainit.EnhancedDescriptorFormat = ETH_DMAENHANCEDDESCRIPTOR_ENABLE;
    + G, m! c) f& T
  19. dmainit.DescriptorSkipLength = 0x0;7 i/ v! U4 ?1 [5 C9 W6 e
  20. dmainit.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1;
    4 H$ d- E8 \6 E0 ~, e  ]- W5 O
  21. uint8_t res =  HAL_ETH_ConfigDMA(heth, &dmainit);% c$ I. I7 F' h( V  j7 g+ n; S6 V
  22. if ((heth->Init).RxMode == ETH_RXINTERRUPT_MODE)& k$ ]! \# u: V& P* L: Z% w
  23. {
    & x3 u/ K, W5 s, R7 D" A6 ?
  24. /* Enable the Ethernet Rx Interrupt */
    " Y( Q1 a  ]+ D; [
  25. __HAL_ETH_DMA_ENABLE_IT((heth), ETH_DMA_IT_NIS | ETH_DMA_IT_R);) m" d0 X# y2 I) b/ a0 `/ M
  26. }. S+ D8 P2 v. Q7 C8 N
  27. return res;+ k' u$ `" E5 X) n% B
  28. }
复制代码

/ j: a6 e* s/ }6 i/ X1 q用来设置MAC地址的函数(其实就是把库函数的static函数取出来直接用了)
  1. <blockquote>//heth: HAL句柄
复制代码
+ Q% @. C# b" j- A( w6 m
然后到最最重要的MAC层过滤设置
+ E, [2 C+ G& j
以MAC1为例% K% \: H, d/ f* e- M$ `' _; P

" P7 q$ X) Y, g; w! U, U
20191124093921254.png

& }' K9 j$ s. _- Z4 j2 ~& D4 X1 P: E8 ?
, n3 I6 Y; U. [7 l; n  r$ M& m
20191124094439199.png
3 X1 V5 p0 ]1 n! w2 F$ t9 [  y+ L9 b

6 V+ Q& c6 t9 g  f- l注意看红框的描述

9 n( h$ T" ?0 S! y6 ?1 E, d功能很好用,可以过滤源地址/目的地址,还可以做掩码功能
3 J" G0 _7 P9 J3 z3 T6 L" L设置MAC层过滤的代码  ^$ s9 @4 j, @2 M+ `: V
  1. static void ETH_MAC_Filter_Setting(ETH_HandleTypeDef *heth,ST_ETH_PAR * para)
    $ p: Z% ]% Z, M( Q  U/ q
  2. {6 V- M& c1 `! G! h& _9 `* a
  3.     //设置本机MAC地址. a7 i# g# b% Y
  4.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);) e) Q6 n) j9 K/ K0 T5 B% I( ?
  5.     //设置UDP-A的对方MAC地址
    5 F, A9 m; s7 V% a1 `+ |' r
  6.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS1,para->UDP_A_MAC);
    ' G6 Y4 J  |! a, {. B
  7.     (heth->Instance)->MACA1HR|=0xC0000000;//需要完全匹配UDP-A的对方MAC才接收
    1 a( ?* ]5 ^4 I8 J7 _
  8.     //设置UDP-B的对方MAC地址2 _3 R8 ]* t! |; x
  9.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS2,para->UDP_B_MAC);$ b  n. j2 |- ?, y# o0 S7 Y" \
  10.     (heth->Instance)->MACA2HR|=0xC0000000;//需要完全匹配UDP-A的对方MAC才接收
    , Q& e/ l7 D5 g* }4 ^9 l0 W
  11. }
复制代码

6 I! l0 q; }% R4 a) g% M1 Z我这里是希望为我的两个UDP精确过滤接收到的源地址6 k& `, G  X" d. u3 X4 M3 Q. z/ Q( i0 e
所以AE位设置为1,SA设置为1,MBC全部为0(MAC地址全部检查)% {1 O  y* V$ }( D4 i: p& ^5 p% ~
! N" y. i0 T0 P$ a
假如我希望过滤MAC中特定的厂家字段
) ~( R& u+ G( E/ p" [例如某个MAC地址

9 n, D! X! G6 |( F! t01-02-03-04-05-06( _: H. `8 B, @: ^: F6 Z
其中01-02-03就是厂家字段4 _/ g4 V3 A8 g$ V5 V

) W5 h  N1 Z, A6 G  ]+ q3 H那么代码要这样修改(MBC的第29位,28位,27位置1)
7 R8 ?& C8 I" b3 r0 b: V( a这样MAC层就不会检查MAC地址里后3个字节(04-05-06)
2 U7 D  Y% A* M" F9 R7 s但是会检查前3个字节,也就是厂家字段% A# R2 d/ K+ M1 S" \1 t
这里需要注意MAC地址的字节序
. _% x0 B/ S! }+ x) g/ b
  1. static void ETH_MAC_Filter_Setting(ETH_HandleTypeDef *heth,ST_ETH_PAR * para)
    + J7 |, R- L* W0 x/ t
  2. {( S% j. y* G, H- S( [
  3.     //设置本机MAC地址
    % ~8 G; N3 f6 T4 x
  4.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);
    4 e3 c9 S3 i) X, A* |1 L6 s: n
  5.     //设置UDP-A的对方MAC地址
    # a' e0 A- G! a3 p( j4 F. T& e
  6.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS1,para->UDP_A_MAC);$ G9 B- N& s3 W8 r
  7.     (heth->Instance)->MACA1HR|=0xF8000000;//需要匹配厂家字段
      J% F  |3 o$ u( J3 J
  8.     //设置UDP-B的对方MAC地址
    2 b7 @8 M/ J0 n! J, e# d$ w$ Z7 R: e
  9.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS2,para->UDP_B_MAC);
    * Z) W) u) }& p% L4 ~
  10.     (heth->Instance)->MACA2HR|=0xF8000000;//需要匹配厂家字段
    # |$ I1 b! R+ O$ m5 T  n. E4 |
  11. }
复制代码

5 |3 w) G8 S9 J) H& e7 `2 d然后这些函数的调用顺序按:
3 O; {. U. k' \1. HAL_ETH_Init9 D% j7 Q$ s! H2 S
2. ETH_MAC_Setting
& \/ e, u" m9 B3. ETH_DMA_Setting9 \6 J: u, L# y3 k
4. ETH_MAC_Filter_Setting7 C7 |; [( \) \1 b( D/ H) Y8 O

5 }5 @" W" @+ E$ [  _用你希望过滤的MAC传递到一个Hash计算函数里,得到一个值,通过这个值产生“映射”关系来过滤MAC地址,所以这个并不是精确的,因为可能会重复~~
! i: F* L; \2 s# e" v( K" H  s. R$ o2 G  v& q
HASH函数
0 i& A; T7 H( [函数
8 F+ ?0 S4 B2 E, @: S8 ?& H# D
  1. / STM32 MACHASH - Copyright (C) 2014-2018 Clive Turvey (<a href="mailto:sourcer32@gmail.com">sourcer32@gmail.com</a>)
    : b, w  x& N2 U( m- V. l4 V
  2. //  All Rights Reserved- }( d" i6 t+ z/ c6 m* C6 J% y* |
  3. 8 W( ~' N/ j1 u4 Q4 v8 X" k
  4. #include <windows.h>& U$ H0 \- ^& q( M/ _3 M
  5. $ n& ^" n! t/ V. Z0 ]
  6. #include <stdio.h>- r: c  O+ b4 N* H- y
  7. #include <stdlib.h>
    ' S% V. l* ]( P! ]

  8. # j4 w: U" h  a9 y
  9. typedef unsigned char uint8_t;
    & g$ W6 y! M  n
  10. typedef unsigned long uint32_t;4 {& P7 I+ J  h& z1 n0 L/ q

  11. % w% z! n# E) b
  12. uint32_t Rev32(uint32_t x)+ T' X& P' r& K! T0 g
  13. {2 M; P7 l! e9 a# P9 G; c
  14.   uint32_t y;$ d' h9 ^( A' k" Q
  15.   int i;
    ) n1 L7 O1 M& D/ O$ k' L

  16. % F! o  O- g) |6 I& {3 U+ h2 |
  17.   y = 0;
    . A0 T% p3 V0 W( n& Y) n9 J  V8 y
  18. 5 C6 t8 N. c  E' _* a
  19.   for(i=0; i<32; i++)
    ; F' i$ Y# L0 j) H' Q+ s; B% {
  20.     if (x & (1 << i))! A  X% X) ~* {1 I9 X" [4 Z
  21.       y |= 1 << (31 - i);1 Z3 X" o- j2 U7 f; c  Q

  22. ( h# G" m; _& C8 f
  23.   return(y);/ w3 k& `5 ^) s" r. D
  24. }0 x9 W  ^) v+ S+ _) j9 r
  25. , ]7 |2 k+ {) W. v' O; w
  26. uint32_t MacHash(const uint8_t *Mac) // <a href="mailto:sourcer32@gmail.com">sourcer32@gmail.com</a>
    5 Y. v" ~5 i) ^* a3 Q% n
  27. {0 t* q" T6 d9 \) @. i
  28.   int i, j;4 |6 K# A) j6 K, t  S" Y0 Q* n
  29.   uint32_t Crc;' s" z3 L- [% ?& }) r1 E/ x
  30. 3 L# w* M  p# |' B2 ]
  31.   Crc = 0xFFFFFFFF;
    ) `: V9 F* _1 R& L

  32. : ^+ [" a  B! ]3 X) p% d  D( A$ {
  33.   for(j=0; j<6; j++)
    5 d3 h5 j) |4 ^  ?( Z! Z) T
  34.   {
    & s0 s0 J3 G6 a+ n0 Y5 e9 W; ]: ^
  35.     Crc = Crc ^ (uint32_t)Mac[j];* c& A. A: F) ^; v" u* D
  36. 6 y- }1 j6 m3 f5 r0 m; P2 `
  37.     for(i=0; i<8; i++)' \7 e0 t- E' u8 u; {* Z+ v
  38.       if (Crc & 1)
    3 ]9 d3 b) T" S7 W
  39.         Crc = (Crc >> 1) ^ 0xEDB88320; // Reversed 0x04C11DB7. Z0 D3 A2 y* N& f/ N# Y. W2 W
  40.       else# X* V# D, t7 o1 ?/ c, m/ O, X
  41.         Crc = (Crc >> 1);
    4 J$ C+ Q4 N8 V0 u# i, o! m9 G! P
  42.   }
    ' a" M2 d$ k; D6 C
  43. % n3 P# j. X% Q
  44.   return(Rev32(~Crc) >> 26); // Get High order 6-bit in reversed/inverted CRC2 f9 q$ K, z0 X; T) B% _
  45. }
    " T# U  y3 H6 S* S$ \
  46. 0 a6 I! f9 k. K2 ~9 @
  47. uint32_t MacHashFast(const uint8_t *Mac) // <a href="mailto:sourcer32@gmail.com">sourcer32@gmail.com</a>! r' ]8 j& J7 F, V7 n: E  `
  48. {
    8 V* x& q1 ]- J9 l9 Y' {
  49.   static const uint32_t Rev6Tbl[] = {
    8 Z3 p9 b$ T5 W  W
  50.     0x00,0x20,0x10,0x30,0x08,0x28,0x18,0x38,
    6 F7 k4 Z0 {2 ]8 ~9 O: A
  51.     0x04,0x24,0x14,0x34,0x0C,0x2C,0x1C,0x3C,9 s6 E& w9 D7 k) v0 v6 f
  52.     0x02,0x22,0x12,0x32,0x0A,0x2A,0x1A,0x3A,
    - W: X4 i, \1 r! G$ u
  53.     0x06,0x26,0x16,0x36,0x0E,0x2E,0x1E,0x3E,) J& \' o, R, a
  54.     0x01,0x21,0x11,0x31,0x09,0x29,0x19,0x39,' U) K; i' b0 x8 ?% }
  55.     0x05,0x25,0x15,0x35,0x0D,0x2D,0x1D,0x3D,
    1 b% A  q3 P1 ~+ y
  56.     0x03,0x23,0x13,0x33,0x0B,0x2B,0x1B,0x3B,
    7 M# X( S0 W/ c
  57.     0x07,0x27,0x17,0x37,0x0F,0x2F,0x1F,0x3F };
    0 q& h0 r% k( C$ L$ R

  58. + P$ ?' x1 o9 Q
  59.   static const uint32_t Crc32Tbl[] = {6 r5 m. r/ R6 y6 z0 u. }
  60.     0x4DBDF21C, 0x500AE278, 0x76D3D2D4, 0x6B64C2B0,
    * |) w' a: K+ M3 e3 \7 Y$ Q
  61.     0x3B61B38C, 0x26D6A3E8, 0x000F9344, 0x1DB88320,! A) S( G2 _7 e3 p1 r  n7 Y/ p% i
  62.     0xA005713C, 0xBDB26158, 0x9B6B51F4, 0x86DC4190,
    : s2 ~# E) A) b8 c
  63.     0xD6D930AC, 0xCB6E20C8, 0xEDB71064, 0xF0000000 };5 F6 |: R0 ]" J  S! D5 X8 ~; F
  64. 0 M4 a. i& p& _' {: N) [8 ~$ @7 }. F
  65.   int i;
    9 ^. z# E1 M& p& w' A# h" R& V, E
  66.   uint32_t Crc;
    ) _# X5 E, Z  Q8 O) ]( K
  67. 5 S8 ~" ^7 l3 g8 V. \$ b
  68.   Crc = 0;
    $ i; B! y- D3 c! t1 r9 k0 l# W2 m

  69. # u8 x1 ?) O2 v0 _( A
  70.   for(i=0; i<6; i++)
    3 n2 k0 ]4 l: w3 j7 l- X
  71.   {
    8 z, d/ I" h2 w
  72.     Crc = Crc ^ (uint32_t)Mac<i>;% B, A* l6 F( j' [0 D4 x  z9 S

  73.   k9 a& c5 l% p/ w
  74. </i>   Crc = (Crc >> 4) ^ Crc32Tbl[Crc & 0x0F];  /* lower nibble */
    0 {+ K' Y. j" i( \$ |7 A/ R
  75.     Crc = (Crc >> 4) ^ Crc32Tbl[Crc & 0x0F];  /* upper nibble */! S4 r9 u8 x+ k6 F) j+ d* ~$ K1 L
  76.   }; G' `; N2 H$ S7 X  z3 C
  77. 3 R7 n: b8 n' o5 ^, J$ l, `* s2 j
  78.   return(Rev6Tbl[Crc & 0x3F]);
    0 A6 [0 M) \0 G& |: s( P: O3 p
  79. }
    * c! ~1 A6 ]$ W6 r- ?6 X# s3 g) n$ |
  80. , O6 }9 R# _' ~9 y
  81. int main(int argc, char **argv)
    0 t! Q1 p; `+ M/ m  h
  82. {' B. V* |8 {# X
  83.   static const uint8_t Test1[] = { 0x1F, 0x52, 0x41, 0x9C, 0xB6, 0xAF }; // 0x2C
    % ^2 m: d7 K7 N/ o7 q1 L
  84.   static const uint8_t Test2[] = { 0xA0, 0x0A, 0x98, 0x00, 0x00, 0x45 }; // 0x07
      P5 B! j6 u/ x: u$ C' ~& O
  85.   static const uint8_t Test3[] = { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x21 }; // 0x24
    # {: t2 V, S8 ~( P' K6 @

  86. ; D( o+ ~5 d0 i% U$ a3 ~  z8 x+ Y
  87.   printf("MacHash %02X\n", MacHash(Test1));6 f. e4 m6 @6 ~' n# r. r3 a) M
  88.   printf("MacHash %02X\n", MacHash(Test2));0 }; q! T: `3 q% e  M
  89.   printf("MacHash %02X\n", MacHash(Test3));
    . w" g( ^- p' u0 j$ Q
  90. ) O5 i" R: u1 O
  91.   printf("MacHashFast %02X\n", MacHashFast(Test1));! S* [- u" y# M. W& w; M- {
  92.   printf("MacHashFast %02X\n", MacHashFast(Test2));6 p4 C3 ~3 f7 q0 F1 f3 V
  93.   printf("MacHashFast %02X\n", MacHashFast(Test3));7 W0 m8 ~. T# u7 H5 P
  94. 9 V" o) U9 p2 g( N9 z2 j
  95.   return(1);
    * h' p7 k) f1 s& `. |" X6 O% k
  96. }
复制代码
" E& m4 n- x7 N0 q/ N' I
. ^6 a$ n' B" [+ E$ T* r4 \
回到手册
. W+ b; ?9 ?1 c. i0 E5 i+ z
. ?( @% [' {  ~
20191124100604140.png

# a6 Z) D6 t/ L9 K0 ~/ j+ f' n# ]3 [" h0 f
20191124100636882.png

1 g7 r  X9 x& u+ W$ o# e7 d3 z2 H9 w4 f- F3 I1 K' v: i
( r" G- |9 R2 w8 h
上面的函数算出来一个数,假如是手册上的那个0x2c,二进制为101100B
: w4 P9 G& C+ V# k1 r/ j* [$ P换句看得懂的人话···就是:, |, R9 O7 F" D7 `! ]7 |
算出来的数先看第6位" t8 i: N8 Q4 M, q1 d, C
是1的话说明用到的是HASH表高位寄存器
0 Y' M4 c% C2 L/ O! W否则用到的是HASH表低位寄存器
4 Z/ L, T, H2 f/ x% ]' j5 l  i然后剩下的5位,转成十进制不是12嘛
3 [& X6 O0 g' Y7 V  s如果你希望过滤这个MAC
, S- f, a8 v8 U: _8 ]8 w8 r1 q那么你就把对应的HASH表高/低位寄存器的对应位置1,否则置0
% B$ k( u* u; r) w, c这里的0x2c就是要把
$ [; Z" l2 w9 R& s7 v! |1 xHASH表高位寄存器的第12位置1
' X5 C2 O; l9 E6 r2 R8 S就可以过滤这条MAC了
& o0 Z% ?) h. d" ?2 T) D然后把你希望的MAC地址都按照上面说的方法弄完  H' t$ E& ~6 h" D/ ~
% K2 U& H. |7 f" T2 ]# g/ `
回到这个函数稍微改一下9 Z1 H( L4 ]: p% a
  1. uint8_t ETH_MAC_Setting(ETH_HandleTypeDef *heth)
    + n: O+ M7 ?2 A5 k! D
  2. {
    , y1 |; b( w2 l6 l9 ?
  3.     ETH_MACInitTypeDef macinit;
    7 c2 {( N. v6 B+ Z, {4 Y
  4.     /* Ethernet MAC default initialization **************************************/% n6 w" q6 O* c  o* u
  5.     macinit.Watchdog = ETH_WATCHDOG_ENABLE;5 U# s: ^2 R9 X: h4 F
  6.     macinit.Jabber = ETH_JABBER_ENABLE;
    4 y7 f5 c! F# `- s/ Z/ F. K
  7.     macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;
    - W8 s& Z0 s! E) B$ ]
  8.     macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;! q$ h9 O, u# k2 a
  9.     macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;
    $ Q% P2 z( s% w+ G
  10.     macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;  ~8 e) {3 e! d0 G& ~' E5 T- Y
  11.     if (heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)
    & O9 ^( F! G; w# U6 m$ W
  12.     {
    3 q& `( ?8 S, b9 D7 e+ g* c- ?7 @$ D
  13.         macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;
    * e' F  J6 @( o
  14.     }
    2 m; w0 F  z1 N$ D* H$ r8 o
  15.     else4 R# a$ E1 O5 A/ w4 }6 ^- i
  16.     {. ~1 i# B" j$ d: g( d
  17.         macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;# P+ A$ _" L  N
  18.     }: T; ]% u$ m" o; `. d) x( K- D" A
  19.     macinit.RetryTransmission = ETH_RETRYTRANSMISSION_ENABLE;          //使能重传) Q7 a7 {5 D% O0 P
  20.     macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_ENABLE;          //使能自动去除
    ; R0 f2 _$ L) ^2 K( y3 q
  21.     macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;  h9 g1 r/ s& V. j/ Y1 s: Q
  22.     macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE;7 k, A( D+ |& K# Z6 j
  23.     macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE; ///不接收所有包4 p( i( a% B( X$ C
  24.     macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_NORMAL_ENABLE; //源地址过滤
    4 j2 a/ f3 f' n  Q! P% E
  25.     macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;- H4 O0 A% n% T, @
  26.     macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_DISABLE; //广播不接收
    ) Q4 {$ I/ @* Q- J* w1 ^: {% R
  27.     macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL; //目的地址过滤
    * F" f9 S' S7 |- W; u- D! A
  28.     macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE; //混乱模式
    7 X7 a  }% `9 X) ^# k) s
  29.     macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECTHASHTABLE; //!!多播HASH完美过滤
    ! k: y) j  w4 t( f
  30.     macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECTHASHTABLE; //!!单播HASH完美过滤
    / J/ t' z/ k4 u2 C
  31.     macinit.HashTableHigh = 0x0; //!!填你最后算完的Hash表高位. H1 ~. R3 \; T! _% e$ D6 \
  32.     macinit.HashTableLow = 0x0; //!!填你最后算完的Hash表低位
    ' T* X# _5 P) ^# y% J7 R( f5 {
  33.     macinit.PauseTime = 0x0;6 t- N4 ?* L+ U' r
  34.     macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;) ^. ~3 ?$ w0 D$ r' K* v+ `' U9 e
  35.     macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;
    ) \1 q4 b, ~1 ]6 U3 @  F) t! o) v1 f
  36.     macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_ENABLE;
    - s) {, a) r* `' ]4 \
  37.     macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE; //接收流控3 T* [/ N( J' Q& ]) ]1 W
  38.     macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE; //发送流控5 S: B8 q) ^9 I- G
  39.     macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;4 c6 i" X- W1 M+ n$ y% g
  40.     macinit.VLANTagIdentifier = 0x0;1 P( ^& l! V5 u0 z+ J  `/ u8 I
  41. ! M! B4 D% _$ W+ I- Y
  42.     return HAL_ETH_ConfigMAC(heth, &macinit);7 \0 |1 r. t% T, L& M4 ]! `0 X
  43. }
复制代码
& b6 ]- E" D/ q' U$ D* H: ^
大概MAC层过滤就这些东西了4 e# m1 f/ @, e6 s
如果有条件弄MAC层过滤真的强烈建议开启,可以大幅减轻协议栈的处理负担,板卡不会因为处理大量无用的数据而白白浪费处理性能。
7 C4 u% ^+ F% x/ W7 ^( E2 h
6 Z( D: n6 y* V, e' K5 G  }' V. p9 q
( V: |) o) {4 W* a8 O/ s8 Y) f( S
* G3 e5 X3 k2 |! v4 Z% U+ u; `
收藏 评论0 发布时间:2021-12-14 10:15

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版