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

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

[复制链接]
STMCU小助手 发布时间:2021-12-14 10:15
前景描述. `/ @! J# k' {% `
我司的以太网实现是LAN8720搭配片上MAC层做的,协议栈用LWIP0 N: K4 r7 T3 Q' _6 v( b" m
9 q1 V; t: C0 S+ \# Q
这种做法应该还是蛮常见的,反正不是LAN8720就是DP83864,再不然就是硬件协议栈的W5500了
6 `  V3 g: c2 \( c7 O/ Y* h( G3 X* S/ O  d: _* i  F
想想还是有MAC层过滤比较好,随手翻了翻它的手册,W5500好像是没得MAC层过滤的
8 n9 j! w) I/ A" ?
3 b0 P4 F8 w5 R+ v$ s+ t4 n4 S假如数据速率比较高,数据量大,而且外面还有乱七八糟无关的数据往板卡送,我也不知道用这个片子到底好不好  \" S% D& P- `/ p/ ]$ }

1 [3 x6 {$ }( ILAN8720也不好改了,就继续用吧9 U( v2 @# i- N% }/ Q

  D( i5 o; `& j, y( c6 d4 ~好好在,发给板卡的数据的MAC还是有特征的,我只需要过滤发送方MAC地址的前3个字节,也就是特定的厂家那段
' @1 g. \: s* P* ]
; [" {/ P' E% h) C, e. M( eMAC地址的科普知识这里就不过多描述了,我们直奔主题
& V* H0 g; y& e$ J% B! _& d# `8 o; ^
* q1 X: V2 U1 ]7 \* j3 C1 f怎么用STM32 F7的片上MAC做MAC层过滤
9 |' `( N( B& ?& U, m* s9 U7 P/ A* O$ |0 U9 H- B' o9 o
写这个的目的,就是我搜了搜,没看见有人写这个MAC层过滤功能,具体代码怎么写才能用
) Y+ e+ [( h9 }! O" q4 U" v7 {
$ j# _9 X, N2 Z3 `2 m9 `. H知识科普-STM32的片上MAC
% a& v8 Q% k+ W% E6 k) R5 bSTM32 F7的MAC层过滤方式有三种(说人话的直白解释,中文手册其实也翻译的不好)$ K: }- y- ?3 q- p; H$ S
精确过滤(手册上叫单播目标/源地址过滤)
- t; h* _5 ~6 H$ l粗糙过滤(手册上叫Hash表过滤)
2 G5 s2 k+ N0 t% e5 P( ~3 g; A特殊过滤(广播,组播过滤等等特殊的过滤)  e: Q. f/ y4 x$ ?8 R( b
我这里着重说第1种和第3种
0 P: v: f( @7 i* b) A
' L: D" V4 c9 N' |* Y1 L  y- D4 O2 uSTM32 F7可以存4个MAC地址/ Y% p1 A9 h- i
其中MAC地址0是自己的MAC,其他三个可以用来做过滤
5 r! @3 ~$ I1 m5 n& K  K* W& Q: t9 T8 s
网络数据包通过PHY进入STM32的MAC,MAC层是可以对目的地址/源地址检查并过滤掉没得用的数据的,默认的HAL库库函数HAL_ETH_Init中
: L. H  h+ \* D# a* e& m# @* C" S有一个static的函数7 j4 C. b/ l3 J0 r
static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err)
5 x0 ]2 B. i# m会帮你在初始化网络功能时初始化默认的MAC层功能:
, J1 W! Z1 z$ i8 [; x0 W& |关闭源地址过滤
8 _& d( n1 o9 w' t- N& A不接收所有数据
' f& u  s9 X7 ?接收广播帧8 v. i+ w8 d% C% {
打开目的地地址过滤
/ M% J8 L9 N- v& t, U5 b  [& b单播数据精确过滤
# ^) ~6 g5 ]$ R! x组播数据精确过滤
& I  e5 u( f2 R. }! w4 iHash表过滤关闭  [2 M+ `3 E, _& Q& v" V
  |# L+ y, y7 C5 D9 c
其他的功能自行研究,我这里捡重要的说
8 i9 _! g7 q! P0 T
  1. static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err)5 i, p. Y$ M8 i2 d, J0 v
  2. {: F9 l5 v* W. h- d
  3. ETH_MACInitTypeDef macinit;' ?( `- G- L! |7 d5 {' `1 [
  4. ETH_DMAInitTypeDef dmainit;& B) f% }. F+ d8 Z
  5. uint32_t tmpreg = 0;: J0 _5 }" c; X3 X

  6. 8 C+ t' E" p# ?# Q8 G5 J
  7. if (err != ETH_SUCCESS) /* Auto-negotiation failed */' J7 G0 d7 e' S8 m: j# z
  8. {
    * }; n4 V$ j5 t5 Y3 z9 Y$ E5 R) i
  9. /* Set Ethernet duplex mode to Full-duplex */
    8 m4 A% P+ e; {! z  z% g+ ~
  10. (heth->Init).DuplexMode = ETH_MODE_FULLDUPLEX;& @# Y# R# W2 [! q0 s
  11. 5 v4 f: P- f# A; d+ d  E
  12. /* Set Ethernet speed to 100M */
    9 C5 r9 V5 q) B+ ^2 J
  13. (heth->Init).Speed = ETH_SPEED_100M;( l+ k! v( R" b$ [$ `
  14. }
    ( v9 A( ^; B0 |, F" r5 S$ g

  15. ; C2 ]+ X- W* T& Z2 U, K8 ]
  16. /* Ethernet MAC default initialization **************************************/
    ' S! n! Q! q! R
  17. macinit.Watchdog = ETH_WATCHDOG_ENABLE;
    7 h; g, T3 |# ?: T' E) s
  18. macinit.Jabber = ETH_JABBER_ENABLE;
    0 x5 Y; q% [5 R' G- U% v
  19. macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;
    6 \  f3 I" P$ J
  20. macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;8 h/ `6 b" j5 X5 Q! w* R. y# C
  21. macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;' v3 q, Z2 q; l1 i, r# q, P$ b* @
  22. macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;5 }- M( B, K) g2 _  ?& g7 l
  23. if(heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)( e$ k# o) r. a8 Q( J7 }; w8 l
  24. {( v$ w0 H7 E# q
  25. macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;( z( D) L. l+ m' o
  26. }, G" W/ L: ~1 J/ o  |' L- z
  27. else4 C' p( z! V+ G! N
  28. {' b3 E* R, Z) i$ z1 m5 W* F$ k/ u
  29. macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;
    - q& K7 W0 p0 `4 o8 p
  30. }, p1 f& S  P/ W! N# N5 O
  31. //这一段是MAC层过滤的设置,下面是DMA的,那个用默认的就可以- `& V( C; Q* Q: e8 A$ V" ]/ G% R$ C. g
  32. macinit.RetryTransmission = ETH_RETRYTRANSMISSION_DISABLE;& R3 I+ v7 p  M; v, b/ Y+ `
  33. macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_DISABLE;
    8 K3 ^6 Z, Z  v- O# t
  34. macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;% R6 V. l9 T: G8 o  k
  35. macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE;
    0 \" E/ t8 E' e0 H% y
  36. macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE;; Q1 _: O7 e' N9 z
  37. macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_DISABLE;
    0 u/ h8 J2 A0 F; ?/ f* e6 Z
  38. macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;
    6 W0 c( ?) U  E2 a$ \# R+ R
  39. macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_ENABLE;5 A8 k0 h- _# i0 p0 E. k+ i/ W2 S3 N3 d
  40. macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL;
    5 Q% v& z$ t$ t5 M
  41. macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE;
    & Y& z. Y( j+ M3 V* l0 K
  42. macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECT;6 k+ h; u! K2 Y& C# [: D
  43. macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT;
    ! C2 M) [$ Z' _8 ^
  44. macinit.HashTableHigh = 0x0;
    : u- i- ?& c# ^- F' x6 {" J
  45. macinit.HashTableLow = 0x0;
    + c/ h$ d5 d7 j; L
  46. macinit.PauseTime = 0x0;0 U( D, ?- J) `. h, s: |5 f4 \
  47. macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;, a1 m' C7 o$ P: b5 c
  48. macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;
    - r1 J' `# D. Z: w4 x9 u8 f' c7 x0 t
  49. macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_DISABLE;: N1 c0 {4 z0 i* Y$ e9 t
  50. macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE;& g# B" L# G6 F0 Y3 I2 {
  51. macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE;
    ; v4 c5 s. e% O% {, _
  52. macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;
    + W$ C) M' ^# b4 I8 M
  53. macinit.VLANTagIdentifier = 0x0;
    - g. ]. B; ]" {+ H7 P$ F

  54. . `& u0 s* C; |: `$ L6 w
  55. /*------------------------ ETHERNET MACCR Configuration --------------------*/
    : u8 z$ Q1 u+ v. R: K
  56. /* Get the ETHERNET MACCR value */
    8 ], V' q+ ]) q) e- U
  57. tmpreg = (heth->Instance)->MACCR;& L0 \% N' Q/ j% Q- I  h
  58. /* Clear WD, PCE, PS, TE and RE bits */3 W4 @2 ?/ ~6 m8 |* `+ K% u. _
  59. tmpreg &= ETH_MACCR_CLEAR_MASK;+ W- H% G& l# S3 g6 f! b. `/ T9 T
  60. /* Set the WD bit according to ETH Watchdog value */
    ( b$ m! J, L5 g+ q! Q. T
  61. /* Set the JD: bit according to ETH Jabber value */
    ) Z4 z- j0 N: Q5 \  P. T
  62. /* Set the IFG bit according to ETH InterFrameGap value */7 R1 P" `, K# w8 H* C! K
  63. /* Set the DCRS bit according to ETH CarrierSense value */2 q5 x0 j% m" ]4 I2 P. t
  64. /* Set the FES bit according to ETH Speed value */
      t, }8 G# |* d4 L+ O8 p
  65. /* Set the DO bit according to ETH ReceiveOwn value */
    ; }% J' T1 D* [5 M6 X7 ]
  66. /* Set the LM bit according to ETH LoopbackMode value */- W0 }8 ?* w) t0 I; B
  67. /* Set the DM bit according to ETH Mode value */# X! U4 J/ d6 w1 L' x9 S
  68. /* Set the IPCO bit according to ETH ChecksumOffload value */
    8 C$ F4 R, D- ^* F: G; q/ J
  69. /* Set the DR bit according to ETH RetryTransmission value */
    $ i) E: H6 A: A( z( L9 Y* t: P9 `
  70. /* Set the ACS bit according to ETH AutomaticPadCRCStrip value */
    8 g3 g2 f4 }7 {# r- d/ d% \& B
  71. /* Set the BL bit according to ETH BackOffLimit value */
    , [* ^9 X5 e) X9 A
  72. /* Set the DC bit according to ETH DeferralCheck value */, b* ]2 c7 T8 D! K7 M0 }) K+ h
  73. tmpreg |= (uint32_t)(macinit.Watchdog |
    : B; C9 S7 O5 `5 ~
  74. macinit.Jabber |
    * S9 O5 |; B1 N( D
  75. macinit.InterFrameGap |
    3 G" Z  ]8 i( E
  76. macinit.CarrierSense |
    ' K2 H: n8 _& C' E* p
  77. (heth->Init).Speed |) [6 T7 \& b7 x& G1 Z- x' V
  78. macinit.ReceiveOwn |
    7 ?& k$ W4 m! u0 \
  79. macinit.LoopbackMode |* h5 H; _! Y3 t& s& P7 `# _2 z  ]6 f
  80. (heth->Init).DuplexMode |
    6 @/ ~7 j0 f5 A
  81. macinit.ChecksumOffload |
    * k% k, p( E- V/ @; b  R2 ]6 R
  82. macinit.RetryTransmission |
    ; {, D" _9 J; R
  83. macinit.AutomaticPadCRCStrip |
    $ \5 Z, T5 y$ }- F) c
  84. macinit.BackOffLimit |
    ) ^' r4 p9 `/ c) F# }
  85. macinit.DeferralCheck);
    & ]  [) ]9 w& \! R# ~6 Q
  86.   a9 t( D& I8 g
  87. /* Write to ETHERNET MACCR */7 p0 F# }+ y( B" {$ W* l
  88. (heth->Instance)->MACCR = (uint32_t)tmpreg;9 B6 l! `( Q  q9 f0 g3 K' W. a
  89. 8 B( B6 j0 D3 ^& ^
  90. /* Wait until the write operation will be taken into account:3 C; b* i9 `7 l& f' [
  91. at least four TX_CLK/RX_CLK clock cycles */. `& z' e7 \- H# ]. e, ], N
  92. tmpreg = (heth->Instance)->MACCR;
    ( e8 A2 A' t( C$ j1 X  B
  93. HAL_Delay(ETH_REG_WRITE_DELAY);
    0 D& d  O  z0 T$ W& ?& r( q
  94. (heth->Instance)->MACCR = tmpreg;
    - \  L) |. `  w1 J7 W
  95. ( m$ v: _. x! Q  Z' U
  96. /*----------------------- ETHERNET MACFFR Configuration --------------------*/
    6 p6 {/ p. q% d" _+ `6 W0 W; z
  97. /* Set the RA bit according to ETH ReceiveAll value */
    3 R6 Y1 O( j# i% A# b2 _
  98. /* Set the SAF and SAIF bits according to ETH SourceAddrFilter value */& b! R4 j& T4 A& g5 A
  99. /* Set the PCF bit according to ETH PassControlFrames value *// F7 ~, p3 `% N$ v
  100. /* Set the DBF bit according to ETH BroadcastFramesReception value */
    : t  w8 s: i$ }: B% ?2 z+ C9 k
  101. /* Set the DAIF bit according to ETH DestinationAddrFilter value */
    9 C4 K) |  B0 g* N7 Y( Z' d, g
  102. /* Set the PR bit according to ETH PromiscuousMode value */
    / k9 e( E3 r* u" P- m! k5 H0 g
  103. /* Set the PM, HMC and HPF bits according to ETH MulticastFramesFilter value */
    - k' b9 W: }/ V6 O! r
  104. /* Set the HUC and HPF bits according to ETH UnicastFramesFilter value */; w* j! Z4 ?- T/ I6 j
  105. /* Write to ETHERNET MACFFR */4 E* N) _8 l0 r$ n
  106. (heth->Instance)->MACFFR = (uint32_t)(macinit.ReceiveAll |
    ( ]! [8 {" h4 N& H
  107. macinit.SourceAddrFilter |
    8 G( }5 ^7 B2 O  {! H: K" A. Z
  108. macinit.PassControlFrames |) j' m& k; u( l( ]- w* K- @
  109. macinit.BroadcastFramesReception |" q3 Z5 N5 {  V: y( v# U; V$ @
  110. macinit.DestinationAddrFilter |7 v! l0 [$ d/ l  L
  111. macinit.PromiscuousMode |
    / A6 G2 t  p, x3 ?6 y+ S& }
  112. macinit.MulticastFramesFilter |7 a4 t. P; |8 f& t/ G
  113. macinit.UnicastFramesFilter);
    % J: q9 {2 q4 F0 c/ B
  114. / X) z8 y: d, ?- J8 B, s
  115. /* Wait until the write operation will be taken into account:, L  d' v' `8 G/ M+ E) W
  116. at least four TX_CLK/RX_CLK clock cycles */
    % I! g7 b6 c6 t& K/ L' T' m. {; {
  117. tmpreg = (heth->Instance)->MACFFR;
    - m! L5 G" h% _5 r
  118. HAL_Delay(ETH_REG_WRITE_DELAY);
    1 w: K+ G: O2 h8 R$ G8 K$ k
  119. (heth->Instance)->MACFFR = tmpreg;
      \2 n- g% M- H. I

  120. & F% R9 J% y9 z1 ?5 S! c
  121. /*--------------- ETHERNET MACHTHR and MACHTLR Configuration --------------*/
    * s, U  F3 a+ x
  122. /* Write to ETHERNET MACHTHR */2 s( A" ^1 Y0 f
  123. (heth->Instance)->MACHTHR = (uint32_t)macinit.HashTableHigh;
    . F( d  `8 D0 @

  124. 1 \6 o1 V7 C! m" P$ H- }; c+ r" Y+ K& q
  125. /* Write to ETHERNET MACHTLR */5 b7 T% [  \+ N1 _' L
  126. (heth->Instance)->MACHTLR = (uint32_t)macinit.HashTableLow;3 j/ I" J  o$ q- k- C" @! p4 a  z
  127. /*----------------------- ETHERNET MACFCR Configuration -------------------*/
    2 s" g/ Z% ^6 L5 H+ g" B! Y: V! j

  128. 6 F' t5 d# t+ A2 S: `
  129. /* Get the ETHERNET MACFCR value */7 v- ]* g1 j' u$ b" D' w
  130. tmpreg = (heth->Instance)->MACFCR;
    9 g' O' N; C; F3 ]7 @
  131. /* Clear xx bits */+ X2 a% e' l3 ~# I* G
  132. tmpreg &= ETH_MACFCR_CLEAR_MASK;2 G3 v, l5 s9 L  }
  133. 8 `, W1 W  d, I- W' b; l. n. U
  134. /* Set the PT bit according to ETH PauseTime value */# ~7 t3 [. g" J% V# d. a7 R& }! P
  135. /* Set the DZPQ bit according to ETH ZeroQuantaPause value */; T# m6 X: U9 {( ]$ R4 H# K+ u8 l
  136. /* Set the PLT bit according to ETH PauseLowThreshold value */0 W* \5 S; ^. O6 e4 c; w
  137. /* Set the UP bit according to ETH UnicastPauseFrameDetect value */5 S* l, r" \7 R' l( [0 @
  138. /* Set the RFE bit according to ETH ReceiveFlowControl value */
    7 C) A( ]! C$ D$ n: C
  139. /* Set the TFE bit according to ETH TransmitFlowControl value */' w( Q' O( b# x3 V5 y4 s5 ?6 ^- Q
  140. tmpreg |= (uint32_t)((macinit.PauseTime Instance)->MACFCR = (uint32_t)tmpreg;
    & ]5 |- e* a$ o* c4 c$ m4 A
  141. . Y; \* E. N' x
  142. /* Wait until the write operation will be taken into account:. @; ~, X$ d7 l
  143. at least four TX_CLK/RX_CLK clock cycles */
    + w3 X" {6 k5 @' I& u4 i) M
  144. tmpreg = (heth->Instance)->MACFCR;+ k4 A/ ^: R% a* g$ p! a; V3 Z# r
  145. HAL_Delay(ETH_REG_WRITE_DELAY);7 \  e- s* l  J9 ]  ~0 Z6 ?0 ?
  146. (heth->Instance)->MACFCR = tmpreg;9 z5 i: F' M  U3 R. Z1 l
  147. ( b' d; h3 y3 ?2 r: w5 `% u
  148. /*----------------------- ETHERNET MACVLANTR Configuration ----------------*/0 D3 L& \* _! C% j; Z
  149. /* Set the ETV bit according to ETH VLANTagComparison value */6 z4 K+ \- m) Q6 ]
  150. /* Set the VL bit according to ETH VLANTagIdentifier value */4 m- E5 \% _1 f5 e. i
  151. (heth->Instance)->MACVLANTR = (uint32_t)(macinit.VLANTagComparison |
    ' C' R8 T$ |7 o3 w2 m8 G  S1 D  M
  152. macinit.VLANTagIdentifier);7 }5 {) K1 y  v: w# E- G9 Q

  153. * ]" N4 L1 ^0 E. s1 S1 V1 |+ }
  154. /* Wait until the write operation will be taken into account:6 `. V( s4 q, }. y
  155.    at least four TX_CLK/RX_CLK clock cycles */
    ! m1 F5 ]% j6 f6 k4 K
  156. tmpreg = (heth->Instance)->MACVLANTR;4 r( s" [$ J6 u$ `+ \) K0 w" \
  157. HAL_Delay(ETH_REG_WRITE_DELAY);
    2 K. r7 K- y1 b
  158. (heth->Instance)->MACVLANTR = tmpreg;- h: n2 O/ \: r* T7 {6 L$ ~& Y

  159. * n7 ^* l5 l- v2 @) J2 u/ p# x/ ~
  160. /* Ethernet DMA default initialization ************************************/
    , {" |6 Y- [& l
  161. dmainit.DropTCPIPChecksumErrorFrame = ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE;
    5 Y& M& c6 F9 }* o! d$ f1 a
  162. dmainit.ReceiveStoreForward = ETH_RECEIVESTOREFORWARD_ENABLE;
    % d- |% o  e, ?5 v# X" ?' O) Y  A
  163. dmainit.FlushReceivedFrame = ETH_FLUSHRECEIVEDFRAME_ENABLE;; `' C/ Q) l! C3 D! d6 T. I
  164. dmainit.TransmitStoreForward = ETH_TRANSMITSTOREFORWARD_ENABLE;) ~# ^3 i' [  u2 l: ?
  165. dmainit.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES;1 T4 ]7 E9 |, u9 Z) s# g3 \
  166. dmainit.ForwardErrorFrames = ETH_FORWARDERRORFRAMES_DISABLE;
    0 [$ s  E- Y& B1 r
  167. dmainit.ForwardUndersizedGoodFrames = ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE;
    ! ^  v8 W. j2 O4 v: p# h
  168. dmainit.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES;6 h6 o4 E3 A7 A2 }
  169. dmainit.SecondFrameOperate = ETH_SECONDFRAMEOPERARTE_ENABLE;6 ?. Y+ H& ~/ o& a9 q/ H
  170. dmainit.AddressAlignedBeats = ETH_ADDRESSALIGNEDBEATS_ENABLE;
    + T" P+ h# `! |- n# f
  171. dmainit.FixedBurst = ETH_FIXEDBURST_ENABLE;: ?3 @- }, m; {1 @6 `) q; v
  172. dmainit.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;
    ) y% c' z2 W3 t* G0 R! ?8 ~2 C+ i
  173. dmainit.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;. s" @  V2 M, h: A, E
  174. dmainit.EnhancedDescriptorFormat = ETH_DMAENHANCEDDESCRIPTOR_ENABLE;
    4 W  f1 a* F  r0 u  q+ X. x
  175. dmainit.DescriptorSkipLength = 0x0;
    7 F& j4 K; T7 ~+ b$ `/ I6 _. ~: U
  176. dmainit.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1;
    ; V, F& K  \, I3 b" S

  177. 7 Y' F1 B' F! c- v; E
  178. /* Get the ETHERNET DMAOMR value */
    6 u' I) D, l4 F
  179. tmpreg = (heth->Instance)->DMAOMR;
    1 g# P9 q/ x3 y; |# d: {
  180. /* Clear xx bits */
    5 m, D5 S  Z; x- s
  181. tmpreg &= ETH_DMAOMR_CLEAR_MASK;
    3 y7 p( A( d( [% i8 y

  182. , A! M" T7 P# \: F( H$ o0 P
  183. /* Set the DT bit according to ETH DropTCPIPChecksumErrorFrame value */
    ) ]/ Q! k% B0 P0 c
  184. /* Set the RSF bit according to ETH ReceiveStoreForward value */4 d0 A* d4 _, i# ?: q& _
  185. /* Set the DFF bit according to ETH FlushReceivedFrame value */
    ! {& n4 W( h3 s& o8 C- S6 ^' Q; U, T
  186. /* Set the TSF bit according to ETH TransmitStoreForward value */
    $ C- z/ E: u, m8 [% r
  187. /* Set the TTC bit according to ETH TransmitThresholdControl value */
    6 K! _/ A$ M$ ~) U- b# b: {* d
  188. /* Set the FEF bit according to ETH ForwardErrorFrames value */6 f, L& V, |, @2 ?
  189. /* Set the FUF bit according to ETH ForwardUndersizedGoodFrames value */2 u0 V' E( i5 C8 g
  190. /* Set the RTC bit according to ETH ReceiveThresholdControl value */
    3 l* K) u( Y8 ]$ J: p$ I' H0 R1 n7 X
  191. /* Set the OSF bit according to ETH SecondFrameOperate value */1 o" ^$ e; ~, y* I& K2 ~
  192. tmpreg |= (uint32_t)(dmainit.DropTCPIPChecksumErrorFrame |
    3 F0 \& Y- v0 c0 l0 ]* r' e9 G
  193.                      dmainit.ReceiveStoreForward |
    ; Y& A! E0 M+ T
  194.                      dmainit.FlushReceivedFrame |3 [3 }0 n$ w2 a- r0 v% u
  195.                      dmainit.TransmitStoreForward |
    % K8 e( s  O2 Z, |5 h* t6 Z- }
  196.                      dmainit.TransmitThresholdControl |
    5 ]% s5 g: g+ ]9 O
  197.                      dmainit.ForwardErrorFrames |. v; Z+ m+ g/ u) ?0 M% Z% j
  198.                      dmainit.ForwardUndersizedGoodFrames |
    " H: R. i# ]! l7 F# X6 g- u, A
  199.                      dmainit.ReceiveThresholdControl |# M: n/ \9 R1 Q8 |/ w
  200.                      dmainit.SecondFrameOperate);( h8 B8 m# j+ C; c3 P/ s* H
  201. $ S+ R# }" z; @3 ]6 V# V9 p# r
  202. /* Write to ETHERNET DMAOMR */# K: J4 w' w0 J& E
  203. (heth->Instance)->DMAOMR = (uint32_t)tmpreg;  s& a! I( T  Q6 r" q+ {6 V
  204. # Q8 ?, T6 y- [; ^! B! }" A' {
  205. /* Wait until the write operation will be taken into account:7 P7 x0 L) M) |3 e" }- F- m$ k3 t$ i
  206.    at least four TX_CLK/RX_CLK clock cycles */; j4 H; p' s4 ~$ p
  207. tmpreg = (heth->Instance)->DMAOMR;* W& V  l5 B0 c% X. }
  208. HAL_Delay(ETH_REG_WRITE_DELAY);" A; W, A: P% Q" T
  209. (heth->Instance)->DMAOMR = tmpreg;7 F6 R' y3 {# g9 X) R
  210. 3 g: H% j$ }, F: Z1 {! W
  211. /*----------------------- ETHERNET DMABMR Configuration ------------------*/" y) E5 r, ^2 H: f$ l* J
  212. /* Set the AAL bit according to ETH AddressAlignedBeats value */
    # d3 f6 J$ ]; g
  213. /* Set the FB bit according to ETH FixedBurst value */! m9 o. n" |& A# s% p9 I
  214. /* Set the RPBL and 4*PBL bits according to ETH RxDMABurstLength value */
    ! i$ ]5 \* s& K- `
  215. /* Set the PBL and 4*PBL bits according to ETH TxDMABurstLength value */* G, Z2 v8 b8 Z0 n$ s
  216. /* Set the Enhanced DMA descriptors bit according to ETH EnhancedDescriptorFormat value*/
    6 k, e, F9 @- v" _2 d3 V1 B# k6 z/ o7 P
  217. /* Set the DSL bit according to ETH DesciptorSkipLength value */
    ) E9 G2 n2 t5 Z, |
  218. /* Set the PR and DA bits according to ETH DMAArbitration value */+ W4 A; t: o4 |
  219. (heth->Instance)->DMABMR = (uint32_t)(dmainit.AddressAlignedBeats |
    2 D% b( C, f* b! S! x
  220.                                       dmainit.FixedBurst |; L( X5 y, S- e
  221.                                       dmainit.RxDMABurstLength |    /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */
    . I$ e, b8 ~6 L/ U
  222.                                       dmainit.TxDMABurstLength |, P) W* s$ ]  ?+ K8 \3 V
  223.                                       dmainit.EnhancedDescriptorFormat |
    2 T$ h$ C+ R4 p6 o
  224.                                       (dmainit.DescriptorSkipLength Instance)->DMABMR;; b7 d  R2 g/ @( u: J" P2 J( I; q% |* n
  225. HAL_Delay(ETH_REG_WRITE_DELAY);
    % c) a" ?: V& K/ h% d  F7 W
  226. (heth->Instance)->DMABMR = tmpreg;: u% C- y3 O4 M' d4 o- B
  227. 5 s- r+ D% e, J  Y
  228. if((heth->Init).RxMode == ETH_RXINTERRUPT_MODE)% s% M- c8 M- R# \# }
  229. {
    : x6 F0 {2 ]/ r) x
  230.    /* Enable the Ethernet Rx Interrupt */
    ' `3 ~. V- a0 E5 S( V
  231.    __HAL_ETH_DMA_ENABLE_IT((heth), ETH_DMA_IT_NIS | ETH_DMA_IT_R);. t6 N3 ^2 ^5 `2 d
  232. }
    2 H: q) q- l5 Y0 j( y

  233. 2 _  R/ V5 {( n
  234. /* Initialize MAC address in ethernet MAC */
    & }. T# c4 m* q/ T% r# t- R/ k
  235. ETH_MACAddressConfig(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);: ^* \+ w5 W" e: |* c; K" S) y
  236. }
复制代码

" e/ Y  _. W% g这里我就要稍微吐槽一下HAL库了
; }- }7 P# z. v2 w$ DMAC层过滤的设置没有预留接口出来,有设置MAC地址的函数" q  \" T9 S/ Z; |. h' f
" ~- G& a% _$ R% f  y" q. o4 K& t% _3 q
static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr)
' h2 P7 D0 ?3 }4 Y; K% I
$ j. E0 O8 }* c4 w7 l! r就不多做一个设置MAC层过滤的函数嘛,连后面用到的宏定义都有~~
, P" ]$ f, v0 J$ P
( A3 i4 `) F) k/ w( o8 F木有办法,自己编一个初始化MAC层过滤的函数吧7 U! J' u0 X& a& R* {6 e
# H6 b' ]3 [! K9 Q
其实也就是把上面这个ETH_MACDMAConfig函数分离成两个单独的设置函数,再编一个设置MAC层过滤的函数
# j  m, a1 {% f( T/ H
& n; d* @$ I' k" C! \; J+ k开启MAC层过滤的初始化代码

5 J3 F) _, Y; F* y/ C+ |
  1. uint8_t ETH_MAC_Setting(ETH_HandleTypeDef *heth)
    - a, i8 }* O/ A7 r& V% C) E. V  H* s
  2. {; _, T/ H9 E. ]) l( I
  3. ETH_MACInitTypeDef macinit;% w$ b" @9 U& L3 M3 L& m- W# ?
  4. /* Ethernet MAC default initialization **************************************/
    ( x  y, n1 T; E  H+ T& W% t1 ~/ \" D
  5. macinit.Watchdog = ETH_WATCHDOG_ENABLE;
    " ^: _5 ~/ J( g- ~: R; I
  6. macinit.Jabber = ETH_JABBER_ENABLE;
    / r: t+ h: z* q+ Q) s& C# Q5 s
  7. macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;' }+ q7 I2 i5 T, ^* g9 V) F) y
  8. macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;
    # p5 |/ g3 t, i. H
  9. macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;
    ; t4 }, `5 i1 }6 {7 L
  10. macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;1 d/ u5 T' Q' k+ T: U
  11. if (heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)3 O& |- x. ?7 g
  12. {. A+ j3 k" W$ o8 L
  13. macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;
    ( Z% \2 ~: }2 h6 f- p
  14. }- ^. r. G/ `" u7 j
  15. else! h" `1 w( r9 s% b& }
  16. {
    4 r) B! h2 e* S  t! o9 B
  17. macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;
    $ h: M5 [8 y' x" B/ G: @
  18. }" F) o" ?' r6 p( n# z3 @
  19. macinit.RetryTransmission = ETH_RETRYTRANSMISSION_ENABLE;          //使能重传; L" d5 b, A8 E+ p: V) z
  20. macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_ENABLE;          //使能自动去除5 _: Q+ N0 d& [) j
  21. macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;( A8 Q  I9 ]' m6 ^1 J1 `: E
  22. macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE;+ n, k' r$ N! e7 C; f' m
  23. macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE; ///不接收所有包5 P" s) d. T9 ]8 _) q
  24. macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_NORMAL_ENABLE; //源地址过滤
    ; G1 N" ]) N' c  r$ l' n
  25. macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;1 t0 C" X' r) `( @- j0 Y* b; m5 D
  26. macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_DISABLE; //广播不接收
    7 `' g6 n7 x) j2 Z, J- {2 W/ h
  27. macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL; //目的地址过滤, B8 }& {8 ^! E. Z9 |; t
  28. macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE; //混乱模式! |2 u' s/ S/ l; n8 C8 a
  29. macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECT; //多播过滤- h" ?4 ]+ t4 h% \
  30. macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT; //单播过滤
    8 e4 }0 x3 y( E( O) ^
  31. macinit.HashTableHigh = 0x0; //Hash表高位9 _+ Y8 a4 ?, I# u- y! ^; u
  32. macinit.HashTableLow = 0x0; //Hash表低位
    . N+ b4 A9 A# i2 o  ?+ a% C% [) w) h* t
  33. macinit.PauseTime = 0x0;2 `* F- p9 M: Z, p5 ~
  34. macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;
    # u+ H& `  m* [3 S0 q( l! f9 K
  35. macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;, }6 H$ j% y6 d
  36. macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_ENABLE;$ P4 T- z4 p2 P$ E3 X
  37. macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE; //接收流控* G  V, k. d% }' J
  38. macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE; //发送流控
    0 p: U3 g5 W9 O, R) ^
  39. macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;
    % ^9 A' p4 a# w, R; O
  40. macinit.VLANTagIdentifier = 0x0;
    : ~+ ~5 V& L- A7 _- ^
  41. . W5 Y- z/ K5 N& w% ^
  42. return HAL_ETH_ConfigMAC(heth, &macinit);( x# h( a0 N' t& r1 v* f
  43. }
复制代码
- Q1 v# ?5 \( H4 [3 o  A; V1 W% F% `
默认的MAC层 DMA初始化函数% G- ?# U1 O# G9 w& M
  1. uint8_t ETH_DMA_Setting(ETH_HandleTypeDef *heth)
    0 V+ I, R: e  x+ D3 |! e4 p' {' E$ t
  2. {2 t6 d7 t* T% x* V
  3. ETH_DMAInitTypeDef dmainit;
    ( C% Z+ g; n! r' O( K
  4. /* Ethernet DMA default initialization ************************************/
    9 t  c2 T: J0 I: {
  5. dmainit.DropTCPIPChecksumErrorFrame = ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE;: o( H) e2 i1 Y" ?) }
  6. dmainit.ReceiveStoreForward = ETH_RECEIVESTOREFORWARD_ENABLE;
    + j. |" T% l. L: K
  7. dmainit.FlushReceivedFrame = ETH_FLUSHRECEIVEDFRAME_ENABLE;
    $ F4 T5 \! R; e+ _; [
  8. dmainit.TransmitStoreForward = ETH_TRANSMITSTOREFORWARD_ENABLE;1 Z9 {, l0 |) q* o& Z- u  l7 q/ t
  9. dmainit.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES;% x9 l& V7 E4 ^6 b  a) ^
  10. dmainit.ForwardErrorFrames = ETH_FORWARDERRORFRAMES_DISABLE;# N  v7 o9 R6 k+ |0 Y3 `# F& b
  11. dmainit.ForwardUndersizedGoodFrames = ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE;
    $ E- S# c7 F6 T! I. S
  12. dmainit.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES;# m  S( k5 ]" s; T; l
  13. dmainit.SecondFrameOperate = ETH_SECONDFRAMEOPERARTE_ENABLE;
    " V! b3 l4 t9 y% n6 }
  14. dmainit.AddressAlignedBeats = ETH_ADDRESSALIGNEDBEATS_ENABLE;3 e4 e$ a& p5 c5 t' O- X# c0 `
  15. dmainit.FixedBurst = ETH_FIXEDBURST_ENABLE;# r' @9 w% y& Z4 z$ d
  16. dmainit.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;* a+ R2 y$ X: n$ A$ R
  17. dmainit.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;
    + r/ j+ @# X' Y  `, m; Q2 c' f
  18. dmainit.EnhancedDescriptorFormat = ETH_DMAENHANCEDDESCRIPTOR_ENABLE;
    3 W' @- b, V7 A% R
  19. dmainit.DescriptorSkipLength = 0x0;6 W; b' Q& n2 S" t5 X( K1 C1 N
  20. dmainit.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1;) O4 X, @0 B1 H8 C0 g; P' v
  21. uint8_t res =  HAL_ETH_ConfigDMA(heth, &dmainit);# j5 Y1 D2 b, F& ]# g4 c0 J9 l
  22. if ((heth->Init).RxMode == ETH_RXINTERRUPT_MODE)
    8 H4 H" f! B$ `8 N' I0 ?
  23. {
    ( D0 o% q& `; c$ e& R
  24. /* Enable the Ethernet Rx Interrupt */5 I' @' {) ]2 O$ `. ~
  25. __HAL_ETH_DMA_ENABLE_IT((heth), ETH_DMA_IT_NIS | ETH_DMA_IT_R);
    7 g2 s! g0 F6 [: x! `
  26. }
    9 b( e$ `. V: Y
  27. return res;
    4 Z6 K7 p8 V- B* @  N$ v/ X
  28. }
复制代码
8 I( D( [& z$ M$ _( U& p+ G" d
用来设置MAC地址的函数(其实就是把库函数的static函数取出来直接用了)
  1. <blockquote>//heth: HAL句柄
复制代码

$ p2 @5 `, B6 ~9 a( {5 x然后到最最重要的MAC层过滤设置

1 X3 Y2 z7 B+ d( L# B以MAC1为例
7 l3 b' x5 n7 F" S5 E2 o4 M" L
  O. ^: {2 Y: a" }
20191124093921254.png
: b  o- w1 G3 M  j! Q2 \, W

: d. P% t% D( Y. O. c3 Z9 m
20191124094439199.png
( D$ d0 I' m3 `
% K$ g) D  u3 N- K# l: }+ ?( l/ s/ h2 K
注意看红框的描述

4 L% I8 T& A: {2 H% a功能很好用,可以过滤源地址/目的地址,还可以做掩码功能! ?4 N7 n" [" Z* F
设置MAC层过滤的代码9 V* |2 Q0 @( [7 M9 L
  1. static void ETH_MAC_Filter_Setting(ETH_HandleTypeDef *heth,ST_ETH_PAR * para)/ [' E* j* J+ C8 }5 U5 z: N
  2. {) S9 B" o2 S( E3 w
  3.     //设置本机MAC地址9 ]- ~9 g5 c" _; f+ ^
  4.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);
    ) M, F/ }9 H( G; X- p/ A! D
  5.     //设置UDP-A的对方MAC地址
    1 T4 k, I9 Y/ I, p# `7 P
  6.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS1,para->UDP_A_MAC);4 S7 j6 \- j# ?; G  K& l
  7.     (heth->Instance)->MACA1HR|=0xC0000000;//需要完全匹配UDP-A的对方MAC才接收
    7 M/ ~2 d" Z- j
  8.     //设置UDP-B的对方MAC地址
    0 }; R+ c- T1 ]- z: W; p
  9.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS2,para->UDP_B_MAC);, |, p! N: B0 Q% O# B: I
  10.     (heth->Instance)->MACA2HR|=0xC0000000;//需要完全匹配UDP-A的对方MAC才接收
    " o" T5 X! z3 G9 u6 h, \
  11. }
复制代码

, n! I7 ?6 U2 i& B3 {! H我这里是希望为我的两个UDP精确过滤接收到的源地址
5 X9 T5 D( D/ o0 g6 m所以AE位设置为1,SA设置为1,MBC全部为0(MAC地址全部检查)' ?* d/ {/ R6 c3 k& B( t% O; q

# d' E  W  Q* [$ a2 D- D& ?假如我希望过滤MAC中特定的厂家字段
# A0 `% k8 p3 q( w5 U1 C, _例如某个MAC地址

  H5 U; o; M. \9 w01-02-03-04-05-06. `  G" |7 Z! r5 ~
其中01-02-03就是厂家字段
0 l6 T* N. {+ D% K& C8 S7 L) H( q+ k9 S8 {/ |. ^" B/ f4 J
那么代码要这样修改(MBC的第29位,28位,27位置1)
* p' @3 B; d: A0 ]' a2 ^) k这样MAC层就不会检查MAC地址里后3个字节(04-05-06)2 l" ]" j( L5 K- i
但是会检查前3个字节,也就是厂家字段
0 u. W# e4 C( y/ j1 r这里需要注意MAC地址的字节序
! _9 D: `2 G3 W; J2 E+ J
  1. static void ETH_MAC_Filter_Setting(ETH_HandleTypeDef *heth,ST_ETH_PAR * para)
    , _! T+ i8 L" G- p0 G& [
  2. {
      {$ g7 z8 D' r9 m- T0 V1 P
  3.     //设置本机MAC地址
    : s# N2 \# W1 v
  4.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);+ F- h# \. b8 s; E7 a) K
  5.     //设置UDP-A的对方MAC地址
    ( p9 x5 V+ O! M# A3 U- S
  6.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS1,para->UDP_A_MAC);
    " x; n$ j, g7 K) S3 a6 h4 {9 g
  7.     (heth->Instance)->MACA1HR|=0xF8000000;//需要匹配厂家字段: z( q$ w* d  p+ L% r6 K- i( j
  8.     //设置UDP-B的对方MAC地址
    . D7 b0 i+ Z2 J& e
  9.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS2,para->UDP_B_MAC);4 }* [3 _: R7 ^, l' l
  10.     (heth->Instance)->MACA2HR|=0xF8000000;//需要匹配厂家字段
    7 }, [; U5 v" y/ }0 ?
  11. }
复制代码
; M! [3 Y) K6 u! z# X% }
然后这些函数的调用顺序按:1 a% E0 o0 J& a
1. HAL_ETH_Init
/ V% u* L4 Q: l: X7 c- c2. ETH_MAC_Setting) f5 V. h& U; ~1 ]6 ]
3. ETH_DMA_Setting) A: Y/ }3 |, x; C4 k$ j
4. ETH_MAC_Filter_Setting& F( W9 m7 z5 `, a9 a8 d
) C  r) |: W1 b
用你希望过滤的MAC传递到一个Hash计算函数里,得到一个值,通过这个值产生“映射”关系来过滤MAC地址,所以这个并不是精确的,因为可能会重复~~/ l" x$ ?. W5 B  x

* {1 u, G' h3 \+ a9 X3 z
HASH函数$ Y, G  s5 G7 U' T9 m$ R2 d
函数) P9 K( o: S/ z7 P. F1 j
  1. / STM32 MACHASH - Copyright (C) 2014-2018 Clive Turvey (<a href="mailto:sourcer32@gmail.com">sourcer32@gmail.com</a>)$ l. ]  c1 l# O. J1 C5 x( u1 H
  2. //  All Rights Reserved' b/ O+ M  Z' F' t' G

  3. / Q5 [8 d: |* z  N! ~* Z# H. b
  4. #include <windows.h>; h! `: _% a0 X8 z: g: {
  5. % U: z- I  V3 ~7 _4 a3 u  T2 |
  6. #include <stdio.h>
    4 A; Y9 O& l; W; p! }, C
  7. #include <stdlib.h>  U! ]3 n& D4 M; b! E* O# k

  8. & x) ]% u+ B) ^  P- I
  9. typedef unsigned char uint8_t;$ f- X1 ~) N- l- `0 W8 B) f; y
  10. typedef unsigned long uint32_t;
    6 ^" Z  i8 B6 Z. p$ v0 c2 A

  11. ) U# D0 |' B' X# [  x0 }" F0 v
  12. uint32_t Rev32(uint32_t x)1 g  o( T1 F9 ^# k
  13. {
    7 `9 m. V/ z4 [- k( }$ W
  14.   uint32_t y;
    ! n; r- r9 }) \; f
  15.   int i;
    * B& Z, Y3 V" ^3 W

  16. ) [: s& r- X" h6 v9 P" ?, X
  17.   y = 0;
    + b  j. k6 U. ~7 L0 |* r  [

  18. : w8 {  A/ h# X7 p0 z
  19.   for(i=0; i<32; i++); H7 A% @4 a* c7 h9 H
  20.     if (x & (1 << i))- w$ L2 e5 j$ V% _3 R3 j3 B# r
  21.       y |= 1 << (31 - i);0 s$ g, b1 N  l4 u7 G

  22. , k2 V% B; m7 l$ P4 A
  23.   return(y);
    # {$ B# o* _* P/ [6 c, E
  24. }
    , L+ v7 A- _+ w8 U3 o* D

  25. ( b, N+ v' t% n$ o, s* f3 R- z
  26. uint32_t MacHash(const uint8_t *Mac) // <a href="mailto:sourcer32@gmail.com">sourcer32@gmail.com</a>' T5 D8 ]8 M- P# I# e) J1 d
  27. {
    $ Q- t/ T: `% }
  28.   int i, j;* T8 U: y: N( _: i
  29.   uint32_t Crc;: t3 o, v7 E. W1 v* {% f

  30. ! F7 G: N- r" I8 U4 c8 `$ r
  31.   Crc = 0xFFFFFFFF;) n/ ^. ~' U( K2 A/ G, ^
  32. 4 C2 J6 [2 p' E+ E4 {; h( P. |
  33.   for(j=0; j<6; j++)
    7 I% d$ ~% V7 C$ o" C+ h: O) c9 Z
  34.   {
    + y7 X, k2 {* s$ P% v
  35.     Crc = Crc ^ (uint32_t)Mac[j];  e- o8 {! z9 R+ G

  36. 4 J6 e- m' A9 e- O& Y: g
  37.     for(i=0; i<8; i++)4 b/ [" m( i0 u# O/ f
  38.       if (Crc & 1)
    0 K8 a) Y9 X  M- y7 j1 W7 O* C) v
  39.         Crc = (Crc >> 1) ^ 0xEDB88320; // Reversed 0x04C11DB7$ s# }5 P) Y7 v. k7 M; Z
  40.       else
    " J; A& A# d7 t2 S) X  Q9 r
  41.         Crc = (Crc >> 1);
    0 M( |% F5 N! n8 ^9 ~' B1 E( W
  42.   }
    , H. K. d2 w# T' R, v8 Z6 a
  43. ( V% Z: T" B6 r8 i0 Q$ D
  44.   return(Rev32(~Crc) >> 26); // Get High order 6-bit in reversed/inverted CRC
    1 D- x7 ~8 M( x5 P# M2 h
  45. }, z" x. U5 `( K- J
  46. # y$ k- ?" M6 m0 U; C
  47. uint32_t MacHashFast(const uint8_t *Mac) // <a href="mailto:sourcer32@gmail.com">sourcer32@gmail.com</a>
    2 P6 t5 A3 p7 v* b) |  `# O+ N
  48. {/ S& l+ L/ e- i9 m( A; F
  49.   static const uint32_t Rev6Tbl[] = {0 O, \9 J. L0 O7 V% z% a0 J4 a' \. X0 t
  50.     0x00,0x20,0x10,0x30,0x08,0x28,0x18,0x38,* H+ M& ]3 g  t* B
  51.     0x04,0x24,0x14,0x34,0x0C,0x2C,0x1C,0x3C,0 w3 o" H$ f/ T' h- k1 @9 w" D, A, o
  52.     0x02,0x22,0x12,0x32,0x0A,0x2A,0x1A,0x3A,
    - |  `. x" m  s. c  g5 k5 ~; ~: F
  53.     0x06,0x26,0x16,0x36,0x0E,0x2E,0x1E,0x3E,/ ]) G9 j: M7 i  _1 f3 O
  54.     0x01,0x21,0x11,0x31,0x09,0x29,0x19,0x39,) w  _7 b& s- o# H3 M' G
  55.     0x05,0x25,0x15,0x35,0x0D,0x2D,0x1D,0x3D,
    6 X9 R+ c' x  W
  56.     0x03,0x23,0x13,0x33,0x0B,0x2B,0x1B,0x3B,
    * o5 ~# z' `1 _" O
  57.     0x07,0x27,0x17,0x37,0x0F,0x2F,0x1F,0x3F };+ x; X) V- T& a! e* p

  58. # U1 b5 ]* m0 c! t- s9 n. m
  59.   static const uint32_t Crc32Tbl[] = {
    # t+ ]7 s% D; i0 U
  60.     0x4DBDF21C, 0x500AE278, 0x76D3D2D4, 0x6B64C2B0,
    . j6 Q9 |) T& _
  61.     0x3B61B38C, 0x26D6A3E8, 0x000F9344, 0x1DB88320,
    1 B; Y8 u4 t6 Q( g. z+ o8 N
  62.     0xA005713C, 0xBDB26158, 0x9B6B51F4, 0x86DC4190,
    / d) u3 E6 b2 f, I8 F. ^) n
  63.     0xD6D930AC, 0xCB6E20C8, 0xEDB71064, 0xF0000000 };9 L1 c8 H7 F, q- n+ d

  64. 6 F  S2 h4 |! y$ s4 [
  65.   int i;
    % A/ A- Q  Z+ V. g/ t% z
  66.   uint32_t Crc;
    4 Q# f, \, r: u: ^* Z- H7 y, l9 r; Z. `

  67. 7 M( a3 v# {& A0 m! ?) s! {
  68.   Crc = 0;) v6 P$ P* s$ H

  69. # y/ I# w. x2 v
  70.   for(i=0; i<6; i++)
    " o9 V4 y9 k) Z4 R
  71.   {
      P, j* Y) d. E. f/ w, t8 s
  72.     Crc = Crc ^ (uint32_t)Mac<i>;0 v! j; K* t4 T) }% s, g2 C
  73. 3 O6 D% L- ~2 E6 s, I
  74. </i>   Crc = (Crc >> 4) ^ Crc32Tbl[Crc & 0x0F];  /* lower nibble */
    # N1 o* Y  ^3 U. r; d
  75.     Crc = (Crc >> 4) ^ Crc32Tbl[Crc & 0x0F];  /* upper nibble */. R9 G3 M6 r1 E, m$ A4 t: \! N
  76.   }5 @0 u5 H3 u9 V' }5 N) q4 D
  77. 7 I4 P- Z- s% P/ t
  78.   return(Rev6Tbl[Crc & 0x3F]);/ z  H+ w$ F$ m' w9 u8 n6 d
  79. }
    ' s* ~4 S2 D! ]+ b4 T9 B+ k* Q

  80. 3 s) O. {, m5 K5 v
  81. int main(int argc, char **argv)/ c. N* A+ F8 A" T
  82. {
    " z2 m: A( S+ P3 u1 @
  83.   static const uint8_t Test1[] = { 0x1F, 0x52, 0x41, 0x9C, 0xB6, 0xAF }; // 0x2C' t9 l. j! l$ k9 s9 A
  84.   static const uint8_t Test2[] = { 0xA0, 0x0A, 0x98, 0x00, 0x00, 0x45 }; // 0x07
    # B$ \( U7 Y- D3 v9 y
  85.   static const uint8_t Test3[] = { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x21 }; // 0x24$ R; {$ e* F: B  s" U: A& ?
  86. 0 |7 z) F7 _$ B% u& ^! N% d7 Y
  87.   printf("MacHash %02X\n", MacHash(Test1));/ O; S0 K, V/ w1 A* Z; I
  88.   printf("MacHash %02X\n", MacHash(Test2));7 P6 D# J3 f' X
  89.   printf("MacHash %02X\n", MacHash(Test3));3 g! `* ]- m9 x: g- l( ?) f6 b
  90. 4 H; [( w. d# A( k2 l& G( f
  91.   printf("MacHashFast %02X\n", MacHashFast(Test1));8 i( ~6 s! `, H& M+ N' I: }; R
  92.   printf("MacHashFast %02X\n", MacHashFast(Test2));9 p, H1 C( p# h& t; p
  93.   printf("MacHashFast %02X\n", MacHashFast(Test3));
    , T$ h- X* n! ?% M" M1 E
  94. " A: `* E' E6 c! e; E, V; k6 r
  95.   return(1);
    ) T! P5 V) n2 }! D3 q. Z1 o& o
  96. }
复制代码
( i2 X/ X; [- t4 N0 @

2 u1 y' \' Q) L- m8 \回到手册
  @* I+ u/ R0 B6 a/ L" x* u7 b! {, D/ ?7 ], W' d$ U
20191124100604140.png
# _9 \: r& d6 s# {7 e
) @0 E) [/ ^7 }! N5 U4 q
20191124100636882.png
5 l: F) \+ T' Q

$ u- E" D9 q2 W: b9 \, Q+ r! V* G0 w4 t- m! n
上面的函数算出来一个数,假如是手册上的那个0x2c,二进制为101100B& Y7 c8 e  y1 A7 T- ~; h. p9 Q
换句看得懂的人话···就是:4 J1 G: X9 Z) U# v; z
算出来的数先看第6位9 [1 `" A* {; L0 L7 u9 o
是1的话说明用到的是HASH表高位寄存器
6 n$ o/ n' G+ Q) T9 B3 d否则用到的是HASH表低位寄存器
( s- A! F+ Q, M2 A- j然后剩下的5位,转成十进制不是12嘛
6 n; ^0 ^  K% I7 d) j2 I8 I+ o如果你希望过滤这个MAC
5 [4 I" b4 W; j那么你就把对应的HASH表高/低位寄存器的对应位置1,否则置0
* o9 f: _9 |# O这里的0x2c就是要把' F5 ?/ @  n" g. Q1 }
HASH表高位寄存器的第12位置1
( ^" Q3 }7 W1 U& w! s4 ]就可以过滤这条MAC了
$ K/ v2 ?  d. ~7 C然后把你希望的MAC地址都按照上面说的方法弄完+ y# s1 z9 Z; j* J: q5 ^$ ^  [

+ Q% y0 f5 U6 \回到这个函数稍微改一下
) `3 V, [: c9 n0 i- T7 }+ p
  1. uint8_t ETH_MAC_Setting(ETH_HandleTypeDef *heth)
    : N* Z9 z- y8 o4 S4 z. }
  2. {* i: k, D  n; g, ~. ~. u
  3.     ETH_MACInitTypeDef macinit;' T9 i2 ]9 p% ^( J
  4.     /* Ethernet MAC default initialization **************************************/0 c  n* r) f) P5 m( [8 e8 a
  5.     macinit.Watchdog = ETH_WATCHDOG_ENABLE;: I4 g% t& C6 g. v! x4 ]9 o
  6.     macinit.Jabber = ETH_JABBER_ENABLE;
    % ]4 N4 {$ b' h" f2 q
  7.     macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;
    ) F; K5 W2 j* N( Y' ^  }, \1 X1 g
  8.     macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;' ?* G2 `! J' l
  9.     macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;* J0 e+ J3 m( Q9 E  C! r, B+ c
  10.     macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;  Q" @6 B. s7 ~# F; e
  11.     if (heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)1 a$ F2 n3 F  W: ~' Q6 ?" U& B
  12.     {. }' i3 w% k: R/ o/ Q5 i0 F
  13.         macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;
    0 Z& J. \. e, w% r6 m9 ?
  14.     }
    ' g2 s; i6 b. w8 G9 i1 e/ T' x
  15.     else/ l) N; N. Y& o8 d; U* S% D
  16.     {9 ]0 }' d" H1 [' |
  17.         macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;
    6 s. Y  Q/ ?2 J' w9 f) D
  18.     }6 a2 S; J+ {6 L
  19.     macinit.RetryTransmission = ETH_RETRYTRANSMISSION_ENABLE;          //使能重传
    , C) n6 G7 Q+ `/ x4 K
  20.     macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_ENABLE;          //使能自动去除
    $ p; M+ q% l$ {! F% O2 [
  21.     macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;' A0 d0 l6 l$ Q. T( U6 S/ U
  22.     macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE;+ H. j* b0 n+ _3 r$ _7 W$ ~1 f$ f
  23.     macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE; ///不接收所有包0 \8 A4 B- c7 O  C. i
  24.     macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_NORMAL_ENABLE; //源地址过滤
    ( S  N1 ]0 G) j8 B# e6 t
  25.     macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;
    0 f5 r7 q- E2 D$ u  I# M9 H
  26.     macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_DISABLE; //广播不接收  @' {% I/ p. C( e
  27.     macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL; //目的地址过滤
    % |! W& W' I5 r. T8 _: g
  28.     macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE; //混乱模式
    1 k- a! @; ^& z: }2 y. z
  29.     macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECTHASHTABLE; //!!多播HASH完美过滤& p) w8 P" G  F$ d6 H. z4 A7 ^
  30.     macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECTHASHTABLE; //!!单播HASH完美过滤. M9 b! t# T$ n
  31.     macinit.HashTableHigh = 0x0; //!!填你最后算完的Hash表高位
    , f8 u0 T; r8 q( w5 P+ X' D! ~
  32.     macinit.HashTableLow = 0x0; //!!填你最后算完的Hash表低位
    6 D5 U$ p! ?1 j- K1 {; @( N
  33.     macinit.PauseTime = 0x0;$ t% k4 H% r! _' P1 k, b% c: [
  34.     macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;
    6 p; V5 R. X1 o) y& @3 N, K
  35.     macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;+ S% p0 H, D! ]
  36.     macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_ENABLE;+ }" F, G2 z2 g8 s0 E& v- D
  37.     macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE; //接收流控8 T; ~: e7 N1 I/ D: o* }
  38.     macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE; //发送流控" d) _/ Z, Q* K  [. G
  39.     macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;' v4 y# [, Q! ?7 d8 [6 H$ C
  40.     macinit.VLANTagIdentifier = 0x0;
    3 o3 t+ R# W  d0 n6 V
  41. 9 a1 \* J2 O- n9 a
  42.     return HAL_ETH_ConfigMAC(heth, &macinit);% p7 \) ]" z# F, q) b0 d: m
  43. }
复制代码

. s; f' v) M7 K- E! P( o" F大概MAC层过滤就这些东西了% n7 B) L2 q# j% y& P
如果有条件弄MAC层过滤真的强烈建议开启,可以大幅减轻协议栈的处理负担,板卡不会因为处理大量无用的数据而白白浪费处理性能。3 d' w/ x* C  C( C, y1 v

' _4 x1 |6 V& {8 O
% a; Q6 y; P0 m2 u! M0 Y$ ]. Y
$ x1 K, v3 u3 H( f- ^" Q% ?% j3 U
: o9 y: ~8 v/ j# @' Q) P
收藏 评论0 发布时间:2021-12-14 10:15

举报

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