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

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

[复制链接]
STMCU小助手 发布时间:2021-12-14 10:15
前景描述; ^- c$ S& Y$ F0 K
我司的以太网实现是LAN8720搭配片上MAC层做的,协议栈用LWIP
9 Z1 }0 L  {) ~! `8 r9 m) y+ h+ ~3 k7 o
这种做法应该还是蛮常见的,反正不是LAN8720就是DP83864,再不然就是硬件协议栈的W5500了* t8 o9 }- T, T4 d
6 t: o7 `$ J  l! x7 S$ B; q" H* o
想想还是有MAC层过滤比较好,随手翻了翻它的手册,W5500好像是没得MAC层过滤的/ ?  ^/ }3 R# G  x( T, l% J

! I: k4 i9 S4 Z9 ~! P  E假如数据速率比较高,数据量大,而且外面还有乱七八糟无关的数据往板卡送,我也不知道用这个片子到底好不好' s5 t# |; V8 W  e! V
2 V8 T+ K( l/ p) ]# b
LAN8720也不好改了,就继续用吧
+ O& G! Z6 X. V4 _0 G8 s. J- _. ]1 H: x; O# |3 D: N
好好在,发给板卡的数据的MAC还是有特征的,我只需要过滤发送方MAC地址的前3个字节,也就是特定的厂家那段5 ~1 c1 `  ?, w' C0 h

  a: ^; I- G) N& c/ l$ _/ O+ LMAC地址的科普知识这里就不过多描述了,我们直奔主题# J1 Y1 Y+ M$ x# E4 {  b) R: i
4 R8 ?& G" F7 b3 ?6 u
怎么用STM32 F7的片上MAC做MAC层过滤
: L% E9 Q$ Z! p' l, g2 L7 [) \* ~1 q8 z3 v( }$ `# e; N' E7 K* ]; `
写这个的目的,就是我搜了搜,没看见有人写这个MAC层过滤功能,具体代码怎么写才能用( p. o" o0 L5 }

. H4 O9 |: H$ [5 O知识科普-STM32的片上MAC
# ~- U  I+ G) g0 j" z8 E& \STM32 F7的MAC层过滤方式有三种(说人话的直白解释,中文手册其实也翻译的不好)
  R( O: V6 ^4 |9 u6 Y& a精确过滤(手册上叫单播目标/源地址过滤)! U5 E' K7 n# h+ b# X& V
粗糙过滤(手册上叫Hash表过滤)
( I$ W0 f, Z* P2 @! b1 M4 L特殊过滤(广播,组播过滤等等特殊的过滤)
& K$ b# k- p% Z* t5 C我这里着重说第1种和第3种
- H2 g* d; A. H1 \4 W2 U) z  Y2 H  R1 E# c  B+ j( l) d; Y5 j9 z9 d+ P
STM32 F7可以存4个MAC地址7 {; S3 t" P/ e* g
其中MAC地址0是自己的MAC,其他三个可以用来做过滤
$ }" u0 t' ]9 n
1 Q, P# q; |& R1 @6 t$ ^$ w, E网络数据包通过PHY进入STM32的MAC,MAC层是可以对目的地址/源地址检查并过滤掉没得用的数据的,默认的HAL库库函数HAL_ETH_Init中# r% U9 N. l4 f+ ?# |  m' u5 |4 C
有一个static的函数2 y+ [5 q) t" y6 t& e0 Y8 C$ W1 N
static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err)
* q. `; Y7 t* x; A会帮你在初始化网络功能时初始化默认的MAC层功能:
7 X& [  {6 [/ e) V/ @& O关闭源地址过滤5 L. N! I" s8 p  O6 }5 }2 p
不接收所有数据; ]# I, u+ X; A7 U5 D* \; Y
接收广播帧
" k4 |! @0 f6 r4 s9 G7 l0 A) d3 F打开目的地地址过滤* \/ J8 M! |6 h8 _
单播数据精确过滤
9 u& l% u" C$ I9 `# d组播数据精确过滤  }6 f$ J8 {4 n
Hash表过滤关闭" l% V( t0 p) d8 `& Q
6 f2 {% Q$ o! c: _# d0 Y
其他的功能自行研究,我这里捡重要的说' f, C2 o# J  w! q, J9 I- |; v0 H/ _
  1. static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err)
    ) h( \( G8 S& Y! S5 P, b
  2. {
    9 L, Z: M1 n: D2 @3 g
  3. ETH_MACInitTypeDef macinit;
    ; S$ g$ m' ?" ?9 M
  4. ETH_DMAInitTypeDef dmainit;& i8 L6 e: u$ X9 e, h9 E
  5. uint32_t tmpreg = 0;
    , Y" S7 M  Y/ {, L
  6. 0 f3 N6 z8 x2 m) q" Z
  7. if (err != ETH_SUCCESS) /* Auto-negotiation failed */) ^" A" P( U7 ^; g1 q" `4 M- H
  8. {
    & |' |1 f, O5 L; `( v; q7 O1 o
  9. /* Set Ethernet duplex mode to Full-duplex */; Z/ R# w8 n% w% z9 W
  10. (heth->Init).DuplexMode = ETH_MODE_FULLDUPLEX;6 y5 _7 F" |2 V

  11. 3 i' E3 w  ]' s3 P; v% w
  12. /* Set Ethernet speed to 100M */
      W+ N# Y# }( \" w+ `( f" I' E
  13. (heth->Init).Speed = ETH_SPEED_100M;
    " T) Q* B, {9 E* y* k+ w9 @
  14. }7 V; |6 n, v5 l6 X0 G/ _! H4 `

  15. 5 a3 \7 f3 d. s/ q+ O  |" r
  16. /* Ethernet MAC default initialization **************************************/4 }" `! f( G0 R9 T9 E( V% ^+ Y/ v( p
  17. macinit.Watchdog = ETH_WATCHDOG_ENABLE;8 e2 B) y) q0 O. y) c
  18. macinit.Jabber = ETH_JABBER_ENABLE;
    ) I9 i- k7 G, H2 S/ N3 h$ i
  19. macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;# T1 W+ G# o! w
  20. macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;8 F1 I" j3 _. n5 ~+ i- R
  21. macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;
    " z  W* l2 H, s4 F3 y
  22. macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;  N2 R$ t: i" G' v: f$ h
  23. if(heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)) }- ]) N! U1 L5 x+ E6 G  x; B
  24. {, j9 N) T2 E, E0 y
  25. macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;2 p' x% ?9 G* t0 P5 v6 `! _
  26. }# u0 @$ o$ k3 o0 s* [
  27. else
    # n5 ]6 b& o, m7 j* k
  28. {
    ( |$ \3 D* `5 F& A' w, A6 U4 [1 q
  29. macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;
    & _( d+ m: `7 z8 }) N- u
  30. }
    " r7 ^* j4 R2 {) O
  31. //这一段是MAC层过滤的设置,下面是DMA的,那个用默认的就可以  k% E3 i- _! ~2 m! p, f
  32. macinit.RetryTransmission = ETH_RETRYTRANSMISSION_DISABLE;
    1 O  N. ~! X1 m  L) I
  33. macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_DISABLE;5 J2 W& x% I2 W8 U
  34. macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;# O! T7 W7 X; H3 `7 \
  35. macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE;
    ' P  E2 |3 y6 A( [5 ?
  36. macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE;
    " T( J$ m4 a# B! J# a. P7 S
  37. macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_DISABLE;
    - N) H: [5 p: R+ }0 d
  38. macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;
    / {/ i7 `  f8 K7 \
  39. macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_ENABLE;
    6 z8 P! ~+ Z+ S# Z6 A( V3 q, P2 E+ I
  40. macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL;
    % M8 Q9 R5 a1 b9 G0 j( L+ S: u
  41. macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE;- Y6 E- y) Y4 o  p
  42. macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECT;1 I) I2 ]0 A: z- W; o1 e8 h0 |( h
  43. macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT;
    : T3 {" R4 \. {0 O7 R
  44. macinit.HashTableHigh = 0x0;( A2 j4 p" g  J+ V
  45. macinit.HashTableLow = 0x0;% p: D0 V. @/ Q% V3 A! ~
  46. macinit.PauseTime = 0x0;3 x) w: r* O. g5 a9 k, ]& j8 p+ o
  47. macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;3 |& p6 A' y  N; t0 q" C
  48. macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;
    + ~: y, ]6 T- x( p
  49. macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_DISABLE;
    ) q0 D' D2 r& J" `: M. ~
  50. macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE;
    " r5 L9 e  I" a$ Y8 Q
  51. macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE;
    : E. m& H. D  r+ e7 e& [) w; s# [
  52. macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;
    6 V2 O1 k( ~9 s1 {# Z  k
  53. macinit.VLANTagIdentifier = 0x0;
    3 J; U4 L! [4 h- D

  54. ) a" a" ~1 Q9 Q( e* N; E' |
  55. /*------------------------ ETHERNET MACCR Configuration --------------------*/- h& J+ H' t; D! R9 X# C
  56. /* Get the ETHERNET MACCR value */
    ( H! @8 ^( a- ^: q9 j: f/ C' b
  57. tmpreg = (heth->Instance)->MACCR;$ @/ c' S0 Q8 ?! r5 ^( W  ?
  58. /* Clear WD, PCE, PS, TE and RE bits */2 `/ ?8 q) D3 `
  59. tmpreg &= ETH_MACCR_CLEAR_MASK;) M# F/ g- t4 s" K3 A8 r2 P3 ~
  60. /* Set the WD bit according to ETH Watchdog value */
    1 c  I( p0 n& K. T; L% ]& t
  61. /* Set the JD: bit according to ETH Jabber value */
    2 M& X, ^; V: y  Q
  62. /* Set the IFG bit according to ETH InterFrameGap value */- v3 ?1 R6 Z8 T0 S' K' F6 X: E
  63. /* Set the DCRS bit according to ETH CarrierSense value */
    3 y% p8 ^! V; D
  64. /* Set the FES bit according to ETH Speed value */
    7 P# G8 K7 `* ]- ?
  65. /* Set the DO bit according to ETH ReceiveOwn value */( ^2 x1 g& f- m8 N
  66. /* Set the LM bit according to ETH LoopbackMode value */
    / A3 T7 Q& m- X3 J
  67. /* Set the DM bit according to ETH Mode value */
    ; f7 f& d7 H: s7 Z/ L
  68. /* Set the IPCO bit according to ETH ChecksumOffload value */# ^) f5 U. K0 _! n; J
  69. /* Set the DR bit according to ETH RetryTransmission value */' U# O% S% W, ]# P3 E9 i
  70. /* Set the ACS bit according to ETH AutomaticPadCRCStrip value */
    5 ~0 i) \. n6 X( Y+ ]+ z7 ^( O; e
  71. /* Set the BL bit according to ETH BackOffLimit value */
    5 V" [! X- t3 J3 t
  72. /* Set the DC bit according to ETH DeferralCheck value *// A3 C2 Y* }# G3 p- |
  73. tmpreg |= (uint32_t)(macinit.Watchdog |  [; Q  I/ c  J' P5 F9 [* Z- X- `
  74. macinit.Jabber |% W5 U+ b5 k4 T2 s" w% Q; ]
  75. macinit.InterFrameGap |
      s% H2 v' R1 z) C& e( z) l" [
  76. macinit.CarrierSense |( F* r( y+ l$ K9 W- j1 I  C
  77. (heth->Init).Speed |1 h+ n/ a' C- T3 `! c0 K- t
  78. macinit.ReceiveOwn |
    , ^4 o& w: H% e# e
  79. macinit.LoopbackMode |
    + l8 i2 v  n) C7 B
  80. (heth->Init).DuplexMode |
    % i/ `' x& f" d
  81. macinit.ChecksumOffload |
    " S5 w. l" `( H4 v7 h8 ]
  82. macinit.RetryTransmission |
    7 g5 d- l: c$ q- @4 j
  83. macinit.AutomaticPadCRCStrip |
    ! d+ a2 T6 N  q! u/ v8 U8 t
  84. macinit.BackOffLimit |
      ]5 J" p$ y7 _
  85. macinit.DeferralCheck);
    7 p7 u) [# W, ?3 `
  86. & q* j2 u, F' D% D! h' h. h% z
  87. /* Write to ETHERNET MACCR */& ~6 G9 C4 A: S2 b# x' y, |4 r" y
  88. (heth->Instance)->MACCR = (uint32_t)tmpreg;8 X$ w6 F8 y% e5 @- t: I5 u$ R
  89. 4 m. x% k% S9 }: ?( Y+ m
  90. /* Wait until the write operation will be taken into account:. D8 o& _2 I% n$ ]: Q4 Q" X
  91. at least four TX_CLK/RX_CLK clock cycles */* e$ T) @1 T& f( o+ v0 O
  92. tmpreg = (heth->Instance)->MACCR;- r7 }. q/ L; S2 W3 c, d' }
  93. HAL_Delay(ETH_REG_WRITE_DELAY);2 v# V4 C8 N+ k. k$ L
  94. (heth->Instance)->MACCR = tmpreg;& a1 P& A/ j9 Z/ `8 B

  95. 4 _/ y& b( |+ H5 `- p
  96. /*----------------------- ETHERNET MACFFR Configuration --------------------*/& u+ c$ w5 T9 m
  97. /* Set the RA bit according to ETH ReceiveAll value */0 R" `6 T8 |- j+ d. y* U
  98. /* Set the SAF and SAIF bits according to ETH SourceAddrFilter value */
    1 i/ g; d8 x6 U
  99. /* Set the PCF bit according to ETH PassControlFrames value */; Q1 W: k8 ^" R0 g/ W( ]
  100. /* Set the DBF bit according to ETH BroadcastFramesReception value */
    3 H* z9 l8 D( U0 z
  101. /* Set the DAIF bit according to ETH DestinationAddrFilter value */
      |: }. q. G" ]) V/ e( F5 P
  102. /* Set the PR bit according to ETH PromiscuousMode value */! D# H" }2 g9 V  `& T3 q
  103. /* Set the PM, HMC and HPF bits according to ETH MulticastFramesFilter value */
    % a: c( p4 a# p) y% U
  104. /* Set the HUC and HPF bits according to ETH UnicastFramesFilter value */
    9 S% p8 n7 ?: S
  105. /* Write to ETHERNET MACFFR */" _6 O  \4 a' h# b& c9 Z
  106. (heth->Instance)->MACFFR = (uint32_t)(macinit.ReceiveAll |
    3 p' S$ ?' m9 A0 x% u) q5 y
  107. macinit.SourceAddrFilter |
    + K3 C8 M8 s9 M/ E  d
  108. macinit.PassControlFrames |
    / a1 x8 c& D) u2 z# m+ E- [  G
  109. macinit.BroadcastFramesReception |
    1 I) I  Q. [' ^3 z: e
  110. macinit.DestinationAddrFilter |# H7 S1 R) F1 O7 E- d% G
  111. macinit.PromiscuousMode |
    0 }4 o* Q" @5 X+ X+ {6 |6 d) ]! s
  112. macinit.MulticastFramesFilter |1 f5 f; z$ l8 E7 v" O! `
  113. macinit.UnicastFramesFilter);1 R' _' M4 u# p1 \2 I2 T( ]

  114. 2 ]- e) x: _% z
  115. /* Wait until the write operation will be taken into account:) v4 e% \$ U, ]$ q
  116. at least four TX_CLK/RX_CLK clock cycles */% T- C7 r+ m9 n: W: j0 i
  117. tmpreg = (heth->Instance)->MACFFR;. p5 `% l5 d& }2 E8 b
  118. HAL_Delay(ETH_REG_WRITE_DELAY);) i- q7 t* e0 S4 r% {, H. s* O
  119. (heth->Instance)->MACFFR = tmpreg;
    4 s1 C4 D4 ~4 Q$ Q! a6 \

  120. % m' r8 Z/ W; a. c( w$ b5 t4 b! }& @
  121. /*--------------- ETHERNET MACHTHR and MACHTLR Configuration --------------*/
    6 m- j; I+ o) ^: M& V0 z
  122. /* Write to ETHERNET MACHTHR */# i( i9 H/ T+ Y9 l
  123. (heth->Instance)->MACHTHR = (uint32_t)macinit.HashTableHigh;( b' B4 j/ n( ]: f* e% @: c

  124. ) K- @. Z% {+ D) W
  125. /* Write to ETHERNET MACHTLR */
    6 A- d, L8 x+ l" Z3 e# j7 J: L6 p
  126. (heth->Instance)->MACHTLR = (uint32_t)macinit.HashTableLow;
    ( Y+ M+ l9 D' @5 o- V; A, _
  127. /*----------------------- ETHERNET MACFCR Configuration -------------------*/
    ) J$ e* ]; }; |( U

  128.   v; s( Y/ |( J1 z
  129. /* Get the ETHERNET MACFCR value */7 N+ F% p# m3 h0 G1 D/ G& ~
  130. tmpreg = (heth->Instance)->MACFCR;
    , Y: i& B3 e9 ?- c, |
  131. /* Clear xx bits */0 K! ~; a5 I; z1 E+ j
  132. tmpreg &= ETH_MACFCR_CLEAR_MASK;
    + w' ]+ v& R$ _8 f( }) {4 K

  133. 3 V6 |9 }% ^0 S# R- X. u
  134. /* Set the PT bit according to ETH PauseTime value */2 p% t2 v; _3 p' X8 p% D
  135. /* Set the DZPQ bit according to ETH ZeroQuantaPause value */2 t7 \5 t% x- Y2 A0 q
  136. /* Set the PLT bit according to ETH PauseLowThreshold value */
    ! v4 k1 i1 x0 n+ `
  137. /* Set the UP bit according to ETH UnicastPauseFrameDetect value */
    ; }8 J8 X9 {! N8 q9 \7 z7 `
  138. /* Set the RFE bit according to ETH ReceiveFlowControl value */6 m, Z7 _5 p2 d) Y
  139. /* Set the TFE bit according to ETH TransmitFlowControl value */$ I2 r: Q) [. w5 [" C& r- F" m
  140. tmpreg |= (uint32_t)((macinit.PauseTime Instance)->MACFCR = (uint32_t)tmpreg;0 k& l6 X# L4 J. w
  141. % F8 s9 O& W* D  y$ W4 X
  142. /* Wait until the write operation will be taken into account:
    $ H9 g7 |, }% V) a& w9 {( z: D% N
  143. at least four TX_CLK/RX_CLK clock cycles */) x- n) M: }; P, w3 @6 a2 n
  144. tmpreg = (heth->Instance)->MACFCR;$ p& n& k5 T( G" \! p
  145. HAL_Delay(ETH_REG_WRITE_DELAY);
    ' d7 K" u9 s# _9 C5 M9 Y3 L7 `
  146. (heth->Instance)->MACFCR = tmpreg;4 x  [) Y8 Z8 {- {- D: L. [8 c

  147. ( |9 I) W9 L0 a, o7 c& j5 m
  148. /*----------------------- ETHERNET MACVLANTR Configuration ----------------*// K/ x/ B- r7 b6 {5 Y
  149. /* Set the ETV bit according to ETH VLANTagComparison value */; q, [4 g7 b* q$ `1 g& K3 j
  150. /* Set the VL bit according to ETH VLANTagIdentifier value */, Q4 h. S1 t4 K+ }$ z
  151. (heth->Instance)->MACVLANTR = (uint32_t)(macinit.VLANTagComparison |
    " F  u9 d' m3 C% b
  152. macinit.VLANTagIdentifier);% N. t: c& T$ F  T2 P$ O
  153. ! m' Q; i- q1 g) f* u
  154. /* Wait until the write operation will be taken into account:
    5 l! V) K, c2 Y' {5 ^8 L/ d
  155.    at least four TX_CLK/RX_CLK clock cycles */" n, f5 E& o, D' q
  156. tmpreg = (heth->Instance)->MACVLANTR;9 U6 L' l7 R% ^2 \
  157. HAL_Delay(ETH_REG_WRITE_DELAY);
    9 Z* e# _; s+ J
  158. (heth->Instance)->MACVLANTR = tmpreg;
    / ?( v  D+ }3 L* A! `
  159. 4 b0 J6 o) Y. w
  160. /* Ethernet DMA default initialization ************************************/* @- l( ]' i1 R
  161. dmainit.DropTCPIPChecksumErrorFrame = ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE;- R) k6 z/ }- {2 Y: @* s# A
  162. dmainit.ReceiveStoreForward = ETH_RECEIVESTOREFORWARD_ENABLE;
    4 `0 w8 I4 W  e& b5 {( ^2 N% T2 t
  163. dmainit.FlushReceivedFrame = ETH_FLUSHRECEIVEDFRAME_ENABLE;2 f( }# _/ U7 @7 b! l
  164. dmainit.TransmitStoreForward = ETH_TRANSMITSTOREFORWARD_ENABLE;) K% A+ r' D# Y2 X
  165. dmainit.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES;
    7 o5 v" B! R0 u
  166. dmainit.ForwardErrorFrames = ETH_FORWARDERRORFRAMES_DISABLE;
    & I5 G  q- v$ r  M  U# C6 \, N
  167. dmainit.ForwardUndersizedGoodFrames = ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE;
    4 [7 g/ _" k2 |9 A
  168. dmainit.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES;9 u! j+ }2 D# T; R' I1 [  q
  169. dmainit.SecondFrameOperate = ETH_SECONDFRAMEOPERARTE_ENABLE;" I' A) n# @$ i( [* @
  170. dmainit.AddressAlignedBeats = ETH_ADDRESSALIGNEDBEATS_ENABLE;
    * w6 @% @6 i' u1 e) c
  171. dmainit.FixedBurst = ETH_FIXEDBURST_ENABLE;9 j9 H8 t1 U+ R( Y9 x% [$ m) y
  172. dmainit.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;4 g# N) s2 Y8 a9 f8 M( x1 o9 }
  173. dmainit.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;6 i7 X# U& q- P: M
  174. dmainit.EnhancedDescriptorFormat = ETH_DMAENHANCEDDESCRIPTOR_ENABLE;* h. y- X1 r/ d
  175. dmainit.DescriptorSkipLength = 0x0;
    / S, ~3 R# t2 S# k/ a" ?' v
  176. dmainit.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1;: h& z7 b0 W+ L4 S3 X. m) S

  177. & {. _6 c' W& \( m
  178. /* Get the ETHERNET DMAOMR value */* U, N& N' C& d( W7 H
  179. tmpreg = (heth->Instance)->DMAOMR;, z$ C( x% n: W9 b
  180. /* Clear xx bits */
    " C0 Y$ f  c  Y" P; Q& @2 e  c# M
  181. tmpreg &= ETH_DMAOMR_CLEAR_MASK;+ }$ T) j; d- D8 h6 j) l. ]

  182. " v9 \; l6 L1 h
  183. /* Set the DT bit according to ETH DropTCPIPChecksumErrorFrame value */
    8 l5 |5 v, u5 E$ B" U5 X
  184. /* Set the RSF bit according to ETH ReceiveStoreForward value */
    2 c1 R. {5 [  k( I- S7 C
  185. /* Set the DFF bit according to ETH FlushReceivedFrame value */
    8 x* g! f) {% ^. ?9 s
  186. /* Set the TSF bit according to ETH TransmitStoreForward value */" \1 B5 L6 B* X8 I0 t6 S  l
  187. /* Set the TTC bit according to ETH TransmitThresholdControl value */- [( O. c0 T! [. v6 h$ I8 ~
  188. /* Set the FEF bit according to ETH ForwardErrorFrames value */9 N/ @/ a& a7 i6 K7 ^8 Q
  189. /* Set the FUF bit according to ETH ForwardUndersizedGoodFrames value */
    0 D! s- C. P3 S+ v. {8 k* q
  190. /* Set the RTC bit according to ETH ReceiveThresholdControl value */
    / k- d+ R5 Q1 x* f0 m/ I5 U) ^: ~
  191. /* Set the OSF bit according to ETH SecondFrameOperate value */
    4 O4 O( Q) M- M* c
  192. tmpreg |= (uint32_t)(dmainit.DropTCPIPChecksumErrorFrame |
    8 x$ y( p+ ]) k% k
  193.                      dmainit.ReceiveStoreForward |
    # S) L$ ?, Y# r1 \" q- r* O. A7 S
  194.                      dmainit.FlushReceivedFrame |
    6 ?& o" J, B3 Y& M- D
  195.                      dmainit.TransmitStoreForward |8 ^+ [; @- v$ M2 V! D
  196.                      dmainit.TransmitThresholdControl |
    . D9 T, v% A: f, w
  197.                      dmainit.ForwardErrorFrames |# \' i  p# Z$ a: ?' U( k" g
  198.                      dmainit.ForwardUndersizedGoodFrames |0 s) u! T6 J/ L5 B
  199.                      dmainit.ReceiveThresholdControl |
    + Q! I/ U5 @! I0 P* e! A3 Y( j
  200.                      dmainit.SecondFrameOperate);( F, F& }6 x$ W) m
  201. 4 p+ q! x/ S( E7 n, w3 V; k- m
  202. /* Write to ETHERNET DMAOMR */' }5 n7 c7 y8 n' |3 G9 X- \
  203. (heth->Instance)->DMAOMR = (uint32_t)tmpreg;& _. d: f: ^+ }' u0 C& J0 ~5 Y
  204. 8 C5 `' ^3 i0 v
  205. /* Wait until the write operation will be taken into account:7 k! V; c  E* F8 L% k( ^
  206.    at least four TX_CLK/RX_CLK clock cycles */4 }* t* h4 i2 J# C
  207. tmpreg = (heth->Instance)->DMAOMR;: W6 p5 R# n) R# c. V) ^
  208. HAL_Delay(ETH_REG_WRITE_DELAY);
    0 t# O6 o9 J% N# `6 u9 x8 i: C
  209. (heth->Instance)->DMAOMR = tmpreg;
    8 T/ L) E, u; P" u/ S) a2 J% v( N

  210. / i# N2 |) q9 Z
  211. /*----------------------- ETHERNET DMABMR Configuration ------------------*/
    2 _: a1 D: _. T8 F# U
  212. /* Set the AAL bit according to ETH AddressAlignedBeats value */. @4 Q1 ~( t8 R1 u
  213. /* Set the FB bit according to ETH FixedBurst value */
    - Y3 B/ l' S4 i! K; Y
  214. /* Set the RPBL and 4*PBL bits according to ETH RxDMABurstLength value */' J0 o+ Z1 u$ X& v+ z% S
  215. /* Set the PBL and 4*PBL bits according to ETH TxDMABurstLength value */
    " h, K5 {9 r* D
  216. /* Set the Enhanced DMA descriptors bit according to ETH EnhancedDescriptorFormat value*/
    3 G5 J' l+ i- Q. Z1 d) t: U9 _
  217. /* Set the DSL bit according to ETH DesciptorSkipLength value */
    7 B; F- h& Z( }$ {8 S3 ~, t
  218. /* Set the PR and DA bits according to ETH DMAArbitration value */
    & O5 ~4 b% B5 C+ l& j
  219. (heth->Instance)->DMABMR = (uint32_t)(dmainit.AddressAlignedBeats |7 S: d& d4 \0 n1 l8 n; w) x
  220.                                       dmainit.FixedBurst |3 N% I4 ^) M+ N  K$ o
  221.                                       dmainit.RxDMABurstLength |    /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */0 s; s7 `( o& o7 ~5 }) ]( s
  222.                                       dmainit.TxDMABurstLength |
    6 O( `9 K& k" F0 x
  223.                                       dmainit.EnhancedDescriptorFormat |2 B, \5 r# c) f+ ~0 y1 o) b
  224.                                       (dmainit.DescriptorSkipLength Instance)->DMABMR;
    $ z/ I) u. X0 p7 a% j( P& j& g
  225. HAL_Delay(ETH_REG_WRITE_DELAY);0 X: ~- z8 w; x5 ?. y8 F
  226. (heth->Instance)->DMABMR = tmpreg;
    2 O5 T% l5 L$ P3 p
  227. 7 Z# R7 q* q; r& m2 {. ]
  228. if((heth->Init).RxMode == ETH_RXINTERRUPT_MODE)
    , K& n0 f) Q- U  p# o; L
  229. {
    # W( w- |% s' S
  230.    /* Enable the Ethernet Rx Interrupt */0 |0 e/ n( E  N: J& M  {/ P
  231.    __HAL_ETH_DMA_ENABLE_IT((heth), ETH_DMA_IT_NIS | ETH_DMA_IT_R);  T9 y. X% u4 X0 Z% [& [3 W
  232. }
    $ q0 N# [. s9 ^2 J3 S# L) q2 K

  233. . G$ T4 x1 z2 a/ x  }/ H; b1 N
  234. /* Initialize MAC address in ethernet MAC */
    6 ]% W) h- h( F; {7 |; M
  235. ETH_MACAddressConfig(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);- Z" a6 [1 f- r2 N' F
  236. }
复制代码
7 k" F* @. \: N
这里我就要稍微吐槽一下HAL库了4 i. |7 P( H$ b3 s$ [1 r7 I
MAC层过滤的设置没有预留接口出来,有设置MAC地址的函数  b8 b* E& V0 D- p( a
# i5 z* X& @& Y! {9 Q& z
static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr)5 g) Z  I4 Q4 E# B. V
2 m; ^$ P2 v( u4 S2 e
就不多做一个设置MAC层过滤的函数嘛,连后面用到的宏定义都有~~
8 v* V- Q# Y7 h- ^% L9 P+ J* ?% s. q% a' E/ A+ ]
木有办法,自己编一个初始化MAC层过滤的函数吧
: _; B7 K: _7 J* d
/ V0 w, N9 S' y+ b其实也就是把上面这个ETH_MACDMAConfig函数分离成两个单独的设置函数,再编一个设置MAC层过滤的函数
* c3 Y0 Z) ]  j' w+ v# L9 ]& Q7 B9 x# _, v& |2 }0 m$ ~7 ]
开启MAC层过滤的初始化代码

! w& W" y( [. b9 A
  1. uint8_t ETH_MAC_Setting(ETH_HandleTypeDef *heth)+ y: c1 p, }: t$ u8 Q( k8 D
  2. {
    / w: ~1 m9 m1 n8 B# U' y& G
  3. ETH_MACInitTypeDef macinit;' B; L9 ~8 G8 f- F
  4. /* Ethernet MAC default initialization **************************************/
    . L% \9 Q5 S9 R! ]. Q: w
  5. macinit.Watchdog = ETH_WATCHDOG_ENABLE;; Q' N$ C7 ~3 k
  6. macinit.Jabber = ETH_JABBER_ENABLE;( g2 X. s5 E% X* I
  7. macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;* G7 W) s( S( _- v2 r
  8. macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;* L7 x& R2 \% }3 s. m) y+ i3 M
  9. macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;
    % d* ~' w, A+ @* ?
  10. macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;
    2 }& o( s$ J- P% ~' F8 I8 ]
  11. if (heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)
    : z1 A8 G+ U7 o3 r( Y$ M# G
  12. {
    % d4 T% g: l0 {" E6 n) A$ F) P
  13. macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;
    $ u6 S4 S8 N& {8 l
  14. }' T4 K) A" G2 U* ?
  15. else& t) s: Y- w0 ?2 K2 `3 o! ?7 J
  16. {9 Z0 |1 l0 @9 |  V5 j
  17. macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;
    ' g4 |& d* S7 P; V
  18. }
    1 d& c% A2 H4 L' }& J
  19. macinit.RetryTransmission = ETH_RETRYTRANSMISSION_ENABLE;          //使能重传
    % f+ p: k9 T6 Q/ ?- E; O
  20. macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_ENABLE;          //使能自动去除8 m- P6 c; t) g& h; i, K& f' l
  21. macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;
    # i8 i8 q2 u$ F  [; n
  22. macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE;. w5 B9 z! a8 q6 d5 s8 y
  23. macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE; ///不接收所有包" ?* |) H) J7 R, V0 l6 k% s- ?
  24. macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_NORMAL_ENABLE; //源地址过滤: Q. L' c- D8 d
  25. macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;- ~( \/ I: r+ e( O
  26. macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_DISABLE; //广播不接收$ W* o9 u2 W) T3 \, \4 G
  27. macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL; //目的地址过滤# V, W9 L: Z, _- N; W/ z
  28. macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE; //混乱模式  I0 [) s: c6 J5 b5 q
  29. macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECT; //多播过滤" V) p( d1 o5 j2 g/ A4 T
  30. macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT; //单播过滤
    * s9 D- o/ C' Y1 p# j
  31. macinit.HashTableHigh = 0x0; //Hash表高位6 ~5 r& E$ k7 D' j1 L
  32. macinit.HashTableLow = 0x0; //Hash表低位1 ?$ N* i# q7 j# k7 `
  33. macinit.PauseTime = 0x0;
    $ O+ V- P3 ]6 ~- G9 f+ l1 w
  34. macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;
    0 e4 l+ P, |, e$ E2 O
  35. macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;2 T" w, C' v+ V5 H
  36. macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_ENABLE;0 x3 J1 w5 @7 B" ?7 ]2 J+ q
  37. macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE; //接收流控! O$ v+ m4 S. g7 B
  38. macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE; //发送流控
    ; v% j. r4 ~8 u/ O  C$ Z
  39. macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;. [: P+ M/ j; {6 G
  40. macinit.VLANTagIdentifier = 0x0;
    5 Q" H$ ?0 t4 ]' v. E. V
  41. - s" R7 s3 K$ v3 c6 Q# ~
  42. return HAL_ETH_ConfigMAC(heth, &macinit);
    : i" s) |7 i+ Y: Q+ X6 R6 o1 T
  43. }
复制代码
2 H+ e9 x4 N2 z5 E
默认的MAC层 DMA初始化函数
+ P4 R* f% i- @7 R
  1. uint8_t ETH_DMA_Setting(ETH_HandleTypeDef *heth)  B6 Z, _) ^8 M+ @) q
  2. {- Y" q2 Z1 X% g% T7 \3 m
  3. ETH_DMAInitTypeDef dmainit;
      w. F+ ]; F3 L
  4. /* Ethernet DMA default initialization ************************************/
    2 r1 |9 t. Z! d" Y- X
  5. dmainit.DropTCPIPChecksumErrorFrame = ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE;
    3 h4 b# L2 J4 v  X' V
  6. dmainit.ReceiveStoreForward = ETH_RECEIVESTOREFORWARD_ENABLE;
    ! K: g" \$ c8 W3 o- s& k9 d8 H" O0 E
  7. dmainit.FlushReceivedFrame = ETH_FLUSHRECEIVEDFRAME_ENABLE;
    , f4 p; E# f6 v% w$ O
  8. dmainit.TransmitStoreForward = ETH_TRANSMITSTOREFORWARD_ENABLE;; R" i& p. W( ^
  9. dmainit.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES;% |1 E; M5 i; Q/ ~# A
  10. dmainit.ForwardErrorFrames = ETH_FORWARDERRORFRAMES_DISABLE;, v8 O, J5 D% J/ R# s
  11. dmainit.ForwardUndersizedGoodFrames = ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE;
    ! v+ |& q" G, o" A/ {* M
  12. dmainit.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES;5 E, r2 m4 X0 u  ^+ \
  13. dmainit.SecondFrameOperate = ETH_SECONDFRAMEOPERARTE_ENABLE;
    : j; y; E$ S) K# q+ G9 h
  14. dmainit.AddressAlignedBeats = ETH_ADDRESSALIGNEDBEATS_ENABLE;$ ^: c3 c# a% J! O# w, D* e' x4 ^
  15. dmainit.FixedBurst = ETH_FIXEDBURST_ENABLE;2 w1 V7 j# y! K. Q5 a6 n( l: }
  16. dmainit.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;. O" F& q" j% K2 |8 T
  17. dmainit.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;
    " _  V, N9 h  R6 h( L; f
  18. dmainit.EnhancedDescriptorFormat = ETH_DMAENHANCEDDESCRIPTOR_ENABLE;
    0 x3 F4 p; d2 F5 x
  19. dmainit.DescriptorSkipLength = 0x0;0 d5 o+ @4 I3 i* y3 `& n
  20. dmainit.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1;9 J6 Y* G- w0 }8 Z/ @5 h! O
  21. uint8_t res =  HAL_ETH_ConfigDMA(heth, &dmainit);
    5 ]  M5 n) U$ `  b. b$ `: P
  22. if ((heth->Init).RxMode == ETH_RXINTERRUPT_MODE)- \+ ^" K6 t, ]& ^/ F
  23. {" ]: r  `9 p& q$ J+ E
  24. /* Enable the Ethernet Rx Interrupt */! L( ?) N% b* l7 |4 h1 m
  25. __HAL_ETH_DMA_ENABLE_IT((heth), ETH_DMA_IT_NIS | ETH_DMA_IT_R);; V2 I0 \' d8 v7 |. Z# ~. r
  26. }
    ! ]6 P( D& d* A% F1 U, o! w* D
  27. return res;
    , Y' l$ H  X2 M, T9 x: e" X
  28. }
复制代码

3 |. M. J5 v- p1 l用来设置MAC地址的函数(其实就是把库函数的static函数取出来直接用了)
  1. <blockquote>//heth: HAL句柄
复制代码

7 z0 l* G- `" ?& i然后到最最重要的MAC层过滤设置

5 j0 y$ D5 ]0 r# n: Q# i以MAC1为例
7 Z4 o* m3 H/ Q- y; y4 d9 a1 R

* p5 k% @( p' H. ~6 {4 N8 D* _( z, N
20191124093921254.png

- H4 [( g0 X4 F, N! n" p( d/ z, ^4 F, s4 h6 q( P  ?) t* I, n7 {; p
20191124094439199.png

' U: U3 F! {& ?9 b- g% T3 D& u
; M3 g1 t! u/ D: J注意看红框的描述
- \! C# k" U! p+ ~- B
功能很好用,可以过滤源地址/目的地址,还可以做掩码功能
; T' R5 j( s6 F4 g" ^: ?" U. X设置MAC层过滤的代码5 J) l: ^) J% W8 S: Z; z
  1. static void ETH_MAC_Filter_Setting(ETH_HandleTypeDef *heth,ST_ETH_PAR * para)
    : i* y+ ^* D' ]. z: E- {
  2. {
    ( p0 `; l* E) M" j8 o
  3.     //设置本机MAC地址, n" j4 `3 n. b
  4.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);5 g1 i  E. n, o) i, H( x5 K: S, k
  5.     //设置UDP-A的对方MAC地址
      Y# w' Y. V0 l9 n7 d! A8 c
  6.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS1,para->UDP_A_MAC);
    ) s1 r7 ~( i7 |, I# V
  7.     (heth->Instance)->MACA1HR|=0xC0000000;//需要完全匹配UDP-A的对方MAC才接收
    ) u% K" D2 F* G  G# @3 K9 G
  8.     //设置UDP-B的对方MAC地址
    " `2 P( L# W+ I6 M2 L
  9.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS2,para->UDP_B_MAC);
    ( F- |9 B) S# B1 \8 g$ I% t6 y1 Q# i
  10.     (heth->Instance)->MACA2HR|=0xC0000000;//需要完全匹配UDP-A的对方MAC才接收% d# ^* }+ G! V. F
  11. }
复制代码
, b0 k. g- E( K, k# ]# E: m- ]/ E
我这里是希望为我的两个UDP精确过滤接收到的源地址
8 E3 ?2 ]$ q4 q; c所以AE位设置为1,SA设置为1,MBC全部为0(MAC地址全部检查)
0 q! x) w4 N/ W+ _* q) Q- _  m( L0 `3 o" a( m
假如我希望过滤MAC中特定的厂家字段
. a0 J0 L. G! H3 H  V例如某个MAC地址
% u* B. h" K" e7 T# l6 N$ w0 u2 ~
01-02-03-04-05-06% u  C/ z) M1 m6 j; O. O
其中01-02-03就是厂家字段7 a! v* }- R8 ~- z3 K
$ |8 \, I5 S1 d$ f# Q
那么代码要这样修改(MBC的第29位,28位,27位置1)
' I5 e# {2 B1 b  T1 w0 u* h这样MAC层就不会检查MAC地址里后3个字节(04-05-06)8 f4 H& }5 ~7 ?+ I
但是会检查前3个字节,也就是厂家字段
8 z, w% T" p) b+ g2 j1 F这里需要注意MAC地址的字节序
" x  |4 m# c/ l0 t
  1. static void ETH_MAC_Filter_Setting(ETH_HandleTypeDef *heth,ST_ETH_PAR * para)* x% G( Z, u# ^  Y
  2. {
    : u/ G  Z4 Q0 _  a: A; L0 O
  3.     //设置本机MAC地址  d/ e: C' g& j& E" l. W; W
  4.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);
    / T" D5 g1 @6 W5 e0 N
  5.     //设置UDP-A的对方MAC地址
    $ {3 V9 Q! O0 S# W, G& n( G
  6.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS1,para->UDP_A_MAC);
    5 |# z3 c% h8 S! `! L" ?) m
  7.     (heth->Instance)->MACA1HR|=0xF8000000;//需要匹配厂家字段
    4 }2 o4 U7 H% A  F0 t
  8.     //设置UDP-B的对方MAC地址) H+ Q$ o% `% i3 O  Z, l
  9.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS2,para->UDP_B_MAC);
      t8 J6 J' M  k8 m! d8 q( y
  10.     (heth->Instance)->MACA2HR|=0xF8000000;//需要匹配厂家字段3 p( J% w( K7 u' ]' `$ m
  11. }
复制代码

  b# v* n3 q1 Q& }" c- @& |  @然后这些函数的调用顺序按:
: X5 i6 c% Q4 K# f& P1. HAL_ETH_Init2 q& h1 K; y" w- x+ X# [7 x3 u5 f
2. ETH_MAC_Setting
% P& ^' J% t0 @8 [& H5 H: [1 P3. ETH_DMA_Setting: b/ P8 s5 J7 d3 r7 s' Z/ n$ r: z
4. ETH_MAC_Filter_Setting2 a/ f4 {0 E; E$ P# K% P6 Z, p5 a
' p$ I* ?0 m& h) U& i7 P
用你希望过滤的MAC传递到一个Hash计算函数里,得到一个值,通过这个值产生“映射”关系来过滤MAC地址,所以这个并不是精确的,因为可能会重复~~- `, z! v( C8 q9 Q( a: ^8 O9 `$ u
7 |% W9 Y6 k' y+ k% i" U5 f
HASH函数5 l6 [& y7 c  {, n0 F
函数
; s$ |* Y2 S9 ~% n7 |
  1. / STM32 MACHASH - Copyright (C) 2014-2018 Clive Turvey (<a href="mailto:sourcer32@gmail.com">sourcer32@gmail.com</a>). r5 m9 A3 U- n! l+ |. k5 i* a
  2. //  All Rights Reserved
    % v4 O% Z7 y' p' n  y3 T
  3. 7 J0 f: @) c& X' A. Q" ?) q+ o9 ?( N  M
  4. #include <windows.h>! {# `/ P, A2 l, @

  5. 0 V' w; m! i3 @5 X; c
  6. #include <stdio.h>0 d7 ^3 i) w: R1 I; K
  7. #include <stdlib.h>
    : C4 a) u5 w# u
  8. % ?2 d$ }+ x2 `& N4 t
  9. typedef unsigned char uint8_t;) A  v: K' k1 T( k. a/ n
  10. typedef unsigned long uint32_t;
    2 @1 F8 o9 ?' ]4 u/ e; ?# d* p

  11. ) w1 {/ [- x7 v+ Z5 B3 r
  12. uint32_t Rev32(uint32_t x)
    2 p8 Z. _9 u, B
  13. {
    2 p2 [" }( x( S' ]7 D
  14.   uint32_t y;
    4 t: p: k' N5 ?1 l- y7 J
  15.   int i;4 \9 }2 e$ \3 `- f4 c& o
  16. 8 c& S; x: A8 k- F. J8 Y/ k
  17.   y = 0;
    : p' e( p; N8 a! c7 R$ m) A) u
  18. 6 ]' N8 t: |7 z& `; C
  19.   for(i=0; i<32; i++)
    % d; w; u# \/ o  B
  20.     if (x & (1 << i))
    % Q$ Q: I; x2 Y0 J9 \( N- s# f
  21.       y |= 1 << (31 - i);4 V3 X6 O& W7 `

  22. 5 x/ M3 I9 C$ V& b% h5 j
  23.   return(y);
    . }% O4 \# j1 _2 N- M
  24. }& y) t: b: r$ L9 l* k% O

  25. 7 \& h3 {: k! Q  B
  26. uint32_t MacHash(const uint8_t *Mac) // <a href="mailto:sourcer32@gmail.com">sourcer32@gmail.com</a>  `, n) X+ x" g
  27. {
    0 }  Y0 s" B; ?# A3 ~. Y
  28.   int i, j;
    / U; T0 M( c! l4 S+ H- q3 g
  29.   uint32_t Crc;0 O) u( |6 k3 Q# w# ~

  30. : F- g9 H3 X0 n
  31.   Crc = 0xFFFFFFFF;
    ! ?' v! g8 W) ?1 J( O* C6 }! ]/ G
  32. " t7 s9 q7 c+ b, r6 N  n
  33.   for(j=0; j<6; j++)
    8 M" D6 b( ?5 t$ [4 t2 c
  34.   {
    ; ^9 d) w" W/ C* K
  35.     Crc = Crc ^ (uint32_t)Mac[j];/ U  l3 L# O9 X0 ?# w) [( `
  36. 7 j5 G& h0 H& G3 R
  37.     for(i=0; i<8; i++)
    ( y" G4 B7 C9 T$ c
  38.       if (Crc & 1)8 A; ]' Q! d$ d
  39.         Crc = (Crc >> 1) ^ 0xEDB88320; // Reversed 0x04C11DB7' \! P8 Q" q, E/ C- p
  40.       else
    / n' ?1 U! L7 |" q/ v* F) B3 L& j
  41.         Crc = (Crc >> 1);1 q4 Z- ]0 u+ B& U- X
  42.   }
      D& v4 j& [$ m. }; I
  43. 1 ^3 j. E5 U' m# o, k/ K* V; v
  44.   return(Rev32(~Crc) >> 26); // Get High order 6-bit in reversed/inverted CRC
    $ O5 s4 u7 G8 y6 q5 K
  45. }4 r4 `% i5 F) W. X4 `
  46. ( N+ `! _4 y1 u# B
  47. uint32_t MacHashFast(const uint8_t *Mac) // <a href="mailto:sourcer32@gmail.com">sourcer32@gmail.com</a>
    5 q1 a, |0 ]: Q8 O, k
  48. {; ]! \1 w# d7 E
  49.   static const uint32_t Rev6Tbl[] = {
    & o3 }- o6 c* P
  50.     0x00,0x20,0x10,0x30,0x08,0x28,0x18,0x38,8 ?# g" Y5 u" Z% K, B
  51.     0x04,0x24,0x14,0x34,0x0C,0x2C,0x1C,0x3C,
    $ i" r+ a1 w' Y8 O! s! A* s# Z
  52.     0x02,0x22,0x12,0x32,0x0A,0x2A,0x1A,0x3A,
    8 G0 V9 g. ?" A; U. r# K
  53.     0x06,0x26,0x16,0x36,0x0E,0x2E,0x1E,0x3E,
    : n/ y1 s$ f- v
  54.     0x01,0x21,0x11,0x31,0x09,0x29,0x19,0x39,
    ; T  k3 G  J: [+ W
  55.     0x05,0x25,0x15,0x35,0x0D,0x2D,0x1D,0x3D,8 w7 W- s1 U, f* v3 Q3 n& B. r0 n: Q
  56.     0x03,0x23,0x13,0x33,0x0B,0x2B,0x1B,0x3B,5 z, i4 s. `, v. k$ I- `+ s8 {+ f
  57.     0x07,0x27,0x17,0x37,0x0F,0x2F,0x1F,0x3F };
    0 t: V2 f* ~2 Y0 T. W) Y
  58. 5 a; h# |; z; R8 w
  59.   static const uint32_t Crc32Tbl[] = {+ F( Y% }0 `/ C
  60.     0x4DBDF21C, 0x500AE278, 0x76D3D2D4, 0x6B64C2B0,
    " _" u9 q5 T% \" h4 C
  61.     0x3B61B38C, 0x26D6A3E8, 0x000F9344, 0x1DB88320,- q1 T+ p; E1 ^  Y; H" D
  62.     0xA005713C, 0xBDB26158, 0x9B6B51F4, 0x86DC4190,% c& q% t% v- M/ A0 c# J
  63.     0xD6D930AC, 0xCB6E20C8, 0xEDB71064, 0xF0000000 };
    5 Z/ p+ z5 B' G  p. |

  64. 3 ^/ ~. i: d- c4 T% e7 X) D
  65.   int i;
    3 d3 L* t& e- C7 W: J
  66.   uint32_t Crc;' [. d1 r2 [% x% B6 H. K# I( {

  67. $ t5 o6 I* {( ^9 R. T' \
  68.   Crc = 0;9 x5 r' k$ ~- q8 l! _

  69. + B! o. u# W+ ~" p- q5 I
  70.   for(i=0; i<6; i++)
    ' f2 Q& M" ~7 N; }
  71.   {$ Y  q2 y# ?! e/ s7 X3 U- \2 H! J6 {
  72.     Crc = Crc ^ (uint32_t)Mac<i>;: e9 w* `# j) }4 a  e  D- [( [* v

  73. $ w- Y1 [! o% E  T4 }
  74. </i>   Crc = (Crc >> 4) ^ Crc32Tbl[Crc & 0x0F];  /* lower nibble */
    ( o* D6 g+ r- l
  75.     Crc = (Crc >> 4) ^ Crc32Tbl[Crc & 0x0F];  /* upper nibble */$ l8 L( M  n7 S: d- H1 z
  76.   }
    # G3 ~9 J  d2 H/ Y: U, ]
  77. " K' Y' T* Z4 d9 Z
  78.   return(Rev6Tbl[Crc & 0x3F]);& C' f2 J# t8 _! Z3 p
  79. }
    + ]* i4 o7 Y- `( j) g/ Z) b. u
  80. 9 T! y  W2 f4 i& Y0 e: E" _, _
  81. int main(int argc, char **argv)
    & L: R2 v( {/ y
  82. {
    $ z- _9 ]: E6 |4 P
  83.   static const uint8_t Test1[] = { 0x1F, 0x52, 0x41, 0x9C, 0xB6, 0xAF }; // 0x2C
    , q, y; s9 [- E+ }7 J
  84.   static const uint8_t Test2[] = { 0xA0, 0x0A, 0x98, 0x00, 0x00, 0x45 }; // 0x07
    2 u2 V, d! |9 B0 D& `
  85.   static const uint8_t Test3[] = { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x21 }; // 0x243 ?. }* A8 ~& ?+ R: f5 @* d6 W
  86. 3 J$ _  k3 T1 K2 [) U( O% m
  87.   printf("MacHash %02X\n", MacHash(Test1));
    7 _: _; I2 o! P3 U6 w
  88.   printf("MacHash %02X\n", MacHash(Test2));
    # H& i4 y4 z, s" U
  89.   printf("MacHash %02X\n", MacHash(Test3));
      T' c, Y% ]* @7 V

  90. : W: ~* d' E4 n; D9 J& D7 h
  91.   printf("MacHashFast %02X\n", MacHashFast(Test1));
    8 p& v) ^) G5 h: ~+ c5 A" f
  92.   printf("MacHashFast %02X\n", MacHashFast(Test2));
    ! L8 P* X% {& I7 ?' p8 S
  93.   printf("MacHashFast %02X\n", MacHashFast(Test3));% d7 U  Z& G2 h: N! j& }

  94. $ f: Q. b& h6 b# F) ~
  95.   return(1);
    - {$ ]* d5 P1 V7 i. X* @  {
  96. }
复制代码

1 r; n; W4 c6 u+ h, l" I  {) {! M) I+ d- v8 B( c6 Z
回到手册
/ Q6 A1 ~; @) ]; ?
; |0 X" u7 l# \5 p) ^* S+ S: v
20191124100604140.png
# b/ H7 h6 I% G  T
7 w8 k! [/ Y2 i2 D: x+ }
20191124100636882.png

5 i) k9 M5 h$ i: i
9 U* `. J/ `3 E! ]% o+ \2 u1 f, y: r" T' \5 N* ^
上面的函数算出来一个数,假如是手册上的那个0x2c,二进制为101100B
* P. E, v) e% h- S/ B) H8 F! y4 Z换句看得懂的人话···就是:  v' G' Y' j/ D' y0 r
算出来的数先看第6位
5 K& R5 y& y% ]是1的话说明用到的是HASH表高位寄存器
0 w$ R# W3 M6 y否则用到的是HASH表低位寄存器8 }# H. b; ?7 p8 w
然后剩下的5位,转成十进制不是12嘛
* |$ {- X  o# r如果你希望过滤这个MAC7 \/ G( J) f$ t* f' ^% K
那么你就把对应的HASH表高/低位寄存器的对应位置1,否则置0
, Z' `5 C, g) l7 Q4 d这里的0x2c就是要把- V# I" V& |+ V, h
HASH表高位寄存器的第12位置1
7 w  x+ w2 O, e就可以过滤这条MAC了; m9 N+ r# {# {
然后把你希望的MAC地址都按照上面说的方法弄完
+ t* I( U$ c( B" R
. [, h) t( ^) x6 g- w6 e) J回到这个函数稍微改一下1 ]8 Y% y) p) Y, ?
  1. uint8_t ETH_MAC_Setting(ETH_HandleTypeDef *heth)5 G5 l7 s  n. x3 |9 x$ x2 E0 g
  2. {8 h: F+ s: p$ ^' \. J" T: S
  3.     ETH_MACInitTypeDef macinit;' m3 X2 @) b' v) E% y
  4.     /* Ethernet MAC default initialization **************************************/$ B2 r+ p6 y+ Z$ F( h. c6 Q1 g) r
  5.     macinit.Watchdog = ETH_WATCHDOG_ENABLE;/ ?# z) P: T" ^0 y- W" g* D
  6.     macinit.Jabber = ETH_JABBER_ENABLE;
    # t+ D2 G, j1 o/ q, F
  7.     macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;
    % e, O: V2 E0 J( g/ L+ @6 J
  8.     macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;# [  ~4 h! t4 K2 k1 n
  9.     macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;' \2 D3 F& ^8 U# I( R: v, \4 q
  10.     macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;* v% g% q& |: ]' g
  11.     if (heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)
    4 ~& V: t) V0 b* U+ d
  12.     {& v" T& |/ _8 l  [! o
  13.         macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;0 e( U" s+ l; N) p# v; W6 m
  14.     }' I9 S# r4 m' R$ d9 F$ q0 R. w
  15.     else3 Q0 |0 ^( G( u" n
  16.     {
    " [: u3 J8 z! R9 s
  17.         macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;
    % r0 x3 t) R% f; g) u0 z& a
  18.     }4 f' @' V. {: C5 z$ G, g
  19.     macinit.RetryTransmission = ETH_RETRYTRANSMISSION_ENABLE;          //使能重传2 r" ?- {' x* A1 `
  20.     macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_ENABLE;          //使能自动去除
    + E$ M" T, t# G8 g
  21.     macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;& C8 k  n8 h- L# M( C, S  j
  22.     macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE;* ~7 Q: R* b( o6 U* j
  23.     macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE; ///不接收所有包4 i0 Z/ X; T5 q3 d8 m. {, h4 [
  24.     macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_NORMAL_ENABLE; //源地址过滤
    / J1 {2 U% i0 {0 U$ Y% P( t! A
  25.     macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;
    $ o5 `! ~( X6 j" z" b' |- H
  26.     macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_DISABLE; //广播不接收
    / i6 Y: O4 {* I7 m; ?0 Y' ?$ H2 U
  27.     macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL; //目的地址过滤5 V6 A% x9 @! T( z4 P
  28.     macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE; //混乱模式
    ; h! Q' b  M9 |% ?9 e
  29.     macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECTHASHTABLE; //!!多播HASH完美过滤
    7 f& _; n" [5 \( |2 {$ b
  30.     macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECTHASHTABLE; //!!单播HASH完美过滤
    ) }0 `3 }  k/ G0 p; n$ B+ b
  31.     macinit.HashTableHigh = 0x0; //!!填你最后算完的Hash表高位
    5 z* b2 T1 C6 k2 n) m" i
  32.     macinit.HashTableLow = 0x0; //!!填你最后算完的Hash表低位
    1 a7 ?& J, B/ D/ y$ ]
  33.     macinit.PauseTime = 0x0;
    5 G/ R8 l) B1 ~4 f- m2 V( W
  34.     macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;1 J$ R2 w% C3 U% ?! M5 m
  35.     macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;0 L+ X1 x% J3 R6 ^. E" L6 g
  36.     macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_ENABLE;
    - ]1 P- X0 j& x
  37.     macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE; //接收流控
    + Y  u$ E0 l8 _& l. o/ |3 |% Z
  38.     macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE; //发送流控6 ^  ^6 z" @* q$ z+ A
  39.     macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;
    + V! `, k/ O* ^% e
  40.     macinit.VLANTagIdentifier = 0x0;
    4 ?1 w- W  O& i6 p

  41. 4 U( y/ @3 O: i( H% P( _2 E' I
  42.     return HAL_ETH_ConfigMAC(heth, &macinit);; P# z5 t+ T8 l) c
  43. }
复制代码

& I4 A. {" r! X, A! u" }0 J$ f9 J大概MAC层过滤就这些东西了
. y+ R( @$ a7 d& I) k/ Y如果有条件弄MAC层过滤真的强烈建议开启,可以大幅减轻协议栈的处理负担,板卡不会因为处理大量无用的数据而白白浪费处理性能。
3 u7 E0 L: i% F# n9 o: P  X
$ |$ ]2 I% |7 ]& E( F' V8 `# e$ }) y/ U5 D+ \

& V- ]! l/ o  X3 `( t
; |0 f* O' t* l
收藏 评论0 发布时间:2021-12-14 10:15

举报

0个回答

所属标签

相似技术帖

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版