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