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

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

[复制链接]
STMCU小助手 发布时间:2021-12-14 10:15
前景描述/ M/ ?; h5 T0 m7 p7 Z
我司的以太网实现是LAN8720搭配片上MAC层做的,协议栈用LWIP
5 `) _  j4 t' X- T& A4 n5 j$ Y
这种做法应该还是蛮常见的,反正不是LAN8720就是DP83864,再不然就是硬件协议栈的W5500了
0 j5 @& t! P7 w/ y7 x' p/ Q, m$ `1 M, b# J7 s8 j
想想还是有MAC层过滤比较好,随手翻了翻它的手册,W5500好像是没得MAC层过滤的
) x% i  Y) O; J2 k
  ~4 u3 P% i$ ?9 [假如数据速率比较高,数据量大,而且外面还有乱七八糟无关的数据往板卡送,我也不知道用这个片子到底好不好
. P) H# d8 d2 {% K0 {) G8 V8 [) i8 X8 }6 f9 H
LAN8720也不好改了,就继续用吧2 V& k9 Z* k1 b! Y0 y' f1 l5 v
0 q+ h/ B. [- K& q) K
好好在,发给板卡的数据的MAC还是有特征的,我只需要过滤发送方MAC地址的前3个字节,也就是特定的厂家那段1 U8 V' i7 C; ]+ ]0 D0 ~3 Z# `
" X1 _0 m4 S; E) W9 l3 l( Z
MAC地址的科普知识这里就不过多描述了,我们直奔主题
' V* e- p4 M8 s, ]6 A4 c3 a2 W6 {! ^5 J( `
怎么用STM32 F7的片上MAC做MAC层过滤2 c5 D! |: j+ S4 J: r- b! n

- v' w% i1 F- @; N写这个的目的,就是我搜了搜,没看见有人写这个MAC层过滤功能,具体代码怎么写才能用" `3 `$ W3 B: I: Z6 o2 L5 O

4 n1 @) s. R$ X9 L3 X6 x1 M知识科普-STM32的片上MAC
- ]: w* w9 j7 f4 E! O) h2 f1 q$ i1 ~STM32 F7的MAC层过滤方式有三种(说人话的直白解释,中文手册其实也翻译的不好)! {! a$ _% s8 L! u2 J4 C* t& v0 [" J, u
精确过滤(手册上叫单播目标/源地址过滤)
9 s8 E( _* j- {) ?+ Y4 ^0 k粗糙过滤(手册上叫Hash表过滤)
0 V, F+ [7 R$ w2 M. F特殊过滤(广播,组播过滤等等特殊的过滤)$ F9 \; C" j3 q% R, O0 }$ c
我这里着重说第1种和第3种
5 ?$ D+ }: _" F) C; [# d1 h! B; h& a( }6 S; x) w. |
STM32 F7可以存4个MAC地址
/ W* G; m+ p# X8 s: q; S其中MAC地址0是自己的MAC,其他三个可以用来做过滤) A" q  A$ a2 m" J2 g! I& e
, Q, z* m% J0 W: h8 [4 m) M
网络数据包通过PHY进入STM32的MAC,MAC层是可以对目的地址/源地址检查并过滤掉没得用的数据的,默认的HAL库库函数HAL_ETH_Init中' C4 @# y# q# ~/ n. i7 ?
有一个static的函数
" H% a4 D) d7 g2 S4 Ustatic void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err)
6 I. w) _+ P( q6 o2 N; p会帮你在初始化网络功能时初始化默认的MAC层功能:$ N, {' n: j! I; L
关闭源地址过滤; o; `4 g" Z! X* q( C" Y5 j5 b4 A
不接收所有数据. t8 B6 y: n+ r' H' U5 o6 P
接收广播帧
4 {/ I, k3 N- ~6 ~- h* ]' l( R打开目的地地址过滤
5 `; q- ^3 r7 D! z& W单播数据精确过滤7 E3 a# ?" D/ z) L2 v3 d, w
组播数据精确过滤
$ g) E3 A$ i) hHash表过滤关闭3 r2 O9 c( T3 I

6 W6 c: P7 W' ~7 s9 X其他的功能自行研究,我这里捡重要的说
. R1 x+ z& ^0 u* G6 J
  1. static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err)
    / z$ [( e5 n; n: f/ u- q# U8 ~
  2. {
    , a1 O/ L/ |6 I2 K
  3. ETH_MACInitTypeDef macinit;8 }% s$ P. B- f% K/ }) u
  4. ETH_DMAInitTypeDef dmainit;
    2 o( a: @( z! k# O5 c6 a0 E2 `2 Q
  5. uint32_t tmpreg = 0;; z/ l5 E3 G# X/ v6 Y% C- H  A
  6. 9 ^: m3 T/ S% S" u) c
  7. if (err != ETH_SUCCESS) /* Auto-negotiation failed */! F, }& U6 |# H+ b/ h- A3 \
  8. {
    ( X- q4 N7 G5 s% b
  9. /* Set Ethernet duplex mode to Full-duplex */! W# l- y$ W! r; F3 W8 `& _4 G/ i
  10. (heth->Init).DuplexMode = ETH_MODE_FULLDUPLEX;; `* c, |; ^7 w8 X5 ^
  11. 5 `" l/ I+ Q' {
  12. /* Set Ethernet speed to 100M */4 @( r! _6 t, x2 l% @& f) D' {$ k
  13. (heth->Init).Speed = ETH_SPEED_100M;+ x, I1 i7 h1 ]0 B4 e; A. J5 H! i4 ^
  14. }/ k2 J5 Q% Z+ ?2 g7 L8 Q( l, ]' d
  15. * @$ W: u$ `/ h8 J! s* p' J3 r
  16. /* Ethernet MAC default initialization **************************************/% m5 n4 t) ]* j6 [! n/ T, H  Q  b
  17. macinit.Watchdog = ETH_WATCHDOG_ENABLE;
      A5 t& I5 V7 c: s2 D
  18. macinit.Jabber = ETH_JABBER_ENABLE;
    1 u- L3 p( F! E- }! n
  19. macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;
    8 h. k2 L  _' N5 J
  20. macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;
    ( U3 c. E2 G; l( A" D; t* O! Z
  21. macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;' y7 u. i( G5 @: |4 h6 |
  22. macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;* V% a" Y+ Y+ L" `0 D  F3 p! n
  23. if(heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)3 H+ G! v( y+ R5 V
  24. {) Q7 d% O" z' k8 W# Z
  25. macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;
    ( F* l  j) _3 Y( }3 x6 J% E
  26. }
    7 g: f2 D! ?# c. a
  27. else
    1 H& e, r- r2 J! }! h  c
  28. {$ ]7 Q4 Z2 }  d  s) f( s: b; y
  29. macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;0 ?% L0 P' i- j, S; F% b  Y
  30. }
    1 Y: b2 Q# R+ q0 q+ P( @
  31. //这一段是MAC层过滤的设置,下面是DMA的,那个用默认的就可以
      u2 B/ z) s0 r2 q4 T: G9 Z! \  E
  32. macinit.RetryTransmission = ETH_RETRYTRANSMISSION_DISABLE;
    - a* h1 U# I1 O+ q& _, H8 n
  33. macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_DISABLE;
    # O3 r2 B2 z, s4 k2 C' L) r
  34. macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;
    5 c. A5 @! l/ Q# z% u* H
  35. macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE;  o& n& J5 M, P7 [% ~$ k5 S
  36. macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE;7 |" x1 @) e/ w
  37. macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_DISABLE;
    # c3 R7 x# }- k
  38. macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;) \9 `% w$ d4 w4 I6 o' i
  39. macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_ENABLE;: Y# |# g" w2 \, {" c. P
  40. macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL;
    0 c  Y& M2 I- k/ `7 R
  41. macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE;9 l& ]1 \# \; R. s  c
  42. macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECT;; C: z. c! c) D; R0 v2 f* F1 h
  43. macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT;
    5 E0 I1 d! r0 X6 a2 R. G
  44. macinit.HashTableHigh = 0x0;
    1 M  [+ t- |( e( H
  45. macinit.HashTableLow = 0x0;
    2 _; i7 e9 s1 e  x% ^) j
  46. macinit.PauseTime = 0x0;9 z2 J: l$ A3 \" {& S; s
  47. macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;
    0 o7 c4 I8 v; X& I% v1 \$ X
  48. macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;
    + l, u( O  H( a( w1 O+ Y" d/ [
  49. macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_DISABLE;
    & @* r, V+ R1 e1 T5 u
  50. macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE;
    : H, j6 [0 N" l; {9 x- `
  51. macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE;; J6 p! C) |% \$ e+ N! g8 w# y+ q0 r
  52. macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;4 z9 f5 C, R+ V7 [. B2 w
  53. macinit.VLANTagIdentifier = 0x0;, k& n* e; q! _; u2 w7 M2 I* f3 M
  54. : \) i4 m) d0 h: G& ^- E/ K9 N& E  x
  55. /*------------------------ ETHERNET MACCR Configuration --------------------*/' K+ C2 Z2 o* z! [  ]
  56. /* Get the ETHERNET MACCR value */
    ) E; w, x2 a7 M7 w
  57. tmpreg = (heth->Instance)->MACCR;
    2 b+ ]5 l5 D3 h& P" X
  58. /* Clear WD, PCE, PS, TE and RE bits */
    . w; B, [5 b3 C0 _* i
  59. tmpreg &= ETH_MACCR_CLEAR_MASK;9 k3 C( K% a  y! \; K
  60. /* Set the WD bit according to ETH Watchdog value */8 x- J& {- c2 F* n! n0 M+ |
  61. /* Set the JD: bit according to ETH Jabber value */
    1 [' Y( _" [+ J1 f+ U1 S# p
  62. /* Set the IFG bit according to ETH InterFrameGap value */$ Z, p/ ?) H) u9 w
  63. /* Set the DCRS bit according to ETH CarrierSense value */
    $ B8 J$ c( w) }3 G
  64. /* Set the FES bit according to ETH Speed value */
    3 o4 J: C% w0 L+ H1 v& Y
  65. /* Set the DO bit according to ETH ReceiveOwn value */4 D* E8 y; y& j+ A, |' W+ q7 D0 A: S! S
  66. /* Set the LM bit according to ETH LoopbackMode value */  C1 j, ]5 J9 s3 g7 N
  67. /* Set the DM bit according to ETH Mode value */
    7 _3 s. @: s) h; ~* g
  68. /* Set the IPCO bit according to ETH ChecksumOffload value */
    ( K/ Y8 Q# S4 N6 J
  69. /* Set the DR bit according to ETH RetryTransmission value */- j( `7 t9 c+ ]; ]% C8 Q
  70. /* Set the ACS bit according to ETH AutomaticPadCRCStrip value */
    + z* @: Y1 c7 t# [/ l
  71. /* Set the BL bit according to ETH BackOffLimit value */
    6 C6 H4 A7 h) |' t# r8 k* T' a
  72. /* Set the DC bit according to ETH DeferralCheck value */
    # y# m7 N" ?; H* F
  73. tmpreg |= (uint32_t)(macinit.Watchdog |
    ' x& k+ S6 o9 n! K, `5 M
  74. macinit.Jabber |
    5 Q5 Z) a4 x. ]4 N
  75. macinit.InterFrameGap |
    ! n3 \  u1 f) z/ ?) C
  76. macinit.CarrierSense |
    , r% |' \3 r' o9 u' z
  77. (heth->Init).Speed |- Q9 b, z6 Q% {  l) ^- f! i
  78. macinit.ReceiveOwn |+ I% q0 j3 z& a  _( M/ `
  79. macinit.LoopbackMode |* C( f9 D5 F8 ]( E- M/ h: h) g! r# K% w
  80. (heth->Init).DuplexMode |
    0 a1 J% ]- D8 P) c6 t. E! Z
  81. macinit.ChecksumOffload |
    * s- b5 r2 G2 l6 [4 j
  82. macinit.RetryTransmission |# [" l! H1 ]7 G0 A. w( }+ W/ z
  83. macinit.AutomaticPadCRCStrip |
    ; b7 K$ y# v5 A( l- t
  84. macinit.BackOffLimit |6 J; _) @1 @6 K% L8 f
  85. macinit.DeferralCheck);. s3 U- i2 n+ E5 F4 Q. x8 v3 i9 Y# N
  86. " K* J1 J- S/ W8 a( R
  87. /* Write to ETHERNET MACCR */6 y2 N9 R% T) Q
  88. (heth->Instance)->MACCR = (uint32_t)tmpreg;
    7 k  C- {, U" @7 E3 \7 w

  89. # g: k. `5 ^3 k) L0 h& d$ a
  90. /* Wait until the write operation will be taken into account:
    ; e  T1 e' d- r  ?+ T
  91. at least four TX_CLK/RX_CLK clock cycles */
      Y8 {" B8 B7 x$ g. x- u; ~0 p! P, b, _
  92. tmpreg = (heth->Instance)->MACCR;4 `! U! F2 I+ E1 z. r
  93. HAL_Delay(ETH_REG_WRITE_DELAY);
    0 o! M* A8 n) \* B
  94. (heth->Instance)->MACCR = tmpreg;
    # e2 C  M- {" G; @7 o

  95. ) E( Q- _% J- Z5 m
  96. /*----------------------- ETHERNET MACFFR Configuration --------------------*/
      i$ y0 d( i' w6 R9 a, F
  97. /* Set the RA bit according to ETH ReceiveAll value */" a/ Z, T9 g+ m/ ]
  98. /* Set the SAF and SAIF bits according to ETH SourceAddrFilter value */5 f3 L; j  s  |6 N; P
  99. /* Set the PCF bit according to ETH PassControlFrames value */
    " B; L" K& n/ y! `" y2 E& r. R
  100. /* Set the DBF bit according to ETH BroadcastFramesReception value */
    ; i( X/ z6 q+ `$ F0 x- c
  101. /* Set the DAIF bit according to ETH DestinationAddrFilter value */
    2 R/ \- |5 ]9 T9 R
  102. /* Set the PR bit according to ETH PromiscuousMode value */2 C" k$ U  ~2 L$ M2 z) f
  103. /* Set the PM, HMC and HPF bits according to ETH MulticastFramesFilter value */
    0 R1 _# |* }% U  D
  104. /* Set the HUC and HPF bits according to ETH UnicastFramesFilter value */
    ( x+ ]( W( N' x- J8 G) l
  105. /* Write to ETHERNET MACFFR */5 K8 x0 v. U/ b$ V/ \& U7 W/ v2 u
  106. (heth->Instance)->MACFFR = (uint32_t)(macinit.ReceiveAll |
    % V9 w9 D8 H5 P8 S; w4 g6 I2 h
  107. macinit.SourceAddrFilter |
    % A# L# q) t* v; v5 J$ [
  108. macinit.PassControlFrames |: P4 T$ k/ ]5 e% Q! D
  109. macinit.BroadcastFramesReception |9 D+ t9 z8 |: b+ P
  110. macinit.DestinationAddrFilter |
    & S( d. G) T0 h! e* T
  111. macinit.PromiscuousMode |# b2 J7 P" @2 ^/ D
  112. macinit.MulticastFramesFilter |
    # o/ j: Q; |* H; `5 |; I
  113. macinit.UnicastFramesFilter);
    6 {$ T9 Y/ c7 c: t7 q2 L/ ~' }
  114. ' R5 b# i* |3 E
  115. /* Wait until the write operation will be taken into account:0 b" G% K1 i, R0 C( n% y9 n" N$ u
  116. at least four TX_CLK/RX_CLK clock cycles */
    7 x$ Y1 H4 a2 p3 _
  117. tmpreg = (heth->Instance)->MACFFR;
    + d0 o  S! @' w+ J* s, v
  118. HAL_Delay(ETH_REG_WRITE_DELAY);8 t3 r! |' P; M7 N% L! S
  119. (heth->Instance)->MACFFR = tmpreg;
    $ C- @; w/ [" h

  120. : S/ Z% K# ^  m3 G
  121. /*--------------- ETHERNET MACHTHR and MACHTLR Configuration --------------*// g8 r5 i9 b( X) |9 `. H. P
  122. /* Write to ETHERNET MACHTHR */6 D6 ?! F) |) M$ E$ w
  123. (heth->Instance)->MACHTHR = (uint32_t)macinit.HashTableHigh;: Y1 J4 C. n5 ^9 k+ l2 n* Q

  124. 2 F; P  _) Q. s) k- a+ p% [) [
  125. /* Write to ETHERNET MACHTLR */" y8 a) `: ]! L4 Y
  126. (heth->Instance)->MACHTLR = (uint32_t)macinit.HashTableLow;
    - i7 x9 p5 L0 w7 F  H5 ?
  127. /*----------------------- ETHERNET MACFCR Configuration -------------------*/" b% @2 }  E' N' e$ i
  128. $ I" F) |- O$ k1 P7 r2 G  t3 b6 b
  129. /* Get the ETHERNET MACFCR value */6 i) _8 V- F: d# X% h
  130. tmpreg = (heth->Instance)->MACFCR;* D; e* m) j4 I/ ~* N
  131. /* Clear xx bits */
    4 ^" h" b- A6 u# T
  132. tmpreg &= ETH_MACFCR_CLEAR_MASK;5 m! s3 m- F$ z! d8 ^9 s' z
  133. * p$ W* q9 W2 ]( J0 A! F
  134. /* Set the PT bit according to ETH PauseTime value */1 L/ G# \  `* r  v0 R4 W8 y/ n
  135. /* Set the DZPQ bit according to ETH ZeroQuantaPause value */% M' }! Z- d3 |( @6 d
  136. /* Set the PLT bit according to ETH PauseLowThreshold value */& ]& w" P; i# t& K( A8 C
  137. /* Set the UP bit according to ETH UnicastPauseFrameDetect value */
    3 M2 L; c+ N* g5 s
  138. /* Set the RFE bit according to ETH ReceiveFlowControl value */
    5 m0 L8 k9 X, [0 z) j
  139. /* Set the TFE bit according to ETH TransmitFlowControl value */3 @- C* C/ Q! P' c& }
  140. tmpreg |= (uint32_t)((macinit.PauseTime Instance)->MACFCR = (uint32_t)tmpreg;
    " a! G# V4 X: F7 I, m

  141. 1 m& o! w: d! c* ~! t) h
  142. /* Wait until the write operation will be taken into account:
    1 {4 Q' }& u+ C! n' k; w2 ]" i
  143. at least four TX_CLK/RX_CLK clock cycles */$ j" p5 Q% }: ]4 H" i
  144. tmpreg = (heth->Instance)->MACFCR;; M+ X; S2 r7 v7 [
  145. HAL_Delay(ETH_REG_WRITE_DELAY);* K! Y% r) _4 T; @# S, W
  146. (heth->Instance)->MACFCR = tmpreg;
    3 K7 m% _$ S, @1 r6 x9 @& A
  147. 8 @$ Q  Z0 W! e
  148. /*----------------------- ETHERNET MACVLANTR Configuration ----------------*/
    6 M. z- j: v  ]( w
  149. /* Set the ETV bit according to ETH VLANTagComparison value */
    9 H$ {% i; o: v
  150. /* Set the VL bit according to ETH VLANTagIdentifier value */' s3 u0 ~0 s2 K! [
  151. (heth->Instance)->MACVLANTR = (uint32_t)(macinit.VLANTagComparison |6 h9 n# R0 \, x& P+ q' f
  152. macinit.VLANTagIdentifier);/ x4 B$ v! D& g9 e& f

  153. ( c" v7 k. E& H6 X
  154. /* Wait until the write operation will be taken into account:) I, U  w9 \& t; y" P$ o
  155.    at least four TX_CLK/RX_CLK clock cycles */" z0 ~* i) u6 U, h  B
  156. tmpreg = (heth->Instance)->MACVLANTR;3 d( m% o; U9 r/ \& Y5 Z
  157. HAL_Delay(ETH_REG_WRITE_DELAY);/ Q. G; s; B9 F5 n; h
  158. (heth->Instance)->MACVLANTR = tmpreg;
    & H- ~' Y* E( d

  159. " L- V% h9 l9 F  O: O3 A( p3 H
  160. /* Ethernet DMA default initialization ************************************/1 x8 {' h. v" T
  161. dmainit.DropTCPIPChecksumErrorFrame = ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE;
    + ]7 C1 r- w4 k$ z/ k% t% p
  162. dmainit.ReceiveStoreForward = ETH_RECEIVESTOREFORWARD_ENABLE;
    - s0 P7 Y* j% c+ @0 b
  163. dmainit.FlushReceivedFrame = ETH_FLUSHRECEIVEDFRAME_ENABLE;
    : K: p: P! G4 d9 f8 t, O  N0 i
  164. dmainit.TransmitStoreForward = ETH_TRANSMITSTOREFORWARD_ENABLE;
    : H: r" [, [7 `8 f$ c9 V
  165. dmainit.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES;
    ' v! C+ z+ ^+ [# G
  166. dmainit.ForwardErrorFrames = ETH_FORWARDERRORFRAMES_DISABLE;- B' M9 g1 I8 }. G2 L
  167. dmainit.ForwardUndersizedGoodFrames = ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE;& m* ?, e. f" T& a# Y/ V
  168. dmainit.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES;& W: W6 M* y# v# t0 p7 j
  169. dmainit.SecondFrameOperate = ETH_SECONDFRAMEOPERARTE_ENABLE;
    1 A% G$ S, Y/ `5 O! C
  170. dmainit.AddressAlignedBeats = ETH_ADDRESSALIGNEDBEATS_ENABLE;
    - ^3 c( [/ v* |+ f# ]- ], A% q
  171. dmainit.FixedBurst = ETH_FIXEDBURST_ENABLE;7 v' ?- k& I$ _" g3 r
  172. dmainit.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;
    4 k7 ]! u* A, @7 N/ K! b
  173. dmainit.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;
    ) g9 @8 |" g& g. D- D* h
  174. dmainit.EnhancedDescriptorFormat = ETH_DMAENHANCEDDESCRIPTOR_ENABLE;
    7 V, H1 {5 t( W$ j  N0 d# b+ D9 z
  175. dmainit.DescriptorSkipLength = 0x0;
    9 A4 H; j$ {  ?' Y
  176. dmainit.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1;
    + B  U4 I1 V' @; d/ O% f  G

  177.   Z* f) [5 i( e
  178. /* Get the ETHERNET DMAOMR value */4 h: O5 v. r8 c  l  W2 a9 b$ p7 Q
  179. tmpreg = (heth->Instance)->DMAOMR;
    / e+ n3 v. A# I  L0 [
  180. /* Clear xx bits */
    % Q0 v( t& s8 L* k, P( X( r) G. \
  181. tmpreg &= ETH_DMAOMR_CLEAR_MASK;" Q8 _$ b0 k5 c  A) C
  182. ) U. D1 Q/ a; n& }
  183. /* Set the DT bit according to ETH DropTCPIPChecksumErrorFrame value */' z  W2 I$ I! ^; x9 y
  184. /* Set the RSF bit according to ETH ReceiveStoreForward value */
    + o, f6 L* o3 {, R
  185. /* Set the DFF bit according to ETH FlushReceivedFrame value */
    , _, X% l/ {" W7 N/ a: ~& U
  186. /* Set the TSF bit according to ETH TransmitStoreForward value */
    4 u$ x2 d" |3 j" p; H9 U
  187. /* Set the TTC bit according to ETH TransmitThresholdControl value */
    " K" x  ^  H- l  Y8 k& j$ e0 |, F
  188. /* Set the FEF bit according to ETH ForwardErrorFrames value */, Q8 ^/ f/ M" C4 _; ^/ I, D
  189. /* Set the FUF bit according to ETH ForwardUndersizedGoodFrames value */
    9 ]  M2 d& _' h8 j1 i
  190. /* Set the RTC bit according to ETH ReceiveThresholdControl value */. Z- Y, l) K! V3 t
  191. /* Set the OSF bit according to ETH SecondFrameOperate value */
    7 P+ `" M3 f$ `
  192. tmpreg |= (uint32_t)(dmainit.DropTCPIPChecksumErrorFrame |' e2 Q* J! _& V# z
  193.                      dmainit.ReceiveStoreForward |. `  A1 R% F% |8 D; E5 G# X
  194.                      dmainit.FlushReceivedFrame |) A$ G/ F2 z' R9 H
  195.                      dmainit.TransmitStoreForward |
    6 a7 u% r& U* m( \. `4 r
  196.                      dmainit.TransmitThresholdControl |
    1 G% V& a# D- ^/ v
  197.                      dmainit.ForwardErrorFrames |) z+ J" A; s2 D3 ~' i8 |7 ?
  198.                      dmainit.ForwardUndersizedGoodFrames |
    2 _2 ~) u# t3 g# H
  199.                      dmainit.ReceiveThresholdControl |& \( {4 a2 Q8 J; R
  200.                      dmainit.SecondFrameOperate);
    ' e! g7 _1 ~# n: ~( f8 z) F+ g1 S

  201. 3 v9 \  [6 _: k
  202. /* Write to ETHERNET DMAOMR */" G! k1 C3 L# I9 ~  j0 C
  203. (heth->Instance)->DMAOMR = (uint32_t)tmpreg;
    # n* F: l0 G" }: m% L4 N, ^0 D4 Q

  204. 2 _9 x4 K% N0 g- V' ^
  205. /* Wait until the write operation will be taken into account:+ f" }* k6 q& i: U$ E2 ~
  206.    at least four TX_CLK/RX_CLK clock cycles */
    7 Z& |# j) O9 c  \9 c- a7 t
  207. tmpreg = (heth->Instance)->DMAOMR;
    * m4 r4 n( {) I0 K2 O
  208. HAL_Delay(ETH_REG_WRITE_DELAY);( i/ W  r, @7 ~' @& X3 u# e. p$ h9 P
  209. (heth->Instance)->DMAOMR = tmpreg;' |+ q# l2 P# L: Y: b. Z
  210. ' \. r( o5 e  J* U% A; m6 G
  211. /*----------------------- ETHERNET DMABMR Configuration ------------------*/
      J! i$ F! ^2 B$ z" h5 H9 Y- o" I, z  p
  212. /* Set the AAL bit according to ETH AddressAlignedBeats value */
    " X1 @2 v+ ?# E6 d- K2 T: U  J  Z" C  d
  213. /* Set the FB bit according to ETH FixedBurst value */
    - P: W7 R& I7 L6 j
  214. /* Set the RPBL and 4*PBL bits according to ETH RxDMABurstLength value */
    : c' T. C2 r. m+ S$ K# v. U3 L
  215. /* Set the PBL and 4*PBL bits according to ETH TxDMABurstLength value */( F; D9 J8 Q3 K* Z) H, f
  216. /* Set the Enhanced DMA descriptors bit according to ETH EnhancedDescriptorFormat value*/
    5 {, Y& U8 I" e  l( y# A& S4 {
  217. /* Set the DSL bit according to ETH DesciptorSkipLength value */
    ; o- ~) u+ i& A" J8 \+ y+ I
  218. /* Set the PR and DA bits according to ETH DMAArbitration value */
    ! E% a- Z! G* H; P  p/ s5 s
  219. (heth->Instance)->DMABMR = (uint32_t)(dmainit.AddressAlignedBeats |
    - [4 `8 `) a6 c5 h0 P! L+ o
  220.                                       dmainit.FixedBurst |! y0 {) g2 H5 s7 o9 |
  221.                                       dmainit.RxDMABurstLength |    /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */
    ( V; q4 t0 c2 [7 o! p# D4 f8 T
  222.                                       dmainit.TxDMABurstLength |6 y+ G+ z0 a2 `5 R
  223.                                       dmainit.EnhancedDescriptorFormat |
    3 Q! w5 c8 h+ ]! e
  224.                                       (dmainit.DescriptorSkipLength Instance)->DMABMR;& \7 I! A& R3 ]! U
  225. HAL_Delay(ETH_REG_WRITE_DELAY);
    . g( L2 q* u; X" S
  226. (heth->Instance)->DMABMR = tmpreg;, C- M- p) r+ ~( c

  227. / A' i& S. a& U( h8 s1 r
  228. if((heth->Init).RxMode == ETH_RXINTERRUPT_MODE)
    % Y" V& D" @; p7 P
  229. {
    & h. A6 I3 g& C% C6 O
  230.    /* Enable the Ethernet Rx Interrupt */
    ! t5 q- \6 P2 A+ B5 c, H
  231.    __HAL_ETH_DMA_ENABLE_IT((heth), ETH_DMA_IT_NIS | ETH_DMA_IT_R);) G* A& F- `6 I! V/ w
  232. }
      \+ ^1 W" n1 n; [3 x9 K

  233. : g7 v* U+ G' a: Y
  234. /* Initialize MAC address in ethernet MAC */
    " U# E# v4 w/ {& ?: Y- t$ u
  235. ETH_MACAddressConfig(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);
    + ]/ ~9 N' h$ ]- m! m5 y
  236. }
复制代码

/ _# w' Z# x6 H, \3 v这里我就要稍微吐槽一下HAL库了
/ n, x# B* [7 z$ u8 rMAC层过滤的设置没有预留接口出来,有设置MAC地址的函数; y3 z" B3 L7 e7 c- _6 F0 w
& x- Y. q4 V$ ?6 E# T% `8 v
static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr)
. \( Q1 M0 r/ f0 w7 V$ i
$ ]! S0 ?- |$ h/ `. W0 c就不多做一个设置MAC层过滤的函数嘛,连后面用到的宏定义都有~~
2 @3 {$ t) y6 R6 k& l2 A
: n2 P; U! y: x3 I+ V) O( [木有办法,自己编一个初始化MAC层过滤的函数吧
. T7 O* m, x; b4 \
" J4 k2 k- D5 I7 z其实也就是把上面这个ETH_MACDMAConfig函数分离成两个单独的设置函数,再编一个设置MAC层过滤的函数
  z8 e. }  R0 f3 j# o
$ x3 f* |% K* y$ z% T5 r0 Y4 v: e开启MAC层过滤的初始化代码
5 l8 {! N- k! Q( j
  1. uint8_t ETH_MAC_Setting(ETH_HandleTypeDef *heth)' O  U+ Y+ g0 m
  2. {% d- s, M+ {7 J# c, r0 l/ ?
  3. ETH_MACInitTypeDef macinit;( e8 I8 V( p  P7 e
  4. /* Ethernet MAC default initialization **************************************/
    " G& E% ]1 m+ u2 A. d
  5. macinit.Watchdog = ETH_WATCHDOG_ENABLE;7 @9 N0 n8 H7 N; r! w, X
  6. macinit.Jabber = ETH_JABBER_ENABLE;
    . g8 A0 \" x3 {6 M2 j7 ~( v
  7. macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;
    ) Z" x  v" Z' i
  8. macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;
    0 n3 t8 l' v% u. u8 w
  9. macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;5 B0 n" W4 i8 y  I
  10. macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;2 p9 v( \$ S2 x, ?- _
  11. if (heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)
      h0 q( l) S7 e1 x/ C" ^
  12. {9 T' L* f4 ?& a, ~  i
  13. macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;
    2 t7 M5 N) L6 m- d: v4 i8 K) P
  14. }( }$ n- P; V' o5 s5 L% u8 f
  15. else
    6 E6 K& m* r0 O/ ~1 @" G
  16. {
    1 j2 N9 ~# j$ R: _2 ^0 T- y! k" U
  17. macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;9 b  p3 r0 @( @
  18. }
    4 N  r6 t8 l0 q4 w% h: r; p7 p
  19. macinit.RetryTransmission = ETH_RETRYTRANSMISSION_ENABLE;          //使能重传
    ! C9 Z, k. @8 T( R4 K$ W! y2 N
  20. macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_ENABLE;          //使能自动去除
    ( Y2 ?5 V. y  a" k, L* G2 s
  21. macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;5 o* ~6 \' @, i. k
  22. macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE;
    ) D) f$ n) g; U' |
  23. macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE; ///不接收所有包/ k/ F( G" o7 ?9 [+ e4 i
  24. macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_NORMAL_ENABLE; //源地址过滤; q5 `  L/ i: b1 L5 S- D% ~; E
  25. macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;
    + d7 |( A, p) S7 T
  26. macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_DISABLE; //广播不接收
    . ?: K! c2 k. o* z
  27. macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL; //目的地址过滤
    % W5 T/ v* C4 O& O1 K4 d) l/ u3 S
  28. macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE; //混乱模式
    , E, d6 `( Q( c
  29. macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECT; //多播过滤
    / G6 a9 L* t( R1 r$ O: x- o0 H5 @
  30. macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT; //单播过滤) X7 g, m0 V, H3 m3 U* b
  31. macinit.HashTableHigh = 0x0; //Hash表高位5 m5 L" w1 t% d7 N1 Y- U  \
  32. macinit.HashTableLow = 0x0; //Hash表低位
    " i3 l% }" O$ l  z3 J1 `8 j/ @; T
  33. macinit.PauseTime = 0x0;* Q, j& @5 i: f4 |0 A7 R
  34. macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;7 q& J5 c0 i% |, F
  35. macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;1 A9 u$ R! J9 [/ p9 s  f
  36. macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_ENABLE;! U  j; ?# f; _$ M( a
  37. macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE; //接收流控- E& J) |  s3 `
  38. macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE; //发送流控
    * x  n5 T' y4 i( H+ [6 \' y
  39. macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;  h% T7 ]& x: t; j. d! z
  40. macinit.VLANTagIdentifier = 0x0;
    " Z5 F7 r& S* X& E. b6 ~

  41. : U9 W; q) r3 ~7 g1 P
  42. return HAL_ETH_ConfigMAC(heth, &macinit);5 l6 W& c# z5 g1 s8 S! C* r2 P
  43. }
复制代码
+ Z' t9 o. S6 y) x4 \7 t. w
默认的MAC层 DMA初始化函数! e, d) ?! H+ ^& O, P& L2 ^) B/ i
  1. uint8_t ETH_DMA_Setting(ETH_HandleTypeDef *heth); n% Q: C: X" W, n- C9 \' ^
  2. {5 a. ~+ o7 }5 L4 X3 p
  3. ETH_DMAInitTypeDef dmainit;
    & j2 T% w' Z3 M5 n8 @+ S
  4. /* Ethernet DMA default initialization ************************************/
    + G/ \4 ?, @' i: }8 Q
  5. dmainit.DropTCPIPChecksumErrorFrame = ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE;3 N1 j, F& D+ C. j5 H6 H
  6. dmainit.ReceiveStoreForward = ETH_RECEIVESTOREFORWARD_ENABLE;
    6 @3 K( o4 \! ]( G: T! H  s
  7. dmainit.FlushReceivedFrame = ETH_FLUSHRECEIVEDFRAME_ENABLE;
    ; y# k# O1 D8 L0 @- o
  8. dmainit.TransmitStoreForward = ETH_TRANSMITSTOREFORWARD_ENABLE;) j5 I- P! a0 J2 r. Z& @7 h
  9. dmainit.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES;# s+ v* y/ B7 Q$ `/ E
  10. dmainit.ForwardErrorFrames = ETH_FORWARDERRORFRAMES_DISABLE;4 F3 i- J  M0 f. F7 u; o
  11. dmainit.ForwardUndersizedGoodFrames = ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE;: k  u0 `  d$ c# C7 q
  12. dmainit.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES;! Z; @8 f4 ?7 X
  13. dmainit.SecondFrameOperate = ETH_SECONDFRAMEOPERARTE_ENABLE;
    . ]5 \  c2 b9 Y' C% q% l  M# ^
  14. dmainit.AddressAlignedBeats = ETH_ADDRESSALIGNEDBEATS_ENABLE;
    : G) a4 T- w  g* J5 m& q6 J
  15. dmainit.FixedBurst = ETH_FIXEDBURST_ENABLE;
    ; {: a6 @( Q$ b5 @  v4 y, o
  16. dmainit.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;
    0 k0 Q& M2 j' O
  17. dmainit.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;
    ) w/ B# J) f8 N9 B3 Z
  18. dmainit.EnhancedDescriptorFormat = ETH_DMAENHANCEDDESCRIPTOR_ENABLE;; s& I! ?/ ^  Z0 c: e: q8 O
  19. dmainit.DescriptorSkipLength = 0x0;
    # }* k$ I& W# d" A) ]8 w
  20. dmainit.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1;! d& L* A3 h# W4 x9 x( h6 H; a
  21. uint8_t res =  HAL_ETH_ConfigDMA(heth, &dmainit);# f! R' `% a# s  S- X" @. {
  22. if ((heth->Init).RxMode == ETH_RXINTERRUPT_MODE)
      g6 j) W5 M: r! _' g
  23. {: Z. x, P2 l! s. O8 q
  24. /* Enable the Ethernet Rx Interrupt */4 s' d  P0 D$ a$ m3 h( `
  25. __HAL_ETH_DMA_ENABLE_IT((heth), ETH_DMA_IT_NIS | ETH_DMA_IT_R);+ Y% L# p0 ]) `" v+ J, p$ F
  26. }
    % C& c* K7 s( }
  27. return res;' v. I; L9 m6 i
  28. }
复制代码

3 ~) |1 R( l9 l2 f" R3 c用来设置MAC地址的函数(其实就是把库函数的static函数取出来直接用了)
  1. <blockquote>//heth: HAL句柄
复制代码

: A6 z  F/ F7 W  ]  v然后到最最重要的MAC层过滤设置
( ^+ Z' D, \1 }
以MAC1为例
9 k1 {2 Z* P& ~4 a9 E& G4 T" n
, A, H' i/ J& l/ z' W0 J
20191124093921254.png

1 h2 Q. z. N0 I( Q) N7 U% T: A) D9 a9 ?4 W
20191124094439199.png

- K8 \8 ^- n' G9 s) |9 H  Q! M! s
8 z! H2 g2 n7 e) s; n+ z注意看红框的描述

/ S, M9 |- F$ ]) O/ _  ~5 h& b5 E功能很好用,可以过滤源地址/目的地址,还可以做掩码功能! n/ {4 |1 i  u( P" e# m
设置MAC层过滤的代码5 ?+ b; r& Q4 G+ }7 m! m( I" X" d
  1. static void ETH_MAC_Filter_Setting(ETH_HandleTypeDef *heth,ST_ETH_PAR * para)
    ! q+ j2 W/ S2 v: D0 m$ {
  2. {
    5 {; ?( C4 C1 K1 H( j4 N" F  m
  3.     //设置本机MAC地址; k3 t% K  j8 c" T
  4.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);
    1 k! f6 P/ n8 p" t. C& T* Y
  5.     //设置UDP-A的对方MAC地址# u; J4 C$ \6 p. b9 i$ E" d- n* s, a
  6.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS1,para->UDP_A_MAC);
    " W' G2 t6 N7 t" R+ `, O
  7.     (heth->Instance)->MACA1HR|=0xC0000000;//需要完全匹配UDP-A的对方MAC才接收. Z9 u7 h3 g# P" j2 ^$ n# s
  8.     //设置UDP-B的对方MAC地址2 V# u0 I8 G+ l. Y: W" i
  9.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS2,para->UDP_B_MAC);6 f8 o% q+ @; \6 {
  10.     (heth->Instance)->MACA2HR|=0xC0000000;//需要完全匹配UDP-A的对方MAC才接收7 V7 o* d2 d4 ^, v' W* I
  11. }
复制代码

: Y# g7 E( r. _) l, M/ I' h我这里是希望为我的两个UDP精确过滤接收到的源地址
6 u+ b. K  }% z- T/ T9 S+ i所以AE位设置为1,SA设置为1,MBC全部为0(MAC地址全部检查)
( X# W" ^) E6 Q  G% D! U
9 U& |0 Z2 N+ Q& b5 g' H假如我希望过滤MAC中特定的厂家字段6 B  a( d, r4 n9 A$ C
例如某个MAC地址

0 |- V# G  Y$ s1 [- ~01-02-03-04-05-06
3 r9 l. D  `9 ^7 L其中01-02-03就是厂家字段
* z  K" K2 k2 C6 B) G! T2 J0 G! @* B7 M- J4 z
那么代码要这样修改(MBC的第29位,28位,27位置1)6 r/ p2 p5 n# P2 e  l  _# A% G
这样MAC层就不会检查MAC地址里后3个字节(04-05-06)
3 Y; A) v# G  N' h7 v0 x但是会检查前3个字节,也就是厂家字段" ]. ?* f9 u! ?0 l7 A
这里需要注意MAC地址的字节序. p& G( S' p* T
  1. static void ETH_MAC_Filter_Setting(ETH_HandleTypeDef *heth,ST_ETH_PAR * para)
    ' J+ J. E5 q# W  H- |. j4 `) H
  2. {+ J5 \) |# T  D! a+ f! g
  3.     //设置本机MAC地址
    % f7 x; h* o3 L/ z2 b8 l8 j; t7 e
  4.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);
    ( d2 @; Y/ P/ q8 c  c3 e
  5.     //设置UDP-A的对方MAC地址4 R7 G2 m3 j' h8 h* ~, F. D8 ]7 f* ^
  6.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS1,para->UDP_A_MAC);2 {, P) y  R7 P7 v  J2 ?
  7.     (heth->Instance)->MACA1HR|=0xF8000000;//需要匹配厂家字段
    3 }; |; z" b! |1 ~: \# \
  8.     //设置UDP-B的对方MAC地址5 e7 k; a8 s5 H4 F1 C
  9.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS2,para->UDP_B_MAC);; H6 U6 t/ l+ x3 n9 r
  10.     (heth->Instance)->MACA2HR|=0xF8000000;//需要匹配厂家字段; k+ S+ O9 j; y/ ~! [
  11. }
复制代码
- N: A* O! W: J2 }: h+ ^. o( z
然后这些函数的调用顺序按:; R+ @9 ]1 w/ ^
1. HAL_ETH_Init; w2 Q5 K9 r0 c9 L. \. Q& K
2. ETH_MAC_Setting
) l$ {/ G5 H# F3. ETH_DMA_Setting5 T: ?  V7 F3 G6 {! {$ J
4. ETH_MAC_Filter_Setting% T8 N& |$ A) \- [4 N

$ d0 R: @! T8 M- a5 X( r用你希望过滤的MAC传递到一个Hash计算函数里,得到一个值,通过这个值产生“映射”关系来过滤MAC地址,所以这个并不是精确的,因为可能会重复~~
- o( o; ~, ^3 A1 f) w: X6 u
, Q7 ]* v, N0 E' I% _
HASH函数
- I+ b) \$ o. @1 {" p函数  ?* i. D- @* s# Y+ z
  1. / STM32 MACHASH - Copyright (C) 2014-2018 Clive Turvey (<a href="mailto:sourcer32@gmail.com">sourcer32@gmail.com</a>)
    2 [' F5 R. J' x" ^+ j$ ^
  2. //  All Rights Reserved7 D" O+ }9 |: V5 W: y" a$ b

  3. 6 d4 g3 E7 N) G0 p: e: Q
  4. #include <windows.h>
    3 v* S5 q- [! i

  5. 7 X# p; N0 \4 L* m+ ~9 c
  6. #include <stdio.h>
    ' Z8 p9 z8 g1 R& ?6 s
  7. #include <stdlib.h>* ~. ]% f( j0 C. Q6 Q: E

  8. 8 Y0 A; _" b2 L. Y6 Y
  9. typedef unsigned char uint8_t;
    ( n& |" ]1 s4 L4 D1 y
  10. typedef unsigned long uint32_t;8 v# e$ `- @" l9 o4 C/ y+ W

  11. % n( r0 w; O! \2 z
  12. uint32_t Rev32(uint32_t x)
    : [! _4 Q" h( Y& ^: L: h
  13. {
    ! a# G/ P3 Y. m, c& T% D4 H
  14.   uint32_t y;& ~  @: ?" V% h5 v: p7 L+ n$ e
  15.   int i;7 k" [) T8 N/ q9 ?0 z

  16. / O- K+ q- i( a# \
  17.   y = 0;- A, ^' m1 \' h, [+ r/ m
  18. 0 ]& E5 U1 [, @) N
  19.   for(i=0; i<32; i++)
    & z$ k! y# o1 k+ v1 ^; H3 A
  20.     if (x & (1 << i))9 M+ m/ t( W% H3 m# O: ^
  21.       y |= 1 << (31 - i);+ J$ o, r) }+ K  ]! Y( D  c

  22. - g. b# A- z% Q# i9 d
  23.   return(y);! w, K- }) _. f( a
  24. }
    % H( K( o+ V' U; Q
  25. / N; M( B2 U2 k/ u) x, b$ @
  26. uint32_t MacHash(const uint8_t *Mac) // <a href="mailto:sourcer32@gmail.com">sourcer32@gmail.com</a>
    7 f% I) Z5 u' J; q" T. g& d
  27. {
    / Y' k, U! H+ `7 Q$ p# ^$ e5 x
  28.   int i, j;
    3 I: ^4 ?# I* s* Z  a- h
  29.   uint32_t Crc;
    4 C  w4 w( f+ O! F( O4 M

  30. # G- h0 l" e- P* Z9 s
  31.   Crc = 0xFFFFFFFF;
    % q( Z" ]9 {  p8 F# @2 B

  32. * J: U5 P4 {: j9 W
  33.   for(j=0; j<6; j++)
    9 P, X! Y7 [  C
  34.   {5 l6 ^! D$ x% N9 G" E0 P
  35.     Crc = Crc ^ (uint32_t)Mac[j];$ O4 j; K! e/ B6 H! c
  36. # V0 }& M* T8 q! x$ U) F* b( H
  37.     for(i=0; i<8; i++)
    * S$ i, e2 D, c, l
  38.       if (Crc & 1)! o$ [  y* x8 j( j
  39.         Crc = (Crc >> 1) ^ 0xEDB88320; // Reversed 0x04C11DB73 X: K- l2 k4 V+ W2 u3 o4 t; D/ ?
  40.       else
    % b. D4 [# i' J1 A" b- E
  41.         Crc = (Crc >> 1);
    6 {# j7 f/ {( Y6 o5 v0 T: o
  42.   }
    5 t8 ^7 A3 O7 Q/ F" `

  43. 0 {& N( p4 s+ v
  44.   return(Rev32(~Crc) >> 26); // Get High order 6-bit in reversed/inverted CRC9 `) w% p  q+ B2 c; \
  45. }
    3 B8 L- D9 G3 P8 o, l
  46. . a+ q( E1 T( b
  47. uint32_t MacHashFast(const uint8_t *Mac) // <a href="mailto:sourcer32@gmail.com">sourcer32@gmail.com</a>
    , |! T: \* A1 K' l% D
  48. {: C  R# `( C; ~/ ~/ H% P& j; n
  49.   static const uint32_t Rev6Tbl[] = {
    ; ]2 @8 K& M3 b
  50.     0x00,0x20,0x10,0x30,0x08,0x28,0x18,0x38," d6 p( g8 t. u+ g5 u2 u0 p
  51.     0x04,0x24,0x14,0x34,0x0C,0x2C,0x1C,0x3C,
    ) W8 ?% Z$ S% j
  52.     0x02,0x22,0x12,0x32,0x0A,0x2A,0x1A,0x3A,8 m: P1 h; [5 S7 s& w
  53.     0x06,0x26,0x16,0x36,0x0E,0x2E,0x1E,0x3E,. P6 B' B4 q+ u0 r# j, w, B' L
  54.     0x01,0x21,0x11,0x31,0x09,0x29,0x19,0x39,
    ) R0 |& r. f2 }* `
  55.     0x05,0x25,0x15,0x35,0x0D,0x2D,0x1D,0x3D,+ y: u$ w$ @9 \% Z# e
  56.     0x03,0x23,0x13,0x33,0x0B,0x2B,0x1B,0x3B,
    % H8 C* `* Z$ y/ i. e
  57.     0x07,0x27,0x17,0x37,0x0F,0x2F,0x1F,0x3F };2 b# I8 U  o& P9 s" |$ `
  58. ) _8 b' t0 b) u* \
  59.   static const uint32_t Crc32Tbl[] = {
    # ^/ V; j- h% ]( c
  60.     0x4DBDF21C, 0x500AE278, 0x76D3D2D4, 0x6B64C2B0,5 T  R' l1 Y0 H6 s9 d7 @! P# e- i( \5 G
  61.     0x3B61B38C, 0x26D6A3E8, 0x000F9344, 0x1DB88320,6 m; n! o3 Y& I6 d% `. c4 q4 V$ w1 |
  62.     0xA005713C, 0xBDB26158, 0x9B6B51F4, 0x86DC4190,
    & }4 E2 T* I# c* l  [4 o) u
  63.     0xD6D930AC, 0xCB6E20C8, 0xEDB71064, 0xF0000000 };
      ^+ k+ o5 M2 a8 }2 S

  64. $ ?. M9 Z/ I7 X. K4 G- R5 {
  65.   int i;- a# v  S; [1 O" r, N
  66.   uint32_t Crc;
    7 D* w: ~  ~' w5 j3 W4 m' _3 j. X8 S
  67. : \1 {1 B. u- y  ~4 A
  68.   Crc = 0;. b; u/ z( N- ]/ H1 k
  69.   A6 E" i. C! P+ R5 h
  70.   for(i=0; i<6; i++), Q% e* [4 L2 W1 p6 f7 ~  f" i! t( ]
  71.   {
    . |1 _, W! Q, p3 p
  72.     Crc = Crc ^ (uint32_t)Mac<i>;
    ) J4 V* {2 j6 d

  73. 0 B/ K7 _# X4 ?6 z1 r& U" G( P  n
  74. </i>   Crc = (Crc >> 4) ^ Crc32Tbl[Crc & 0x0F];  /* lower nibble */
    3 x1 Q5 q+ i1 z
  75.     Crc = (Crc >> 4) ^ Crc32Tbl[Crc & 0x0F];  /* upper nibble */
    " W7 m# \( @/ X
  76.   }* u2 d! v* P0 I

  77. ; o4 I2 w2 ]/ X4 R
  78.   return(Rev6Tbl[Crc & 0x3F]);
    - G3 e; O/ l( ]1 |* }
  79. }
    ) ~$ U: H7 J; J/ g* k

  80. 0 t9 z0 l: J& e
  81. int main(int argc, char **argv)
    ' m, @6 D* o7 p5 N% A! U
  82. {
    ) g7 |1 c4 C$ K5 F/ j- Q! o3 D
  83.   static const uint8_t Test1[] = { 0x1F, 0x52, 0x41, 0x9C, 0xB6, 0xAF }; // 0x2C4 W& c0 _/ |+ C2 G
  84.   static const uint8_t Test2[] = { 0xA0, 0x0A, 0x98, 0x00, 0x00, 0x45 }; // 0x07
    % m" p) N& E1 u, |6 |$ _+ r
  85.   static const uint8_t Test3[] = { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x21 }; // 0x242 p. K9 C" m  p

  86. $ J# o) L. `' z7 R
  87.   printf("MacHash %02X\n", MacHash(Test1));* L: O/ D( [; P7 I
  88.   printf("MacHash %02X\n", MacHash(Test2));5 T* n/ m0 V$ Z5 K* _
  89.   printf("MacHash %02X\n", MacHash(Test3));
    ( Q7 R8 b, u+ o% X; f4 p
  90. # [; C- [$ t8 I. n- h* x0 r
  91.   printf("MacHashFast %02X\n", MacHashFast(Test1));! Q; C( K, m) Y& ?. R
  92.   printf("MacHashFast %02X\n", MacHashFast(Test2));5 L  j$ T1 K5 J) L9 [
  93.   printf("MacHashFast %02X\n", MacHashFast(Test3));0 H* H; S7 ~1 j+ i
  94. * `# `: {* G+ _/ W2 s" ]" a
  95.   return(1);
    & }2 _0 v( W, U2 S7 T/ ^
  96. }
复制代码
' l) A# d, a) t2 [7 Y

/ h) R+ p: \/ |6 v7 z6 I. H回到手册
% ~3 w7 Q/ |& I# x" c
4 |+ d, a% L% ~7 K) w) O
20191124100604140.png

) W, z- _3 F) ^. A3 ?: N1 u- a# A0 D" S& y9 M+ `. o" K9 G9 @( Q- R
20191124100636882.png

8 l! u- o9 x( Y$ n4 t
1 [, T' D- c- @
$ J- g+ W+ A( I0 D$ H上面的函数算出来一个数,假如是手册上的那个0x2c,二进制为101100B
6 n* S3 C3 J$ z5 l. O$ `+ b8 _$ j+ g换句看得懂的人话···就是:
( f  U+ X7 z3 T' J) M  ~算出来的数先看第6位
9 |7 N0 M' ^* W; B! h0 B) J/ u* b是1的话说明用到的是HASH表高位寄存器
$ t+ k# S& y) c否则用到的是HASH表低位寄存器
2 A2 a3 |6 F2 K/ N; E然后剩下的5位,转成十进制不是12嘛1 f4 z1 J+ V+ \" j0 p
如果你希望过滤这个MAC; q  S9 n+ H( G! ~
那么你就把对应的HASH表高/低位寄存器的对应位置1,否则置0  M( y0 ~) {: ~' e+ y& P' V5 x
这里的0x2c就是要把; @( i4 B& P: X. q- E8 [
HASH表高位寄存器的第12位置1' _$ ]6 ^! E* N# t% R( P- v+ q
就可以过滤这条MAC了
! e0 R# S/ {* x% F' M6 p& g3 j然后把你希望的MAC地址都按照上面说的方法弄完7 o) l5 L! ?: J
5 |: V7 k* h4 k' F
回到这个函数稍微改一下8 }$ v  {, r/ X$ b' Y' R
  1. uint8_t ETH_MAC_Setting(ETH_HandleTypeDef *heth)
    / O" b/ d+ N( e8 X. u4 B
  2. {- |9 e- n9 }9 {6 x( A( Y
  3.     ETH_MACInitTypeDef macinit;
    ( T$ l0 |! ?+ C
  4.     /* Ethernet MAC default initialization **************************************/
    3 r1 F2 K5 `  D# s8 V$ Q
  5.     macinit.Watchdog = ETH_WATCHDOG_ENABLE;
    ( H1 ]* _& G/ a: g! ^# n: i
  6.     macinit.Jabber = ETH_JABBER_ENABLE;( y" G; c- A& O. g9 y
  7.     macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;
    - s6 U8 W# y, a& c+ y6 i# U
  8.     macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;
    / @% y" H+ e$ G/ o) y: H
  9.     macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;
    8 {! h' X6 x0 A" e
  10.     macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;3 A+ B( ?! N$ j/ k' V( r( o
  11.     if (heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)9 j+ r% q/ m0 Q; W
  12.     {
    # R& @6 j' ?2 o
  13.         macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;
    6 l' H7 a2 k; p  h
  14.     }
    * ~/ S, u7 e6 {  y# r  J
  15.     else
    + O) S8 h' c% `8 m+ `% b
  16.     {
    2 K: ^% ~* u  E+ X! n
  17.         macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;1 j  u/ Z* K9 I: A3 v4 n
  18.     }. |6 u& E$ ^. k
  19.     macinit.RetryTransmission = ETH_RETRYTRANSMISSION_ENABLE;          //使能重传
    ; ~* D, v% M% ]
  20.     macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_ENABLE;          //使能自动去除
    ' T! m0 L& J+ m" B
  21.     macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;
    ) R* {4 n& {& C6 h- I' ?! }
  22.     macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE;
    , I; t/ {* H/ m, A& l( k* q8 r- z
  23.     macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE; ///不接收所有包! C# f3 R, X7 e9 u0 q" x
  24.     macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_NORMAL_ENABLE; //源地址过滤) ~1 U9 S6 _2 g" g% A# L
  25.     macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;- F! P! |" ]8 Q
  26.     macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_DISABLE; //广播不接收, C# U$ ?9 \9 V( E: w
  27.     macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL; //目的地址过滤- k) u7 b, _$ _; `5 L2 E) m; b
  28.     macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE; //混乱模式
    6 b& U3 K3 c, d' c4 r* Y
  29.     macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECTHASHTABLE; //!!多播HASH完美过滤) ^2 P% i2 [: h) P4 l
  30.     macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECTHASHTABLE; //!!单播HASH完美过滤
    $ x& V# Z8 j: F$ S0 V" b# L
  31.     macinit.HashTableHigh = 0x0; //!!填你最后算完的Hash表高位
    2 D% V5 i5 V/ k' l- `8 L/ K1 K
  32.     macinit.HashTableLow = 0x0; //!!填你最后算完的Hash表低位0 r' z. p( S" \; H8 C/ l( N
  33.     macinit.PauseTime = 0x0;, X/ f* f7 W8 M# W& ]7 c; X
  34.     macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;9 R3 j3 V% w; @
  35.     macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;" r# W: r$ `3 K+ O0 p1 N2 N
  36.     macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_ENABLE;, d$ N$ H1 u5 i: K. F
  37.     macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE; //接收流控" ^* Z; p" E/ \
  38.     macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE; //发送流控9 \% }' G' K& B+ k
  39.     macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;
    9 P8 w# h: P3 T$ ~; \; Z2 j
  40.     macinit.VLANTagIdentifier = 0x0;5 K/ `! H7 C& h. F6 L7 F
  41. $ |: z* T4 _1 e
  42.     return HAL_ETH_ConfigMAC(heth, &macinit);
    & p: w& K& i9 F, d) T; ?
  43. }
复制代码
; }7 O. ~, l6 y5 c" C5 Q% y
大概MAC层过滤就这些东西了: l% w+ B2 q7 L! m0 g
如果有条件弄MAC层过滤真的强烈建议开启,可以大幅减轻协议栈的处理负担,板卡不会因为处理大量无用的数据而白白浪费处理性能。
: j3 r3 _# v1 f# j$ a* M/ X3 ~7 I5 l0 L2 Z# U! Q

: l' L2 Q& c. q# t5 ^+ _' H
! Y6 I7 e* l( a0 |2 b4 V+ P: L9 i; L
收藏 评论0 发布时间:2021-12-14 10:15

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版