本帖最后由 Switcc 于 2018-3-14 17:40 编辑 . F3 d8 V. E, h3 `0 c! Y4 o! @ 上上周本人发帖询问stm32H7平台移植DP83848 PHY驱动的帖子,详见( o. H n# L) |$ ^: _) H' j9 u2 J https://www.stmcu.org.cn/module/forum/thread-614912-1-1.html,3 m- `. W* d% v; {' X# p 按照回帖建议直接使用cube库里LAN8742里的驱动,然后对照不同PHY芯片寄存器查看,可以读到寄存器数据,但是网络一直没有调通,特别是gratuitous arp设备上线的广播都抓不到,更不谈能PING通设备了。 ) E! ?: o/ C7 M0 b 经过长达两周的反复测试和问题排查,直接问题出在MPU和CACHE处理上。现分享使能MPU、CACHE和不使能MPU、CACHE两种模式配置说明:7 o( w2 U( |. n: o k . r, N9 Z7 Z$ _! [ 一、使能MPU、CACHE情况* b" `' P. B2 w 1、main.c中 HAL_Init()上加上MPU和CACHE配置 /* USER CODE BEGIN 1 */ MPU_Config();6 e$ }+ o4 C8 x' v1 ~6 } CPU_CACHE_Enable();% w E9 k, J. n3 Y0 L% F1 [ /* USER CODE END 1 */" C/ v' J) G' F) u* p% m 6 r. I9 A6 \ G0 l3 B /* Reset of all peripherals, Initializes the Flash interface and the Systick. */# _! _3 y' p8 a: q- \ HAL_Init(); /* USER CODE BEGIN 4 */ /**& l- A/ m* \: b( \' ]' V. ` * @brief Configure the MPU attributes * @param None * @retval None& a* K% F; y# W9 s3 f+ C */ static void MPU_Config(void) {) \3 A5 \( q( O/ x% u, F0 x MPU_Region_InitTypeDef MPU_InitStruct; /* Disable the MPU */ HAL_MPU_Disable(); . Z, [7 x2 K+ @0 s- | /* Configure the MPU attributes as Device not cacheable 2 ~% i( T+ j+ G for ETH DMA descriptors */& h. U: o- j- w+ @ MPU_InitStruct.Enable = MPU_REGION_ENABLE; MPU_InitStruct.BaseAddress = 0x30040000; MPU_InitStruct.Size = MPU_REGION_SIZE_256B; MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;% T7 E; L/ q( |; r$ e/ Y N8 u0 H MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE; MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;8 [( H5 e9 V- ?% i MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;4 I. n8 F9 L4 o7 Q' g MPU_InitStruct.Number = MPU_REGION_NUMBER0;! W& v" O& p. r& {: n MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; MPU_InitStruct.SubRegionDisable = 0x00;7 Y, _; {6 h" |& T- N1 `$ o8 j) z MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;$ V6 W% p N6 @0 D0 l * B: {. D6 h1 F' ^/ t* A HAL_MPU_ConfigRegion(&MPU_InitStruct);5 l1 x0 Y9 L, I, \) ~7 G% w /* Configure the MPU attributes as Cacheable write through for LwIP RAM heap which contains the Tx buffers */( p1 A1 k" U- n7 m0 r0 B& S- i* N/ B MPU_InitStruct.Enable = MPU_REGION_ENABLE; MPU_InitStruct.BaseAddress = 0x30044000; MPU_InitStruct.Size = MPU_REGION_SIZE_16KB;5 h) C2 k/ X3 \$ D MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;( i! g% U$ [ i MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;# b" d8 P' h0 C% @" x6 [ MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; MPU_InitStruct.Number = MPU_REGION_NUMBER1; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;9 ?' ]6 Y! K7 h" ? MPU_InitStruct.SubRegionDisable = 0x00; MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); / d+ P; X! s( b6 {# i* l7 k /* Enable the MPU */2 I+ C8 H3 u S HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);& s' T8 m# T' [3 x1 O" l* g } /**2 q8 m; A5 l2 O Q( e5 C$ T * @brief CPU L1-Cache enable.8 ^ I0 {" U, W0 r7 r, H' F * @param None * @retval None/ b9 K. e% _& I3 Z% L$ C0 Q */ static void CPU_CACHE_Enable(void) { /* Enable I-Cache */; J" K" ?& \9 w. d+ ?( | SCB_EnableICache();2 R. Y e. H' K: W$ M /* Enable D-Cache */& d8 ^5 q' W( @* R/ p SCB_EnableDCache();9 f8 ^/ f# p4 z) v3 O# G% k$ k }2 n; p8 B) m+ z' Z0 {) g5 t Y4 C1 E. W& \, w$ l0 n2 C/ O 2、main.c中时钟配置中加上一句 使能SRAM3时钟, H2 U; Z& R: z+ ]3 ] /* Enable D2 domain SRAM3 Clock (0x30040000 AXI)*/ __HAL_RCC_D2SRAM3_CLK_ENABLE(); ) \ f* q0 i U6 }; m6 A1 z : C, Z5 h, U) t7 h/ K; W' H% r$ ? 3、ethernetif.c中DMARxDscrTab、DMATxDscrTab地址分配,注意和MPU对比9 F( V% I! x' S+ d 3 O' t: y8 c, C1 ] #if defined ( __ICCARM__ ) /*!< IAR Compiler */" v: N% x' H, d/ X# N* ?8 r! \ 9 V. J" h. M- f7 r: R #pragma location=0x300400002 N d' s; |/ R, T, L- E+ }8 a ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */ #pragma location=0x30040060: c( u; ^ o5 X2 j( U* L ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */ #pragma location=0x30040200 uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffers */ #elif defined ( __CC_ARM ) /* MDK ARM Compiler */ __attribute__((at(0x30040000))) ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */ __attribute__((at(0x30040060))) ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */$ V5 f) }4 [8 y2 B! ?; ]4 ?1 O( `# H __attribute__((at(0x30040200))) uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffer *// ]0 W3 h2 ~% c #elif defined ( __GNUC__ ) /* GNU Compiler */ ! h, s6 c4 |& `( B ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT] __attribute__((section(".RxDecripSection"))); /* Ethernet Rx DMA Descriptors *// X8 Q/ k, \0 T0 Q- L/ N/ M ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT] __attribute__((section(".TxDecripSection"))); /* Ethernet Tx DMA Descriptors */ uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE] __attribute__((section(".RxArraySection"))); /* Ethernet Receive Buffers */ #endif( H' V M9 y$ |1 [ i9 N" p5 {9 g + c! S. Z) F4 e8 }7 k5 P 1 Z( o! @- }) v' }0 G1 y 4、low_level_output中: G( i0 B: _, V% A; h 6 ~& o% @& W# M1 o8 x8 a SCB_CleanInvalidateDCache(); 1 p+ T H. ^4 r! P HAL_ETH_Transmit(&heth, &TxConfig, 5);" y/ {9 m3 k8 `- ~* W7 p- h 5、low_level_input中 ' `+ a" N- |. t' p$ M/ s) ~ ) _5 Z! e# H3 z6 X6 N /* Clean and Invalidate data cache */+ q$ b/ g# t: c# K6 s8 R SCB_CleanInvalidateDCache(); 3 n i: B* ^ _- n5 M$ { HAL_ETH_GetRxDataBuffer(&heth, &RxBuff); HAL_ETH_GetRxDataLength(&heth, &framelength); SCB_InvalidateDCache_by_Addr((uint32_t *)Rx_Buff, (ETH_RX_DESC_CNT*ETH_RX_BUFFER_SIZE)); W( T; ~. m, {7 q1 q/ L& A6 o 4 Y. t5 A* R& I4 q- C 6 A5 X6 z5 i( ^' O2 _, B 6、lwipopts.h中,注意和MPU对比 /* USER CODE BEGIN 1 */ #define LWIP_RAM_HEAP_POINTER (0x30044000)0 }2 x, f! @% @' Q 8 O! g4 R6 m i8 \" o$ S 7、ETH_RX_BUFFER_SIZE要一致 D0 ]: X) z1 Y. J9 q heth.Init.RxBuffLen = ETH_RX_BUFFER_SIZE;" b+ L4 j- S: E# A7 b / |. T1 l2 c, L# ~8 w0 } __attribute__((at(0x30040200))) uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffer */ , e$ `$ v% W) k+ k/ R SCB_InvalidateDCache_by_Addr((uint32_t *)Rx_Buff, (ETH_RX_DESC_CNT*ETH_RX_BUFFER_SIZE));% ^& u5 d: {4 k# ~ p = pbuf_alloced_custom(PBUF_RAW, framelength, PBUF_POOL, &rx_pbuf[current_pbuf_idx], RxBuff.buffer, ETH_RX_BUFFER_SIZE); - z# C2 ]& |, x! J- u* E " `1 H9 G z+ v6 T1 w7 p, N% @ 8、keil配置RAM如下,勾线IRAM2,不勾选IRAM10 d7 j+ w3 U! E$ C* J 见附件。3 {/ P! o, H. {' A 二、不使能MPU、CACHE情况 上述1,4,5,6标红代码全部注释掉。 三、注意事项; I% e0 r$ \& @- k 1、网络相关管脚配置成高速,cube默认是低速 2、可以先禁止MPU和cache,屏蔽掉相关代码,待网络测通后再开启MPU和cache,进行对应配置 3、H7目前官方库支持不到位,特别是有些examples完全没有经过验证,需特别注意 4、使用MPU和cache时,多看看手册,弄懂机制避免入坑 & g* Z4 D* s) f3 o' M $ v% i, _& n% p9 c3 X, ]) P' T8 i 1 h1 E( b6 l$ m9 y8 ~ 2 h7 _) c* U6 f+ }9 v4 H7 r0 \1 T |
【经验分享】STM32_H7_ADC
STM32H7R/S高性能MCU:安全性,大存储和优异图显赋能更多应用创新
Stm32H7XX GCC下分散加载实现
【银杏科技ARM+FPGA双核心应用】STM32H7系列10——ADC
DIY-STM32H750核心板
[nucleo-H7A3ZI-Q]1-点亮一个皮皮灯
DIY-STM32H743核心板
【银杏科技ARM+FPGA双核心应用】STM32H7系列57——MDK_FLM
1月10日有奖直播 | 基于STM32 的CODESYS智能自动化解决方案
STM32的CAN FD位定时设置注意事项
在大数据量通信交互时,会造成TCP链接中断,抓包显示服务器端有RST,ACK异常,同时ping大包ping不通。经过调试分析,原因是定义的DMA描述定义和RX_buff不够,同时ETHIN的优先级较低导致Lwip内存访问异常。
修改方法:
1.ETH_RX_DESC_CNT 和 ETH_TX_DESC_CNT默认个数是4,根据通信负荷需要扩大,我这里分别扩大到16;
2.修改ETH_DMADescTypeDef
RX:0x30040000
TX:0x30040180
Rx_buff:0x30040400
3.修改MPU的配置
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x30040000;
MPU_InitStruct.Size = MPU_REGION_SIZE_256B; //从256B 修改为 1K
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
4.串口打印可能有影响,视情况关闭;
5.将ETHIN 和 Lwip的任务优先级提高
% ]4 c" L6 O6 e( T2 P; I
之前用的是F207+DP83848,很容易就调通了,这次换了H7之后,CubeMX里面配置完全不一样了,卡了2天,看到楼主发的注意事项,1个小时就调通了,非常感谢!
我再补充一点,在配置LWIP之前,需要先给PHY芯片一个硬复位,不然配置不成功,H7的RAM起始地址一定要是0x24000000,我用的是IAR,修改RAM起始地址的方法跟KEIL不太一样,ALT+F7打开“option”选项,然后选择“Linker”>"Config">"Edit">"Memory Regions"修改即可;
3 r# l* Y; i) I7 J0 G/ C1 @
另外有点注意的就是 使用CubeMX生成的“ethernetif.c”里面,默认的heth.Init.RxBuffLen是1524,但是在"stm32h7xx_hal_eth.h"中,默认的ETH_MAX_PACKET_SIZE 大小是1528,这两个是不一样的,需要手动改成一样的数。3 z5 V0 R- R/ B( Z A
9 v0 [" m( v& k9 o
要是早两天看到你的帖子我就告诉你这个问题出在cache上了,我也正在调试H743的ETH,也是碰到了cache问题。。。不过楼主也是蛮厉害的。不知道楼主有测速没有?我现在遇到的问题是Rx速度不堪入目。
netio:. }+ h' v: ~# J' Q+ G; ]7 v
楼主能加方式交流一下吗?
L- `5 s& m" Z9 l5 Y: u
我耽搁了两周啊,后面被搞得没脾气了
https://www.stmcu.org.cn/module/forum/thread-615031-1-1.html
7 w' a; e, Y0 p6 ?
你好,你的速度是多少?
815201002