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

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

[复制链接]
STMCU小助手 发布时间:2021-12-14 10:15
前景描述  p+ |7 {  R6 l4 T7 ?& y
我司的以太网实现是LAN8720搭配片上MAC层做的,协议栈用LWIP
! e0 z& _$ T+ M  P$ k& ]! \
9 u  B- O3 Y0 }) M! E5 k  m这种做法应该还是蛮常见的,反正不是LAN8720就是DP83864,再不然就是硬件协议栈的W5500了
6 {3 q4 v. q  r! e# m1 R/ ?4 d( C" Z9 a+ h! s9 v' g. W" w* D
想想还是有MAC层过滤比较好,随手翻了翻它的手册,W5500好像是没得MAC层过滤的0 O" ?- [+ x! t. U

  a+ ~3 V% D8 \  F1 }) T5 m, m- C, {假如数据速率比较高,数据量大,而且外面还有乱七八糟无关的数据往板卡送,我也不知道用这个片子到底好不好
; b( N. a$ }* @
! P3 [- `, E% \, T) m' x' @0 c6 W" hLAN8720也不好改了,就继续用吧
+ Q8 X& u/ G+ S1 ?1 D% a
3 E, _2 _; p2 U+ E: l% q好好在,发给板卡的数据的MAC还是有特征的,我只需要过滤发送方MAC地址的前3个字节,也就是特定的厂家那段! a7 l7 N1 e  H% a6 G& N

" D" j+ k" p7 C6 |+ J$ ]MAC地址的科普知识这里就不过多描述了,我们直奔主题: T: V+ \1 O  Z! y! _- t

. T# J5 u+ Y+ s: h4 ]* Z4 U! y* m5 @怎么用STM32 F7的片上MAC做MAC层过滤
  c4 l3 A, v( c1 f' E
/ x: G9 p8 m) s( W9 Z3 w5 m6 Z, U3 j写这个的目的,就是我搜了搜,没看见有人写这个MAC层过滤功能,具体代码怎么写才能用$ n' G& X$ ]4 f" k* B; x+ m

5 S% j" W& ~. O0 _! T* M1 R知识科普-STM32的片上MAC
" J( R- R0 Q- k) [$ X6 _STM32 F7的MAC层过滤方式有三种(说人话的直白解释,中文手册其实也翻译的不好)1 \6 u) z5 u( \* t
精确过滤(手册上叫单播目标/源地址过滤)
' I5 A2 p) g2 v, B5 \' i2 [8 p粗糙过滤(手册上叫Hash表过滤)( J+ z: f8 `4 k
特殊过滤(广播,组播过滤等等特殊的过滤)8 }* @0 r/ {5 N
我这里着重说第1种和第3种3 j& ?; u$ J' G( f
$ n6 {& N' u. N( a/ I$ q" l
STM32 F7可以存4个MAC地址# ?3 `! B% J. N5 G  V
其中MAC地址0是自己的MAC,其他三个可以用来做过滤
+ Y  i; z. i4 ]% m, P2 w8 p7 e
3 j: [0 r6 M: Z  U( m网络数据包通过PHY进入STM32的MAC,MAC层是可以对目的地址/源地址检查并过滤掉没得用的数据的,默认的HAL库库函数HAL_ETH_Init中- L% H% ~6 y: a4 I% q0 i
有一个static的函数
4 f, o" X% c+ Z) i0 W/ qstatic void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err)- T9 m* Q2 ~/ h! y
会帮你在初始化网络功能时初始化默认的MAC层功能:
& s$ [. B# ?' W; D& H( ]2 G6 n* k关闭源地址过滤4 e( X& e* w8 e$ e9 u- p6 n
不接收所有数据' [7 c7 a8 E7 l- _: W( ~
接收广播帧
7 D# \4 \1 u" v打开目的地地址过滤
; w5 G* e3 c2 J/ L, u: y  ~单播数据精确过滤
! K; ~! ]8 f. g/ o5 C7 J4 K* w* h组播数据精确过滤. F5 A9 K# @! x( {' z# j/ N( @
Hash表过滤关闭3 z$ U' A9 V" T8 s+ I- l

; L1 a5 E3 }6 B& e* j1 C其他的功能自行研究,我这里捡重要的说( f0 l' P4 Z9 {- T0 E+ W
  1. static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err)" Y& ]- k* J0 `: J2 \
  2. {
    . {6 e; V. ^. I! T+ ~; ?5 y3 v9 q: y
  3. ETH_MACInitTypeDef macinit;
    % |: g5 ]9 h+ |6 D! {
  4. ETH_DMAInitTypeDef dmainit;! H. \9 {, r& I
  5. uint32_t tmpreg = 0;
    & H1 n) v0 N* j# }2 H" s" y7 a( F7 c

  6. : F7 X. E! b9 S( J' ^
  7. if (err != ETH_SUCCESS) /* Auto-negotiation failed */' i3 j! Y: k, N8 o3 w
  8. {- z1 u7 c% j! }
  9. /* Set Ethernet duplex mode to Full-duplex */
    ' l' z/ b  X3 `5 t$ B( b
  10. (heth->Init).DuplexMode = ETH_MODE_FULLDUPLEX;
    ( P. S' \( F: t# e- b

  11. & c. B/ X# {( n5 b1 N
  12. /* Set Ethernet speed to 100M */) P' K+ j- i% c4 i
  13. (heth->Init).Speed = ETH_SPEED_100M;0 h1 c! _$ U6 \+ Q; C- @2 w- a6 M
  14. }
    ) @- J* n+ k4 b: ?6 b8 d

  15. 9 d7 C4 f5 C- p$ m5 B
  16. /* Ethernet MAC default initialization **************************************/
    8 M3 c' Q8 U; ?' F: r, G
  17. macinit.Watchdog = ETH_WATCHDOG_ENABLE;
    5 u  q& s% K9 ], M9 s
  18. macinit.Jabber = ETH_JABBER_ENABLE;! Y2 v: g/ f, s) D, |
  19. macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;& i+ k' z, Z' h* o/ W' |+ t
  20. macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;9 B% @; G! K  T7 X* _
  21. macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;
    $ J) \) X% N( `) `: {  A! i% I
  22. macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;( x) \/ X6 @5 G4 T; O# n7 f( D- |
  23. if(heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)2 h1 M3 D. N" W4 h/ _3 Y; |
  24. {/ L& n, k6 s8 q2 T
  25. macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;6 s  S& H# ~' o- O8 Q; F
  26. }6 c% n  Z! ?9 q  h/ D. [
  27. else
    . J5 }' \0 N3 _( l0 C6 D( {* ~
  28. {
    ' [# ^; T8 D! [6 X' c
  29. macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;' y! y8 K: U: q5 H
  30. }
    ; l. f5 P( ~5 U+ v# P7 U, `* h
  31. //这一段是MAC层过滤的设置,下面是DMA的,那个用默认的就可以
    . l# m- l8 N3 }3 s0 l2 v
  32. macinit.RetryTransmission = ETH_RETRYTRANSMISSION_DISABLE;
    & e& i  g- K" }1 J; Q
  33. macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_DISABLE;
    + F# R" o7 v5 d2 Z' \1 b
  34. macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;7 C' {+ E- q1 L  r/ R) s
  35. macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE;3 Y" e- P. h5 P3 J" I
  36. macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE;7 g) ?5 q2 n% g4 x
  37. macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_DISABLE;
    * s8 g6 |( I5 d' v9 q' K+ {, X7 s* S# x
  38. macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;( c( P- l+ Q" [
  39. macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_ENABLE;
    3 C- q& I! Q% n7 d  l
  40. macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL;
    8 Q3 `' E0 E5 L* t& g/ u: Z5 q
  41. macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE;$ [0 Q/ y' E6 E0 Q
  42. macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECT;
    + m5 B0 u  ~: j; X2 u
  43. macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT;* W+ G- I/ }2 X, O/ W
  44. macinit.HashTableHigh = 0x0;
    5 h+ R' b# A7 G! O: s4 O4 ^  w0 d) q9 A: d
  45. macinit.HashTableLow = 0x0;
      M5 O4 E; K$ ~! g
  46. macinit.PauseTime = 0x0;
      ]4 o# ^! w2 I3 I
  47. macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;( t4 y4 O; c/ t0 I7 i- l, ^
  48. macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;
    & d; B. N0 J6 }* }8 p! `
  49. macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_DISABLE;/ B& Q7 h* B+ O  E
  50. macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE;/ E$ N  O# b  M9 g6 @+ a: P
  51. macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE;8 w+ }; u" R4 x7 t* e6 p8 o
  52. macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;' t1 ], L$ w% m1 O/ t
  53. macinit.VLANTagIdentifier = 0x0;
    # F, y7 f, j& W% b! u& }2 F4 E7 l& E6 B

  54. 4 m! c+ @4 ~* s
  55. /*------------------------ ETHERNET MACCR Configuration --------------------*/9 Z* k7 P2 l1 ?
  56. /* Get the ETHERNET MACCR value */
    3 ~5 n% g; w, G7 M: Y" N6 C& v
  57. tmpreg = (heth->Instance)->MACCR;
    5 R# S4 j: u, T+ j) o5 O; n, R' J
  58. /* Clear WD, PCE, PS, TE and RE bits */
    $ [. N: D2 {+ ]+ @
  59. tmpreg &= ETH_MACCR_CLEAR_MASK;
    4 R8 O+ M" A1 [3 ?0 G, i. P. L0 M" ^
  60. /* Set the WD bit according to ETH Watchdog value */
    ; g7 H0 f0 F# Y3 [# q) Z) T3 d' e- ]
  61. /* Set the JD: bit according to ETH Jabber value */+ D4 q: {  |8 Z  ?
  62. /* Set the IFG bit according to ETH InterFrameGap value *// i7 N2 O: ~2 X0 _# m5 ?
  63. /* Set the DCRS bit according to ETH CarrierSense value */  Y9 B. ]9 G; D6 O! Y& m5 l3 P
  64. /* Set the FES bit according to ETH Speed value */
    7 ^7 P+ h# o+ d6 D* Q0 }" o
  65. /* Set the DO bit according to ETH ReceiveOwn value */) D" u  E0 O- _3 ~5 y
  66. /* Set the LM bit according to ETH LoopbackMode value */
    7 u' ?% n! x8 k- `( a: v
  67. /* Set the DM bit according to ETH Mode value */
    - ~# |; ]2 Z' `' t0 |4 S2 u5 Y
  68. /* Set the IPCO bit according to ETH ChecksumOffload value */
    * F8 ?. Y: h' g9 ?
  69. /* Set the DR bit according to ETH RetryTransmission value */6 o/ R% {! A) |2 Y4 r4 f
  70. /* Set the ACS bit according to ETH AutomaticPadCRCStrip value */
    5 ^- q  V$ R0 }8 H, r  z3 i+ h
  71. /* Set the BL bit according to ETH BackOffLimit value */) _4 N8 {! n" _$ [5 d
  72. /* Set the DC bit according to ETH DeferralCheck value */7 l/ w& ]3 l0 F2 {& l
  73. tmpreg |= (uint32_t)(macinit.Watchdog |; w/ G; J6 G# t( @& O
  74. macinit.Jabber |
    5 @( c0 R! Z, Y) i+ V
  75. macinit.InterFrameGap |
    6 q- Y* Q6 p$ c, D) I3 Q
  76. macinit.CarrierSense |
    . a* x( @8 M6 q7 e
  77. (heth->Init).Speed |. O' n# h4 N) F) X: p8 z
  78. macinit.ReceiveOwn |
    2 i( _$ @6 v6 l) v8 @
  79. macinit.LoopbackMode |
    * H. M8 y1 @3 o# N
  80. (heth->Init).DuplexMode |9 g0 ~8 t4 G8 U1 H
  81. macinit.ChecksumOffload |- @5 \& F# h; m, `( H3 T) ]$ h. g
  82. macinit.RetryTransmission |
    ; @) w7 h' Q: [- V% ~
  83. macinit.AutomaticPadCRCStrip |
    6 ]* h) K' U6 _6 G0 {
  84. macinit.BackOffLimit |/ I# J# m, i8 o" [
  85. macinit.DeferralCheck);! |; v9 y# f  e! O+ Z

  86. 7 y$ i% n: g$ f0 c
  87. /* Write to ETHERNET MACCR */
    $ y1 b+ O% o0 ]9 y) B6 d* W
  88. (heth->Instance)->MACCR = (uint32_t)tmpreg;
    / R5 [+ p# w( m' c$ `$ M. x
  89. 8 R6 O4 Y/ _+ ]7 [' S% O1 ^
  90. /* Wait until the write operation will be taken into account:2 t. Y  b$ \+ i1 c: p4 E+ I
  91. at least four TX_CLK/RX_CLK clock cycles */6 N/ ?3 P; e* b2 `3 j7 ^- O& n
  92. tmpreg = (heth->Instance)->MACCR;
    4 v; ^- P+ D3 F
  93. HAL_Delay(ETH_REG_WRITE_DELAY);# G  u7 X  C# Y/ \! \7 ~
  94. (heth->Instance)->MACCR = tmpreg;  g- J  k+ k  n) t% A2 M% E5 e

  95. ; Q/ ^3 Q6 {2 u, R; p5 x7 o
  96. /*----------------------- ETHERNET MACFFR Configuration --------------------*/
    ( V8 N3 E9 ~) ]" B" O1 f: W
  97. /* Set the RA bit according to ETH ReceiveAll value */
    + R. D; c3 |, n1 r% n. v3 a
  98. /* Set the SAF and SAIF bits according to ETH SourceAddrFilter value */& {" \/ O0 k- v5 O% F- f  C! [
  99. /* Set the PCF bit according to ETH PassControlFrames value */
    ' T# a# O0 M+ V
  100. /* Set the DBF bit according to ETH BroadcastFramesReception value *// C8 [' o8 a+ c  H
  101. /* Set the DAIF bit according to ETH DestinationAddrFilter value */0 m* ~% I6 j: Q- [6 T( C/ I5 r$ C
  102. /* Set the PR bit according to ETH PromiscuousMode value */" i' {+ m: G( _! E
  103. /* Set the PM, HMC and HPF bits according to ETH MulticastFramesFilter value */
    % W# [9 ]  V% Z# g+ N4 l* ~* k
  104. /* Set the HUC and HPF bits according to ETH UnicastFramesFilter value */5 p4 u& P  `) K; z
  105. /* Write to ETHERNET MACFFR */8 l. C- Q7 o- h9 S% u
  106. (heth->Instance)->MACFFR = (uint32_t)(macinit.ReceiveAll |
    , L5 @4 d/ ^2 Y+ q4 u2 i5 S
  107. macinit.SourceAddrFilter |
    & }! E/ R5 n! B7 _! m" U9 W# i7 z* F. P/ G
  108. macinit.PassControlFrames |
    ' c/ c! `6 k5 A* s* r1 ?" a1 h
  109. macinit.BroadcastFramesReception |7 U6 i: S) X4 Z
  110. macinit.DestinationAddrFilter |0 T# w4 b8 {* W( \) |
  111. macinit.PromiscuousMode |- o- M0 n% b8 i6 n
  112. macinit.MulticastFramesFilter |
    + |- N/ O9 l8 i9 E: h
  113. macinit.UnicastFramesFilter);( \7 S3 |  K9 G' [) L( w3 ^  L! ^

  114. - {( c( w. D+ S
  115. /* Wait until the write operation will be taken into account:
    9 a- v! [- K. T$ Y8 A
  116. at least four TX_CLK/RX_CLK clock cycles */
    / z, x7 D; Z; N( B; e
  117. tmpreg = (heth->Instance)->MACFFR;0 r8 R5 S" w! b7 d5 z
  118. HAL_Delay(ETH_REG_WRITE_DELAY);
    $ Y; u9 Y( a$ l, J4 L
  119. (heth->Instance)->MACFFR = tmpreg;' j& b3 L& n1 y3 K8 [' a
  120. " ]4 L8 t5 q+ b$ u/ g) S
  121. /*--------------- ETHERNET MACHTHR and MACHTLR Configuration --------------*/
      U5 f$ b" V5 _& q, N
  122. /* Write to ETHERNET MACHTHR */& k, t4 p7 ?: D" u
  123. (heth->Instance)->MACHTHR = (uint32_t)macinit.HashTableHigh;- \: P$ g3 d1 y& m/ b& I, X

  124. ( `/ W0 n2 v9 N* `1 k
  125. /* Write to ETHERNET MACHTLR */
    5 b& }0 M% q/ M& t
  126. (heth->Instance)->MACHTLR = (uint32_t)macinit.HashTableLow;6 e& T+ b; h4 w- a
  127. /*----------------------- ETHERNET MACFCR Configuration -------------------*/% p/ `) r2 U$ T/ y3 k9 a4 K

  128. 3 d! W" h7 g) S( Q" w; H
  129. /* Get the ETHERNET MACFCR value */
    ) K) e- K7 I) f9 {" Q* j4 Q2 S! I( f
  130. tmpreg = (heth->Instance)->MACFCR;. Z) n/ y4 T/ h% h6 L  D
  131. /* Clear xx bits */
    3 \0 C0 U; ^$ b1 s# X3 @! h  B
  132. tmpreg &= ETH_MACFCR_CLEAR_MASK;
    3 F" C( W: c, P; ^& ^+ e8 n* l9 V
  133. 8 D5 [, S1 g" n
  134. /* Set the PT bit according to ETH PauseTime value */+ c+ J/ y" V; q* ~% X7 J
  135. /* Set the DZPQ bit according to ETH ZeroQuantaPause value */3 g/ J) {  N% z* i: M
  136. /* Set the PLT bit according to ETH PauseLowThreshold value */
    + }1 `5 G' s" A. o
  137. /* Set the UP bit according to ETH UnicastPauseFrameDetect value */& G4 }& N; T. _7 M
  138. /* Set the RFE bit according to ETH ReceiveFlowControl value */( b/ k7 t9 Q8 \( l* {9 g9 T; ], G
  139. /* Set the TFE bit according to ETH TransmitFlowControl value */
    2 M9 Q$ R) S4 u; f9 E
  140. tmpreg |= (uint32_t)((macinit.PauseTime Instance)->MACFCR = (uint32_t)tmpreg;9 U" l' G( g* h! _; B
  141. / ~. S/ T- c+ l' J, ~
  142. /* Wait until the write operation will be taken into account:# i+ m$ m" n' H6 t9 i
  143. at least four TX_CLK/RX_CLK clock cycles */0 a, T7 _* A7 |6 B% d
  144. tmpreg = (heth->Instance)->MACFCR;6 x6 \( i2 X  f8 h* T
  145. HAL_Delay(ETH_REG_WRITE_DELAY);
    : V( q  d1 b8 i
  146. (heth->Instance)->MACFCR = tmpreg;
    ( Q6 V- V) {0 y+ B
  147. 2 e* z. [# ^1 j# o: z" V: v4 t8 _
  148. /*----------------------- ETHERNET MACVLANTR Configuration ----------------*/
    - q( D3 ?. s% B. J: z. }
  149. /* Set the ETV bit according to ETH VLANTagComparison value */0 h# W9 A  A9 T5 K' Z$ }
  150. /* Set the VL bit according to ETH VLANTagIdentifier value */
    ( h/ h! l& i0 y6 |- @
  151. (heth->Instance)->MACVLANTR = (uint32_t)(macinit.VLANTagComparison |* ]/ i% a5 B; `: @2 i" {
  152. macinit.VLANTagIdentifier);9 ]  n  S: _( j4 }9 C  }3 K

  153. 6 S" w- n# H, b0 D
  154. /* Wait until the write operation will be taken into account:2 l( F2 P( v7 V$ v% Q
  155.    at least four TX_CLK/RX_CLK clock cycles */  X7 S0 ]5 o4 @3 X' t5 a4 {7 L* d
  156. tmpreg = (heth->Instance)->MACVLANTR;, I4 {6 P2 d) r/ \/ v, l
  157. HAL_Delay(ETH_REG_WRITE_DELAY);
    2 [: A3 I: q8 r+ Q' w- C( S
  158. (heth->Instance)->MACVLANTR = tmpreg;4 ~% _) {- w* v7 }- @: l

  159. 8 |1 ?$ r# Y+ K7 x2 W/ A
  160. /* Ethernet DMA default initialization ************************************/* w: S: H- }+ l6 p4 m$ P7 C, e
  161. dmainit.DropTCPIPChecksumErrorFrame = ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE;
    . ^7 U, ~/ u- w/ v0 b+ M, Z2 m
  162. dmainit.ReceiveStoreForward = ETH_RECEIVESTOREFORWARD_ENABLE;
    # }) ~8 E9 f& }2 [
  163. dmainit.FlushReceivedFrame = ETH_FLUSHRECEIVEDFRAME_ENABLE;
    & g! K  g  h5 O# Z
  164. dmainit.TransmitStoreForward = ETH_TRANSMITSTOREFORWARD_ENABLE;/ g9 a5 _, z5 E3 G
  165. dmainit.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES;
    ( F" h9 ]2 q$ i
  166. dmainit.ForwardErrorFrames = ETH_FORWARDERRORFRAMES_DISABLE;# n3 _! q; N5 p5 H" w% C4 K/ d; v
  167. dmainit.ForwardUndersizedGoodFrames = ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE;
    - V: l$ i) v% ~" j' J3 D. k: {. K
  168. dmainit.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES;
    6 f' E3 F! \# r3 v! S/ K6 u
  169. dmainit.SecondFrameOperate = ETH_SECONDFRAMEOPERARTE_ENABLE;* M* s# C( p8 y8 R
  170. dmainit.AddressAlignedBeats = ETH_ADDRESSALIGNEDBEATS_ENABLE;' ^. `) L5 b  }' s3 Z! R: |3 A8 ~
  171. dmainit.FixedBurst = ETH_FIXEDBURST_ENABLE;
    1 \3 |% c6 b1 ?' S
  172. dmainit.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;( h- o8 V* ~3 u4 h4 O0 u
  173. dmainit.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;" J% r. i6 X5 o' M
  174. dmainit.EnhancedDescriptorFormat = ETH_DMAENHANCEDDESCRIPTOR_ENABLE;
    : k2 k% a' `) s  E1 B
  175. dmainit.DescriptorSkipLength = 0x0;. X" b' q8 _3 `1 {- r. H/ v! f8 ~
  176. dmainit.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1;
    ! Y2 ~& o* B$ x$ z8 c
  177. 2 J6 N" R6 R2 C" L5 y
  178. /* Get the ETHERNET DMAOMR value */
    , U, [8 F7 J0 D' n3 Z- i9 C
  179. tmpreg = (heth->Instance)->DMAOMR;1 v9 q8 ^& t* l; ?
  180. /* Clear xx bits */
      E6 E) T4 ?& L" E
  181. tmpreg &= ETH_DMAOMR_CLEAR_MASK;5 {- k0 @+ ?  I, `) \
  182. 5 I. H6 S( u2 t# O3 ~  i3 S; @
  183. /* Set the DT bit according to ETH DropTCPIPChecksumErrorFrame value */
    , Q" g1 J/ ^/ Y1 ^  S, D
  184. /* Set the RSF bit according to ETH ReceiveStoreForward value */* _# s0 L8 m  {2 ]9 z4 x# \
  185. /* Set the DFF bit according to ETH FlushReceivedFrame value */) O* B. L! C; \
  186. /* Set the TSF bit according to ETH TransmitStoreForward value */
    * ]5 ?7 `  v* ^- a
  187. /* Set the TTC bit according to ETH TransmitThresholdControl value *// I2 D5 m7 A$ O- m
  188. /* Set the FEF bit according to ETH ForwardErrorFrames value */
    ! _, j- M; u/ I. T8 p9 |  ?, S: ]
  189. /* Set the FUF bit according to ETH ForwardUndersizedGoodFrames value */) R  x7 H, d' g4 ]
  190. /* Set the RTC bit according to ETH ReceiveThresholdControl value */
    " n+ k) K) o4 u/ e
  191. /* Set the OSF bit according to ETH SecondFrameOperate value */
    " D( ~5 q$ O& [
  192. tmpreg |= (uint32_t)(dmainit.DropTCPIPChecksumErrorFrame |, ]' ^- U/ C8 }' r3 y4 `
  193.                      dmainit.ReceiveStoreForward |9 H7 q* h& Q$ s# g1 e
  194.                      dmainit.FlushReceivedFrame |5 Y5 @0 ~# F4 t+ N
  195.                      dmainit.TransmitStoreForward |
    5 W% a: T3 i* [* J1 @5 ?8 W
  196.                      dmainit.TransmitThresholdControl |
    ) }9 y4 R4 H# W  x* E% m
  197.                      dmainit.ForwardErrorFrames |
    & @( F" y; Q8 H7 G) @
  198.                      dmainit.ForwardUndersizedGoodFrames |
    & G' Q4 a& D$ @0 _6 _) t! u9 f
  199.                      dmainit.ReceiveThresholdControl |6 e% t  m1 \, v# W! N# r5 A+ G9 t
  200.                      dmainit.SecondFrameOperate);
    + m: U+ q! d: m5 A2 s
  201.   ]+ L* s3 P: u8 m6 g' c
  202. /* Write to ETHERNET DMAOMR */  [& d% S- F8 t& l. Q
  203. (heth->Instance)->DMAOMR = (uint32_t)tmpreg;# W6 h) U0 `9 u( N

  204. % m; ~2 M$ ~+ s: P$ I5 k8 m
  205. /* Wait until the write operation will be taken into account:
    5 [( x, q8 l2 t. ^/ C0 g
  206.    at least four TX_CLK/RX_CLK clock cycles */6 ^  z( O2 t3 y
  207. tmpreg = (heth->Instance)->DMAOMR;0 F* G/ v+ q5 S
  208. HAL_Delay(ETH_REG_WRITE_DELAY);) a3 A+ n% b- t- O! O& n/ P  V
  209. (heth->Instance)->DMAOMR = tmpreg;
    / M1 d0 A& g  q% S4 u8 O7 W

  210. 3 a) g; G- `9 _) }( h
  211. /*----------------------- ETHERNET DMABMR Configuration ------------------*// p! C# t1 @& S/ J- N  ?3 v) n
  212. /* Set the AAL bit according to ETH AddressAlignedBeats value */, e1 @8 u9 Q# s, e) n
  213. /* Set the FB bit according to ETH FixedBurst value */  n: e0 ^) D( S( u
  214. /* Set the RPBL and 4*PBL bits according to ETH RxDMABurstLength value */) j: t8 x, ~. W# s+ ?
  215. /* Set the PBL and 4*PBL bits according to ETH TxDMABurstLength value */+ S6 b* U% k  w; I
  216. /* Set the Enhanced DMA descriptors bit according to ETH EnhancedDescriptorFormat value*/
      J, e3 J. j9 J  _$ D7 o
  217. /* Set the DSL bit according to ETH DesciptorSkipLength value */$ P/ s9 D/ ^0 A
  218. /* Set the PR and DA bits according to ETH DMAArbitration value */: [* r" c+ ~, A9 z; P" o3 M
  219. (heth->Instance)->DMABMR = (uint32_t)(dmainit.AddressAlignedBeats |
    * t( I4 L; Y6 i9 B' y4 t( l
  220.                                       dmainit.FixedBurst |
    $ V0 J# ]5 E. Z- q# p- Y" M
  221.                                       dmainit.RxDMABurstLength |    /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */
    & Z* i/ o6 N# P2 ?
  222.                                       dmainit.TxDMABurstLength |, O" L0 W( b. N9 ^/ Y4 Z) i& X$ o
  223.                                       dmainit.EnhancedDescriptorFormat |
    ) T2 h; d' V/ J" v& t  e4 f
  224.                                       (dmainit.DescriptorSkipLength Instance)->DMABMR;
    8 H5 l) m* H6 J
  225. HAL_Delay(ETH_REG_WRITE_DELAY);& M* X2 h2 f# A9 @  A
  226. (heth->Instance)->DMABMR = tmpreg;
    - [" F$ B; R* }1 @
  227. 2 j# h& z' C/ j' o" E4 M) u
  228. if((heth->Init).RxMode == ETH_RXINTERRUPT_MODE)( K" F1 a3 k' }& o3 Y; p: k
  229. {* N. }; k8 Z+ T1 p
  230.    /* Enable the Ethernet Rx Interrupt */
    / t# a7 F' w' E9 v: _
  231.    __HAL_ETH_DMA_ENABLE_IT((heth), ETH_DMA_IT_NIS | ETH_DMA_IT_R);
    + q  B/ F- l: I' A' ?* V
  232. }& O* }+ D+ T) K- a) [/ @' n

  233. ' r6 i  i& H  V
  234. /* Initialize MAC address in ethernet MAC */
    6 F& B- N) }5 n" J$ z
  235. ETH_MACAddressConfig(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);$ p3 y) o9 e4 V# O4 d3 q
  236. }
复制代码
# ~" z+ _* n8 A9 W
这里我就要稍微吐槽一下HAL库了. H  m, N4 H2 @7 e
MAC层过滤的设置没有预留接口出来,有设置MAC地址的函数
: s4 H  p6 v3 J! i; x& K" d$ S" C" u! P
static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr)( X- ^' t% ^; k" H% |

& h% k) l  E' e* j9 n就不多做一个设置MAC层过滤的函数嘛,连后面用到的宏定义都有~~
7 S; s" q3 G. ~8 S' G3 Y* A! d8 J3 U& j3 l3 f8 J# o
木有办法,自己编一个初始化MAC层过滤的函数吧' T' x( {* g/ N  \" W% ~# X
) s: k# g/ p, B$ J  h
其实也就是把上面这个ETH_MACDMAConfig函数分离成两个单独的设置函数,再编一个设置MAC层过滤的函数
, r& U, v  O9 u/ }* j
, k- C. x6 N$ L4 i  ]' c( Q开启MAC层过滤的初始化代码

: p( H/ ?6 v  v: K  B# c* o9 U
  1. uint8_t ETH_MAC_Setting(ETH_HandleTypeDef *heth)! D/ v  R$ W; C4 T9 y" D
  2. {
    & K3 m1 p% v+ Y' j9 S8 d% H4 E* n
  3. ETH_MACInitTypeDef macinit;
    1 i1 L7 j$ T3 L+ v1 c+ @, X0 J! F
  4. /* Ethernet MAC default initialization **************************************/
    $ r3 R" k2 `. ]8 C' n; N9 F
  5. macinit.Watchdog = ETH_WATCHDOG_ENABLE;1 _  {$ F' J2 T/ b) h* _# ^+ ?
  6. macinit.Jabber = ETH_JABBER_ENABLE;
    : |! t4 @+ `; R% o2 I$ u1 E4 B
  7. macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;7 C! J3 u) y6 b1 f& b
  8. macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;' R4 c' `) X( z" d7 ^2 l; J
  9. macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;
    8 r- C- [2 m4 C' f
  10. macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;% m7 H( h2 {" Q4 V' P: G
  11. if (heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)
    & {  Y, N2 n3 @6 f: T0 E
  12. {; I" y4 j7 C0 Y5 @" |' A* p; Q
  13. macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;) J, m: a$ Y2 {8 G. R" C! ~
  14. }7 j* \+ M1 Y3 h6 ]! h
  15. else
    6 L! i( W' a! W4 O/ q  @. M: ?
  16. {
    2 B: u( [$ F# a4 W: y' d( H3 S' Y
  17. macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;
    5 a5 C5 c) }- L1 s* m* |+ l
  18. }) g, ~+ E: @0 B; Q' x& m
  19. macinit.RetryTransmission = ETH_RETRYTRANSMISSION_ENABLE;          //使能重传. `) j$ L* A' c
  20. macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_ENABLE;          //使能自动去除
    , a! ^4 ~% Y4 a5 v' Q, J% [
  21. macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;2 q7 W" k- B. l
  22. macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE;4 k" X$ t! [, e/ L/ `% k9 Z; `
  23. macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE; ///不接收所有包
    4 Y' N2 t: |5 h9 n3 a8 I; m- @2 t; `; l8 A& Y
  24. macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_NORMAL_ENABLE; //源地址过滤
    6 Q8 o3 }* t7 s, a' F* |
  25. macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;
    + q+ x# M# w/ k! L1 ?' ^( j/ W
  26. macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_DISABLE; //广播不接收
    & d4 U4 Z0 `1 T" _- P7 B' u0 o
  27. macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL; //目的地址过滤7 j1 q# ^, T8 B
  28. macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE; //混乱模式( c. z$ ^% H  k8 G$ ?# \, z& Y
  29. macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECT; //多播过滤
    8 ~$ s% [4 k2 a+ s
  30. macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT; //单播过滤6 z. v. C8 A; @9 n6 Q
  31. macinit.HashTableHigh = 0x0; //Hash表高位2 R% n1 T) B0 [4 f' p* [- q" m5 B
  32. macinit.HashTableLow = 0x0; //Hash表低位
    : E9 [1 q" A7 X" M, `6 _
  33. macinit.PauseTime = 0x0;; M4 N6 O8 ^1 f6 ]- |5 G8 f
  34. macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;
    . E- s9 K+ G" _* k
  35. macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;
    , R/ b" c6 m, c: A% ]
  36. macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_ENABLE;  S1 |. Z5 k, p5 `  c, R  y% k
  37. macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE; //接收流控
    ( V9 j2 d, ]: y! Q) ^* f
  38. macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE; //发送流控9 T, b* w3 x; Q/ r' v) ?1 Y5 @
  39. macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;
    5 J8 ?$ A) n7 H; F% t
  40. macinit.VLANTagIdentifier = 0x0;
    % ]  D5 m2 S) L6 m0 [

  41. + M' m- [' w+ U) Y( R7 B
  42. return HAL_ETH_ConfigMAC(heth, &macinit);
    # O2 p. H1 E. A( S6 B3 o9 Z4 S! f
  43. }
复制代码

- F/ W" t9 z( B4 S( ]默认的MAC层 DMA初始化函数. \' C) H' g! X& L) V# V: v
  1. uint8_t ETH_DMA_Setting(ETH_HandleTypeDef *heth)- d; ?( ^6 M6 Y( i; r
  2. {
    / E( e* U  Z) @. s# U
  3. ETH_DMAInitTypeDef dmainit;4 V, ?" K9 z- S  D0 l. x) ]' I
  4. /* Ethernet DMA default initialization ************************************/. [/ |; Q! o( U' f" r- o
  5. dmainit.DropTCPIPChecksumErrorFrame = ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE;  M- G- T0 y* G0 G& |" M1 O' t- P/ j
  6. dmainit.ReceiveStoreForward = ETH_RECEIVESTOREFORWARD_ENABLE;
    ) r* d: k' \' }  w: K7 x4 `, c/ n
  7. dmainit.FlushReceivedFrame = ETH_FLUSHRECEIVEDFRAME_ENABLE;8 H+ f! [$ T; h1 i
  8. dmainit.TransmitStoreForward = ETH_TRANSMITSTOREFORWARD_ENABLE;
    0 ^$ w! `6 o1 S8 P
  9. dmainit.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES;9 X9 B" W# ?9 f; z) U' l
  10. dmainit.ForwardErrorFrames = ETH_FORWARDERRORFRAMES_DISABLE;
    0 Q" Z/ U' v+ d+ u" o1 H# D
  11. dmainit.ForwardUndersizedGoodFrames = ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE;
    8 C% y. `3 g# J; ?. D
  12. dmainit.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES;
    ) E2 m/ t/ ^. M9 B5 e2 Q5 v7 r4 g- ^4 J
  13. dmainit.SecondFrameOperate = ETH_SECONDFRAMEOPERARTE_ENABLE;! Y& `: u6 ]9 P- m9 J6 V! V
  14. dmainit.AddressAlignedBeats = ETH_ADDRESSALIGNEDBEATS_ENABLE;& f; ~$ K1 ]( J) \# o% j; ?/ O
  15. dmainit.FixedBurst = ETH_FIXEDBURST_ENABLE;$ X8 ^+ n6 q/ r  |6 u! x1 v% y
  16. dmainit.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;. ~" }$ m0 `% u- l. n) N* }
  17. dmainit.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;
    * ?5 m. ^( t- f* B
  18. dmainit.EnhancedDescriptorFormat = ETH_DMAENHANCEDDESCRIPTOR_ENABLE;3 w( @" _1 t3 |; H
  19. dmainit.DescriptorSkipLength = 0x0;- _/ x  ~2 W, g6 Q
  20. dmainit.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1;" o7 E; Z2 a8 l  R; I* ?3 N
  21. uint8_t res =  HAL_ETH_ConfigDMA(heth, &dmainit);
    9 N9 r9 N: \) P6 [
  22. if ((heth->Init).RxMode == ETH_RXINTERRUPT_MODE)
    " z; n/ E2 l5 p+ _6 _
  23. {5 s4 b6 K) v. M1 a7 a- L, I
  24. /* Enable the Ethernet Rx Interrupt */% g4 d  v4 j9 x
  25. __HAL_ETH_DMA_ENABLE_IT((heth), ETH_DMA_IT_NIS | ETH_DMA_IT_R);
    & X( y7 h/ R" r4 y# ]4 @% h, V0 j
  26. }, u0 m( r6 D5 c9 \
  27. return res;
    $ L2 i# {4 o. [1 j) ^4 ~
  28. }
复制代码
0 f& O& r0 X+ W
用来设置MAC地址的函数(其实就是把库函数的static函数取出来直接用了)
  1. <blockquote>//heth: HAL句柄
复制代码
0 ]7 F( ], O( Y7 ~8 T( r; \( S* c
然后到最最重要的MAC层过滤设置
) A+ j6 r; q  h0 g7 t
以MAC1为例
. [' t# x( h" j7 ~) p% r# c
( e+ g2 G' j3 w0 m
20191124093921254.png

7 ~$ Z: E# k1 q* c0 M& M8 u# G/ m1 v* E5 z: [: d
20191124094439199.png
" ~( q; X- X! |+ |! @8 }" Z
9 C4 j4 Z. w: w) \
注意看红框的描述
% ~8 i2 W' z  J4 s! T1 I
功能很好用,可以过滤源地址/目的地址,还可以做掩码功能5 Y1 w* q, a' Y9 Q/ |% x* x
设置MAC层过滤的代码
2 g1 h8 w2 r* J* ?: I( V
  1. static void ETH_MAC_Filter_Setting(ETH_HandleTypeDef *heth,ST_ETH_PAR * para)0 U! h: |" P& P- r/ ]" v- e
  2. {: q3 y  E0 p. r) @
  3.     //设置本机MAC地址5 W1 {2 a( j% I3 `0 e; j
  4.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);0 M" U% z9 ?6 V, R$ D3 u
  5.     //设置UDP-A的对方MAC地址
      S; M1 P1 P8 P: D* U& m
  6.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS1,para->UDP_A_MAC);" v; y* b9 Z, S. H) y# A* e1 b
  7.     (heth->Instance)->MACA1HR|=0xC0000000;//需要完全匹配UDP-A的对方MAC才接收' v& I! {" R, d
  8.     //设置UDP-B的对方MAC地址7 E+ k" D0 @9 K8 I
  9.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS2,para->UDP_B_MAC);' O& U* C. Y: q+ f& ?. E, v) E. V
  10.     (heth->Instance)->MACA2HR|=0xC0000000;//需要完全匹配UDP-A的对方MAC才接收
    ' L+ V  j9 ~2 L' z4 _
  11. }
复制代码
' q8 F, z( O1 [) H
我这里是希望为我的两个UDP精确过滤接收到的源地址
3 U8 w2 z& `: ?7 _# }9 e' K所以AE位设置为1,SA设置为1,MBC全部为0(MAC地址全部检查)3 n3 h. Z/ M' j

5 A' y" Z: ]2 ~假如我希望过滤MAC中特定的厂家字段" _+ Q8 T9 ~+ P0 q8 ?; z
例如某个MAC地址

" L2 r+ h5 `$ ?# A- I) ~01-02-03-04-05-067 K* T4 y  p8 E. R; D
其中01-02-03就是厂家字段' p/ |/ c6 X5 {& d2 f

8 y. J& g5 O2 f8 |& n5 w那么代码要这样修改(MBC的第29位,28位,27位置1)
% M5 {9 R! T% S# V" B  ]这样MAC层就不会检查MAC地址里后3个字节(04-05-06)
% I: c4 n8 K* R4 a6 E但是会检查前3个字节,也就是厂家字段
. h$ o- x& l6 I. E; n这里需要注意MAC地址的字节序- `6 J& ~% m8 `' L  ~4 G! M1 S) E
  1. static void ETH_MAC_Filter_Setting(ETH_HandleTypeDef *heth,ST_ETH_PAR * para)
    3 S% x$ c8 K. a: n# v1 R
  2. {
    ! l, f( z: |. [; ?0 g$ a" f" M
  3.     //设置本机MAC地址
    * V/ [5 m. \% l3 h6 t/ q
  4.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);
    4 ?' w! k4 u, n! `; `4 }( P
  5.     //设置UDP-A的对方MAC地址. ~% i* Z: {. S2 P8 Y
  6.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS1,para->UDP_A_MAC);
    2 |# P" H  O! R* C# `: ?* s3 r4 [
  7.     (heth->Instance)->MACA1HR|=0xF8000000;//需要匹配厂家字段
    / T# t. k; `- t) P$ a
  8.     //设置UDP-B的对方MAC地址/ S' p' f, e4 A% y$ V- i
  9.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS2,para->UDP_B_MAC);
    : }' k! V, u7 t; m  {6 u
  10.     (heth->Instance)->MACA2HR|=0xF8000000;//需要匹配厂家字段7 E4 T7 @% W) A% P3 U( W( f, b
  11. }
复制代码
( Y2 i6 @* }; V: L& H
然后这些函数的调用顺序按:
" S1 l+ @8 W' u) @: x/ A1. HAL_ETH_Init
( Z# E, @- u0 X6 C+ K! U7 Z) C2. ETH_MAC_Setting( H$ {; e9 U% l! @
3. ETH_DMA_Setting7 C- W; |5 V; P. p7 M
4. ETH_MAC_Filter_Setting6 `4 `, m, q9 `! L1 [8 S, d( X
# L& b6 m. h6 N7 v) P
用你希望过滤的MAC传递到一个Hash计算函数里,得到一个值,通过这个值产生“映射”关系来过滤MAC地址,所以这个并不是精确的,因为可能会重复~~
7 {: y9 N" V' i* H  a7 ~& t% C7 G4 X( B) @' O
HASH函数
' l7 j, \$ l$ J! j* ~* N4 f函数
) V9 ^' C" |' g* N
  1. / STM32 MACHASH - Copyright (C) 2014-2018 Clive Turvey (<a href="mailto:sourcer32@gmail.com">sourcer32@gmail.com</a>)
    7 t; U2 ]  _- ^/ f5 @* d
  2. //  All Rights Reserved
    / D7 A( {+ J' `0 t: p

  3. 7 d% v  T' B/ F4 Z
  4. #include <windows.h>0 d% X- u9 v* j0 L# y1 b

  5. 7 F5 Y7 m7 q: i  B
  6. #include <stdio.h>0 s  n" h; c8 p# }. w) ^
  7. #include <stdlib.h>! x9 x, S  |/ v( |
  8. ; Q  F% I9 i1 T* u/ y) ^; d- ]/ ~
  9. typedef unsigned char uint8_t;
    ! S* ?3 X' |8 |
  10. typedef unsigned long uint32_t;
    ' \) U. B1 n( K

  11. - @# r$ D8 L" N4 E6 b) W
  12. uint32_t Rev32(uint32_t x)  R: l' S" G, r, m4 ?0 N0 D
  13. {7 ^6 d) F1 d0 k# ~& D6 p1 S
  14.   uint32_t y;1 E2 R) t, R$ r0 b0 N' ?8 I( O
  15.   int i;- ?4 W# W& N, P; D  g4 ^4 X7 l

  16. " Z1 d. W) F4 J/ S1 f
  17.   y = 0;5 V1 d2 B) |6 l! B" W3 I- f
  18. 9 R$ Q2 I  E9 f9 z5 l3 t! a
  19.   for(i=0; i<32; i++)! N: T& f$ n4 E1 `' u! b+ q: j
  20.     if (x & (1 << i))0 o* Q. ~0 l! ~& X* \  @0 v$ P* \
  21.       y |= 1 << (31 - i);+ y+ ~- P/ x' f3 D
  22. * q! }$ Y7 c$ \% C1 e8 e
  23.   return(y);2 X8 k8 g: T3 R2 y4 M, |
  24. }
    ; K. q9 Q* W. ^1 G* z& I8 z# e2 J% l

  25. : c- T) Y% ^7 z
  26. uint32_t MacHash(const uint8_t *Mac) // <a href="mailto:sourcer32@gmail.com">sourcer32@gmail.com</a>5 j  c/ U: C0 T$ ?( y+ }
  27. {7 o" }6 W5 K( X# E
  28.   int i, j;# @% X; @5 N: j; `$ F
  29.   uint32_t Crc;
      z! ^9 W: _  V

  30.   k% [/ W/ T& j: h) Z4 [
  31.   Crc = 0xFFFFFFFF;
    1 h( q  L" g7 y

  32. + |' o2 ^8 w* k( \: U- U0 `& m, f
  33.   for(j=0; j<6; j++)1 E% ~9 ^- V0 W( H0 ]6 I) N
  34.   {) l  f) o( H* L- K; r. R3 O
  35.     Crc = Crc ^ (uint32_t)Mac[j];* V2 [' D# {* y- `

  36. + H) T& }1 B, O9 P/ ~% |6 f
  37.     for(i=0; i<8; i++)8 j7 p9 }  ?1 s; Y
  38.       if (Crc & 1)
    $ Y2 P7 r/ {2 }
  39.         Crc = (Crc >> 1) ^ 0xEDB88320; // Reversed 0x04C11DB7
      K% ^$ E/ K  C2 n5 `- N3 v
  40.       else
    ! z4 m9 T. w) W- |; M
  41.         Crc = (Crc >> 1);
    ; k6 K4 ~4 V* ]* T& m  v# z; i
  42.   }9 T% k; c' K- d
  43. % I4 J. u! Y! S. |+ C# a
  44.   return(Rev32(~Crc) >> 26); // Get High order 6-bit in reversed/inverted CRC4 `8 `; B0 ~+ b5 L+ w# b: W" G
  45. }
    7 L; x/ `( V" i, }7 A% A
  46. & b. H$ N4 `( u% H
  47. uint32_t MacHashFast(const uint8_t *Mac) // <a href="mailto:sourcer32@gmail.com">sourcer32@gmail.com</a>7 J9 \5 ]. L4 m- N* K" h
  48. {
    : ~) P) v$ Z' G
  49.   static const uint32_t Rev6Tbl[] = {
    7 x$ o& e8 B$ `% O; ]
  50.     0x00,0x20,0x10,0x30,0x08,0x28,0x18,0x38,
    7 [5 |4 h7 J3 ~: F9 Y
  51.     0x04,0x24,0x14,0x34,0x0C,0x2C,0x1C,0x3C,9 f- s# R, p* F* ]( f
  52.     0x02,0x22,0x12,0x32,0x0A,0x2A,0x1A,0x3A,/ U) v. ?5 u  [8 b3 t
  53.     0x06,0x26,0x16,0x36,0x0E,0x2E,0x1E,0x3E,
    5 L5 G0 {; }- f' Q7 r5 i0 R! Z6 X6 L1 ~
  54.     0x01,0x21,0x11,0x31,0x09,0x29,0x19,0x39,- d6 P5 y3 Z- x+ L  i, F
  55.     0x05,0x25,0x15,0x35,0x0D,0x2D,0x1D,0x3D,
    2 E3 }$ `3 M/ m
  56.     0x03,0x23,0x13,0x33,0x0B,0x2B,0x1B,0x3B,
    / b3 m* `0 z% j% S
  57.     0x07,0x27,0x17,0x37,0x0F,0x2F,0x1F,0x3F };! p2 a" z& p; D# h
  58. 3 h' a9 n! D  ^* \0 o& n  X1 y
  59.   static const uint32_t Crc32Tbl[] = {+ l; V1 N$ O$ T( J' X: x
  60.     0x4DBDF21C, 0x500AE278, 0x76D3D2D4, 0x6B64C2B0,
      C% l. s" V/ Y; U* t
  61.     0x3B61B38C, 0x26D6A3E8, 0x000F9344, 0x1DB88320,
    + ?8 ?& z: @5 E
  62.     0xA005713C, 0xBDB26158, 0x9B6B51F4, 0x86DC4190,
    2 h1 U" ^) i# N2 t
  63.     0xD6D930AC, 0xCB6E20C8, 0xEDB71064, 0xF0000000 };
    % P% s, h  z( p4 [

  64. 3 s% B8 n5 p- X0 r# g0 K+ L8 h3 u% J9 s: I
  65.   int i;7 v( e& z$ ^- _4 h1 ^2 U
  66.   uint32_t Crc;$ i6 [$ I1 {  A. ?0 p$ {9 w

  67. 6 ~; Q' S9 m& G5 ]9 L3 {+ M; C
  68.   Crc = 0;
    & D" l5 q1 ~6 j2 u3 u! _
  69. ! u2 V' K9 d: {& r0 b; J
  70.   for(i=0; i<6; i++)" o- i3 c3 D6 ?, {, ~
  71.   {
    $ }# o# c+ I! \, A2 I9 Q
  72.     Crc = Crc ^ (uint32_t)Mac<i>;0 C- F1 X* e; S5 O" i

  73. # f( O  N& G0 R# i, X
  74. </i>   Crc = (Crc >> 4) ^ Crc32Tbl[Crc & 0x0F];  /* lower nibble */6 H" b0 Y* J- a& ]. F* |6 U
  75.     Crc = (Crc >> 4) ^ Crc32Tbl[Crc & 0x0F];  /* upper nibble */
    " ^8 V3 A+ p: o0 g( f  `: w
  76.   }& t0 [* {* o8 V. ~6 ]0 R

  77. 4 `( u4 W. K2 W# v' O9 b$ X! G
  78.   return(Rev6Tbl[Crc & 0x3F]);
    6 v8 E: ^# f4 Q5 L* W" s
  79. }
    2 M  g1 g4 c; ?  j5 x/ O

  80. & v/ v6 ]) D3 c. H
  81. int main(int argc, char **argv)( `% n* G/ @) l5 W
  82. {
    ; e) f! e- m' x9 |8 n
  83.   static const uint8_t Test1[] = { 0x1F, 0x52, 0x41, 0x9C, 0xB6, 0xAF }; // 0x2C
    ' q7 m- k6 k) o0 q! C- Q
  84.   static const uint8_t Test2[] = { 0xA0, 0x0A, 0x98, 0x00, 0x00, 0x45 }; // 0x07* T; Z/ E/ m" V% q$ d3 ^4 I
  85.   static const uint8_t Test3[] = { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x21 }; // 0x241 X! I- F' Q! ^* S
  86. . V1 U' J+ Z. b) L6 f
  87.   printf("MacHash %02X\n", MacHash(Test1));
    : h' o4 X& r# L# V1 ?
  88.   printf("MacHash %02X\n", MacHash(Test2));2 S) v+ x+ {. E, M- g4 U
  89.   printf("MacHash %02X\n", MacHash(Test3));
    % a. }# O' r" l) U$ z- m* o% e. f4 |

  90. " h. ]  T5 s. A' a* e- X
  91.   printf("MacHashFast %02X\n", MacHashFast(Test1));
    $ L  p$ q2 B3 u  R. W4 ?- u
  92.   printf("MacHashFast %02X\n", MacHashFast(Test2));7 }) x6 d% ^5 w+ X
  93.   printf("MacHashFast %02X\n", MacHashFast(Test3));
    4 V* L7 J9 g" m9 Y! d& R& l: T
  94. / _/ J: H1 v) m7 Y
  95.   return(1);8 t6 w7 p5 |0 ?: {; p
  96. }
复制代码
- D& E0 V/ z  W! H2 t( @# f

/ q9 l% u  T4 S" D: V4 H回到手册" [+ {- v2 W# M0 F" c) Z
6 T# ^- p' F2 C: ^6 Q$ K  [
20191124100604140.png

9 y2 I; c* ~& r% K1 \
6 c- H  Q( d' Q4 P4 z# Q
20191124100636882.png
# k2 J- w& N5 b
2 c/ {$ b% a: t
8 M, ~9 |) q- ]2 d! Q* k( f
上面的函数算出来一个数,假如是手册上的那个0x2c,二进制为101100B, q+ Z9 X* y* ]
换句看得懂的人话···就是:
1 a3 g& @( K1 j4 c  e, H算出来的数先看第6位
( U5 ~" r5 B2 S8 e+ K是1的话说明用到的是HASH表高位寄存器' v# A/ A7 w1 l+ |* W: Q' G, c& r
否则用到的是HASH表低位寄存器
" E2 }. j  \/ i然后剩下的5位,转成十进制不是12嘛, w" m- e; w2 R; q. p
如果你希望过滤这个MAC' I/ F; U* e$ s1 d4 [$ ^
那么你就把对应的HASH表高/低位寄存器的对应位置1,否则置00 y: R$ u$ V) y0 h$ G
这里的0x2c就是要把+ p+ q0 f# R* M% u
HASH表高位寄存器的第12位置1
  w* e5 m. D; k  V2 u就可以过滤这条MAC了' y6 ?6 `5 _% i9 p4 k" |# r2 Q! |# C2 B
然后把你希望的MAC地址都按照上面说的方法弄完3 T+ w" F" l/ K  n; S& x

+ I  M1 p5 Y1 |# y. O回到这个函数稍微改一下
8 b- H) K: j) _0 F. M
  1. uint8_t ETH_MAC_Setting(ETH_HandleTypeDef *heth): |- K( b  \, i! O7 z1 k
  2. {
    : V. ~. a% ?; @& Q$ F0 G4 z
  3.     ETH_MACInitTypeDef macinit;- ~. A1 J( V7 n0 x
  4.     /* Ethernet MAC default initialization **************************************/; ^% U6 t- Q7 |5 N- l
  5.     macinit.Watchdog = ETH_WATCHDOG_ENABLE;
    ' }% Y9 w+ }  \9 t0 Z- ^
  6.     macinit.Jabber = ETH_JABBER_ENABLE;) t6 O# \, K) J: r! A5 D! u8 s4 v
  7.     macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;/ m9 u, o4 e2 A) h
  8.     macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;  x. [( `3 C9 c' u
  9.     macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;8 H' Z7 r, S4 s* R: ~' r. T
  10.     macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;3 l1 _" V/ U7 |! X- u% J
  11.     if (heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)
    8 K% f# A' ]6 W: U# D! o. k
  12.     {" B# `& t: l& q$ ]& _7 H
  13.         macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;5 }9 f) S3 P( p  \7 Q& w
  14.     }/ U7 |/ }2 ]9 u! L
  15.     else3 Q; [0 o. t. S5 z  z% U
  16.     {3 k2 B& q$ Q9 y. |9 R# L
  17.         macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;" a/ }; g: l4 ?8 N$ t/ U% S$ s
  18.     }
    3 p1 K3 @: A6 A
  19.     macinit.RetryTransmission = ETH_RETRYTRANSMISSION_ENABLE;          //使能重传8 |, ^4 j4 Y2 d: g% F" l; ?
  20.     macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_ENABLE;          //使能自动去除" G) F/ T7 k* x
  21.     macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;
    & B1 E; h  U, ?7 X& I" h
  22.     macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE;( R6 t! e0 L, i; i8 ^2 v
  23.     macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE; ///不接收所有包
    4 d- g0 W& F7 P+ E3 \
  24.     macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_NORMAL_ENABLE; //源地址过滤  o$ ?; a2 Z% j0 {2 Z" [$ P
  25.     macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;
    + I) z$ k! g3 b0 e6 C  H
  26.     macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_DISABLE; //广播不接收
    3 d& O4 d; q0 V" n% r" D
  27.     macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL; //目的地址过滤5 Y- x% j' K8 }. b6 N* p) {8 A
  28.     macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE; //混乱模式
    % x+ r( g+ \; }9 G& I- p- C
  29.     macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECTHASHTABLE; //!!多播HASH完美过滤% Q' i6 b% o( ?& `
  30.     macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECTHASHTABLE; //!!单播HASH完美过滤
    - u4 B5 V, m% u3 e" V3 c# z8 T# Y
  31.     macinit.HashTableHigh = 0x0; //!!填你最后算完的Hash表高位& ?( ^. r2 F2 z. n! P6 H
  32.     macinit.HashTableLow = 0x0; //!!填你最后算完的Hash表低位
    ) D( Y" f% G5 A3 B) f
  33.     macinit.PauseTime = 0x0;" X$ T8 T8 t5 @+ ~( I9 p+ U
  34.     macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;1 p4 Z0 t/ K: s6 X( K
  35.     macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;
    3 r; h0 D# s  n
  36.     macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_ENABLE;. g+ @( _- f) Q: o" U; O( }
  37.     macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE; //接收流控
    % _  M2 s4 i* V9 I! v3 m* H3 h7 s
  38.     macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE; //发送流控
    # C+ i% F) M) e  o
  39.     macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;
    * l7 K# Q/ I" m! W4 r% q- y
  40.     macinit.VLANTagIdentifier = 0x0;; o% j' b5 `; S) y. h# c

  41. ; N6 k# |5 X' Y9 [9 ?. Y) g6 h
  42.     return HAL_ETH_ConfigMAC(heth, &macinit);) z1 S" i9 v) e8 r! W- \9 G
  43. }
复制代码

$ e# v, X& Q: Y+ a* u4 I大概MAC层过滤就这些东西了, H* z) y7 j2 K& p* b2 r
如果有条件弄MAC层过滤真的强烈建议开启,可以大幅减轻协议栈的处理负担,板卡不会因为处理大量无用的数据而白白浪费处理性能。
* q2 Z$ F4 f. R- j
/ ^; `6 o! [# M
' c, L) e6 I' l# Q& t- h
- Q! H; A5 o6 m, T2 e4 Q; o8 q; v/ P; y1 j. |
收藏 评论0 发布时间:2021-12-14 10:15

举报

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