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