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

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

[复制链接]
STMCU小助手 发布时间:2021-12-14 10:15
前景描述
6 n  L+ r8 s3 E" H3 T% L, x我司的以太网实现是LAN8720搭配片上MAC层做的,协议栈用LWIP
! @  E/ n/ R+ d' f0 [* g; o6 B8 S% [) l  u9 U# ^" f
这种做法应该还是蛮常见的,反正不是LAN8720就是DP83864,再不然就是硬件协议栈的W5500了
8 C# F" o- P& A; |- g/ \
+ I4 R5 j) D2 K2 J8 Q+ I$ w1 A( q+ ]想想还是有MAC层过滤比较好,随手翻了翻它的手册,W5500好像是没得MAC层过滤的6 P7 E; \' `) `" Z6 ^) l

5 r" v; i8 p) t! q假如数据速率比较高,数据量大,而且外面还有乱七八糟无关的数据往板卡送,我也不知道用这个片子到底好不好
7 F" Q$ }) u; A, J/ |( Y% p% A+ m: [( O! B  t3 p- c3 w
LAN8720也不好改了,就继续用吧
5 l* a% q5 p4 v: C. q8 s) a" Q: M: C* x, Q0 ?
好好在,发给板卡的数据的MAC还是有特征的,我只需要过滤发送方MAC地址的前3个字节,也就是特定的厂家那段
2 L/ M1 [, f8 _( p4 U/ k9 l3 W, P; p3 u" q. Z
MAC地址的科普知识这里就不过多描述了,我们直奔主题
# m0 p' K0 O) g& B* I
6 L) R! ]8 q+ I7 U怎么用STM32 F7的片上MAC做MAC层过滤
, M# u; h4 A/ H; o6 W; z3 E$ e' X6 `$ f  S
写这个的目的,就是我搜了搜,没看见有人写这个MAC层过滤功能,具体代码怎么写才能用' |- s; ^/ A5 e( K; V: }

7 z4 M% K- d# t) K7 A知识科普-STM32的片上MAC
& s" g7 W2 R# S# P' b1 B% bSTM32 F7的MAC层过滤方式有三种(说人话的直白解释,中文手册其实也翻译的不好)
% Z0 {) I& D' l5 \精确过滤(手册上叫单播目标/源地址过滤)! H: f8 m" a7 F3 z
粗糙过滤(手册上叫Hash表过滤)! L9 w# k4 n6 |
特殊过滤(广播,组播过滤等等特殊的过滤)
* D% P; z* Y9 Q  J, _) [7 P& C我这里着重说第1种和第3种% u" G/ ?! r: w
  ~7 H/ s3 C4 U  g+ Q$ m& W
STM32 F7可以存4个MAC地址
/ J6 z2 g( r. _; ]5 y6 J- Z( l其中MAC地址0是自己的MAC,其他三个可以用来做过滤$ j/ W( z! g9 c0 h
' E" J' u- t9 O: W, i) I! R6 a
网络数据包通过PHY进入STM32的MAC,MAC层是可以对目的地址/源地址检查并过滤掉没得用的数据的,默认的HAL库库函数HAL_ETH_Init中
2 M1 P0 O8 W" Q  o有一个static的函数
! d, r0 O; t7 g0 `  ]0 V9 U, astatic void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err); K# J) g  j( P0 j* `
会帮你在初始化网络功能时初始化默认的MAC层功能:/ e9 ?. v3 e( X4 S; Z+ v6 D# n
关闭源地址过滤
* A# z: |- }7 M不接收所有数据
& O" @) i/ B% I. g# Y接收广播帧
' N2 ^# O& q4 d1 H6 t7 B5 k3 f打开目的地地址过滤; s& l& O4 V3 o8 x1 V
单播数据精确过滤- _3 n& w$ M( z* X& G: W
组播数据精确过滤
1 A. w: j2 m/ \Hash表过滤关闭
  w' u7 C% U0 \
6 n+ R# ]- u6 A+ i7 |6 d% i+ j其他的功能自行研究,我这里捡重要的说
; c, o) q0 ~& d& a6 z- Q7 q9 \
  1. static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err)
    $ q# b# l. H7 x/ O9 C
  2. {* z, i5 Y3 _' f
  3. ETH_MACInitTypeDef macinit;" M5 [+ t, o# R! h( z# n
  4. ETH_DMAInitTypeDef dmainit;
    ! R: k- U* S4 o8 Y  m
  5. uint32_t tmpreg = 0;" t  U$ A  J; J- @: a

  6. & o+ P; a3 G" e' I) \6 D: K5 E
  7. if (err != ETH_SUCCESS) /* Auto-negotiation failed */$ H: W8 Z9 w% n0 v& ^) [. l0 I
  8. {
    / E0 L: b/ I8 y
  9. /* Set Ethernet duplex mode to Full-duplex */
    % f# E& s' ]* n6 ]& @7 m; X( n, U
  10. (heth->Init).DuplexMode = ETH_MODE_FULLDUPLEX;: D  T0 l$ ]# a% Y( y- u
  11. ) L; X+ l% z. ^- T, P+ x1 q
  12. /* Set Ethernet speed to 100M */
    " U8 f: a. x/ {' o! ^2 m
  13. (heth->Init).Speed = ETH_SPEED_100M;2 r. Y& m. B' T/ F) ~* q5 Y# U- v% _
  14. }
    " ?. H# e) @* j+ j' N

  15. 2 i9 Z: K% i! r! ?  T
  16. /* Ethernet MAC default initialization **************************************/
    $ j( K% ^8 Z, i( Q9 D& Q. ?" [& c
  17. macinit.Watchdog = ETH_WATCHDOG_ENABLE;1 P! q8 ]" F0 F" }* _/ ]
  18. macinit.Jabber = ETH_JABBER_ENABLE;
    : a" f" V3 [% c# K  D
  19. macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;
    8 A' q9 d6 s+ e5 e4 {
  20. macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;
    # T1 J0 E; D% H- L. h
  21. macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;
    , Y8 }; N' l4 q3 _  H' W* F) P
  22. macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;
    1 J( S$ A& H% x4 t  c5 X3 U; q
  23. if(heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)
    , k5 c, u; _# C7 L3 r( L
  24. {1 d$ X. I8 H$ @1 s
  25. macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;) `# O! K8 \5 c/ Q: i! H
  26. }
    5 t# e7 Q$ Y1 ?  z1 T
  27. else
    1 _2 `$ W! N4 h8 M+ G
  28. {
    7 Y$ b+ f( y6 ~! [
  29. macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;# l8 K" |( |$ F; C
  30. }
    # @4 r& ?, F6 H3 i) e
  31. //这一段是MAC层过滤的设置,下面是DMA的,那个用默认的就可以
    % V8 l% S. h0 t8 ~9 K: w6 a# _3 r
  32. macinit.RetryTransmission = ETH_RETRYTRANSMISSION_DISABLE;! e# @+ C: H2 f8 Y8 ]
  33. macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_DISABLE;
    . K; c" \  y5 h7 Y+ j
  34. macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;" J3 j6 {) {+ I; a+ b; r1 L
  35. macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE;/ Z7 u4 b* v* y) U
  36. macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE;+ H% A% N; s9 t$ [, ^
  37. macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_DISABLE;
    ( E3 D# n0 G8 U  x# _$ i
  38. macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;
    3 `. d, d6 C  |# L1 F7 t' s# \
  39. macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_ENABLE;
    ) z$ k2 A+ o6 ~1 }$ L
  40. macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL;% h5 i" q# R4 W9 q* ?" i
  41. macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE;
    . B$ E' t) x, B+ ~) y# ~) b
  42. macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECT;
      B5 a/ }) }- I; n8 a% G
  43. macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT;
    9 z! F& o7 [( @3 Q& p' i$ G# ^
  44. macinit.HashTableHigh = 0x0;
    " R* A) q  c- C7 ~! ?
  45. macinit.HashTableLow = 0x0;! u3 V$ ~# \. a( r' {
  46. macinit.PauseTime = 0x0;! }% C4 F/ J2 u/ i/ E! V6 f
  47. macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;
    / B9 t# Q! s8 `" ^! @7 N. b
  48. macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;
    , b, J7 @2 x# f# ^% \
  49. macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_DISABLE;
    7 F2 ]" l, a  [3 v, P
  50. macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE;
    , X4 |5 Q2 Z$ u6 @+ s
  51. macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE;1 [" L2 |" a2 Q/ w& n8 F' w4 X
  52. macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;
    2 ]  v; ?+ c" C" q- k0 H# [
  53. macinit.VLANTagIdentifier = 0x0;
    5 E, Z) E( h; U+ t& ~

  54. ' u7 K% Y2 ^; W
  55. /*------------------------ ETHERNET MACCR Configuration --------------------*/
    " q. W) J9 c& `4 Z9 F$ r: E/ Z, E
  56. /* Get the ETHERNET MACCR value */
    7 z& L+ j- b% S6 Z& q
  57. tmpreg = (heth->Instance)->MACCR;
    0 k1 I9 @5 F" B3 A) H
  58. /* Clear WD, PCE, PS, TE and RE bits */2 U/ P) K% f' ^( \$ `$ d
  59. tmpreg &= ETH_MACCR_CLEAR_MASK;, H% m9 d6 `: Y+ r  X' X! O
  60. /* Set the WD bit according to ETH Watchdog value */) w" E7 n9 ]- `
  61. /* Set the JD: bit according to ETH Jabber value */
    / W8 t7 O$ M3 E9 E* i4 D2 ^
  62. /* Set the IFG bit according to ETH InterFrameGap value */& G) e' ^6 X- L- r1 k6 t
  63. /* Set the DCRS bit according to ETH CarrierSense value */4 V( v/ T4 z( j7 ?+ B- m* @! t
  64. /* Set the FES bit according to ETH Speed value */
    % _5 Q. F. T! Y6 ^# d
  65. /* Set the DO bit according to ETH ReceiveOwn value */9 g- C' U3 G5 m  e- k; m2 S3 B
  66. /* Set the LM bit according to ETH LoopbackMode value */2 }- X3 J# J$ H& R* X+ O
  67. /* Set the DM bit according to ETH Mode value */3 g2 i( }8 I0 L! u  ^4 r. m: r4 g
  68. /* Set the IPCO bit according to ETH ChecksumOffload value */$ b6 y# ]1 F" Y. G2 Q6 m) Q  V' }
  69. /* Set the DR bit according to ETH RetryTransmission value */4 \- o: l* @4 F
  70. /* Set the ACS bit according to ETH AutomaticPadCRCStrip value */
    * G% J* e) f' H" C! Q5 Y9 W( M* E
  71. /* Set the BL bit according to ETH BackOffLimit value */; f6 Z* C  k( w
  72. /* Set the DC bit according to ETH DeferralCheck value */
    ) t; h& s" t2 j- H9 W
  73. tmpreg |= (uint32_t)(macinit.Watchdog |7 h9 A$ N7 k  \! {8 R9 n0 F
  74. macinit.Jabber |
    3 p8 ^& V9 G* j4 C4 ?( n
  75. macinit.InterFrameGap |
    7 d1 g7 Y, B% x6 J
  76. macinit.CarrierSense |1 N1 m/ k) E2 S- O7 Z% i$ ]
  77. (heth->Init).Speed |
    " V7 h  S( v3 y& D) a3 ?
  78. macinit.ReceiveOwn |2 v6 I: S# H5 f: [! y
  79. macinit.LoopbackMode |
    2 [. B5 ]3 ?1 ~' M+ ^
  80. (heth->Init).DuplexMode |, x0 [" D7 i; Z* K/ ]6 u( B
  81. macinit.ChecksumOffload |/ w8 P. {$ Z3 J3 G$ \& ^5 v
  82. macinit.RetryTransmission |
    0 l3 q& I( Q2 b
  83. macinit.AutomaticPadCRCStrip |3 I9 ~0 @2 [# z$ ?- Y. U: E& V
  84. macinit.BackOffLimit |
    - K% [) _0 q" z
  85. macinit.DeferralCheck);
    ) n: @# K$ G9 g6 D7 x# B" R; O! i
  86. # o# I' t7 ~8 Y
  87. /* Write to ETHERNET MACCR */9 z- C! [. @7 y7 c" V. j& M5 \+ r0 C
  88. (heth->Instance)->MACCR = (uint32_t)tmpreg;
    9 \, X' Z4 M$ w! J" \

  89. . w( F8 m7 T5 x- w2 G/ h3 t: ?! G% B! j
  90. /* Wait until the write operation will be taken into account:
      Q5 T  G& T: b5 c5 d
  91. at least four TX_CLK/RX_CLK clock cycles */
    ; b& ]: B+ m( o0 Q' q
  92. tmpreg = (heth->Instance)->MACCR;( ?' L* t, p- A) d6 l
  93. HAL_Delay(ETH_REG_WRITE_DELAY);
    * n. `' Y* _3 u4 ^' E; ?. G
  94. (heth->Instance)->MACCR = tmpreg;
    4 V7 q2 k+ S$ `) F" ?) [
  95. 6 o" J5 l) Q5 P$ _3 b
  96. /*----------------------- ETHERNET MACFFR Configuration --------------------*/
    , l' A5 m. a! z- b
  97. /* Set the RA bit according to ETH ReceiveAll value */1 U$ r$ u, l9 \+ U( H
  98. /* Set the SAF and SAIF bits according to ETH SourceAddrFilter value */1 z1 T( o4 ~9 m' N) J7 b9 H' v
  99. /* Set the PCF bit according to ETH PassControlFrames value */
    4 Z" f7 ]2 n6 Q) ]# \
  100. /* Set the DBF bit according to ETH BroadcastFramesReception value */
    $ z3 C2 E! T$ X4 J  U# H
  101. /* Set the DAIF bit according to ETH DestinationAddrFilter value */7 C* R. e/ p, u3 T( \
  102. /* Set the PR bit according to ETH PromiscuousMode value *// @& H; ?( i) Y  i* H: ~
  103. /* Set the PM, HMC and HPF bits according to ETH MulticastFramesFilter value */" E) r0 a  {- k4 J2 O. ~
  104. /* Set the HUC and HPF bits according to ETH UnicastFramesFilter value */! K% k0 F) T! {
  105. /* Write to ETHERNET MACFFR */
    ; l/ z( M, Z! F& L1 C
  106. (heth->Instance)->MACFFR = (uint32_t)(macinit.ReceiveAll |8 ?8 }/ H; D+ d
  107. macinit.SourceAddrFilter |, d+ c1 @) z0 k( ]( E. k6 m6 ?
  108. macinit.PassControlFrames |
    $ |4 M" Q& B. s; I' l* h
  109. macinit.BroadcastFramesReception |; h6 W$ `+ }2 k
  110. macinit.DestinationAddrFilter |+ B) Z6 k4 O) ?. Q5 f, ^
  111. macinit.PromiscuousMode |
    * L, Q& i4 X' Q: G1 C4 x3 G
  112. macinit.MulticastFramesFilter |
    # Q  x7 H7 k/ R2 I) s
  113. macinit.UnicastFramesFilter);
    ; Q4 m0 y- q% k% W! H+ r% w

  114.   s$ n0 F4 K: ?' ]! Y
  115. /* Wait until the write operation will be taken into account:
    - V. z: i9 j2 `% {1 o2 ]9 N
  116. at least four TX_CLK/RX_CLK clock cycles */- G( X! h. F1 m, ~
  117. tmpreg = (heth->Instance)->MACFFR;5 A5 _* x$ B* A$ |# ]6 e
  118. HAL_Delay(ETH_REG_WRITE_DELAY);* k: v" J# L) U7 `/ }6 ]3 m2 [
  119. (heth->Instance)->MACFFR = tmpreg;" N8 R: e& P9 e" l0 x) ?6 [
  120. ; \0 c! X: R: o/ o  Y3 G) i- k$ o
  121. /*--------------- ETHERNET MACHTHR and MACHTLR Configuration --------------*/8 q( j/ N3 g3 J9 l: K# j  n% K5 Z
  122. /* Write to ETHERNET MACHTHR */" S- t: K9 S# }/ j% ^
  123. (heth->Instance)->MACHTHR = (uint32_t)macinit.HashTableHigh;
    ! C) r5 n# J, Y* ]/ U! q' t% u
  124. 9 w: W' g' Z! ^5 T! q3 `. `
  125. /* Write to ETHERNET MACHTLR */9 K' ^5 z- |) X: T5 H- C; O
  126. (heth->Instance)->MACHTLR = (uint32_t)macinit.HashTableLow;( Z- t0 J6 h/ T# L5 H" l
  127. /*----------------------- ETHERNET MACFCR Configuration -------------------*/
    " D6 a* d; y, G

  128. , j8 R0 ?$ U* r( H- v4 }. L
  129. /* Get the ETHERNET MACFCR value */
    1 s$ O; b1 U1 W& k8 e1 E  T
  130. tmpreg = (heth->Instance)->MACFCR;/ E& D' l' M3 D$ n- Q  i
  131. /* Clear xx bits */% q( {  J' ~9 P0 k
  132. tmpreg &= ETH_MACFCR_CLEAR_MASK;
    4 i" m; L" H$ @

  133. - ]: E, [" ^8 Q  Y6 P* p- h
  134. /* Set the PT bit according to ETH PauseTime value */8 \6 e2 K: m( D1 `! m6 K8 _* k
  135. /* Set the DZPQ bit according to ETH ZeroQuantaPause value */. {4 j) ^' c( W0 A) o& e
  136. /* Set the PLT bit according to ETH PauseLowThreshold value */+ z6 {# O/ s) [! d6 k
  137. /* Set the UP bit according to ETH UnicastPauseFrameDetect value */1 q, ?! `) e; T5 j9 y
  138. /* Set the RFE bit according to ETH ReceiveFlowControl value */: I: y$ V' g3 ^( P9 k. v# A9 k4 h
  139. /* Set the TFE bit according to ETH TransmitFlowControl value */8 q! b- s, `5 L" [
  140. tmpreg |= (uint32_t)((macinit.PauseTime Instance)->MACFCR = (uint32_t)tmpreg;+ L5 l/ Z6 x3 E: Z: b
  141. + W' z2 o% H, a+ e# s8 H7 }( P% R8 R
  142. /* Wait until the write operation will be taken into account:8 o! R  u' z+ ~; k: S( u, ^" t, J
  143. at least four TX_CLK/RX_CLK clock cycles */# `6 n0 @6 I9 q+ X- _/ R$ s
  144. tmpreg = (heth->Instance)->MACFCR;
    ; J7 ], n( B2 x0 w6 W+ w7 C
  145. HAL_Delay(ETH_REG_WRITE_DELAY);" m3 Q- s4 P8 z3 ~/ E& D6 I! f) v
  146. (heth->Instance)->MACFCR = tmpreg;
    - J) y/ w0 m7 e+ k8 z- g
  147. , N2 L% U# p+ [
  148. /*----------------------- ETHERNET MACVLANTR Configuration ----------------*/0 f2 S( C2 K3 s0 w
  149. /* Set the ETV bit according to ETH VLANTagComparison value */
    3 U% I" d8 u1 \+ G
  150. /* Set the VL bit according to ETH VLANTagIdentifier value */
    5 I3 b; n0 `( N, ^1 _/ a
  151. (heth->Instance)->MACVLANTR = (uint32_t)(macinit.VLANTagComparison |7 h4 g: B5 n. F& O
  152. macinit.VLANTagIdentifier);
    ( L+ m, J0 Z/ Q: O4 {
  153. # G0 \% L  Q6 o5 @- Y
  154. /* Wait until the write operation will be taken into account:
    6 B6 f2 o. w; ]  o3 a; v( F
  155.    at least four TX_CLK/RX_CLK clock cycles */
    + C! u: ?2 E% c7 q, s2 Q+ q7 g
  156. tmpreg = (heth->Instance)->MACVLANTR;
    ) G3 Y# W( W3 _2 |5 O# q1 U
  157. HAL_Delay(ETH_REG_WRITE_DELAY);1 v7 @2 s5 B5 R# y/ `- K
  158. (heth->Instance)->MACVLANTR = tmpreg;; U5 z+ ]# I' \7 E
  159. 2 e9 t, S: I  X$ X9 H4 r/ v! C
  160. /* Ethernet DMA default initialization ************************************/
    6 u0 G# y) R* e  E
  161. dmainit.DropTCPIPChecksumErrorFrame = ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE;  O- t0 H4 M/ w; G
  162. dmainit.ReceiveStoreForward = ETH_RECEIVESTOREFORWARD_ENABLE;; H" K! D& d" D
  163. dmainit.FlushReceivedFrame = ETH_FLUSHRECEIVEDFRAME_ENABLE;
    ; Y+ E9 v/ ^3 I: f% I
  164. dmainit.TransmitStoreForward = ETH_TRANSMITSTOREFORWARD_ENABLE;
    8 l4 `( D9 y8 A0 a. B* q7 q: L
  165. dmainit.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES;
    " d+ t7 F2 f( J2 G
  166. dmainit.ForwardErrorFrames = ETH_FORWARDERRORFRAMES_DISABLE;
    " m5 Q1 ?0 t" p* {8 |
  167. dmainit.ForwardUndersizedGoodFrames = ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE;
    6 ~9 g0 N. U- |' {. c# J! u
  168. dmainit.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES;/ h% o: Z$ p1 u+ G
  169. dmainit.SecondFrameOperate = ETH_SECONDFRAMEOPERARTE_ENABLE;
    & j' ^# ?- A' F  U; p+ N
  170. dmainit.AddressAlignedBeats = ETH_ADDRESSALIGNEDBEATS_ENABLE;$ e/ D7 Y: p/ v. \) j
  171. dmainit.FixedBurst = ETH_FIXEDBURST_ENABLE;
    . ?5 P. ^% M. S; D
  172. dmainit.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;
    ( c, _3 l4 z7 \% ]
  173. dmainit.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;& \/ P" C" `* l  f. d
  174. dmainit.EnhancedDescriptorFormat = ETH_DMAENHANCEDDESCRIPTOR_ENABLE;- q% f" V) g- P
  175. dmainit.DescriptorSkipLength = 0x0;: d- r6 O1 ]  B. d, M; |- f
  176. dmainit.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1;
    , q$ |8 V; w0 Y3 M6 @
  177. 3 I0 W3 ]0 ]) z* b& e% B
  178. /* Get the ETHERNET DMAOMR value */
    ( e: Z+ @4 ~& L. I+ G% U
  179. tmpreg = (heth->Instance)->DMAOMR;
    % j4 |$ Y4 \5 @4 X- r
  180. /* Clear xx bits */) T- X; \3 y7 \3 ~; X# j$ G. l
  181. tmpreg &= ETH_DMAOMR_CLEAR_MASK;
    ) S- J  c$ p  w1 v5 s! W
  182. ( e( J2 {3 m! j% S( ~5 _
  183. /* Set the DT bit according to ETH DropTCPIPChecksumErrorFrame value */
    3 K2 U. D. n7 g' `5 I+ _. h* j' K& q* v
  184. /* Set the RSF bit according to ETH ReceiveStoreForward value */. O, M( G  O& M7 G7 D: U; I
  185. /* Set the DFF bit according to ETH FlushReceivedFrame value */9 v6 C* X% A7 [+ E# R# Q
  186. /* Set the TSF bit according to ETH TransmitStoreForward value */* d: I; H! u0 D' |- r
  187. /* Set the TTC bit according to ETH TransmitThresholdControl value */0 Q+ q6 q) R3 Z) `, K4 }9 j% P, n$ T
  188. /* Set the FEF bit according to ETH ForwardErrorFrames value */
    3 C" k  J7 b: G
  189. /* Set the FUF bit according to ETH ForwardUndersizedGoodFrames value */
    . i! G' c0 [+ D! s
  190. /* Set the RTC bit according to ETH ReceiveThresholdControl value */& [2 \5 c) C  d3 L- ]* ]3 k
  191. /* Set the OSF bit according to ETH SecondFrameOperate value */
    3 t: L! D2 K* D( B
  192. tmpreg |= (uint32_t)(dmainit.DropTCPIPChecksumErrorFrame |
    3 J! P. a7 h! u& `. f0 V0 M6 F9 A
  193.                      dmainit.ReceiveStoreForward |" |2 P) e2 w6 ]5 a  n
  194.                      dmainit.FlushReceivedFrame |
    ; h! g3 e- Q6 l6 S. }
  195.                      dmainit.TransmitStoreForward |9 K$ S# @) _( S) P& w
  196.                      dmainit.TransmitThresholdControl |
    7 D3 c; s: f$ e2 g' ?* ~
  197.                      dmainit.ForwardErrorFrames |
    " h, `7 ^+ a9 K3 w# M7 c* a
  198.                      dmainit.ForwardUndersizedGoodFrames |
    " H! ^. j6 B/ p8 s
  199.                      dmainit.ReceiveThresholdControl |6 S3 p7 Y* S8 N0 F# m: {2 e
  200.                      dmainit.SecondFrameOperate);
    # b' }7 @8 d% i+ I7 A
  201. 3 l& Y! S- ~- z- ]5 C6 A2 U
  202. /* Write to ETHERNET DMAOMR */$ c% G6 ]2 y7 q& z" ~
  203. (heth->Instance)->DMAOMR = (uint32_t)tmpreg;7 R0 ~+ f: V& D6 M1 Y
  204. : A) I" q4 ]1 p4 v/ D3 l' @
  205. /* Wait until the write operation will be taken into account:
    6 t6 f. N% }6 e; p
  206.    at least four TX_CLK/RX_CLK clock cycles */
    # }; q  ^1 {" d  y
  207. tmpreg = (heth->Instance)->DMAOMR;& v0 q/ }8 ~+ y  L5 ~* d8 G  L
  208. HAL_Delay(ETH_REG_WRITE_DELAY);+ G3 y) f) a7 l, ]
  209. (heth->Instance)->DMAOMR = tmpreg;
    % H/ D0 M+ Q) ?3 I0 ?$ Q9 n: p

  210. * e. L" Z$ q2 D0 h7 v
  211. /*----------------------- ETHERNET DMABMR Configuration ------------------*/: p9 Z" Q" P) o; d  h! F+ x
  212. /* Set the AAL bit according to ETH AddressAlignedBeats value */
    . X3 {- h5 i- t5 F9 E4 z
  213. /* Set the FB bit according to ETH FixedBurst value */
    / P: ^0 R2 ?$ T7 Z8 L! d7 E: h; E
  214. /* Set the RPBL and 4*PBL bits according to ETH RxDMABurstLength value */
    & T# j& i5 i0 I9 J* E  t9 B' b6 B
  215. /* Set the PBL and 4*PBL bits according to ETH TxDMABurstLength value */2 [6 v5 X! {  |8 u  b# @& T$ Q
  216. /* Set the Enhanced DMA descriptors bit according to ETH EnhancedDescriptorFormat value*/
    " X1 o' H7 R! k4 m
  217. /* Set the DSL bit according to ETH DesciptorSkipLength value */3 r2 a$ ^0 ~" i# ^% B2 w
  218. /* Set the PR and DA bits according to ETH DMAArbitration value */
    1 G* I- ~  [3 _9 ]
  219. (heth->Instance)->DMABMR = (uint32_t)(dmainit.AddressAlignedBeats |7 F3 t5 L5 j8 @. u0 m; ~
  220.                                       dmainit.FixedBurst |% k8 F) @! Z/ C# ^5 y
  221.                                       dmainit.RxDMABurstLength |    /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */
    : r3 ^0 w" n2 e, z9 o) S2 a& m
  222.                                       dmainit.TxDMABurstLength |
    3 ^0 b) ]) D) a$ X( L+ T0 Q: X
  223.                                       dmainit.EnhancedDescriptorFormat |
    7 S& c- b7 T' L: q7 H
  224.                                       (dmainit.DescriptorSkipLength Instance)->DMABMR;
    4 |- C9 O4 b% w8 z1 b- P- W% Y
  225. HAL_Delay(ETH_REG_WRITE_DELAY);
    , p1 Y$ N" e- u: Q' I; i
  226. (heth->Instance)->DMABMR = tmpreg;
    ! k4 X6 r! V" p, g, y+ h

  227. 9 D! {, M+ D5 x5 \: l
  228. if((heth->Init).RxMode == ETH_RXINTERRUPT_MODE)% n; S2 Q. n( ?
  229. {
    4 _- o$ ?) f' o$ J
  230.    /* Enable the Ethernet Rx Interrupt */
    2 E$ s% X$ M& @% ?
  231.    __HAL_ETH_DMA_ENABLE_IT((heth), ETH_DMA_IT_NIS | ETH_DMA_IT_R);  O6 Q3 W+ n% E! O% S! U
  232. }5 ]$ z& R2 K% j& p5 d- K  r

  233. 2 L1 l& {6 U7 q7 @# R
  234. /* Initialize MAC address in ethernet MAC */7 G& [( w1 A7 c* L
  235. ETH_MACAddressConfig(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);
    $ R7 l: A' w0 @8 v, }; Z
  236. }
复制代码

# b, Z+ a: w$ Q2 a这里我就要稍微吐槽一下HAL库了; V7 f9 R6 P, {  C
MAC层过滤的设置没有预留接口出来,有设置MAC地址的函数
( d. q4 ~  q: f0 b/ N; b" T% ]4 o* s
static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr)
' |. G& w. s; e; k. S
! |# s3 f3 X3 {" g( s4 p就不多做一个设置MAC层过滤的函数嘛,连后面用到的宏定义都有~~9 ~, P2 `: i  a& i* H6 U

9 a* p6 {3 W% |6 v7 F' H3 d木有办法,自己编一个初始化MAC层过滤的函数吧
9 j# n& m" X- \; f4 ?7 {
5 ^! q* J+ \& U/ w1 t# l其实也就是把上面这个ETH_MACDMAConfig函数分离成两个单独的设置函数,再编一个设置MAC层过滤的函数6 h% z( g4 \' l7 i$ S( H: a9 d

. ~" W6 ^! s3 ^# I4 u开启MAC层过滤的初始化代码
" L1 P; Z2 g. t! b, A
  1. uint8_t ETH_MAC_Setting(ETH_HandleTypeDef *heth); G, m- ]6 `4 G1 |" _
  2. {2 w: Q& k, E& p1 h
  3. ETH_MACInitTypeDef macinit;! {& y2 K8 c1 q, H7 n
  4. /* Ethernet MAC default initialization **************************************/4 D+ b: q- g* s% G7 S
  5. macinit.Watchdog = ETH_WATCHDOG_ENABLE;
    * Q9 A5 K2 l/ }9 p7 h
  6. macinit.Jabber = ETH_JABBER_ENABLE;2 B3 f( Z1 L) N# C
  7. macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;, a' |7 k' \% i4 n
  8. macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;& Y  k! D; S$ U0 d: Z
  9. macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;
    , ]0 O% U( F5 `8 S; U
  10. macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;
    7 {' O. o0 e& K1 f8 N" `
  11. if (heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)- N9 Q3 ^9 B; k& y
  12. {' P0 a% L0 U' q  ^
  13. macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;$ X) Z: l* a6 d# A  @; C
  14. }
    8 r. r! s7 T1 d2 X
  15. else
    . v2 y' L$ e) c8 Y: E- D
  16. {+ K' ]2 f" @& `: ^5 A
  17. macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;9 y/ a. J9 y; v" F- r! U8 m
  18. }' N7 _& S% V& y- H$ z6 k" |! |& [; u
  19. macinit.RetryTransmission = ETH_RETRYTRANSMISSION_ENABLE;          //使能重传& U1 ^9 R+ t" w7 F5 V9 |' o
  20. macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_ENABLE;          //使能自动去除; C' O7 Q. Y# c- [+ V) u: _
  21. macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;' N( O, x, F) Q# k4 l4 T1 b+ z5 v
  22. macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE;
    & g; U, D; K$ g( Z2 b" o/ E  `$ D
  23. macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE; ///不接收所有包
    7 I1 p& a$ V, ]6 _8 t
  24. macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_NORMAL_ENABLE; //源地址过滤# |- }/ J9 N8 f( y6 R
  25. macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;
    4 n# G& H& S* U
  26. macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_DISABLE; //广播不接收. W* I- V6 a+ Q; M" _# a
  27. macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL; //目的地址过滤
    & f( U. p- p1 o- J
  28. macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE; //混乱模式6 k" Y! L9 }6 y) u+ \  p; Q, V( F& e
  29. macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECT; //多播过滤, z9 ^" U- _# h  N( S
  30. macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT; //单播过滤9 o2 e1 d# G* A5 m
  31. macinit.HashTableHigh = 0x0; //Hash表高位
    . d3 v; Y( t  n0 o' ~, G
  32. macinit.HashTableLow = 0x0; //Hash表低位" S5 o; p& }& w9 d" s
  33. macinit.PauseTime = 0x0;, ~: t4 `1 r) u% f$ r# H6 Y2 B
  34. macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;7 t4 L5 A- \1 I/ |; F* \
  35. macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;7 o0 n4 G. A' Y: T4 {
  36. macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_ENABLE;
    ( o/ ^' X0 ?3 I" w3 g3 n
  37. macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE; //接收流控
    ' |' ]; g" [4 U6 |1 W2 U6 B; t
  38. macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE; //发送流控
    & R- ~1 w" h, |3 I) G+ f4 D: V
  39. macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;
    9 T& X/ k# x8 K5 L1 \9 g
  40. macinit.VLANTagIdentifier = 0x0;
    : {1 K% f1 |7 P

  41. 6 O1 v9 a( ?0 T; U
  42. return HAL_ETH_ConfigMAC(heth, &macinit);& A+ x- A% l. T# [, y4 R" F
  43. }
复制代码
% i: A. ?, @' u+ _* G! ~
默认的MAC层 DMA初始化函数
: T! J. V7 I8 z( c! a
  1. uint8_t ETH_DMA_Setting(ETH_HandleTypeDef *heth)9 b' v) `2 v. R, T: Z3 }
  2. {
    * F7 f3 t8 N1 i2 d# c& Y! B
  3. ETH_DMAInitTypeDef dmainit;
    ! h/ p) m3 G1 D2 n, s4 ^6 Y5 H
  4. /* Ethernet DMA default initialization ************************************/
    ; F7 M' H, V3 k+ y( [. }
  5. dmainit.DropTCPIPChecksumErrorFrame = ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE;
    ( R, T; \* ?7 \# w
  6. dmainit.ReceiveStoreForward = ETH_RECEIVESTOREFORWARD_ENABLE;
    4 G4 ?" a/ a' t. g  w
  7. dmainit.FlushReceivedFrame = ETH_FLUSHRECEIVEDFRAME_ENABLE;6 L$ Q' n+ q0 r5 ]. T( j
  8. dmainit.TransmitStoreForward = ETH_TRANSMITSTOREFORWARD_ENABLE;
    ) U9 x+ k7 [, ]
  9. dmainit.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES;! u+ e* T# ~( R+ H
  10. dmainit.ForwardErrorFrames = ETH_FORWARDERRORFRAMES_DISABLE;; r! T; f/ K" ]% z2 M: A; p2 G
  11. dmainit.ForwardUndersizedGoodFrames = ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE;
    ( v7 ^  D/ l! y6 L! ]
  12. dmainit.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES;
    , }; T( N! v( b& J% `
  13. dmainit.SecondFrameOperate = ETH_SECONDFRAMEOPERARTE_ENABLE;* e0 V: O4 A: t" }
  14. dmainit.AddressAlignedBeats = ETH_ADDRESSALIGNEDBEATS_ENABLE;- e8 ~  k  m, y: u& A" f
  15. dmainit.FixedBurst = ETH_FIXEDBURST_ENABLE;
    / \* v+ F% g/ Z. G/ L" ~
  16. dmainit.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;; b% v- z. G7 d. }
  17. dmainit.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;
    6 G8 |- S; l2 ?2 g, ], C0 T' o
  18. dmainit.EnhancedDescriptorFormat = ETH_DMAENHANCEDDESCRIPTOR_ENABLE;/ \4 _2 X; f) L$ Z7 e0 l/ G
  19. dmainit.DescriptorSkipLength = 0x0;
    : @3 w6 j; u8 f" p8 J
  20. dmainit.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1;& u" X4 z# s- s1 D2 F
  21. uint8_t res =  HAL_ETH_ConfigDMA(heth, &dmainit);% U' D% V9 ]( I: M9 O
  22. if ((heth->Init).RxMode == ETH_RXINTERRUPT_MODE)
    & u+ Q' V  e8 w0 V
  23. {
    2 S! y9 C& Z5 }4 [3 }
  24. /* Enable the Ethernet Rx Interrupt */& R4 N3 k0 K& O9 H$ ?+ B
  25. __HAL_ETH_DMA_ENABLE_IT((heth), ETH_DMA_IT_NIS | ETH_DMA_IT_R);) p  Y' y1 F$ h. w8 [# w6 L( S6 Q% [
  26. }# ^' v8 E$ \, ]1 }7 P% v; S
  27. return res;% G% Q( c, {( j2 D; Y0 h
  28. }
复制代码
" H2 p: H$ F) J; t2 a. k9 L
用来设置MAC地址的函数(其实就是把库函数的static函数取出来直接用了)
  1. <blockquote>//heth: HAL句柄
复制代码
6 e7 S1 z0 d9 P
然后到最最重要的MAC层过滤设置

+ W: }4 ^* f( l; n以MAC1为例
- F* q- d" Q' B  M
4 ?% n& k0 X& X/ @" I4 a) V
20191124093921254.png
  ?, B1 E4 {7 S' @2 ?/ F- a
% F1 i% t6 N. n, B0 i& G
20191124094439199.png

' S- ~) b  {- u. `  Y4 k2 Z4 e0 g% G. I
注意看红框的描述
/ N, i+ O5 L2 q9 c0 ~
功能很好用,可以过滤源地址/目的地址,还可以做掩码功能  W. p5 q* E/ O( y. F
设置MAC层过滤的代码
$ y: f  P; u8 W$ o# A  c4 c0 W. L9 |
  1. static void ETH_MAC_Filter_Setting(ETH_HandleTypeDef *heth,ST_ETH_PAR * para)7 T/ N# `" S  B' s$ Q- d
  2. {
    4 H3 @. H2 ]3 D7 h0 r; x9 U
  3.     //设置本机MAC地址5 [) ]- ~# I' o% [4 v: n! ?
  4.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);5 \+ c4 G% _3 [7 j  \* w" e
  5.     //设置UDP-A的对方MAC地址# {. z8 `4 {8 [1 @6 V3 [
  6.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS1,para->UDP_A_MAC);5 `0 Y) ?# P" L3 ?3 h
  7.     (heth->Instance)->MACA1HR|=0xC0000000;//需要完全匹配UDP-A的对方MAC才接收% D/ F- @; q% d
  8.     //设置UDP-B的对方MAC地址, W# u+ l  _$ e) }# ?3 f
  9.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS2,para->UDP_B_MAC);) q1 h) n/ r/ J1 [9 W; ]  {2 q$ |
  10.     (heth->Instance)->MACA2HR|=0xC0000000;//需要完全匹配UDP-A的对方MAC才接收  E( n- R( h5 o+ N1 [
  11. }
复制代码
0 S$ t1 N6 T1 j+ p& p8 C5 ]; Z
我这里是希望为我的两个UDP精确过滤接收到的源地址
& M7 @4 s/ }: w所以AE位设置为1,SA设置为1,MBC全部为0(MAC地址全部检查)
. f8 G: j) b" c1 y; i. o" a  n  K7 q
假如我希望过滤MAC中特定的厂家字段
4 w0 Y. e8 U; f+ {& ^! i例如某个MAC地址

# }- e/ k* ~! G01-02-03-04-05-06
4 L, U% I* s5 i其中01-02-03就是厂家字段
. \  a4 I$ h# ]' a
4 g5 A% X7 w( ^: ]  X3 M. T那么代码要这样修改(MBC的第29位,28位,27位置1)3 }# s: v4 E% ?' R" n' w5 L
这样MAC层就不会检查MAC地址里后3个字节(04-05-06)
  s, k$ L- K0 t' T2 ?% y但是会检查前3个字节,也就是厂家字段7 k5 _$ Q# N! \! d/ T. @
这里需要注意MAC地址的字节序7 |* `0 @5 E9 W8 M7 e
  1. static void ETH_MAC_Filter_Setting(ETH_HandleTypeDef *heth,ST_ETH_PAR * para)
    9 o% P* m" _  x
  2. {
    / l% ~. u7 J. v& F$ h
  3.     //设置本机MAC地址
    ; j4 Q- c2 Y. F6 ~7 s
  4.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);4 p% m* U% V3 |" t* s5 Q7 N' v
  5.     //设置UDP-A的对方MAC地址- e3 ~  s: r5 q/ w$ @- x9 ~8 F& p
  6.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS1,para->UDP_A_MAC);
    8 X. R9 [6 ?) o6 X, A7 f: g) @% S, j# A
  7.     (heth->Instance)->MACA1HR|=0xF8000000;//需要匹配厂家字段
    " N# g% C* E- ]' h4 n
  8.     //设置UDP-B的对方MAC地址
      O3 m5 {! q3 G0 i
  9.     ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS2,para->UDP_B_MAC);
    * y( L2 t( Q2 [! h: N
  10.     (heth->Instance)->MACA2HR|=0xF8000000;//需要匹配厂家字段) |8 b: k2 a  K  Z
  11. }
复制代码
) M" c' K  H; b: p  t( f  `
然后这些函数的调用顺序按:
* K& A2 c) D& y0 h: P1. HAL_ETH_Init2 v* ]$ B4 \* W- o& f( E
2. ETH_MAC_Setting
4 p9 Q0 x" x3 ]; B' W6 k3. ETH_DMA_Setting; I6 t8 y: ^9 R7 b* c8 D
4. ETH_MAC_Filter_Setting! S; i, e8 u4 u7 @- ~) {1 U
5 @* C9 J# e6 M; Y% H* t7 L1 E# e
用你希望过滤的MAC传递到一个Hash计算函数里,得到一个值,通过这个值产生“映射”关系来过滤MAC地址,所以这个并不是精确的,因为可能会重复~~
9 l; y* Q# ^2 E; [
7 m# d3 Z! P4 }
HASH函数
8 l9 f8 }4 S5 P* p/ b1 v函数. U. o) A+ Y5 g* M
  1. / STM32 MACHASH - Copyright (C) 2014-2018 Clive Turvey (<a href="mailto:sourcer32@gmail.com">sourcer32@gmail.com</a>)8 \9 [7 t, i  L0 ^# g
  2. //  All Rights Reserved
    % m4 J5 D5 D* M

  3. , {; v- X& n. L6 P4 `+ d5 M' v
  4. #include <windows.h>+ b( u7 {7 ]8 q
  5.   l0 [3 \( k* O- z+ y' e
  6. #include <stdio.h>
      p" P' \: I* u/ F7 ~' K+ l; t
  7. #include <stdlib.h>/ K. H- R1 Y( }# x, m# t4 r6 n
  8. 8 h6 N! H( d9 w+ t1 H
  9. typedef unsigned char uint8_t;' d1 T0 a% G7 N" {
  10. typedef unsigned long uint32_t;2 q$ S7 \! L' d8 O) l+ N
  11. ! N$ ?+ O/ o, H5 t+ }. p; P, S
  12. uint32_t Rev32(uint32_t x)
    # a. p! x9 P5 s) s/ H6 ?$ C
  13. {" x6 N4 k; v! x% d$ ^) s3 n
  14.   uint32_t y;( Z0 B$ @1 i9 {- i2 C9 u9 u# A
  15.   int i;5 l; b  L7 U( [' a0 {  S

  16. 5 m$ \  G1 v+ ~* N
  17.   y = 0;
    ! H. z/ s1 g( O( M, p

  18. ' p$ N/ {9 ]9 W$ ?$ o
  19.   for(i=0; i<32; i++)
    * b3 _% v: C! G, `. z
  20.     if (x & (1 << i))
    ; o: c/ L0 k1 y2 o
  21.       y |= 1 << (31 - i);
    4 P1 R* k8 M! Q# ?# w
  22. - `3 I2 G, C: s* u
  23.   return(y);
    * m( P: o8 G- ^. G7 J6 N! r
  24. }
    ' o- G0 \) W7 x! I1 I' C
  25. 8 }" i- h! ^; ?) I0 ?# G
  26. uint32_t MacHash(const uint8_t *Mac) // <a href="mailto:sourcer32@gmail.com">sourcer32@gmail.com</a>4 e# `9 A4 \' l5 a+ ?# r2 Z$ J
  27. {
    0 z/ W. f# ~' B* }1 C8 f+ t$ a
  28.   int i, j;! f+ a, ^- K# D- D" H. C* v  X
  29.   uint32_t Crc;
    8 r% t2 z0 |, e3 `$ o* @  V

  30. / Y( U' R, e1 x8 C  [3 i
  31.   Crc = 0xFFFFFFFF;
    0 ~" [& U( N" L/ H- t! e2 |- H

  32. 6 F. ^0 ?+ t! e) O1 f- J% h7 [
  33.   for(j=0; j<6; j++)4 h3 \: w! x) K8 @
  34.   {; W/ w  d0 k# @% O
  35.     Crc = Crc ^ (uint32_t)Mac[j];2 G6 t% j3 O  f, Z: D$ ^
  36. 3 K/ Q" [8 D5 G5 f% k  R
  37.     for(i=0; i<8; i++)
    / N$ O1 K$ ]" E, z7 H3 k
  38.       if (Crc & 1)
    4 J. r  |% x9 i7 L& ]1 |+ `7 c
  39.         Crc = (Crc >> 1) ^ 0xEDB88320; // Reversed 0x04C11DB7! f# w! A& z, g. f
  40.       else
    ; g4 W$ H* l! Z: M6 ~8 t( t
  41.         Crc = (Crc >> 1);
    " l. T4 Y6 {( n* J
  42.   }" T* p- {+ \1 Q
  43. / |: V) v( H: `4 u% X
  44.   return(Rev32(~Crc) >> 26); // Get High order 6-bit in reversed/inverted CRC' }4 c; \8 [* Q2 C" p- r: u. ]
  45. }5 `9 H6 z. z' ^* A5 Z

  46. 8 p" X- Q" d% `  k0 w) [
  47. uint32_t MacHashFast(const uint8_t *Mac) // <a href="mailto:sourcer32@gmail.com">sourcer32@gmail.com</a>
    ( U! p1 q7 q5 {" W; ?; R- _4 W
  48. {
    9 F+ l! ]! T5 ?! }
  49.   static const uint32_t Rev6Tbl[] = {
    2 N; G9 ?. @" S& ^* O, y' i
  50.     0x00,0x20,0x10,0x30,0x08,0x28,0x18,0x38,
    % T* q1 J3 b; a- |- l2 v, J
  51.     0x04,0x24,0x14,0x34,0x0C,0x2C,0x1C,0x3C,$ U8 }$ M! C6 j& ?- \
  52.     0x02,0x22,0x12,0x32,0x0A,0x2A,0x1A,0x3A,9 V: L6 Z/ m- P/ i7 W! I
  53.     0x06,0x26,0x16,0x36,0x0E,0x2E,0x1E,0x3E,
    0 v; M& g! B  f' c. e, j/ p
  54.     0x01,0x21,0x11,0x31,0x09,0x29,0x19,0x39,1 i( {& C* p1 G1 F
  55.     0x05,0x25,0x15,0x35,0x0D,0x2D,0x1D,0x3D,& n' g0 G; P2 n( P9 |
  56.     0x03,0x23,0x13,0x33,0x0B,0x2B,0x1B,0x3B,, c  I  E- l  x- a/ W# M7 X' t/ P& G- t
  57.     0x07,0x27,0x17,0x37,0x0F,0x2F,0x1F,0x3F };
    2 V* X$ e6 C" c! A: B# q

  58. 5 ^# |1 O( h; V* @3 C& i
  59.   static const uint32_t Crc32Tbl[] = {* b. ]% i% @& S' n
  60.     0x4DBDF21C, 0x500AE278, 0x76D3D2D4, 0x6B64C2B0,
    # Z0 K& \) [- S, o
  61.     0x3B61B38C, 0x26D6A3E8, 0x000F9344, 0x1DB88320,. @% O3 f& Z1 f3 V  p8 d
  62.     0xA005713C, 0xBDB26158, 0x9B6B51F4, 0x86DC4190,
    2 u5 p* @4 f/ C9 ^, f/ G/ f3 }
  63.     0xD6D930AC, 0xCB6E20C8, 0xEDB71064, 0xF0000000 };) J; B2 o+ F9 n, J

  64. 1 q% m& S( t( J7 v+ I
  65.   int i;$ I" m8 T: F# f  m3 M0 d2 q6 D6 x9 e
  66.   uint32_t Crc;: [  Q/ x; `* B5 j
  67. + x  ]- M! [* J! g
  68.   Crc = 0;) c; f. D( {% n2 Y5 C* {2 s# O

  69. . C9 m# P3 |8 c* j: l
  70.   for(i=0; i<6; i++)/ e+ O8 [! \$ k* y' d" ^
  71.   {* O" Z1 x3 c, k4 o$ T8 e0 I* C$ u
  72.     Crc = Crc ^ (uint32_t)Mac<i>;
    ) A5 T/ ?( z" j

  73. % X4 E/ S- ~3 z: g) g
  74. </i>   Crc = (Crc >> 4) ^ Crc32Tbl[Crc & 0x0F];  /* lower nibble */- l5 L& a* S; I3 }) B
  75.     Crc = (Crc >> 4) ^ Crc32Tbl[Crc & 0x0F];  /* upper nibble */
    1 ?8 l6 ]" I5 u1 k2 M
  76.   }# d* A; X: y1 t: w$ Z
  77. 7 `$ |  X) f+ ~4 v, h: I1 A
  78.   return(Rev6Tbl[Crc & 0x3F]);
    $ k/ ]9 z) P5 k& n
  79. }
    8 q4 p7 L+ P7 x) n4 [" U2 Q
  80.   J! ~! \1 r, J3 M6 K/ c
  81. int main(int argc, char **argv)( B3 Z' ?) J3 m2 v' x
  82. {2 k* y/ i: P* B( E% J* s9 Z
  83.   static const uint8_t Test1[] = { 0x1F, 0x52, 0x41, 0x9C, 0xB6, 0xAF }; // 0x2C
    + ^, e* t9 o5 s, e- B
  84.   static const uint8_t Test2[] = { 0xA0, 0x0A, 0x98, 0x00, 0x00, 0x45 }; // 0x07
    8 q' W5 @7 ]- p
  85.   static const uint8_t Test3[] = { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x21 }; // 0x24
    0 D5 r! ~; ?( W0 T, {4 q

  86. / c) n6 R) a3 v
  87.   printf("MacHash %02X\n", MacHash(Test1));
    6 W' w: F) @7 X  E( _
  88.   printf("MacHash %02X\n", MacHash(Test2));  i2 P/ l( M$ t' q" k  J" F0 U6 a( V$ I
  89.   printf("MacHash %02X\n", MacHash(Test3));0 k: W! f. Z3 w( x9 b( [

  90. 1 U9 i/ C1 U* P) e/ q0 U
  91.   printf("MacHashFast %02X\n", MacHashFast(Test1));0 B' O: U( R: K: o- {
  92.   printf("MacHashFast %02X\n", MacHashFast(Test2));
    # t! e6 `+ d# U& K
  93.   printf("MacHashFast %02X\n", MacHashFast(Test3));1 P; c/ {* j& Y0 d, |

  94.   W% b# f- H, ^
  95.   return(1);
    2 h3 F" P1 z% ]
  96. }
复制代码

; O* S# ~* t6 I0 p% ~9 P7 Y5 k; x* V( `0 ^. M2 V
回到手册
6 O$ q. J' L" @) F
) j5 D) {( R7 n- B( Y3 r# U
20191124100604140.png

: n% |+ ^, s, a2 d* J1 }9 x; g  }' b1 @2 u. r# H4 N
20191124100636882.png

( U1 }: B, b- q
! H! T9 R$ P) h$ Z% r5 f6 i
' [8 [7 M0 }* K# \' G$ ~6 b* b& X上面的函数算出来一个数,假如是手册上的那个0x2c,二进制为101100B
, X+ L. {; P+ c! f' b6 O换句看得懂的人话···就是:
8 B! Y* H- y1 V8 _; o算出来的数先看第6位1 v7 r: b. ~  Z
是1的话说明用到的是HASH表高位寄存器
" L" g! i" p0 N  D* `# {9 |7 j+ a否则用到的是HASH表低位寄存器
) Q# ?# B6 K3 P8 S# |# G1 x6 }然后剩下的5位,转成十进制不是12嘛
; @+ o9 j1 U8 m* B如果你希望过滤这个MAC
. Q7 R$ G" _5 C' t: P8 Q6 a' E7 X3 z4 n那么你就把对应的HASH表高/低位寄存器的对应位置1,否则置0
0 A* H3 ^5 I$ G0 K+ w5 s2 S这里的0x2c就是要把$ p* s. w* Z( s: u4 O, A
HASH表高位寄存器的第12位置17 Y! D8 t1 q& Q
就可以过滤这条MAC了
6 ]' `% P, z9 t然后把你希望的MAC地址都按照上面说的方法弄完4 y/ @% w8 |5 P& y

. m/ C: ]8 p0 q" g3 j: I4 @8 U回到这个函数稍微改一下
& {: l* ]( a1 i2 _. d% D+ m, ^' Y
  1. uint8_t ETH_MAC_Setting(ETH_HandleTypeDef *heth), S* h- B9 ~8 X" z" d' l. p
  2. {
    & C$ k1 x! J, @
  3.     ETH_MACInitTypeDef macinit;
    . }9 u" w+ R# M/ U5 @2 Q- R) }% H" f
  4.     /* Ethernet MAC default initialization **************************************/1 V9 H# `0 V4 B. \4 m2 p$ |6 E2 z
  5.     macinit.Watchdog = ETH_WATCHDOG_ENABLE;+ h( Q, J) f' K) |, I
  6.     macinit.Jabber = ETH_JABBER_ENABLE;& V! b8 F9 U1 s9 {3 t! k+ q
  7.     macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;0 W7 j; ]) c  i. H! R) X
  8.     macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;" u' f$ `% n" y1 w: f- h1 }
  9.     macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;
    + Q2 L* |; H( [$ C& K0 f+ b
  10.     macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;
    6 B& V6 Q5 B+ r% Z; h. @9 P$ j. ~
  11.     if (heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)7 y# G; Z4 h# q& z4 }- S% G
  12.     {3 ~: d8 f. s  W' \. R) q4 }% [
  13.         macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;
    6 @- G; K. ]7 w/ t+ }; ]* `
  14.     }
    1 I( x' {  q2 W3 t: B: V
  15.     else
    6 G+ N7 j7 ?& q( {
  16.     {
    ) n$ |- V; d4 E
  17.         macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;
    - T1 d0 F. e" l
  18.     }: X- J9 ~+ b. m" e
  19.     macinit.RetryTransmission = ETH_RETRYTRANSMISSION_ENABLE;          //使能重传# ?+ t* ^0 W  E& S* i& O" T
  20.     macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_ENABLE;          //使能自动去除+ D8 Z% \+ g  e# b# K$ s
  21.     macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;; h8 x( F( y( E9 t
  22.     macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE;
    # K, V( S0 |9 a: x% d" G3 I+ y' W
  23.     macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE; ///不接收所有包+ J. E7 h4 V  V9 B7 I2 V* b4 a3 ^# s
  24.     macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_NORMAL_ENABLE; //源地址过滤
    / `& S7 e( u6 N' K
  25.     macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;
    ! o4 t0 e- V- C% v0 H4 h& F
  26.     macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_DISABLE; //广播不接收
    3 c- c, ?2 A4 f7 N& F7 C. S
  27.     macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL; //目的地址过滤8 M0 L7 [& W$ W) s5 L4 m# C
  28.     macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE; //混乱模式% y* c: a5 @6 y! S5 u; b. g
  29.     macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECTHASHTABLE; //!!多播HASH完美过滤
    ' Q* _( l1 z0 k. x
  30.     macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECTHASHTABLE; //!!单播HASH完美过滤" p. }, o, g. M# Q
  31.     macinit.HashTableHigh = 0x0; //!!填你最后算完的Hash表高位8 K% H1 T: P) r: O& W; [" H
  32.     macinit.HashTableLow = 0x0; //!!填你最后算完的Hash表低位
    9 O2 P- t1 N- t3 B# }
  33.     macinit.PauseTime = 0x0;+ d* |) W( H9 l: _9 C
  34.     macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;
    + [' f4 a8 e' M0 r3 X8 l( v2 r) I1 V
  35.     macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;
    ) l/ r% W! k. w% e' M
  36.     macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_ENABLE;
    & ]( B: X1 o" Z2 ]5 f! }
  37.     macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE; //接收流控
    2 W. D% m& x! Q8 j) V
  38.     macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE; //发送流控0 V% K5 ?  p* G' R6 h
  39.     macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;
    6 n( W; m4 [6 [. b  b
  40.     macinit.VLANTagIdentifier = 0x0;; K  w$ `! }  y8 E
  41. ! `' M- ^7 g: V" `( _
  42.     return HAL_ETH_ConfigMAC(heth, &macinit);& H( g, F6 s5 u' N
  43. }
复制代码
9 c* h, l; d$ b( @) t
大概MAC层过滤就这些东西了
2 {' o2 L( V4 y如果有条件弄MAC层过滤真的强烈建议开启,可以大幅减轻协议栈的处理负担,板卡不会因为处理大量无用的数据而白白浪费处理性能。
) f! R6 o- y8 ?, O
/ u6 [. e+ z4 N
7 x8 _0 e* a6 n, I: e# n( O6 ~! i, a! s* ^: ^: e
  s- y( f4 D% ]/ _: T, E2 i' O
赞 收藏 评论0 发布时间:2021-12-14 10:15

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版