前景描述
+ z4 N# g% M) `- [7 @9 B我司的以太网实现是LAN8720搭配片上MAC层做的,协议栈用LWIP" o9 h8 I9 t+ A1 N% v9 P
5 P) R, J. j: i6 |; M这种做法应该还是蛮常见的,反正不是LAN8720就是DP83864,再不然就是硬件协议栈的W5500了
: z3 d% j5 B$ m0 v7 J/ {9 b3 r
9 `! o6 o$ P- P- d2 ?( M" ^0 j5 y+ D想想还是有MAC层过滤比较好,随手翻了翻它的手册,W5500好像是没得MAC层过滤的
9 c) Y7 s$ a4 b2 [8 w k; @6 G ?. ^: n _- }0 d" D3 J6 o" K
假如数据速率比较高,数据量大,而且外面还有乱七八糟无关的数据往板卡送,我也不知道用这个片子到底好不好
) s: W4 Y k6 l" i7 [* q, G: q7 t2 A
LAN8720也不好改了,就继续用吧
' ]$ `* o# E$ c6 m6 K( t/ H" u, s+ R9 l! o; E) v/ c
好好在,发给板卡的数据的MAC还是有特征的,我只需要过滤发送方MAC地址的前3个字节,也就是特定的厂家那段
) ^" R: x( C9 f: H
2 J3 M6 m; Z2 r, CMAC地址的科普知识这里就不过多描述了,我们直奔主题
# k7 f6 Q# G1 S6 K( | u/ W
- F: C: ^; y, s' w6 r怎么用STM32 F7的片上MAC做MAC层过滤
$ |$ j7 X6 U. a7 I/ A
& D' |* S7 h0 w# X写这个的目的,就是我搜了搜,没看见有人写这个MAC层过滤功能,具体代码怎么写才能用6 F* o) }) G7 w' @
! N9 m- b7 H' Y5 L! a. c
知识科普-STM32的片上MAC
7 f6 y( ^) o ZSTM32 F7的MAC层过滤方式有三种(说人话的直白解释,中文手册其实也翻译的不好)
7 ~! {1 c8 ^' N m精确过滤(手册上叫单播目标/源地址过滤)
2 D( W$ I u8 z# i0 D! A* Y粗糙过滤(手册上叫Hash表过滤)
# d/ ?, a6 w& ]特殊过滤(广播,组播过滤等等特殊的过滤). _% C- B- n& o% j0 O8 G! {
我这里着重说第1种和第3种
. X6 \' }. X4 h) S0 N, h7 ], d5 e
STM32 F7可以存4个MAC地址& V5 v7 N' x# Z: P6 }. T* f
其中MAC地址0是自己的MAC,其他三个可以用来做过滤: [1 q9 {' R4 y3 C. |
: c* I, C7 k4 f! {7 L网络数据包通过PHY进入STM32的MAC,MAC层是可以对目的地址/源地址检查并过滤掉没得用的数据的,默认的HAL库库函数HAL_ETH_Init中- u! h7 E# N9 c) o
有一个static的函数1 F% [ b* j% @9 h0 E, V9 X
static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err)
" u" G6 E: }9 A: j会帮你在初始化网络功能时初始化默认的MAC层功能:
5 K7 y5 q; A2 p1 ~8 T关闭源地址过滤" P! `3 F/ {- w" l/ H
不接收所有数据: a% S; W0 {: O$ ?; B- e& G: V
接收广播帧, a* N6 `; X( l
打开目的地地址过滤
5 j, U9 }$ e9 w$ n1 y$ g单播数据精确过滤
4 J1 ?. ?5 {1 o' q组播数据精确过滤
7 l' I, c6 F1 ^( T6 V9 zHash表过滤关闭. V6 {0 G' O2 N: v
b* Z+ D' r, b# }
其他的功能自行研究,我这里捡重要的说
4 P( w5 g8 B. a! `. Q: p0 w- static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err)/ Z: j- w4 E1 k& G' Z
- {
1 Q6 O# O" T. f2 \4 \ - ETH_MACInitTypeDef macinit;
3 H9 l; E" v! C/ g _: ~ - ETH_DMAInitTypeDef dmainit;0 z; r1 |/ m. h5 [* L# c
- uint32_t tmpreg = 0;
- r# t- H$ p* x+ d0 h
/ R& B$ v. s; `/ a: n( T; `- if (err != ETH_SUCCESS) /* Auto-negotiation failed */
& r+ O( d" \7 N, z' y% ?( z$ j5 m - {" `; P, _$ i) C1 @
- /* Set Ethernet duplex mode to Full-duplex */
/ B3 n2 a! d. C3 W }* }$ r - (heth->Init).DuplexMode = ETH_MODE_FULLDUPLEX;
' W; U# [9 L/ [7 V! n- |/ R
# E+ q+ ^; ^2 j( K- /* Set Ethernet speed to 100M */$ N8 V' j5 W/ w8 C( Q# o
- (heth->Init).Speed = ETH_SPEED_100M;
& l- k4 K& |" Y" w - }& @8 e) W2 r, X6 m8 d2 K
- - ]+ b/ [! r* p! m5 H' T- R
- /* Ethernet MAC default initialization **************************************/ A: W5 M+ |# C
- macinit.Watchdog = ETH_WATCHDOG_ENABLE;
- {' r& Q) ?/ b, k" W* Y% J2 P - macinit.Jabber = ETH_JABBER_ENABLE;* G! D' M! u- C8 G. {5 W T
- macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;3 H1 Q) J9 l0 P* P8 z# A4 M) [+ I1 d
- macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;7 }. G2 U5 o2 _( H
- macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;
1 g. M; b4 s: T9 t, X - macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;
, j; K2 }& F4 Y" C6 d - if(heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)
2 Q1 ~0 k6 C1 o" M5 M! n4 J6 K - {+ b5 R1 m( B8 ~$ J0 Y$ r
- macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;
, m! G3 k7 U: o - }1 j" Z/ G: e4 `1 u* p+ i! t: [& j7 E
- else
2 T5 U& u3 w" r, o$ ~1 Z# { - {. N% ]6 n$ [) {2 j- G& S
- macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;4 M3 Y6 ]4 t5 p/ C5 T: I2 w; @
- }
8 @7 X; t4 A$ J - //这一段是MAC层过滤的设置,下面是DMA的,那个用默认的就可以
# w& g4 Y. {2 l' F - macinit.RetryTransmission = ETH_RETRYTRANSMISSION_DISABLE;! X* {. k; ^6 F$ I( o3 n
- macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_DISABLE;( B$ Z0 I3 L- Q H# x( Y& e
- macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;1 E0 @, F3 K. b8 Q# w6 @
- macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE;* R4 H8 _1 ?+ H. a
- macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE;
. A4 A( m K0 L( J, | - macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_DISABLE;/ ~, w4 Z' [3 q$ ^1 j
- macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;
1 k0 k( x4 t$ h3 c& ?1 Z1 e - macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_ENABLE;
. T% s& d9 u, G4 o0 M4 L& Y - macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL;
0 ?. k6 S- \9 }, B5 E - macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE;# |. g$ | y; ^- t/ H
- macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECT;
# t- I3 S' ?9 h: J+ N! j - macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT;
( \! x% [7 y* O9 I4 N - macinit.HashTableHigh = 0x0;- C6 j$ n$ d( c5 }$ u
- macinit.HashTableLow = 0x0;
& h& a) O Q2 R* y% x+ ?( ? - macinit.PauseTime = 0x0;5 a. Y7 g, W; x, [! Z
- macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;
8 {6 [4 p1 b& Z0 j/ e i$ a - macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;
& [& h2 N" B1 Z - macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_DISABLE;
4 _4 O. p- }+ ~8 K- ] - macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE;
$ W& K+ _$ t9 K3 {% f( y* {6 T - macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE;
) K9 ~1 x1 T8 k* e }- N( @ - macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;
+ `) p- f4 S q4 ?+ T, ? - macinit.VLANTagIdentifier = 0x0;5 [: b' X& y& Q+ n& A9 I
- 8 ]* v- l' L, |; O' w' o
- /*------------------------ ETHERNET MACCR Configuration --------------------*/8 E0 z* d" W9 H/ @- [/ N0 J
- /* Get the ETHERNET MACCR value */
1 W- W1 j7 G# s - tmpreg = (heth->Instance)->MACCR;0 S, y" O1 S7 p* s0 b" q. O: ?* M
- /* Clear WD, PCE, PS, TE and RE bits */: u5 k' c9 B8 ^
- tmpreg &= ETH_MACCR_CLEAR_MASK;- H6 w7 I' O% J% B1 M
- /* Set the WD bit according to ETH Watchdog value */2 V; _+ Q- y' `# ^" V: k
- /* Set the JD: bit according to ETH Jabber value */) c/ \: i1 Y+ \8 j
- /* Set the IFG bit according to ETH InterFrameGap value */0 d% V; w2 y V/ h6 b1 f/ m5 r" W+ w
- /* Set the DCRS bit according to ETH CarrierSense value */
3 A$ a$ [% T7 c - /* Set the FES bit according to ETH Speed value */- O, B( w9 p/ v$ w
- /* Set the DO bit according to ETH ReceiveOwn value */. I7 `9 {4 k S! m8 z2 j
- /* Set the LM bit according to ETH LoopbackMode value */0 d6 Q& H! R: q0 Z, y Q
- /* Set the DM bit according to ETH Mode value */
! t0 m6 [3 i' v& {. L, N2 ? - /* Set the IPCO bit according to ETH ChecksumOffload value */
8 p% W7 t& i; l. s% v - /* Set the DR bit according to ETH RetryTransmission value */' N3 F6 X0 n3 ?0 B% [* Q
- /* Set the ACS bit according to ETH AutomaticPadCRCStrip value */* ^' U& | Z6 v* ?+ x
- /* Set the BL bit according to ETH BackOffLimit value */( q7 v: k% d" ~( U s" C
- /* Set the DC bit according to ETH DeferralCheck value */6 q& ?) t1 i+ ^% Y7 d2 M* y" G6 F
- tmpreg |= (uint32_t)(macinit.Watchdog |9 e+ p4 G1 B/ f* g' R( `: n6 H
- macinit.Jabber |
2 o% r+ |3 a8 J | `8 `5 y - macinit.InterFrameGap |& k/ I% s/ g: @0 p' u- ^) y* u7 A6 v2 f
- macinit.CarrierSense |
/ f& C4 {" ^8 K" T" q - (heth->Init).Speed |: T, G+ D4 w& P) Q: ]8 P( I8 E
- macinit.ReceiveOwn |
w1 g7 w2 |3 |) L8 Q3 F - macinit.LoopbackMode |& Z" s2 _2 I4 n# C" p+ Q! ^
- (heth->Init).DuplexMode |
# `2 x: n: U) Q - macinit.ChecksumOffload |
' M$ @5 c0 y. P. P - macinit.RetryTransmission |
/ f/ U2 Y2 y0 q - macinit.AutomaticPadCRCStrip |) z: z; u" b5 g; b5 ^0 T
- macinit.BackOffLimit |/ E; G9 ?0 ], T: Y* D
- macinit.DeferralCheck);7 m5 l: L! m0 E
4 \: k: z2 q2 O- j) t- /* Write to ETHERNET MACCR */
# k3 Z) V- U2 Z' C+ F - (heth->Instance)->MACCR = (uint32_t)tmpreg;
; F) b0 p: R; q+ O6 z2 Y! m - ! @+ @3 k! [7 T( y
- /* Wait until the write operation will be taken into account:1 f3 t" F0 u3 ?* C
- at least four TX_CLK/RX_CLK clock cycles */
, B: k+ R7 J% C% Q7 d8 m! Z6 o+ v - tmpreg = (heth->Instance)->MACCR;+ G! z# ?" e3 c! B% U; i
- HAL_Delay(ETH_REG_WRITE_DELAY);
) c( L0 t, F( C/ h+ U - (heth->Instance)->MACCR = tmpreg;
0 U0 G) f0 G) \( V - 7 s, h5 U) B4 q' M7 \- d
- /*----------------------- ETHERNET MACFFR Configuration --------------------*/7 ?1 w1 ]- F) g8 E! |# f
- /* Set the RA bit according to ETH ReceiveAll value */8 G" M* u/ ]; }7 z e
- /* Set the SAF and SAIF bits according to ETH SourceAddrFilter value */; J7 q' J9 r0 @4 |
- /* Set the PCF bit according to ETH PassControlFrames value */
5 D% a4 a% v' a0 A0 v+ k - /* Set the DBF bit according to ETH BroadcastFramesReception value */# j5 Z8 T4 @/ H# Q3 |
- /* Set the DAIF bit according to ETH DestinationAddrFilter value */
; J1 \5 W, w, Q# ?2 v - /* Set the PR bit according to ETH PromiscuousMode value */
$ P$ f: k- e. T( R! t2 y* a) P - /* Set the PM, HMC and HPF bits according to ETH MulticastFramesFilter value */& _, i U7 o; N
- /* Set the HUC and HPF bits according to ETH UnicastFramesFilter value */! o+ R% P5 A# H& a2 ?3 P
- /* Write to ETHERNET MACFFR */
5 o, ~' Q! l, c G9 S6 l - (heth->Instance)->MACFFR = (uint32_t)(macinit.ReceiveAll |8 E6 j' b% k( \8 m- Q
- macinit.SourceAddrFilter |
5 o* N2 h. i. | - macinit.PassControlFrames |. f& @+ ^/ B, I7 |' M( h
- macinit.BroadcastFramesReception |
w% t7 N& g* D8 z" {6 w' X - macinit.DestinationAddrFilter |
4 R ?) d# T: ^3 ?5 ^+ q& M7 M - macinit.PromiscuousMode |1 o4 [; X4 V2 N, S& y/ k6 Q6 L
- macinit.MulticastFramesFilter |
5 w6 e; G. `' F. q, ^) Z5 H. I - macinit.UnicastFramesFilter);7 B) F1 a2 c; W6 Y
1 a$ B+ G: Z8 d9 f/ k- /* Wait until the write operation will be taken into account:7 G; C' I( F# j" @& p
- at least four TX_CLK/RX_CLK clock cycles */" V1 o8 X7 X# Z: [
- tmpreg = (heth->Instance)->MACFFR;8 J0 V, n1 `* _! }. j. S& ~; Y
- HAL_Delay(ETH_REG_WRITE_DELAY);
" `4 }. I& I7 \ a- D7 `0 X - (heth->Instance)->MACFFR = tmpreg;
) {! u0 ~6 }3 I+ W# R' g - 0 M% L! {6 D3 @# r* }1 g
- /*--------------- ETHERNET MACHTHR and MACHTLR Configuration --------------*/+ U4 B. `+ w+ j! J; v+ m
- /* Write to ETHERNET MACHTHR */
5 q4 g9 v' Y. \/ {& E1 U - (heth->Instance)->MACHTHR = (uint32_t)macinit.HashTableHigh;
8 J% L) x; j- Y: |2 V0 S7 _0 q | - % C5 Y/ W3 k0 D! q( Z& W9 H# Z
- /* Write to ETHERNET MACHTLR */
* C% C0 b1 Y* h8 g- \ z2 M% R! S - (heth->Instance)->MACHTLR = (uint32_t)macinit.HashTableLow;! i- |- G0 I Y3 c+ U8 y. I/ \
- /*----------------------- ETHERNET MACFCR Configuration -------------------*/+ p2 q; e( ?+ J2 b, ~; M
- 8 Y3 \7 z2 s3 L$ d
- /* Get the ETHERNET MACFCR value */
7 b4 ]! q. \+ Q# ^* o9 d! P - tmpreg = (heth->Instance)->MACFCR;# I% j1 P5 n% C) d4 w
- /* Clear xx bits */
' J& h/ k* z) y" A* U# ^( n% t7 `' r - tmpreg &= ETH_MACFCR_CLEAR_MASK;/ y: \5 R3 U& ~% n& v% L
- 6 Z% c/ L3 a+ I& ?% B n
- /* Set the PT bit according to ETH PauseTime value */* O6 P6 D2 `8 f- Y; r
- /* Set the DZPQ bit according to ETH ZeroQuantaPause value */
2 m% L5 }5 Y' j2 @, [/ T1 i - /* Set the PLT bit according to ETH PauseLowThreshold value */1 [! l% F- H9 {, {9 w4 Z1 R& b
- /* Set the UP bit according to ETH UnicastPauseFrameDetect value */
1 E- f1 {2 p$ w# l$ x7 J. T - /* Set the RFE bit according to ETH ReceiveFlowControl value */
: O/ M/ \& i$ @8 k8 i! a* _ - /* Set the TFE bit according to ETH TransmitFlowControl value */
( a5 T# X( @. G - tmpreg |= (uint32_t)((macinit.PauseTime Instance)->MACFCR = (uint32_t)tmpreg;
% q: P, C3 X5 l" ]+ |( H, h3 L8 A* N; ] - 4 c$ @+ d3 }& K; k. M6 ?8 N; O T+ g
- /* Wait until the write operation will be taken into account:: S0 S) N( s3 I& c! R. e
- at least four TX_CLK/RX_CLK clock cycles */
! b2 |) W2 I2 v& ?/ t6 T9 s - tmpreg = (heth->Instance)->MACFCR;
* R* ]: x/ T# H% }: n* S - HAL_Delay(ETH_REG_WRITE_DELAY);
3 |* R: s* T. M+ N8 C: e# B - (heth->Instance)->MACFCR = tmpreg;
4 K# Y6 E/ {) h: [. P - ' a2 ^- i4 N6 A- j( g+ _. N3 ?3 Y
- /*----------------------- ETHERNET MACVLANTR Configuration ----------------*/
7 |5 o' I K8 e+ z. p+ S - /* Set the ETV bit according to ETH VLANTagComparison value */
+ i& W9 R- O2 l- u! w# F Y/ h8 G$ P - /* Set the VL bit according to ETH VLANTagIdentifier value */( L, c5 {7 k' l
- (heth->Instance)->MACVLANTR = (uint32_t)(macinit.VLANTagComparison |
, ]& c3 e; [: Y2 }5 D - macinit.VLANTagIdentifier);0 A7 t6 C$ j s& v K
- ! m6 U; R4 _9 ~: d* A
- /* Wait until the write operation will be taken into account:
; J& a d6 P) Z - at least four TX_CLK/RX_CLK clock cycles */# i3 E. [" M( O; Y3 y3 v
- tmpreg = (heth->Instance)->MACVLANTR;/ g( C' l* p, c. r. k
- HAL_Delay(ETH_REG_WRITE_DELAY);% C: E/ ~4 F& K. R6 v$ D( e
- (heth->Instance)->MACVLANTR = tmpreg;
) k% B* U, q/ W - + i b" Z8 c# x
- /* Ethernet DMA default initialization ************************************/
& Y5 a( i: A& m - dmainit.DropTCPIPChecksumErrorFrame = ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE;, L# k0 b* ^, |
- dmainit.ReceiveStoreForward = ETH_RECEIVESTOREFORWARD_ENABLE;, F. x0 j' Y6 n' N/ m: B! ]4 J" _
- dmainit.FlushReceivedFrame = ETH_FLUSHRECEIVEDFRAME_ENABLE;
4 U; |1 { i- O# d0 |/ k - dmainit.TransmitStoreForward = ETH_TRANSMITSTOREFORWARD_ENABLE;' Z" s5 t0 _1 d% ^" K- I
- dmainit.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES;
% K" {' P" o$ c2 P/ X - dmainit.ForwardErrorFrames = ETH_FORWARDERRORFRAMES_DISABLE;
: d& U: t2 u Z; `* Q - dmainit.ForwardUndersizedGoodFrames = ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE;( `4 e2 O( [7 G) d& _! j5 `
- dmainit.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES;
4 R: m5 ^3 q$ Q. Q - dmainit.SecondFrameOperate = ETH_SECONDFRAMEOPERARTE_ENABLE;
1 Y5 ?6 c: u" B% Y3 j - dmainit.AddressAlignedBeats = ETH_ADDRESSALIGNEDBEATS_ENABLE;
5 [5 t) l- W$ Z/ B& f - dmainit.FixedBurst = ETH_FIXEDBURST_ENABLE;
4 |$ i* c1 T( F! k" H, d - dmainit.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;
+ P- y4 I+ s- M5 z1 W - dmainit.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;
" g4 j, U. P; j2 F7 g. b - dmainit.EnhancedDescriptorFormat = ETH_DMAENHANCEDDESCRIPTOR_ENABLE;5 Z6 c6 m) ~8 V# @* F1 ]
- dmainit.DescriptorSkipLength = 0x0;
& j' N, \ n9 M' v( A - dmainit.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1;6 L n. e# q; A2 i: `; W0 L
- 5 y* K2 y4 R1 }6 w3 r
- /* Get the ETHERNET DMAOMR value */
$ D4 ]7 T+ {# K* i: | - tmpreg = (heth->Instance)->DMAOMR;' L. {" W9 G9 R+ S' M; V9 B: A
- /* Clear xx bits */" B. `( D! ^8 v
- tmpreg &= ETH_DMAOMR_CLEAR_MASK;8 p4 ?! k8 f& f# U
# }/ Z E3 ]" c# h- /* Set the DT bit according to ETH DropTCPIPChecksumErrorFrame value */6 H0 V- D3 d- f% P
- /* Set the RSF bit according to ETH ReceiveStoreForward value */
3 N; ]2 _5 q9 ?. ~8 U N- T0 _ - /* Set the DFF bit according to ETH FlushReceivedFrame value */
5 o# h! I' E s5 f9 u9 t - /* Set the TSF bit according to ETH TransmitStoreForward value */
' g, s6 l* ^( `9 G8 B) z Z - /* Set the TTC bit according to ETH TransmitThresholdControl value */
+ V& n& _' w, b Y4 i% F& X - /* Set the FEF bit according to ETH ForwardErrorFrames value */ D* G' V+ f8 _6 M6 n8 e
- /* Set the FUF bit according to ETH ForwardUndersizedGoodFrames value */% P( |9 y7 x6 ~4 n/ o2 }
- /* Set the RTC bit according to ETH ReceiveThresholdControl value */
; G* y; I; g0 T/ |6 c" X* ]- B - /* Set the OSF bit according to ETH SecondFrameOperate value */2 I# H n* d! \3 H; K( T4 v9 S1 @
- tmpreg |= (uint32_t)(dmainit.DropTCPIPChecksumErrorFrame |% F+ Q. s( O' c' Z# J. g+ U5 [
- dmainit.ReceiveStoreForward |
8 M4 l: C( x. E( @ - dmainit.FlushReceivedFrame |
# Y; P1 c# c4 \; K i! x0 }- a - dmainit.TransmitStoreForward |
0 ]8 X, r6 C/ ]5 k - dmainit.TransmitThresholdControl |4 O7 o+ H' e& Z N O2 D
- dmainit.ForwardErrorFrames |
, b: M; \. ^0 P& w/ j - dmainit.ForwardUndersizedGoodFrames |
* E; }% K; W6 E' m/ ^" K - dmainit.ReceiveThresholdControl |
9 {' M/ w; t$ _9 C+ L* Z8 b. _; r - dmainit.SecondFrameOperate);1 y( ]: ~1 h7 W3 {; Z/ a
- ( a) L- G( I$ _1 w& d
- /* Write to ETHERNET DMAOMR */1 Y& T z) R! t S
- (heth->Instance)->DMAOMR = (uint32_t)tmpreg;) q2 p: h0 N' E5 _4 n! R. q @
0 w; X% Y% ?1 c% i3 U/ u+ M- /* Wait until the write operation will be taken into account:! t }! W! u% I$ W
- at least four TX_CLK/RX_CLK clock cycles */
3 J9 h' F$ C( q( o - tmpreg = (heth->Instance)->DMAOMR;
e" _9 U3 F; j( I, u - HAL_Delay(ETH_REG_WRITE_DELAY);
/ k! i* x. r5 o+ u0 Q0 b) s - (heth->Instance)->DMAOMR = tmpreg;
7 b4 H, z/ }, \2 k - 9 S3 f( \4 U8 O" B6 G
- /*----------------------- ETHERNET DMABMR Configuration ------------------*/
- F7 q+ r. m7 v& U/ [5 j2 B2 \ - /* Set the AAL bit according to ETH AddressAlignedBeats value */) d7 x9 t& l% g4 m2 n# o
- /* Set the FB bit according to ETH FixedBurst value */3 V/ C3 X5 S; {- T
- /* Set the RPBL and 4*PBL bits according to ETH RxDMABurstLength value */$ {0 P1 K' X9 k* K
- /* Set the PBL and 4*PBL bits according to ETH TxDMABurstLength value */" H1 D' N$ i: m* G
- /* Set the Enhanced DMA descriptors bit according to ETH EnhancedDescriptorFormat value*/6 T& \9 Z9 F9 x" @$ y
- /* Set the DSL bit according to ETH DesciptorSkipLength value */( t+ i6 t+ I7 d' Y8 d6 I5 E7 F* K
- /* Set the PR and DA bits according to ETH DMAArbitration value */) Z5 R3 K& H) ]7 Z, \( G1 {
- (heth->Instance)->DMABMR = (uint32_t)(dmainit.AddressAlignedBeats |6 t V4 |9 y& o4 i
- dmainit.FixedBurst |
! p6 i$ i$ Y' X6 W2 x - dmainit.RxDMABurstLength | /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */
; ]0 @: p! ?) y# W ?' |2 s - dmainit.TxDMABurstLength |% W$ V% ^6 P# @; A; @# N% J
- dmainit.EnhancedDescriptorFormat |
( C! h+ u/ ~% U" X4 W* u7 x - (dmainit.DescriptorSkipLength Instance)->DMABMR;7 }; c+ v% s; N, g) k
- HAL_Delay(ETH_REG_WRITE_DELAY);# t P2 {' p0 c8 R A
- (heth->Instance)->DMABMR = tmpreg;& e3 ]( d. E! x- ~( H
- b; H( v7 x2 z9 g- if((heth->Init).RxMode == ETH_RXINTERRUPT_MODE)+ j# x* p* F* k8 @* J5 G
- {
. {: [2 c, C. u- b0 U, {0 t3 M - /* Enable the Ethernet Rx Interrupt */
' K! b7 ~' ]9 c8 L4 e - __HAL_ETH_DMA_ENABLE_IT((heth), ETH_DMA_IT_NIS | ETH_DMA_IT_R); i1 x& Y: U* o* K. q
- }
& X! U0 y) r; } ^7 O& Z! @& | - 6 B' N, I, u& y. R& W
- /* Initialize MAC address in ethernet MAC */
. }& V# j$ q. L' j: J - ETH_MACAddressConfig(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);
8 W) ^/ L* {. w C" x - }
复制代码 0 M% L; G' J- m' J1 O3 T
这里我就要稍微吐槽一下HAL库了
6 d! ]+ u$ D9 ]1 N# wMAC层过滤的设置没有预留接口出来,有设置MAC地址的函数
( E) t" y/ H9 Z M5 e' Z. Y
" g8 w/ Q; E7 E; ] ostatic void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr)3 O% G+ N& m; t: e
" X `: b: @/ H4 n$ I9 V1 i& P
就不多做一个设置MAC层过滤的函数嘛,连后面用到的宏定义都有~~; d2 K3 d4 ]8 X8 N* e1 k
- H( u# c/ s. h7 v. D/ H* X$ @木有办法,自己编一个初始化MAC层过滤的函数吧/ R1 H8 j4 [" L# H" M: S
5 m! l, { {2 B$ S5 K其实也就是把上面这个ETH_MACDMAConfig函数分离成两个单独的设置函数,再编一个设置MAC层过滤的函数/ g' C. D: M+ B4 n
3 d, V O7 I4 F# b. l
开启MAC层过滤的初始化代码
3 ]4 f2 V8 J8 w" [" `$ {6 m- uint8_t ETH_MAC_Setting(ETH_HandleTypeDef *heth), o2 N D; ^$ M C4 k
- { c7 _" Z- j' v! o# H( n% [" y4 t
- ETH_MACInitTypeDef macinit;8 p$ D9 C3 b) V" ^" y
- /* Ethernet MAC default initialization **************************************/, L9 t+ I* i- p
- macinit.Watchdog = ETH_WATCHDOG_ENABLE;- {( f% Z' P( n
- macinit.Jabber = ETH_JABBER_ENABLE;9 t+ O9 g2 p7 V6 j
- macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;6 [) E; d- J# g
- macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;
' m- E2 j, e% k# X - macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;
& m2 Q! K8 B2 V0 z' |9 j - macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;
4 _+ d# ?# C* s& i& k% G: {! G% q( v - if (heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)
$ J: r& o+ i6 I& P. Q' P - {
0 Q; X) L0 ^ I1 {3 X* s5 { - macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;& E% t+ I: O1 I7 w3 Q
- }* v7 W; ]; |( C% j6 G& g
- else
2 T# {2 g* Y9 G( c - {
. S) ?6 F6 h4 u: A - macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;+ D2 ?& V5 b# p2 z; l& M5 r
- }
, r, _+ a+ _9 X0 _, @7 C/ ?; Z - macinit.RetryTransmission = ETH_RETRYTRANSMISSION_ENABLE; //使能重传
% }& K: e! Y2 `: @5 A" x0 W8 t9 t - macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_ENABLE; //使能自动去除
* W0 B* F& x# H - macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;
4 Y. n# ]) r2 F' i8 ?+ w- Q; B - macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE; v9 H) S7 r& v3 F+ l# L! M2 d
- macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE; ///不接收所有包$ w: r$ l6 z* H$ H8 `: O
- macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_NORMAL_ENABLE; //源地址过滤8 q% R6 e8 ?* R0 T* A' }
- macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;- L9 b& Q, g& v4 ]- d0 W4 q
- macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_DISABLE; //广播不接收$ v$ P' i F5 U" S
- macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL; //目的地址过滤& P' z# V* R' n2 n! b( `
- macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE; //混乱模式5 H! U% z7 l7 W* o( v: S
- macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECT; //多播过滤
) o, S t6 i8 W - macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT; //单播过滤
4 A; F/ q1 N; N8 N; f - macinit.HashTableHigh = 0x0; //Hash表高位
; O! {# r) b( J: ^ - macinit.HashTableLow = 0x0; //Hash表低位
9 F3 v+ M/ v# ?' A. C - macinit.PauseTime = 0x0;2 ?2 j* e" ~$ R- V1 A
- macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;' m, u6 @, D+ M$ H. n( R) h
- macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;. M, ?( _' C) \( [. N2 q, {2 O4 d
- macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_ENABLE;
: _" e8 g+ f" Y; ]. z - macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE; //接收流控
1 z7 A" `% y6 j& H. _" f - macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE; //发送流控
; L4 x3 c$ U& R* _% P1 d/ z9 q - macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;' u- l+ j C. J7 |( ` k0 A1 |, p
- macinit.VLANTagIdentifier = 0x0;$ X( ]/ b1 z' M$ U [8 D
- 9 d! _$ b& |& h. `5 N0 B4 W
- return HAL_ETH_ConfigMAC(heth, &macinit);4 @- l8 V7 z- [
- }
复制代码
6 i/ J% X6 t. u8 m/ ]默认的MAC层 DMA初始化函数
9 S( v6 }/ k5 O8 n- uint8_t ETH_DMA_Setting(ETH_HandleTypeDef *heth)3 h8 Y( R% a* G' @5 P5 H7 v! ^
- {7 ]( g8 d) V4 @
- ETH_DMAInitTypeDef dmainit;
+ M5 g+ Y( ^5 Q - /* Ethernet DMA default initialization ************************************/
5 G* |; O9 Y5 |9 z6 P- _ - dmainit.DropTCPIPChecksumErrorFrame = ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE;; C# g. v* E3 y y( V' q$ V6 A0 N1 B
- dmainit.ReceiveStoreForward = ETH_RECEIVESTOREFORWARD_ENABLE;$ y4 s, K1 a4 R) r; J+ _
- dmainit.FlushReceivedFrame = ETH_FLUSHRECEIVEDFRAME_ENABLE;$ j& n/ G! f2 t
- dmainit.TransmitStoreForward = ETH_TRANSMITSTOREFORWARD_ENABLE;
. r4 R1 `% A/ `7 x* y - dmainit.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES;+ y0 b$ x+ U+ o9 q5 a' \
- dmainit.ForwardErrorFrames = ETH_FORWARDERRORFRAMES_DISABLE;7 P P/ g2 P2 B2 Z- L' z+ m% s8 B
- dmainit.ForwardUndersizedGoodFrames = ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE;
! K2 q4 v. ]/ w+ ?- F- n8 m1 O - dmainit.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES;
8 a3 K8 ~9 b+ O5 L8 w" U9 z - dmainit.SecondFrameOperate = ETH_SECONDFRAMEOPERARTE_ENABLE;; b! L2 E! ?5 w
- dmainit.AddressAlignedBeats = ETH_ADDRESSALIGNEDBEATS_ENABLE;6 X [% H, i) M5 R
- dmainit.FixedBurst = ETH_FIXEDBURST_ENABLE;% b: Z- d" o& D, L5 v6 ~, M4 N7 T
- dmainit.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;- S" \2 }2 Q3 I6 |
- dmainit.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;
& S$ ?' p: y4 C) T4 | - dmainit.EnhancedDescriptorFormat = ETH_DMAENHANCEDDESCRIPTOR_ENABLE;
& R/ y' a; M. }1 u - dmainit.DescriptorSkipLength = 0x0;2 d+ N7 s2 }; n" P; k
- dmainit.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1;) T I0 w6 e0 [6 F, t9 L' R
- uint8_t res = HAL_ETH_ConfigDMA(heth, &dmainit);) | w# M; n! O% I
- if ((heth->Init).RxMode == ETH_RXINTERRUPT_MODE)
) i. ~' p! b- s( Y' ~& t3 V/ e& c - {
( u" r, p0 e$ x1 Q# \% h - /* Enable the Ethernet Rx Interrupt */4 m9 \0 w; t+ g0 L C
- __HAL_ETH_DMA_ENABLE_IT((heth), ETH_DMA_IT_NIS | ETH_DMA_IT_R);
7 E1 G; B+ O, R% D - }
g: r7 [7 `; W* _- r - return res;0 j- P% {- b+ M- b
- }
复制代码 ; Z# I& b3 E1 }: ?
用来设置MAC地址的函数(其实就是把库函数的static函数取出来直接用了)- <blockquote>//heth: HAL句柄
复制代码
1 o7 H7 Q, [* ?& Z1 j然后到最最重要的MAC层过滤设置
$ X) S" Z; C |( y* y以MAC1为例
; @' A# ~9 S3 I. H: L- Z! @7 p5 U8 l# J; g- }. A& {
9 Y2 g) L8 {1 i
1 ?; q% p1 ^: u2 \ V$ j# C
! T3 B5 j7 Y8 p# |5 `0 q8 c3 L5 Y9 M1 c9 ^* T% `1 r
注意看红框的描述
2 Q5 Y9 n7 N8 ?/ p+ S' K功能很好用,可以过滤源地址/目的地址,还可以做掩码功能
: Z. t0 N: b$ `' `; F: O- N设置MAC层过滤的代码
% c I& X( f# Y5 W5 }: Q2 |# C, h- static void ETH_MAC_Filter_Setting(ETH_HandleTypeDef *heth,ST_ETH_PAR * para)6 \7 I5 E0 x5 p4 }/ T1 ]
- {3 l! i1 O0 f' e9 b+ p
- //设置本机MAC地址* z" _. r8 o! Y" h
- ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);! y E7 j. X: U8 q& g
- //设置UDP-A的对方MAC地址) x7 u% r" G) T+ H8 J
- ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS1,para->UDP_A_MAC);
; ~( x& @0 ~4 N2 ^* M8 J - (heth->Instance)->MACA1HR|=0xC0000000;//需要完全匹配UDP-A的对方MAC才接收
# P U: H% y, Q j4 j - //设置UDP-B的对方MAC地址
, M6 d+ {6 O" j8 `, K0 d9 x - ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS2,para->UDP_B_MAC);; S; ^0 I7 X7 }) Z" A* `- b
- (heth->Instance)->MACA2HR|=0xC0000000;//需要完全匹配UDP-A的对方MAC才接收
/ g, B0 ~$ W0 n - }
复制代码
8 Q& E' i. V& ]" g' c- j我这里是希望为我的两个UDP精确过滤接收到的源地址$ Y" w3 J* j, d* y( W, G1 F6 y9 z
所以AE位设置为1,SA设置为1,MBC全部为0(MAC地址全部检查)( p0 u7 p2 b' y# k+ I6 C
' `' z# A x: F. D+ C2 a7 |- D假如我希望过滤MAC中特定的厂家字段
: F T; E* [3 {7 Q/ \6 W例如某个MAC地址% \ H' M8 I5 N% n
01-02-03-04-05-06
( l) i- g0 C" d) G4 ? T其中01-02-03就是厂家字段
0 ~$ d/ b1 n$ s* E% O, G6 y, ]8 B& X( ?. l1 r
那么代码要这样修改(MBC的第29位,28位,27位置1)
9 D! E" G7 w. x; X) Q$ k a这样MAC层就不会检查MAC地址里后3个字节(04-05-06)
6 a! `1 H! r D: G6 d# _' G" [( X; W0 Q但是会检查前3个字节,也就是厂家字段
' d) L1 c4 m' q这里需要注意MAC地址的字节序! B' d; U% q# t
- static void ETH_MAC_Filter_Setting(ETH_HandleTypeDef *heth,ST_ETH_PAR * para)5 p3 h) w7 p2 _
- {
4 \' D- R, o2 f+ w5 L, b; z1 Y - //设置本机MAC地址( t& V1 V6 P& E/ I( \# l( X
- ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr); Z8 K4 T8 A8 ~* C `# g
- //设置UDP-A的对方MAC地址0 {6 J% u3 u0 j# u6 K6 Z7 `
- ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS1,para->UDP_A_MAC);: }1 U7 a2 }) q! ?' {; |) ^$ }% f( S
- (heth->Instance)->MACA1HR|=0xF8000000;//需要匹配厂家字段
3 y" E; v2 y1 u# O/ } - //设置UDP-B的对方MAC地址
; ?/ S% g2 d1 N* K: X - ETH_MAC_ADDR_Config(heth, ETH_MAC_ADDRESS2,para->UDP_B_MAC);
4 q: A' m4 { p - (heth->Instance)->MACA2HR|=0xF8000000;//需要匹配厂家字段
* s9 g/ s Y' e( L+ D - }
复制代码
, D. E9 o+ L m然后这些函数的调用顺序按:) N9 E# U. n) q7 a
1. HAL_ETH_Init
' c- r5 h& K, g2 X2. ETH_MAC_Setting
0 {4 C7 v5 W* l! p+ r* s3 ?3. ETH_DMA_Setting
9 W" T7 H e8 U. U' D# R' N' ?! k4. ETH_MAC_Filter_Setting
" U+ h3 _0 V& W: N6 w) p% r% ]; G" ?7 C+ y
用你希望过滤的MAC传递到一个Hash计算函数里,得到一个值,通过这个值产生“映射”关系来过滤MAC地址,所以这个并不是精确的,因为可能会重复~~0 S. \2 p5 [+ V5 o* H$ |5 x
+ x6 K& l$ @9 \' a; R" l5 bHASH函数9 [8 v8 X, u% a. d
函数- V6 g) ?) y3 X5 y+ i( A1 k
- / STM32 MACHASH - Copyright (C) 2014-2018 Clive Turvey (<a href="mailto:sourcer32@gmail.com">sourcer32@gmail.com</a>)
; q, C, d. u6 q: ~, n! W% C - // All Rights Reserved
" j! m7 C: x; t7 l7 h
( s% o3 L1 O$ Q& _- #include <windows.h>
# h2 P- `1 W( @% ~; Z' P$ N - ~+ m% D. u4 _/ v# O y
- #include <stdio.h>: t: O* ^6 i; Y1 f
- #include <stdlib.h>! [% Q. t9 m* d
- 3 }' |, X; P8 Y3 K/ J9 Z' B3 o
- typedef unsigned char uint8_t;
4 q V; g9 U% v& }. R - typedef unsigned long uint32_t;
2 H1 ?4 G; Y; y7 e& O' h - " B1 n6 R3 b4 U- a4 R) @' @5 j
- uint32_t Rev32(uint32_t x)) _: \* V0 j, H4 F5 m( s3 W" H
- {
- m" ? c' B3 @, i: O - uint32_t y;6 L# [# s8 i) \/ G& Q1 O
- int i;. z& N+ V( i; {
" M" D2 T5 {4 `) k# i/ r5 ~4 B- y = 0;
; F7 i; }! c$ G* p3 T$ w$ V/ A8 s
( d3 D, c3 `9 {- for(i=0; i<32; i++)
0 } B9 X' n6 y! x5 s G - if (x & (1 << i))
( l$ M. z& @0 v+ ]+ E - y |= 1 << (31 - i);1 ?& M9 P3 V! b% Y% P& Y
- * N9 X! E% {* M; g; B4 _0 @0 w
- return(y);
9 O$ Q! W: v8 R- @$ ?1 Q - }' j6 R7 s3 k) C! k( q
0 v; j! Y" `9 G P- uint32_t MacHash(const uint8_t *Mac) // <a href="mailto:sourcer32@gmail.com">sourcer32@gmail.com</a>
7 |# ~2 k- s5 J- ?- O# A - {
g8 C! J6 t" \. E- Y7 G" V - int i, j;
+ q; {* r9 z3 J% G/ p - uint32_t Crc;
! [6 Y4 A6 q6 o/ V: o7 w
" j! S. g9 H0 z4 b- Crc = 0xFFFFFFFF;
2 C0 ?: a6 c! L! j$ e
9 u2 H2 i/ r- b" C- for(j=0; j<6; j++)
$ `' |# i9 W3 Y* L7 ?( z - {
- w# H2 d' {- U6 ~7 y1 d8 Y, N - Crc = Crc ^ (uint32_t)Mac[j];
0 u: C9 F* b+ y8 \ - * A# }& D) ?& r3 H+ `0 O! i
- for(i=0; i<8; i++)5 V' G+ d9 x8 `! ?: C/ Q
- if (Crc & 1)
) I* b7 `; a' y+ L' K - Crc = (Crc >> 1) ^ 0xEDB88320; // Reversed 0x04C11DB73 l& [: i; e4 `( K6 Z6 @; b
- else
* D) U {7 f4 |1 K3 n0 T - Crc = (Crc >> 1);6 J2 n1 V, o5 Z2 [
- }! _- W6 ^ \$ T. Z* m
1 T. q" M: b0 Y; s% L, I5 o- return(Rev32(~Crc) >> 26); // Get High order 6-bit in reversed/inverted CRC
* ^ O) P: ^+ y" y2 |$ } - } I5 w$ \. ^) k5 q
- , h' B9 V% g8 `6 R0 L2 a+ s
- uint32_t MacHashFast(const uint8_t *Mac) // <a href="mailto:sourcer32@gmail.com">sourcer32@gmail.com</a>
9 ]: {$ n$ B/ h2 m3 |2 Q/ L$ K. L - {
- t5 m4 m0 y' w7 ^' p - static const uint32_t Rev6Tbl[] = {
+ R9 W3 q O$ q% Q |$ {. ? - 0x00,0x20,0x10,0x30,0x08,0x28,0x18,0x38,- N9 {! c3 g! \% u* b/ t7 h! I
- 0x04,0x24,0x14,0x34,0x0C,0x2C,0x1C,0x3C,
, R/ g# U# T3 I% u, G7 Q+ h$ v5 f7 B - 0x02,0x22,0x12,0x32,0x0A,0x2A,0x1A,0x3A,
- a: \, g+ c. I - 0x06,0x26,0x16,0x36,0x0E,0x2E,0x1E,0x3E,
9 B0 @" Q1 Y3 T7 O* I: ]& U$ O - 0x01,0x21,0x11,0x31,0x09,0x29,0x19,0x39,
4 D' _1 O0 Q& E1 e; Z - 0x05,0x25,0x15,0x35,0x0D,0x2D,0x1D,0x3D,; {, a: w. f6 \$ O& C$ X) J0 `$ R A
- 0x03,0x23,0x13,0x33,0x0B,0x2B,0x1B,0x3B,
$ j' E( w' W/ [ - 0x07,0x27,0x17,0x37,0x0F,0x2F,0x1F,0x3F };- \7 P w6 j& v- ^7 B8 ^
- ) T& F: e% ^) j0 q" H5 @1 r+ T( {' \
- static const uint32_t Crc32Tbl[] = {5 i2 I; o9 ]9 T( f# R
- 0x4DBDF21C, 0x500AE278, 0x76D3D2D4, 0x6B64C2B0,1 D8 g; f0 Q7 h$ O, p. |4 V) ]
- 0x3B61B38C, 0x26D6A3E8, 0x000F9344, 0x1DB88320,5 f7 ?' @3 f- H6 ]# Z! C( q
- 0xA005713C, 0xBDB26158, 0x9B6B51F4, 0x86DC4190,
4 R3 G; z) a1 D U0 j N. g - 0xD6D930AC, 0xCB6E20C8, 0xEDB71064, 0xF0000000 };; ?: a3 H$ F3 ]2 h! x M6 @8 b8 U
- ! `# ?* ]0 S& t! {7 p! a
- int i;3 v! [8 y4 `' ^6 }) @3 j! r
- uint32_t Crc;
% _ e" N' C3 r4 M - + x- S1 V; P9 c2 g6 i+ E
- Crc = 0;
! H/ w7 O, u) k' w3 ] - # e M S' o) j8 p3 Q( b
- for(i=0; i<6; i++)$ Y& r/ A6 z, P! ^. Z
- {
% \) ~$ c/ x( G - Crc = Crc ^ (uint32_t)Mac<i>;
% B: y. a. {) c. b; E
9 b4 O! ^% |! T! X- </i> Crc = (Crc >> 4) ^ Crc32Tbl[Crc & 0x0F]; /* lower nibble */
; g1 I2 q ?. I: w5 l2 f" ~" ^ x - Crc = (Crc >> 4) ^ Crc32Tbl[Crc & 0x0F]; /* upper nibble */" U9 b( i% M* v8 F" `
- }) `7 A; X" {- o: u' Y; E
- 3 d* l) k: y$ W" a6 L2 s
- return(Rev6Tbl[Crc & 0x3F]);
0 C, ]' A$ a8 b& h - }# \6 O; j8 \2 l5 f# L w7 C. }6 q; H+ h
- % t* f8 F1 u/ \5 M1 a1 o" `' y
- int main(int argc, char **argv)
+ ?6 c% y9 c e - {) Q8 H: W m+ G4 a N1 M
- static const uint8_t Test1[] = { 0x1F, 0x52, 0x41, 0x9C, 0xB6, 0xAF }; // 0x2C
; y8 G. F O7 P* \" D5 \& }1 q5 C4 S - static const uint8_t Test2[] = { 0xA0, 0x0A, 0x98, 0x00, 0x00, 0x45 }; // 0x07
8 s3 ~. I' ?4 Z - static const uint8_t Test3[] = { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x21 }; // 0x24
4 W2 Q4 W# l4 T, |7 s1 g% H" b2 _' Z - ( s) \9 `# o' x# y/ o: s8 V+ H
- printf("MacHash %02X\n", MacHash(Test1));
7 P- _# j5 _5 B1 l4 W2 S6 P e - printf("MacHash %02X\n", MacHash(Test2));
& ^6 Q# c" b7 b5 I' k - printf("MacHash %02X\n", MacHash(Test3));
$ g* e5 l t% U0 G5 A& T - 2 n- z. y @; V0 X0 E g
- printf("MacHashFast %02X\n", MacHashFast(Test1));
- G* K* m- q" a% X7 v, r v - printf("MacHashFast %02X\n", MacHashFast(Test2));
1 h! {, t; X" L - printf("MacHashFast %02X\n", MacHashFast(Test3));
5 P0 x% x" s7 k* z t$ v0 o/ R! l - 6 ~8 C8 c9 X! ]0 {5 n: D4 E9 v3 ?
- return(1);- Z! v/ ?( M2 q
- }
复制代码 / d5 a9 q2 `* X9 H+ D; }
0 E& \8 M8 }# z
回到手册- Z% K5 ?8 d' M% M! B' V; G
" N( s6 U1 y2 a' d
' E4 C) l0 Y" m6 l2 b2 V9 r! f9 h! f! e
" o" {) D5 e, A8 f" E7 @! }
8 ?* V8 c5 o0 Y$ H/ u
% O9 h; g$ T! I* [! |8 |上面的函数算出来一个数,假如是手册上的那个0x2c,二进制为101100B
4 H; `$ |- j, \/ w" e换句看得懂的人话···就是:1 u3 @( i/ ?' y% d8 y" l! v& B
算出来的数先看第6位- `% p0 P" l, N+ ^9 w
是1的话说明用到的是HASH表高位寄存器3 L; a I f0 t4 n; o
否则用到的是HASH表低位寄存器! j6 H# A' X! T% B- f% @6 k
然后剩下的5位,转成十进制不是12嘛- k+ [8 P8 j7 c* [' g0 }
如果你希望过滤这个MAC+ ? J1 _' y4 {/ O
那么你就把对应的HASH表高/低位寄存器的对应位置1,否则置0* R( w H: t: H" J5 [ W
这里的0x2c就是要把2 A1 D8 X/ Q( |; K4 Q* ~+ B
HASH表高位寄存器的第12位置1
; v9 w9 X2 c3 U就可以过滤这条MAC了
M, I2 h5 m" r4 H, l' x+ I5 ]然后把你希望的MAC地址都按照上面说的方法弄完7 k4 @( D6 ]1 q; _7 X4 k$ c4 e
: W4 z. V# H5 z回到这个函数稍微改一下. P' @0 ^- ]/ t+ s+ N
- uint8_t ETH_MAC_Setting(ETH_HandleTypeDef *heth)
2 M$ y) x4 P" s4 S, u& C1 I, u - {( V3 h' q! E, J) o3 T
- ETH_MACInitTypeDef macinit;8 \# ]8 r" ]/ A7 l2 U
- /* Ethernet MAC default initialization **************************************/: \1 a- e6 Z' ~0 F
- macinit.Watchdog = ETH_WATCHDOG_ENABLE;
6 M# u+ f/ O1 k3 R4 U$ | - macinit.Jabber = ETH_JABBER_ENABLE;
% X2 d( b7 n d6 r0 Q( ` - macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;% `0 K, P! a8 J0 X' P+ q
- macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;
! x% r B7 V; T* ? - macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;2 c, S6 s" |: U% U _( Q
- macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;
4 V! A% d, C2 {$ Z( ^$ J: ^ - if (heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)
, w5 V7 n# F' g& t. B/ o0 {& G - {. x8 z9 {, y n! H: O4 @
- macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;
! Y/ l5 y* ^2 C8 }! d7 U - }3 k2 Y! D# K0 Q' N
- else
9 h7 t2 B* u. L2 Q( N. M8 h* R - {0 ]" J3 h8 y( x; G0 V
- macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;; w3 P3 o! W: M8 c% H+ ]
- }8 y5 H& b9 T& l, z& i
- macinit.RetryTransmission = ETH_RETRYTRANSMISSION_ENABLE; //使能重传
/ `# i5 u% P9 U t) u5 Q1 ?; @ - macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_ENABLE; //使能自动去除
$ N( k5 d' ~: o - macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;
4 m1 H7 r4 ]6 q b& R3 E% Y - macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE;! U: H% C" p& G4 f/ b8 s
- macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE; ///不接收所有包1 o( Q! Z9 J$ }" a: t" e6 c& `( ]
- macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_NORMAL_ENABLE; //源地址过滤0 l- Q# |" N- Q
- macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;4 J7 a' v. j4 J+ i
- macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_DISABLE; //广播不接收
# _; j& W. ?, w1 a/ C4 V) \# B9 N9 T - macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL; //目的地址过滤& d( L0 o7 b! N( U
- macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE; //混乱模式. ~; [6 H) H" e, h. O* A0 s2 ]
- macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECTHASHTABLE; //!!多播HASH完美过滤
! W- \( q! A' W- t2 s - macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECTHASHTABLE; //!!单播HASH完美过滤6 k" m: a% x6 y0 P7 j
- macinit.HashTableHigh = 0x0; //!!填你最后算完的Hash表高位
, x8 k' O* d4 u; e - macinit.HashTableLow = 0x0; //!!填你最后算完的Hash表低位
! A9 k/ l. E; h2 x' g6 X - macinit.PauseTime = 0x0;
# \- l0 x6 m$ f* h - macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;" [0 j" ~ U4 z* T9 z4 i5 E
- macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;
" x2 y2 |2 q9 c( W+ y - macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_ENABLE;+ H3 D$ ]$ K, r) z( L V4 ^
- macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE; //接收流控
8 i0 `9 n$ @. `0 s) g& e; H - macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE; //发送流控0 f# t' b# J5 w! h/ Y
- macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;% t" y% ?, Y+ A0 |8 j( Y! [; ~7 n
- macinit.VLANTagIdentifier = 0x0;/ t" g9 U' O% n6 g, Z: p
- 0 u3 t# S3 X4 k
- return HAL_ETH_ConfigMAC(heth, &macinit); q( J) r! h( W; h F: a
- }
复制代码
" y) `3 u8 A% [: y& C大概MAC层过滤就这些东西了
: U4 W0 l S5 |: N如果有条件弄MAC层过滤真的强烈建议开启,可以大幅减轻协议栈的处理负担,板卡不会因为处理大量无用的数据而白白浪费处理性能。7 p+ |+ i8 |1 k6 Q- Y1 x
' X# f/ z9 M4 D, z
4 y5 a" W2 A. C, \/ s* y7 `: r
! L& _. b2 g; l3 {6 N0 V# O) S1 v0 j a- a, X7 M7 ?0 m
|