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

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

[复制链接]
STMCU小助手 发布时间:2021-12-14 10:15
前景描述& E/ X+ j* }# B4 _7 ^8 A
我司的以太网实现是LAN8720搭配片上MAC层做的,协议栈用LWIP. d& u: F+ Z( Z) V0 J# \2 E2 z

9 b2 l, T- ]4 E4 ~; N- t8 x这种做法应该还是蛮常见的,反正不是LAN8720就是DP83864,再不然就是硬件协议栈的W5500了0 H* F5 _$ l$ {; i
6 T; f% V5 S) P" S! X
想想还是有MAC层过滤比较好,随手翻了翻它的手册,W5500好像是没得MAC层过滤的
! f6 U" X# o; T4 q7 Y  ]; |
, z/ l% P: |* i假如数据速率比较高,数据量大,而且外面还有乱七八糟无关的数据往板卡送,我也不知道用这个片子到底好不好
3 ]: Q5 k" r4 m; K( d$ G) D  l/ B0 w1 i$ Y7 J
LAN8720也不好改了,就继续用吧/ _2 v# o0 a2 i8 E

0 }% z7 D! m3 F8 {" n好好在,发给板卡的数据的MAC还是有特征的,我只需要过滤发送方MAC地址的前3个字节,也就是特定的厂家那段
# R6 Y# b+ S/ C1 p, P. ?: d# K8 D" l# D' f9 }, b8 p
MAC地址的科普知识这里就不过多描述了,我们直奔主题5 V) V# }7 X$ y5 n( N
3 K+ i* ^" F' v$ Q3 K% o/ d
怎么用STM32 F7的片上MAC做MAC层过滤
0 s8 r/ _4 R- @( f* r- _
5 E" j" Q1 K% u; w$ E3 _写这个的目的,就是我搜了搜,没看见有人写这个MAC层过滤功能,具体代码怎么写才能用  u; I3 B, u/ O& f) C
. A$ n; V0 I; u; M
知识科普-STM32的片上MAC
% R" C- w6 g- y7 i! \STM32 F7的MAC层过滤方式有三种(说人话的直白解释,中文手册其实也翻译的不好)" c4 y4 H# E3 I1 X( G
精确过滤(手册上叫单播目标/源地址过滤)
6 K" y1 ?8 L$ ^/ @$ l粗糙过滤(手册上叫Hash表过滤)
, A( ~# G& Z% E6 P3 q特殊过滤(广播,组播过滤等等特殊的过滤)$ t6 z. P. @7 E& T0 S& j
我这里着重说第1种和第3种; [+ U3 v0 A, K1 p& a

, B4 T% a8 U( H6 L- |- J7 `# }STM32 F7可以存4个MAC地址
9 h3 j- |% T5 Y0 w! @9 J, B: ?# w/ h! h其中MAC地址0是自己的MAC,其他三个可以用来做过滤
2 r! m" f2 M7 c; {6 Z4 X( D+ u
- b( f( @3 Z% H5 a0 ]$ F网络数据包通过PHY进入STM32的MAC,MAC层是可以对目的地址/源地址检查并过滤掉没得用的数据的,默认的HAL库库函数HAL_ETH_Init中& f7 w. v& X0 Y+ K
有一个static的函数  e, @5 W- |% g0 g
static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err)& s7 A0 f6 P# r2 Y" f9 \
会帮你在初始化网络功能时初始化默认的MAC层功能:# q! q- t9 o( D7 b2 L3 n
关闭源地址过滤
, C. d/ }! |: X+ u) G2 m不接收所有数据
  T& l+ B0 m2 ~$ R) k, a7 v接收广播帧$ E+ m* T1 R0 v( x
打开目的地地址过滤
  U0 a) i" A; X单播数据精确过滤
, A" t% L4 {! G  x组播数据精确过滤
, ]2 X+ ^/ c5 X4 ^# X' r6 QHash表过滤关闭
4 q) Z' o. j2 @3 r9 W! ?
8 t0 x+ I' g& z: h/ ]( u, L其他的功能自行研究,我这里捡重要的说
. _3 p) O$ v- T- y9 {  ~! k3 q
  1. static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err). N+ O. W3 y5 t" B7 ?
  2. {
    2 d" F* I) z- `' U2 `# M$ {, g" Y
  3. ETH_MACInitTypeDef macinit;- {9 I7 Z, u: D0 v1 d3 Q
  4. ETH_DMAInitTypeDef dmainit;
    % K, Z% ~' N% B
  5. uint32_t tmpreg = 0;
      u# u# }: ?4 D0 r' _. Y# I
  6. : b" w& I$ @" `# \; h
  7. if (err != ETH_SUCCESS) /* Auto-negotiation failed */
    ! [( V& H, ~" R7 X5 W
  8. {/ N1 }8 L% s8 k; G. @" R: m* {
  9. /* Set Ethernet duplex mode to Full-duplex */7 O0 P% e. r# {8 M; B
  10. (heth->Init).DuplexMode = ETH_MODE_FULLDUPLEX;
    5 O, N& G+ z8 m# `

  11. % N! k% O1 f4 a2 ]
  12. /* Set Ethernet speed to 100M */
    : k6 e2 m7 P/ D, e7 `! W' u
  13. (heth->Init).Speed = ETH_SPEED_100M;2 G$ n8 i" q9 x. \2 s5 Z
  14. }
    8 {4 S1 q1 [* f, m
  15. & q$ {- o* g+ Y' K
  16. /* Ethernet MAC default initialization **************************************/- n4 n% G3 P: n$ J) R3 s5 A
  17. macinit.Watchdog = ETH_WATCHDOG_ENABLE;
    / h* `# f& `0 V# [& ^5 q
  18. macinit.Jabber = ETH_JABBER_ENABLE;) R! i& Q1 }$ p; N0 `% Y6 B
  19. macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;1 q, G+ A2 {/ Q9 U' F4 V
  20. macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;6 y+ ^7 ~+ @+ h- u: t
  21. macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;9 E/ @* x8 U9 q! b6 [: E0 a  o
  22. macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;% K- J+ y+ J$ ?/ ^9 @4 S3 Y2 a$ A
  23. if(heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)
    2 P( K' l1 Q  P+ I# N
  24. {
    7 a- j" D; |7 a4 t  v
  25. macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;
    - ~) i) ?) I9 z. M6 f# z
  26. }9 H- M) V5 ~9 y- s- t, f
  27. else8 }* P3 w. J  g5 h0 u* l3 |, _
  28. {( s# @; s. K% o. o8 V$ A
  29. macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;4 O+ L- R: ^$ Z
  30. }
    / B, v3 S. K0 A+ a/ b! q" y( t+ \5 |
  31. //这一段是MAC层过滤的设置,下面是DMA的,那个用默认的就可以/ M" c# Q$ B& i$ W4 V
  32. macinit.RetryTransmission = ETH_RETRYTRANSMISSION_DISABLE;/ H5 g, l* y' p( |8 z
  33. macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_DISABLE;
    7 A0 p4 h, \2 ?' E! v1 P
  34. macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;: k, U- E+ R' a
  35. macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE;+ Z; f: Q3 j* S3 O$ L$ _
  36. macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE;. K9 x5 N# C/ V7 M! k" Q4 k7 Z
  37. macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_DISABLE;6 _% n  `6 k$ _  c$ ?2 g! `
  38. macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;
    & k" P( C; q5 K. ~! V/ g
  39. macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_ENABLE;
    8 t# O# q1 Q/ l* I; j& H( B
  40. macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL;/ n0 x: j/ P4 P% F0 V0 {7 g: F' S1 T
  41. macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE;
    ) A  ]& ~( m! y' M. T
  42. macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECT;8 p5 s1 D% q7 ?- }. F
  43. macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT;
    2 Y" O; W: A$ @) u
  44. macinit.HashTableHigh = 0x0;
    2 q( n, O/ W* d% Y+ v  }
  45. macinit.HashTableLow = 0x0;
    ; x4 r, ]: M" P
  46. macinit.PauseTime = 0x0;' m6 n% _) W$ K; w/ S0 J
  47. macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;
    3 d; r  Q8 L& w. I1 V' B
  48. macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;
    3 ]* c2 Y/ p, ~2 v. \. _
  49. macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_DISABLE;
    9 l+ N( T6 r! u3 e# J2 ^3 H
  50. macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE;
    % Z6 h! a8 F6 H- X3 l9 A- }
  51. macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE;3 u/ h7 f. G; i# }' I6 q$ i
  52. macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;
    % U- C% N5 S1 v9 D' j- D0 M" ^$ X; b9 q
  53. macinit.VLANTagIdentifier = 0x0;
    % Z6 E) M% p' P) o6 k8 G

  54. 9 a! `  S  O9 j6 D6 J3 Z
  55. /*------------------------ ETHERNET MACCR Configuration --------------------*/" s- {" _' z9 C9 L3 `, J  s- {
  56. /* Get the ETHERNET MACCR value */9 T- g2 s% E! {2 C" a# }" R* h6 R
  57. tmpreg = (heth->Instance)->MACCR;, {# V6 N" E4 i$ J
  58. /* Clear WD, PCE, PS, TE and RE bits */
    0 H4 l8 d' @/ c0 X4 i' P
  59. tmpreg &= ETH_MACCR_CLEAR_MASK;4 D* |2 q3 p$ E1 L) Z+ [- h
  60. /* Set the WD bit according to ETH Watchdog value */3 Y3 A) h; M" k9 c: `$ `
  61. /* Set the JD: bit according to ETH Jabber value */
    . q1 P& d6 ?. S8 [4 l& v/ t' Y" ~0 H
  62. /* Set the IFG bit according to ETH InterFrameGap value */
    & y+ }) V) [/ g- j
  63. /* Set the DCRS bit according to ETH CarrierSense value */
    9 n6 s+ y# |& s+ [8 H9 N! ?" u9 M
  64. /* Set the FES bit according to ETH Speed value */( H: p0 U( T4 E% a& v) T! Q* r
  65. /* Set the DO bit according to ETH ReceiveOwn value */) N) P3 g+ J) Q, g
  66. /* Set the LM bit according to ETH LoopbackMode value */6 w/ W$ J: l( s& z! ]
  67. /* Set the DM bit according to ETH Mode value */  s# b- O* L- j% O
  68. /* Set the IPCO bit according to ETH ChecksumOffload value */
    & T5 B+ K" x& q0 p2 j4 U
  69. /* Set the DR bit according to ETH RetryTransmission value */
    $ i7 n2 v6 j2 B
  70. /* Set the ACS bit according to ETH AutomaticPadCRCStrip value */
      j7 W* F% R8 {: r0 w
  71. /* Set the BL bit according to ETH BackOffLimit value */. x& F5 Q( l; n0 z. I
  72. /* Set the DC bit according to ETH DeferralCheck value */
    $ ~0 D* z" [* H2 q8 a, _8 I
  73. tmpreg |= (uint32_t)(macinit.Watchdog |& X  _) x; i& }9 U% @
  74. macinit.Jabber |- A+ M+ }. v( R% _# Y, V1 W( Y
  75. macinit.InterFrameGap |2 A7 ]% v9 X: v6 F% H
  76. macinit.CarrierSense |
    & g1 C$ V6 C2 T7 l. i3 j. j- O
  77. (heth->Init).Speed |2 M. q1 n2 A/ p3 C. V$ N
  78. macinit.ReceiveOwn |
    - C$ Z  g) s2 x; T; u6 X
  79. macinit.LoopbackMode |
    % d4 ?/ R; G; {+ F# o' Z- O6 |1 R
  80. (heth->Init).DuplexMode |' e3 F3 y. m2 Z! R4 W8 V
  81. macinit.ChecksumOffload |
    9 }% V  i' n, H5 j9 j
  82. macinit.RetryTransmission |/ `3 o: z/ X# t' [* l! d
  83. macinit.AutomaticPadCRCStrip |
    ) u  _, ^7 E/ e7 Z, l4 k5 ?# X
  84. macinit.BackOffLimit |& o; ~2 M: d2 o( ]
  85. macinit.DeferralCheck);
    ) c  Z1 a  x# w  j

  86. : b+ X! ~* R& U- P
  87. /* Write to ETHERNET MACCR */
    * _$ }1 \) L9 O' t7 h
  88. (heth->Instance)->MACCR = (uint32_t)tmpreg;
    : B, b! o- ?# G2 D
  89. 9 M& R. q: I! e: x0 J3 T% ], @
  90. /* Wait until the write operation will be taken into account:
    $ F8 \' I' _) v6 |+ ?  ^
  91. at least four TX_CLK/RX_CLK clock cycles */
    ( Z+ L: W+ }/ w7 C. G
  92. tmpreg = (heth->Instance)->MACCR;
    * J2 h. c; P( f# F( e
  93. HAL_Delay(ETH_REG_WRITE_DELAY);
    / L+ X* u( G+ u$ P$ [# n" e. z
  94. (heth->Instance)->MACCR = tmpreg;) d- d5 }# `* q
  95. * I5 l2 x3 }7 w5 O9 I. y
  96. /*----------------------- ETHERNET MACFFR Configuration --------------------*/
    , j0 S* _, b- a; x$ q4 u# X2 n
  97. /* Set the RA bit according to ETH ReceiveAll value */* `* v& r& G/ [6 g9 P, u5 X
  98. /* Set the SAF and SAIF bits according to ETH SourceAddrFilter value */2 n9 _! n2 I" a, a" j3 F1 Y
  99. /* Set the PCF bit according to ETH PassControlFrames value *// s  Z: P, l' ?9 P% L' @1 w
  100. /* Set the DBF bit according to ETH BroadcastFramesReception value */  L2 m* Y3 C! D% d6 v
  101. /* Set the DAIF bit according to ETH DestinationAddrFilter value */- [4 W. k* J; d8 X
  102. /* Set the PR bit according to ETH PromiscuousMode value */7 [( S% L8 O) Q' Q+ t- k
  103. /* Set the PM, HMC and HPF bits according to ETH MulticastFramesFilter value */% d" F" v6 r4 `7 r0 A6 e0 ]/ B
  104. /* Set the HUC and HPF bits according to ETH UnicastFramesFilter value */
    9 s! f3 v  w: A- ]0 |/ m
  105. /* Write to ETHERNET MACFFR */2 O, J( c. l' G: A( @
  106. (heth->Instance)->MACFFR = (uint32_t)(macinit.ReceiveAll |% e, l, b1 N& R9 Z7 A3 d9 Z3 \
  107. macinit.SourceAddrFilter |
    : U1 E  o3 D7 K  @/ G4 G
  108. macinit.PassControlFrames |
    3 A% l/ E% `! z' J3 C- v
  109. macinit.BroadcastFramesReception |
    % |# ^! y9 P4 i- U! K- |$ e0 V
  110. macinit.DestinationAddrFilter |
    % N2 f. c5 z- _7 _, n' @
  111. macinit.PromiscuousMode |. h% |' K7 G0 t  Q, k; O5 O/ ~% s2 M' i
  112. macinit.MulticastFramesFilter |, ~: f; L# t& n) ?
  113. macinit.UnicastFramesFilter);
    2 M. Q+ i/ F. t9 k6 [
  114. $ Q7 H; b/ Q$ m0 S, n/ X0 w; k7 |
  115. /* Wait until the write operation will be taken into account:5 \( I! F9 L2 }: C2 k) n
  116. at least four TX_CLK/RX_CLK clock cycles */
    $ D- t  M) K3 c$ [- D- _
  117. tmpreg = (heth->Instance)->MACFFR;
    7 U( H7 ]# ~0 I7 ~3 D
  118. HAL_Delay(ETH_REG_WRITE_DELAY);" q  ^. H* \* H; ~1 h; t
  119. (heth->Instance)->MACFFR = tmpreg;  g' T* R; h* C, ?

  120. + ^* I) u6 i0 R5 h) L
  121. /*--------------- ETHERNET MACHTHR and MACHTLR Configuration --------------*/
    1 p" Q8 y9 E9 J' W8 @% x  ~
  122. /* Write to ETHERNET MACHTHR */3 x9 E2 `4 r+ G. d! A
  123. (heth->Instance)->MACHTHR = (uint32_t)macinit.HashTableHigh;
    5 o+ w- }+ q* n. u7 ^6 U$ D& w
  124. 8 p  p2 k# E" |3 H: P* Q
  125. /* Write to ETHERNET MACHTLR */
    * ]% T0 a" H+ w: K
  126. (heth->Instance)->MACHTLR = (uint32_t)macinit.HashTableLow;% C4 \$ u7 h2 n5 J7 W# E( {6 j
  127. /*----------------------- ETHERNET MACFCR Configuration -------------------*/
      v2 R# L9 _& g8 w

  128. ; l0 i! f+ n% z- Q" r* {
  129. /* Get the ETHERNET MACFCR value */( j/ V( B( |. ^# P9 N! T
  130. tmpreg = (heth->Instance)->MACFCR;
    , D/ H+ W4 \+ n5 T& R
  131. /* Clear xx bits */' L, ^' k! k: J
  132. tmpreg &= ETH_MACFCR_CLEAR_MASK;7 `" @5 S9 d  p1 n; s7 p

  133. % t0 D/ ~# }4 [+ s
  134. /* Set the PT bit according to ETH PauseTime value */
    ! O; T2 t/ a' w( b7 @; ^
  135. /* Set the DZPQ bit according to ETH ZeroQuantaPause value */, F. X! n1 z8 Q) O( ?
  136. /* Set the PLT bit according to ETH PauseLowThreshold value */
    - ?# {. I& p% V5 ~( a, b  K
  137. /* Set the UP bit according to ETH UnicastPauseFrameDetect value */5 ^$ x/ O4 [, l( _9 N
  138. /* Set the RFE bit according to ETH ReceiveFlowControl value */0 j5 [& }. r- N! j
  139. /* Set the TFE bit according to ETH TransmitFlowControl value */
    3 w, }9 N5 v9 E$ Q( }+ C6 A
  140. tmpreg |= (uint32_t)((macinit.PauseTime Instance)->MACFCR = (uint32_t)tmpreg;
    7 w4 T: b  ]' Q! Q0 g) n9 F$ a

  141. - j; B# {/ h  @
  142. /* Wait until the write operation will be taken into account:
    1 W( g$ F3 {+ S8 G8 y
  143. at least four TX_CLK/RX_CLK clock cycles */
    " O% i( |" Z* C, q/ i6 r1 j# A
  144. tmpreg = (heth->Instance)->MACFCR;3 B6 h5 c/ ~; s
  145. HAL_Delay(ETH_REG_WRITE_DELAY);
    ) F1 S! d: h7 L9 r" q% v8 {/ a
  146. (heth->Instance)->MACFCR = tmpreg;$ V$ S6 a# i% s  D

  147. + j8 T, W6 g* ~3 S  t( k' W/ q
  148. /*----------------------- ETHERNET MACVLANTR Configuration ----------------*/
    3 x; Y# W+ U3 r
  149. /* Set the ETV bit according to ETH VLANTagComparison value */
    6 J7 h. W* m% t; {; A* n
  150. /* Set the VL bit according to ETH VLANTagIdentifier value */! O, M7 n" h: `% j
  151. (heth->Instance)->MACVLANTR = (uint32_t)(macinit.VLANTagComparison |( O+ J1 X2 o) O
  152. macinit.VLANTagIdentifier);" d: h% P& N3 q5 _4 b, f8 D7 ]) b
  153. / U9 e; Y& b* O( ?( ~1 L- C
  154. /* Wait until the write operation will be taken into account:) A/ Q5 R9 @& X- _6 E, H
  155.    at least four TX_CLK/RX_CLK clock cycles */
    ! y6 S# P$ y3 u$ |3 o/ a
  156. tmpreg = (heth->Instance)->MACVLANTR;
    5 e% V$ y$ M! l2 ^$ x( z
  157. HAL_Delay(ETH_REG_WRITE_DELAY);% O" i8 |3 X$ y3 ^. S
  158. (heth->Instance)->MACVLANTR = tmpreg;- V9 y/ F0 {' }; K: ?, r8 }
  159. / H7 B" H  g6 a9 Z$ A
  160. /* Ethernet DMA default initialization ************************************/
    1 w6 l: }  b+ d, i
  161. dmainit.DropTCPIPChecksumErrorFrame = ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE;
    1 {% F* |: l! u6 P; M% a0 [
  162. dmainit.ReceiveStoreForward = ETH_RECEIVESTOREFORWARD_ENABLE;
    % R* m$ k& O, }; R. e
  163. dmainit.FlushReceivedFrame = ETH_FLUSHRECEIVEDFRAME_ENABLE;4 r' Q1 }4 I  |- W+ J+ b; l
  164. dmainit.TransmitStoreForward = ETH_TRANSMITSTOREFORWARD_ENABLE;
    # R: {$ N& Z  t- j- L/ {
  165. dmainit.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES;. e% S5 K5 V: B) f
  166. dmainit.ForwardErrorFrames = ETH_FORWARDERRORFRAMES_DISABLE;
    $ t' M+ B# L+ \
  167. dmainit.ForwardUndersizedGoodFrames = ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE;
    1 g( k: u" Q  [
  168. dmainit.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES;' r8 O2 l  ^  m
  169. dmainit.SecondFrameOperate = ETH_SECONDFRAMEOPERARTE_ENABLE;
    & q, Y1 r% `4 J( G6 I& H. W
  170. dmainit.AddressAlignedBeats = ETH_ADDRESSALIGNEDBEATS_ENABLE;
    5 J) R5 x& H$ r9 q3 T
  171. dmainit.FixedBurst = ETH_FIXEDBURST_ENABLE;( ?; q+ X! D1 S1 z1 x+ k% w
  172. dmainit.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;% ~2 }( _( L" U) N% A1 Y
  173. dmainit.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;
    $ B0 a; _$ P0 c! Z
  174. dmainit.EnhancedDescriptorFormat = ETH_DMAENHANCEDDESCRIPTOR_ENABLE;
    0 [5 m) Q2 {# y- w" H& {
  175. dmainit.DescriptorSkipLength = 0x0;
      o3 ^1 H& X( @2 U
  176. dmainit.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1;
    9 U* T5 O/ z4 F, ?* Z3 T

  177. 0 R' w$ e; ?- l9 H0 U
  178. /* Get the ETHERNET DMAOMR value */
    , [8 h* G) d* \6 \8 R/ ^" B; t
  179. tmpreg = (heth->Instance)->DMAOMR;5 m- J  Z8 V" r- ~8 N- U( @
  180. /* Clear xx bits */
    # y1 J( U. m" W/ m( Y# s
  181. tmpreg &= ETH_DMAOMR_CLEAR_MASK;! ~0 p) G! z$ x

  182. 2 \1 I, n9 Y$ F" Z: ^
  183. /* Set the DT bit according to ETH DropTCPIPChecksumErrorFrame value */# ^+ z! `/ m# }+ p  ^% p9 C
  184. /* Set the RSF bit according to ETH ReceiveStoreForward value */# G' U8 F5 A  l9 D/ _& f
  185. /* Set the DFF bit according to ETH FlushReceivedFrame value */2 M4 A( n4 B0 k. M. n: c0 e# s
  186. /* Set the TSF bit according to ETH TransmitStoreForward value */- D* J0 S2 H  _1 w
  187. /* Set the TTC bit according to ETH TransmitThresholdControl value */
    * [: N( W" R7 v0 a: J
  188. /* Set the FEF bit according to ETH ForwardErrorFrames value */1 q0 Q. P# w$ Z
  189. /* Set the FUF bit according to ETH ForwardUndersizedGoodFrames value */
    5 V9 ?; `& B# x/ I4 {
  190. /* Set the RTC bit according to ETH ReceiveThresholdControl value */3 s7 q2 C2 a$ }3 [( d5 v. C
  191. /* Set the OSF bit according to ETH SecondFrameOperate value */0 K: {: d: E0 q1 @! t' ~0 s
  192. tmpreg |= (uint32_t)(dmainit.DropTCPIPChecksumErrorFrame |
    5 R( o0 U' ?' X% v! Y- b/ J; }
  193.                      dmainit.ReceiveStoreForward |
    1 M3 w% \; z1 d7 u$ T, z
  194.                      dmainit.FlushReceivedFrame |' p0 a6 U# z" x: {4 l- k
  195.                      dmainit.TransmitStoreForward |. ~+ ~) K& o  e0 w+ X4 R1 q  E. Y
  196.                      dmainit.TransmitThresholdControl |! ~( G' c" F9 ]  @0 q  L
  197.                      dmainit.ForwardErrorFrames |
    ; j% }& ?( J( v- _
  198.                      dmainit.ForwardUndersizedGoodFrames |: x, ]: a0 p$ ?6 w2 B
  199.                      dmainit.ReceiveThresholdControl |* f( M  _5 d- [
  200.                      dmainit.SecondFrameOperate);; [# V6 E2 B- u6 K: u; _
  201. ' B5 }2 y) R" s. J
  202. /* Write to ETHERNET DMAOMR */. c/ R# M- d; `% Q/ q" @9 O, w8 _
  203. (heth->Instance)->DMAOMR = (uint32_t)tmpreg;% J, u6 W3 e1 i% y5 h# l
  204. : d  x4 n* u6 }- g9 F
  205. /* Wait until the write operation will be taken into account:( i7 l1 R: W; A1 ]8 _' y
  206.    at least four TX_CLK/RX_CLK clock cycles */
    + a6 d8 i* e* q- M- z
  207. tmpreg = (heth->Instance)->DMAOMR;5 @$ ^% K- O; v
  208. HAL_Delay(ETH_REG_WRITE_DELAY);( q2 R" p0 U! f9 f/ ^
  209. (heth->Instance)->DMAOMR = tmpreg;% ?/ b' C3 N9 @0 i7 q  J0 ^' z$ ?
  210. ( N" T# v4 L1 e
  211. /*----------------------- ETHERNET DMABMR Configuration ------------------*/6 ]: s- B' T8 o* H: X2 d
  212. /* Set the AAL bit according to ETH AddressAlignedBeats value */: Z9 R) }/ n# e8 x2 W- m! |
  213. /* Set the FB bit according to ETH FixedBurst value */) |- @& J( ]$ Q% u2 _/ G+ q
  214. /* Set the RPBL and 4*PBL bits according to ETH RxDMABurstLength value */
    7 a) c/ m* E' M
  215. /* Set the PBL and 4*PBL bits according to ETH TxDMABurstLength value */3 [$ ~% z8 I) }7 R# v: O1 Z5 E
  216. /* Set the Enhanced DMA descriptors bit according to ETH EnhancedDescriptorFormat value*/
    1 V* Z! s8 X4 M
  217. /* Set the DSL bit according to ETH DesciptorSkipLength value */
    / G/ ]" D/ I! O- x  _! _* h
  218. /* Set the PR and DA bits according to ETH DMAArbitration value */
    2 f; V/ H& V8 B6 k
  219. (heth->Instance)->DMABMR = (uint32_t)(dmainit.AddressAlignedBeats |
    4 X- j. W) D( z# w
  220.                                       dmainit.FixedBurst |
    % \; T! Q( V, L+ P3 o6 [
  221.                                       dmainit.RxDMABurstLength |    /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */
    ) I2 Q  ?" V/ X8 Z8 a
  222.                                       dmainit.TxDMABurstLength |
    8 X$ i$ @3 H& Q6 Z. @8 ?
  223.                                       dmainit.EnhancedDescriptorFormat |0 o3 J4 c9 t* e
  224.                                       (dmainit.DescriptorSkipLength Instance)->DMABMR;
    % C3 Q; ]0 X# ], f) \  u* B7 y
  225. HAL_Delay(ETH_REG_WRITE_DELAY);
    % M5 W5 y) c" _& j4 J6 [
  226. (heth->Instance)->DMABMR = tmpreg;
    0 W7 D" e& T  v2 V; o, A

  227. 7 |5 C) Q: ~6 Z6 t2 J0 ]* o# p3 V
  228. if((heth->Init).RxMode == ETH_RXINTERRUPT_MODE)
    $ i( ]7 g. _- p0 _8 }
  229. {
    + w1 z! z5 r) [* A% A& I2 X
  230.    /* Enable the Ethernet Rx Interrupt *// z8 Y$ V& o% e$ ?
  231.    __HAL_ETH_DMA_ENABLE_IT((heth), ETH_DMA_IT_NIS | ETH_DMA_IT_R);
      F! A" ]% G7 [2 v2 L  |! F
  232. }( |. v1 c0 h$ O6 ^& a$ u  ?% b

  233. ( d' S, B! O8 P' ~* j: I9 U- J+ V
  234. /* Initialize MAC address in ethernet MAC */' {- h3 g/ I  x! I( Q
  235. ETH_MACAddressConfig(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);
    ( X: P+ a" ]/ n' F% o; n
  236. }
复制代码

5 E8 g! O. e9 D. t1 r. z* D! A这里我就要稍微吐槽一下HAL库了7 V' d& w# Y  w! Y/ U7 b
MAC层过滤的设置没有预留接口出来,有设置MAC地址的函数  i3 ~4 V8 s! q
# t% X/ l' F9 ~
static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr)' i' h- Q) M6 i" L0 P

: q& l9 f# R( z( m就不多做一个设置MAC层过滤的函数嘛,连后面用到的宏定义都有~~$ m4 Z8 n5 B" J8 B* v* R
- X& r7 i& J; [" Z
木有办法,自己编一个初始化MAC层过滤的函数吧  t* ~! ?: L$ V# C
5 {  j, J+ W* m
其实也就是把上面这个ETH_MACDMAConfig函数分离成两个单独的设置函数,再编一个设置MAC层过滤的函数
; o9 d/ ~$ B6 T4 M4 h
& S: U* ~9 R: m9 O# g8 O开启MAC层过滤的初始化代码
& J: t$ W7 I& m- {- F; X+ {# N0 V
  1. uint8_t ETH_MAC_Setting(ETH_HandleTypeDef *heth)6 D, b, W4 J& w2 y
  2. {) p; h$ |1 `' L5 j
  3. ETH_MACInitTypeDef macinit;
    4 W# W# }) P% }; R7 v) ~5 t/ ?. E
  4. /* Ethernet MAC default initialization **************************************/: q  o. A3 i) W4 s" l/ ~
  5. macinit.Watchdog = ETH_WATCHDOG_ENABLE;0 ~! d% Y  a$ C" H2 p3 h
  6. macinit.Jabber = ETH_JABBER_ENABLE;
    . f8 G. K( |0 s" H3 t; m* S) H
  7. macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;; d) L6 ?' r+ |2 F( J
  8. macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;' |$ [) E- r+ {! D8 r8 F
  9. macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;7 v1 V8 i* m; Q  a9 W- R& Y6 W
  10. macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;
    - ]( ]' o6 A% Q' m, C4 `6 @
  11. if (heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)( g/ Z  M1 w- O; j4 E
  12. {/ ^+ r4 F' @3 O* {' r; x7 M( C
  13. macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;& ^: k/ b# ^# W' h5 Q7 f
  14. }0 \0 S# z6 @" K
  15. else
    9 ?; N+ n- [% C
  16. {
      F/ j( w% d$ s" @' a% N$ q: N
  17. macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;
      N; Z9 W# }+ N2 e, m+ g. \
  18. }* K4 {  x/ f) {% X: J; g) o
  19. macinit.RetryTransmission = ETH_RETRYTRANSMISSION_ENABLE;          //使能重传
    7 O1 u* A5 b" N; u( Q
  20. macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_ENABLE;          //使能自动去除0 d  O+ }. Z" s$ t
  21. macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;
    & ^  Z( ^8 \2 s: Z- D! V5 T( a5 k% _
  22. macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE;3 f& l1 C; k1 o7 ]# `9 e* r$ n
  23. macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE; ///不接收所有包. l4 }" n+ N, w: ~1 ~) i& W
  24. macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_NORMAL_ENABLE; //源地址过滤
    : K! I) P2 s. [  B
  25. macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;, L; d' d! }8 I1 j/ [% x( k- {
  26. macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_DISABLE; //广播不接收7 J9 U# N! D% c- B' A
  27. macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL; //目的地址过滤% P9 ~9 P2 C9 D; c
  28. macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE; //混乱模式
    1 F1 H; }! h, g9 S' [+ f
  29. macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECT; //多播过滤- C* r) M' I: \! S  R
  30. macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT; //单播过滤
    " b/ h$ v1 r0 d5 r
  31. macinit.HashTableHigh = 0x0; //Hash表高位
    6 u) C9 M' Y; P& z
  32. macinit.HashTableLow = 0x0; //Hash表低位
    ' M6 ]6 l1 \" p! `1 Z/ p7 R
  33. macinit.PauseTime = 0x0;
    4 L3 F- S! e* M
  34. macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;# {% y+ g2 m4 L) c" ?9 D4 A! O
  35. macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;
    ' j+ |+ Y6 z( l* Y5 t$ j$ j) ^
  36. macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_ENABLE;
    " N; W1 j2 J( i/ k
  37. macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE; //接收流控* V" S$ p; g  |
  38. macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE; //发送流控
    . @* q5 P3 m8 m, i) A* T
  39. macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;2 N8 m- ?/ `# s
  40. macinit.VLANTagIdentifier = 0x0;, B3 `3 h8 M) L# x3 h2 C# f8 M4 U
  41. 2 e1 o' o, H1 ]$ E
  42. return HAL_ETH_ConfigMAC(heth, &macinit);4 y# H) q& l; v7 h" [% K
  43. }
复制代码

2 i, U  g3 |' q. |$ W) G( r默认的MAC层 DMA初始化函数) w$ f, E9 \# s5 C1 O3 P2 b, m
  1. uint8_t ETH_DMA_Setting(ETH_HandleTypeDef *heth)
    ) c8 d2 r7 T; [0 I" X6 m3 m* z
  2. {
    3 E$ f/ m3 Y7 _: F$ t; @
  3. ETH_DMAInitTypeDef dmainit;7 Q8 @8 i4 ~4 ^0 B% p) R6 R/ o
  4. /* Ethernet DMA default initialization ************************************/. w; P: s- Q( H7 o% E: V& \
  5. dmainit.DropTCPIPChecksumErrorFrame = ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE;8 C3 n$ Y. J4 D, j7 e
  6. dmainit.ReceiveStoreForward = ETH_RECEIVESTOREFORWARD_ENABLE;
    6 S; _1 B5 h( G6 L8 h
  7. dmainit.FlushReceivedFrame = ETH_FLUSHRECEIVEDFRAME_ENABLE;& S) [( c6 ^/ C; t( E+ ]" W
  8. dmainit.TransmitStoreForward = ETH_TRANSMITSTOREFORWARD_ENABLE;
    / L/ C3 k1 {( p" h& T
  9. dmainit.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES;7 M- w4 q  w% f! T
  10. dmainit.ForwardErrorFrames = ETH_FORWARDERRORFRAMES_DISABLE;
      ^8 h/ M7 @0 X: l% R; Q$ ^8 [5 E
  11. dmainit.ForwardUndersizedGoodFrames = ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE;
    , i7 ^  w% w  M  W* e/ L/ Y
  12. dmainit.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES;" b3 P- \3 V* U( O& Q( k, _5 B
  13. dmainit.SecondFrameOperate = ETH_SECONDFRAMEOPERARTE_ENABLE;
    ) B- y- b/ E& F
  14. dmainit.AddressAlignedBeats = ETH_ADDRESSALIGNEDBEATS_ENABLE;5 m+ g( p( ]% i) s  r
  15. dmainit.FixedBurst = ETH_FIXEDBURST_ENABLE;
    1 ^6 n, Z$ C$ Z+ k/ x( X
  16. dmainit.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;
    + ^5 ?8 e; `  M0 @( H) ?- f2 A
  17. dmainit.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;. q' {6 t2 u- O2 P: B% ]+ a
  18. dmainit.EnhancedDescriptorFormat = ETH_DMAENHANCEDDESCRIPTOR_ENABLE;6 R8 g! P0 f5 g: x( ]  o5 |6 P) f1 b
  19. dmainit.DescriptorSkipLength = 0x0;" G5 h% c4 V: K8 ~8 E- L/ \% S
  20. dmainit.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1;
    0 q5 F# W# ^1 u9 j5 P
  21. uint8_t res =  HAL_ETH_ConfigDMA(heth, &dmainit);
    8 i* M. J3 ]# g8 P( B' L  c
  22. if ((heth->Init).RxMode == ETH_RXINTERRUPT_MODE)/ @+ H& G2 E5 a, q) J! U
  23. {. K- N- Y! W; d  }. r3 h  j
  24. /* Enable the Ethernet Rx Interrupt */* F0 P1 y+ h7 L7 d  _
  25. __HAL_ETH_DMA_ENABLE_IT((heth), ETH_DMA_IT_NIS | ETH_DMA_IT_R);* e9 g6 w1 h  s7 s" x3 |3 Q0 _# h
  26. }! o% W9 J& F3 j2 B. H( R
  27. return res;
    ; ]! |0 V/ e# f2 I9 G+ }" y
  28. }
复制代码

4 J/ O6 c, ?% E. V; G7 r用来设置MAC地址的函数(其实就是把库函数的static函数取出来直接用了)
  1. <blockquote>//heth: HAL句柄
复制代码
* r! r6 b2 a4 F# J0 c- O
然后到最最重要的MAC层过滤设置

& }2 g2 N4 W* ]# ?" \以MAC1为例+ E- F4 [4 i* |( ^: {2 P
0 G9 r& K( p* ]. H
20191124093921254.png
3 d7 W: W: b- j1 {' Q- j8 m) c% N& F
! G$ ?# }/ }3 h1 h& T" V. H$ s
20191124094439199.png
2 m& b  @# F: f6 Q/ w0 ~' ?! Y3 l

; a  H+ T# l5 G$ G; i* ]注意看红框的描述

% `! Y; O* ^* L( s2 v0 j; u! c功能很好用,可以过滤源地址/目的地址,还可以做掩码功能* [4 L( \1 u6 c. r* |. t) A8 n! j& o
设置MAC层过滤的代码1 j: c/ S' s) `$ m* R+ r; w! K0 q/ d6 O
  1. static void ETH_MAC_Filter_Setting(ETH_HandleTypeDef *heth,ST_ETH_PAR * para)% ?7 N' R, f. p3 Q. u; T
  2. {: u# J- G5 K! `! {* @0 B( f
  3.     //设置本机MAC地址
    & n0 `7 j) ^! l3 x, n. X- w/ M
  4.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);
    ! {. K: G5 F  I& N; f( \$ f! U
  5.     //设置UDP-A的对方MAC地址9 x' W( n1 W3 W0 \- Z5 R
  6.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS1,para->UDP_A_MAC);
    , t" H1 b, V/ [7 v- g8 Q; b
  7.     (heth->Instance)->MACA1HR|=0xC0000000;//需要完全匹配UDP-A的对方MAC才接收
    8 T* G; `, G* w0 T2 n; B" Z' M1 m% {2 W
  8.     //设置UDP-B的对方MAC地址
    # P& i$ }8 J3 J/ q/ ]6 s" f
  9.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS2,para->UDP_B_MAC);3 e+ V; I1 Q, W! o6 h) K. ?8 G& a
  10.     (heth->Instance)->MACA2HR|=0xC0000000;//需要完全匹配UDP-A的对方MAC才接收. V( {$ x7 n! z) {$ i, t
  11. }
复制代码

  ]( h4 N$ u9 o' `我这里是希望为我的两个UDP精确过滤接收到的源地址8 i" a6 f; n3 v4 j" P$ V. \
所以AE位设置为1,SA设置为1,MBC全部为0(MAC地址全部检查)
8 g8 }2 j6 M7 `6 c6 F; F
4 L6 Y& S" v  z9 d假如我希望过滤MAC中特定的厂家字段
4 b  u1 \0 `% s& M* @0 G3 Q7 E) t例如某个MAC地址
$ R0 }1 m3 h  e6 G# g% e
01-02-03-04-05-068 z& M& _4 `. q
其中01-02-03就是厂家字段3 L3 |7 ~& y: z. c

- B8 i; c( k# q. X9 A4 J* u那么代码要这样修改(MBC的第29位,28位,27位置1)( g0 N9 m+ U) V7 w; O
这样MAC层就不会检查MAC地址里后3个字节(04-05-06)
: w0 H' C( X- \% c; y4 i但是会检查前3个字节,也就是厂家字段# e3 V8 L. @+ R0 g( X: _: G' p+ O
这里需要注意MAC地址的字节序
" H- B" Y; @& F' {5 l5 M7 q) b& x
  1. static void ETH_MAC_Filter_Setting(ETH_HandleTypeDef *heth,ST_ETH_PAR * para)( m& ~; _4 _3 N  |: ~6 e. {
  2. {, Q5 ~  z/ o$ ?0 F0 o: p' O
  3.     //设置本机MAC地址4 w3 T: Q1 J1 W* A$ n+ u% x
  4.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);# g4 e0 {. \  ?5 P  }
  5.     //设置UDP-A的对方MAC地址
    0 v" M- ?, D7 A  b6 @
  6.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS1,para->UDP_A_MAC);3 v! \" l0 j8 ~: n3 ^% D
  7.     (heth->Instance)->MACA1HR|=0xF8000000;//需要匹配厂家字段8 m: s- J* K$ a, {) V/ H
  8.     //设置UDP-B的对方MAC地址
    ' V4 l7 ?( f0 r. S7 @
  9.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS2,para->UDP_B_MAC);
    ; c9 }: m" ~& n- O0 ]: o( Z
  10.     (heth->Instance)->MACA2HR|=0xF8000000;//需要匹配厂家字段
    , t7 Q; R" D/ v/ P" {
  11. }
复制代码

& o, v8 P  l; w! J3 n然后这些函数的调用顺序按:0 X$ f* X- G0 {+ I$ O" R, c! q
1. HAL_ETH_Init; D. B  V+ J' h6 f1 b! _$ D
2. ETH_MAC_Setting
- }9 s5 v; |8 I* e3. ETH_DMA_Setting/ Y( s5 F0 C* ~  w6 N; P
4. ETH_MAC_Filter_Setting
" k  ~# r; T! c! g6 N* \# |% n, s' S4 I2 U/ L
用你希望过滤的MAC传递到一个Hash计算函数里,得到一个值,通过这个值产生“映射”关系来过滤MAC地址,所以这个并不是精确的,因为可能会重复~~
# t4 D' Z; F4 Y% t4 B4 m$ U4 z; s. s4 ^
HASH函数4 Q5 ~, r4 I# V/ P/ r
函数) \) I6 ~/ \3 Y+ n8 M2 V' E, A
  1. / STM32 MACHASH - Copyright (C) 2014-2018 Clive Turvey (<a href="mailto:sourcer32@gmail.com">sourcer32@gmail.com</a>)8 f/ [% p8 @. x6 \
  2. //  All Rights Reserved
    ; X) H2 b+ H+ @

  3.   j  g# i* X6 p8 R4 c
  4. #include <windows.h>
    ! M' R5 \+ B) ?5 f, Q' _
  5. 7 A, G# m5 M! p
  6. #include <stdio.h>
    2 Z) U& q  t6 M8 o( N& [3 t9 E
  7. #include <stdlib.h>& N" V# B0 O# m6 s3 ]

  8. " q: i2 r  q) _3 R
  9. typedef unsigned char uint8_t;' |3 U/ O, m: B: Y
  10. typedef unsigned long uint32_t;' X! C/ z7 y, g7 t( X" P  ?

  11. 2 g( b0 h5 x4 P0 Y7 j+ V; V& i/ x
  12. uint32_t Rev32(uint32_t x)- p& N& W" r5 L8 m4 g
  13. {' \  A' Q+ |$ H
  14.   uint32_t y;
    / D' ~; m  Z4 ~2 }* z
  15.   int i;' _+ o2 T2 ]7 f  m; x

  16. 5 H  J" J0 O9 [9 x# P) T+ d/ F, s" [
  17.   y = 0;9 c: H5 h+ _8 ?4 T( F
  18. ( h1 N) @$ F: M9 Q
  19.   for(i=0; i<32; i++)4 M* s# l6 k8 j% P1 X: k
  20.     if (x & (1 << i))
    " _: X# T: m' @( }% d9 s
  21.       y |= 1 << (31 - i);
    ; K) h/ e* e/ X" Z4 V
  22. " i2 o  W' p+ K2 V
  23.   return(y);" V8 L: l; Q' `$ F# v! I' o
  24. }
    5 B, ?" |' U" F% G( j7 h3 B
  25. - I( k, _" X* t6 z% U, X3 r' q4 i: j
  26. uint32_t MacHash(const uint8_t *Mac) // <a href="mailto:sourcer32@gmail.com">sourcer32@gmail.com</a>
    ; @( I  R# ?( b0 j8 T" k+ X, j
  27. {
    : H6 L/ A5 ^8 ?4 f% R
  28.   int i, j;
    ) F2 I9 r4 s- A8 s
  29.   uint32_t Crc;% g) w7 ^+ R) \0 {$ N! a( N
  30. & T/ z, R, }3 @9 R! f6 o
  31.   Crc = 0xFFFFFFFF;
    # Z) }& i4 Z4 V7 Y
  32.   Q* y5 m7 E1 U3 l5 B, m" R
  33.   for(j=0; j<6; j++)4 Y6 z* x$ ^1 X; l
  34.   {; ^) H  [$ \6 @% O/ z
  35.     Crc = Crc ^ (uint32_t)Mac[j];
    9 b- L0 \' m) n& S1 H7 h0 U' j/ t

  36. + c. @5 U" [" j. o  ~. H4 l
  37.     for(i=0; i<8; i++)* N: y: G! E) b/ H; C2 f0 G
  38.       if (Crc & 1)
    2 o( e9 @; a0 @& f/ R% X
  39.         Crc = (Crc >> 1) ^ 0xEDB88320; // Reversed 0x04C11DB7
    * P7 L) E" W+ @5 u" a0 ^. S
  40.       else
    0 A/ B, l% f0 ~' N* n
  41.         Crc = (Crc >> 1);
    ; i+ K- e( g, J2 N7 o: j
  42.   }
    - R$ H/ E% Y1 B4 u' k: c" T' H
  43. $ c8 V/ L3 P: g/ V
  44.   return(Rev32(~Crc) >> 26); // Get High order 6-bit in reversed/inverted CRC( n% e, F7 l3 P* W3 k6 _
  45. }
    ; o" G9 y% N" ^0 ~
  46. ( [' e. [9 d3 C6 F4 e' j+ g2 B
  47. uint32_t MacHashFast(const uint8_t *Mac) // <a href="mailto:sourcer32@gmail.com">sourcer32@gmail.com</a>3 j  V- f4 \0 [- E% D$ R
  48. {
    . f! X. s; {8 w$ ?7 M
  49.   static const uint32_t Rev6Tbl[] = {2 _2 Q* p0 i3 A# Y7 {
  50.     0x00,0x20,0x10,0x30,0x08,0x28,0x18,0x38,+ I3 X- f4 y; a. k
  51.     0x04,0x24,0x14,0x34,0x0C,0x2C,0x1C,0x3C,
    3 h7 C2 l" b/ y+ n; i* {
  52.     0x02,0x22,0x12,0x32,0x0A,0x2A,0x1A,0x3A,
    * H7 Z! s2 A; ^+ W+ M! @
  53.     0x06,0x26,0x16,0x36,0x0E,0x2E,0x1E,0x3E,' G$ F; E6 o5 o. P
  54.     0x01,0x21,0x11,0x31,0x09,0x29,0x19,0x39,( C: A7 {# m& S- d6 o) v0 D
  55.     0x05,0x25,0x15,0x35,0x0D,0x2D,0x1D,0x3D,( A# G1 [5 i2 R, k  h$ u* x" u
  56.     0x03,0x23,0x13,0x33,0x0B,0x2B,0x1B,0x3B,6 d9 H3 L/ ^+ x3 P+ U, q2 L
  57.     0x07,0x27,0x17,0x37,0x0F,0x2F,0x1F,0x3F };
    0 ~3 B- _- ^- a( z1 X! D9 W

  58. ; n% m4 [7 @- ~6 K2 Q  x5 p, N8 R5 {
  59.   static const uint32_t Crc32Tbl[] = {/ ]1 h6 u5 O  [- V% U+ `# `; k4 B. q5 p
  60.     0x4DBDF21C, 0x500AE278, 0x76D3D2D4, 0x6B64C2B0,
    ( y' K: _2 F* I# p; _
  61.     0x3B61B38C, 0x26D6A3E8, 0x000F9344, 0x1DB88320,+ R; V9 ]' k1 H! ~8 @
  62.     0xA005713C, 0xBDB26158, 0x9B6B51F4, 0x86DC4190," W9 Q5 t$ U5 p4 f$ O4 J
  63.     0xD6D930AC, 0xCB6E20C8, 0xEDB71064, 0xF0000000 };9 x; v9 U5 g# y7 V( Z
  64. 0 q; ]4 z7 C& N4 U* h2 g
  65.   int i;2 d) f) k7 u7 U, M2 [. z1 ?: u, H
  66.   uint32_t Crc;  h* [  c4 g1 j! x1 A6 I

  67. ( _* k1 y" j; I& w( K
  68.   Crc = 0;
    / N) k# e1 W  c
  69. # g4 Y* }+ X  _
  70.   for(i=0; i<6; i++)
    3 {/ a* g3 D! l5 W
  71.   {
    8 ]0 y4 j" x4 n* |4 m; q
  72.     Crc = Crc ^ (uint32_t)Mac<i>;
    ) e1 a0 T4 N% X1 q0 r, C% W

  73. 1 c6 _1 i2 D, Q1 g' b2 a
  74. </i>   Crc = (Crc >> 4) ^ Crc32Tbl[Crc & 0x0F];  /* lower nibble */7 F& m1 M# u7 m2 O' L% j1 d
  75.     Crc = (Crc >> 4) ^ Crc32Tbl[Crc & 0x0F];  /* upper nibble */
    & g; o: a/ Z. K5 F* P  A$ [
  76.   }% z3 k- o: S2 l5 _6 Z7 d3 \. P/ }0 @
  77. 8 Y$ K3 G9 C- {9 X) [+ y8 w" f
  78.   return(Rev6Tbl[Crc & 0x3F]);
    2 v; ]; t3 A" t4 ^0 M8 [/ L- v
  79. }
    $ Q' P8 v7 s7 V% H: z

  80. $ ?# }/ k" e3 j6 }8 r% n! |
  81. int main(int argc, char **argv)1 N* |/ B% }$ Q* [5 X* j
  82. {
    2 y. e' z% s4 S) c) P: Z, C" X; ~
  83.   static const uint8_t Test1[] = { 0x1F, 0x52, 0x41, 0x9C, 0xB6, 0xAF }; // 0x2C! N5 m! B* E% T6 `. U' B) Z
  84.   static const uint8_t Test2[] = { 0xA0, 0x0A, 0x98, 0x00, 0x00, 0x45 }; // 0x07
    / K- A' y2 l; _' [% |
  85.   static const uint8_t Test3[] = { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x21 }; // 0x24
    $ O( z% o, m& Y# T- M* ^  x  }
  86. , P5 C# `9 p* R. k6 {# l% Z( `
  87.   printf("MacHash %02X\n", MacHash(Test1));# C2 `0 {: {0 s/ k
  88.   printf("MacHash %02X\n", MacHash(Test2));
    & F. u" }  }/ [8 n6 m( I
  89.   printf("MacHash %02X\n", MacHash(Test3));
      k, ^' I/ i3 k* }. G
  90. ! e7 B, O8 V9 [+ K# m* G
  91.   printf("MacHashFast %02X\n", MacHashFast(Test1));* q4 K0 F! ]7 j' T: r* X4 k+ S4 b# f
  92.   printf("MacHashFast %02X\n", MacHashFast(Test2));8 y0 J% ~  m+ A5 y
  93.   printf("MacHashFast %02X\n", MacHashFast(Test3));
    , S6 Q( E5 z5 {& `/ I/ X

  94. # \+ l* y% O) k2 k2 N
  95.   return(1);
    0 @; j: U! \; ?: e$ J% T& q) _
  96. }
复制代码
- J  R( I1 N6 D7 j) h4 m$ d% D
, L7 E) a4 r( A" ]. G; m/ r
回到手册2 D! l( B! t( K/ M- U* `! k0 N

' L( |0 U, ?! u# T2 D. }! J
20191124100604140.png
# j- L6 B$ L* J4 }1 |& K8 Z% L

9 f% c& C2 l  o2 \( ^$ |' h7 M
20191124100636882.png

8 f0 [2 R1 \  a. ]+ M
3 g1 ~4 |7 M, H+ _
. k( F4 }) o" `1 B4 k+ V7 Q/ [) c上面的函数算出来一个数,假如是手册上的那个0x2c,二进制为101100B
: O$ {1 m3 f# z) P2 z4 \9 s换句看得懂的人话···就是:/ n" @( u2 J/ I0 c( V+ _
算出来的数先看第6位
. S: c/ p5 a9 q& l是1的话说明用到的是HASH表高位寄存器
' W. b0 [3 i  A. d' `否则用到的是HASH表低位寄存器
3 |0 t, Y+ E5 M/ ?然后剩下的5位,转成十进制不是12嘛
& y+ v1 z, r2 A! K# G4 V- H# ~; `如果你希望过滤这个MAC8 R: S3 ^0 _8 r  T' K1 K# y/ Z# M' z
那么你就把对应的HASH表高/低位寄存器的对应位置1,否则置0  N# L4 B6 d) `9 W$ x+ M" }
这里的0x2c就是要把
! g$ m6 V) w& ?" {* l- }; v) SHASH表高位寄存器的第12位置10 s" O, s* w/ @' L- e
就可以过滤这条MAC了% T$ ]1 K$ ~7 o  e7 y1 Q
然后把你希望的MAC地址都按照上面说的方法弄完
% i8 n( P- z: p  a7 x
/ V- Y6 Q- V* Q' _' t" k回到这个函数稍微改一下
# Q0 n$ b2 l9 @: o5 D) \
  1. uint8_t ETH_MAC_Setting(ETH_HandleTypeDef *heth)
    7 s& t1 Z; b; {( k2 a
  2. {: f7 |* K4 G) R* A; ]1 M; t
  3.     ETH_MACInitTypeDef macinit;
    0 \* ~; z1 {1 p
  4.     /* Ethernet MAC default initialization **************************************/
    % D  z0 H# R5 z/ n+ _
  5.     macinit.Watchdog = ETH_WATCHDOG_ENABLE;
    : A! V/ U+ Z7 E6 |% o
  6.     macinit.Jabber = ETH_JABBER_ENABLE;' i4 {; d9 w7 W) U' a
  7.     macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;
    . n$ ]% u/ O% Z5 N9 h
  8.     macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;$ i8 }) H) ]6 `! H# X/ l9 t, G
  9.     macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;
    # q3 d! h; ]7 s1 |
  10.     macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;
    5 z' M" Q# S: ~9 {; T9 h& [
  11.     if (heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)' A0 D$ q# B% y' i2 a$ o
  12.     {
    % K+ c! q- u, N3 |3 {) ?% ]
  13.         macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;2 }8 o4 {7 x, s/ _) H
  14.     }' G  F/ Y9 W. z
  15.     else6 k0 p0 ?' H3 d  Q$ i
  16.     {
    6 F4 _9 V3 m9 P: v* l
  17.         macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;3 m5 p3 k, o* E; ~# |
  18.     }& |8 o+ w' s, p! O) [* K: n  B. @
  19.     macinit.RetryTransmission = ETH_RETRYTRANSMISSION_ENABLE;          //使能重传: n* K9 x, z$ c
  20.     macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_ENABLE;          //使能自动去除1 O: ^" O3 k" ]+ A1 j
  21.     macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;
    ( r8 L, ^' C8 @- R0 S* N
  22.     macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE;9 v% r" S* K) o
  23.     macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE; ///不接收所有包+ h0 U5 `/ a8 n: V/ o* `/ H
  24.     macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_NORMAL_ENABLE; //源地址过滤9 o& q% C- C2 m' u; E
  25.     macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;& C' w8 b2 u+ ^( u5 O
  26.     macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_DISABLE; //广播不接收
    3 P3 c4 d2 \( ^
  27.     macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL; //目的地址过滤- S& l8 l3 v+ R5 }: D; P
  28.     macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE; //混乱模式
    7 q) l2 q4 n2 u3 n. [2 X$ ]) k8 E
  29.     macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECTHASHTABLE; //!!多播HASH完美过滤
    5 `4 S, R5 H* y6 {+ a9 n1 n
  30.     macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECTHASHTABLE; //!!单播HASH完美过滤
      s; s7 j" f6 q; V% X
  31.     macinit.HashTableHigh = 0x0; //!!填你最后算完的Hash表高位
    ) y+ Q6 }* {0 H" m9 |# @
  32.     macinit.HashTableLow = 0x0; //!!填你最后算完的Hash表低位
    8 `# h8 ?: V9 S: q, K* K
  33.     macinit.PauseTime = 0x0;: u6 E. |+ u! h8 j5 I" ~, ~0 L
  34.     macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;
    1 g+ J7 L0 {/ j. F) L( M
  35.     macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;
    / P5 t& U3 j: y/ T- y
  36.     macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_ENABLE;
    $ Y  A" \# `8 v" ~
  37.     macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE; //接收流控' M$ {6 S5 r: G$ j$ i9 c7 z& e
  38.     macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE; //发送流控
    $ G* w5 ^, U$ c
  39.     macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;4 U4 t) D1 R; h. K2 H7 T
  40.     macinit.VLANTagIdentifier = 0x0;
    & ?0 ?. v" G3 C

  41. , J0 }: i5 l" m9 M: ]) p: j
  42.     return HAL_ETH_ConfigMAC(heth, &macinit);
    / {* t4 S4 e4 R: S9 `8 D
  43. }
复制代码

7 z" l  U5 t, B- I大概MAC层过滤就这些东西了
& g2 l7 T4 u$ y# o, {" d如果有条件弄MAC层过滤真的强烈建议开启,可以大幅减轻协议栈的处理负担,板卡不会因为处理大量无用的数据而白白浪费处理性能。
4 h6 z* q& C9 H
' o, \" O/ u$ D; i; i! o  l9 W3 E1 ?) E$ U# h

0 n! ~) [' @/ a5 Q# A
7 N% a  `3 P# T. f8 U
收藏 评论0 发布时间:2021-12-14 10:15

举报

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