
本帖最后由 Switcc 于 2018-3-14 17:40 编辑 5 {4 O- _3 z3 h$ v+ D5 O 上上周本人发帖询问stm32H7平台移植DP83848 PHY驱动的帖子,详见' z0 Y) X4 N- A) n9 m https://www.stmcu.org.cn/module/forum/thread-614912-1-1.html,3 t$ b6 V3 T' x; f' A ! G7 s6 w4 l/ z5 @ 按照回帖建议直接使用cube库里LAN8742里的驱动,然后对照不同PHY芯片寄存器查看,可以读到寄存器数据,但是网络一直没有调通,特别是gratuitous arp设备上线的广播都抓不到,更不谈能PING通设备了。. d, j5 S0 |" \7 L9 c# H" f 经过长达两周的反复测试和问题排查,直接问题出在MPU和CACHE处理上。现分享使能MPU、CACHE和不使能MPU、CACHE两种模式配置说明:+ O* H9 z! t' _+ `; F- f' A' _! q 一、使能MPU、CACHE情况. g9 w. g2 o4 F- f, q$ F 1、main.c中 HAL_Init()上加上MPU和CACHE配置 /* USER CODE BEGIN 1 */ MPU_Config();: T. G* N+ F5 e, R0 Y8 f' _ CPU_CACHE_Enable();1 d$ K7 ~4 O: Y! Y7 [. w# W) { /* USER CODE END 1 */% U' r5 D9 C" A6 ]- ]6 s /* Reset of all peripherals, Initializes the Flash interface and the Systick. */' y! f) h) V- {8 w HAL_Init(); /* USER CODE BEGIN 4 */ /** * @brief Configure the MPU attributes # l* M, N e* Y6 [ * @param None * @retval None# P+ _+ j3 p+ ^ */ static void MPU_Config(void) { MPU_Region_InitTypeDef MPU_InitStruct;% F- ?! U9 ?- V! ~! b1 {! r. [ /* Disable the MPU */ HAL_MPU_Disable(); 8 ~$ e/ g, X( T( E m$ Y/ J /* Configure the MPU attributes as Device not cacheable % G1 `) g" q! k for ETH DMA descriptors */: n- d7 r. x/ }6 U MPU_InitStruct.Enable = MPU_REGION_ENABLE;$ O5 K# g3 u, l4 i$ U5 W: h MPU_InitStruct.BaseAddress = 0x30040000; MPU_InitStruct.Size = MPU_REGION_SIZE_256B;$ o" E2 V+ x( _- R7 D MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;; z p! z( E7 m) w- `" `7 | MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;- p5 F% N# _6 f! t0 j MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; MPU_InitStruct.Number = MPU_REGION_NUMBER0; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; MPU_InitStruct.SubRegionDisable = 0x00;& F! L; a$ `3 I6 M1 n' V8 [ MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;8 t7 H' l1 H# g. T1 K/ J$ k( ?2 e. T 3 n* r X. @' h) g& q+ c HAL_MPU_ConfigRegion(&MPU_InitStruct); /* Configure the MPU attributes as Cacheable write through 3 q* I. {: M o A" B for LwIP RAM heap which contains the Tx buffers */ MPU_InitStruct.Enable = MPU_REGION_ENABLE;( V/ N2 G8 b0 s3 h2 O+ [% S MPU_InitStruct.BaseAddress = 0x30044000;, u K- k" U; E5 p) ~- D MPU_InitStruct.Size = MPU_REGION_SIZE_16KB;% j d+ t% y5 ?! ~) ? MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;5 a+ Z# r0 V$ F3 w5 m, { MPU_InitStruct.Number = MPU_REGION_NUMBER1;8 O* S, q5 h7 h1 r: @( A$ w" s9 Y MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; MPU_InitStruct.SubRegionDisable = 0x00;! e- Q+ m, o; n9 c MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct);: b# l$ S8 B: O* A9 ~. U+ c /* Enable the MPU */ HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT); } 6 \5 V( M+ o8 J3 @9 V /** * @brief CPU L1-Cache enable.+ y6 J' g5 ]6 ?, V3 Y+ y: u( h$ F * @param None * @retval None$ W6 m% l, X6 f3 A" Q2 N- S8 f$ ^ */ static void CPU_CACHE_Enable(void)2 Y9 C) `" a* s% ]$ q7 `- \( o9 p {8 ~* G( j/ {2 e9 \ /* Enable I-Cache */ SCB_EnableICache(); ~' c) Y) N, B& j /* Enable D-Cache */, y! J* a, B8 {' `" t& c, n SCB_EnableDCache();) P4 X; k- h5 o4 J } / F' [$ s6 `1 |9 J, |2 H5 b % u& F9 e" O( S9 B- x8 t 2、main.c中时钟配置中加上一句 使能SRAM3时钟$ F6 D. Q' ?! N8 u /* Enable D2 domain SRAM3 Clock (0x30040000 AXI)*/ __HAL_RCC_D2SRAM3_CLK_ENABLE(); # c/ c8 ^- ]1 [1 g; U, T 3、ethernetif.c中DMARxDscrTab、DMATxDscrTab地址分配,注意和MPU对比 #if defined ( __ICCARM__ ) /*!< IAR Compiler */, P" v) P* P/ M& P$ m- i* n8 e ! _6 _$ n1 d- ~4 N1 _- X1 D #pragma location=0x30040000 ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */8 M- m7 g: w) B ?1 o3 m #pragma location=0x30040060' f# r. c2 `4 y+ k: t. |+ I ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */0 T3 `! j" X" |* q# i( G, g: H% m #pragma location=0x30040200 uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffers */ - k5 d, Y& e5 h: c6 I: M #elif defined ( __CC_ARM ) /* MDK ARM Compiler */; Q9 g3 c" i0 T' G8 r 5 B% z8 B/ E7 {3 Z1 e __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 */, I( Y& O- R) q- q __attribute__((at(0x30040200))) uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffer */ ( R: k$ i6 N, c- R: u% d; n #elif defined ( __GNUC__ ) /* GNU Compiler */ 0 o9 ?# I$ `" F7 O& h7 S2 e/ v ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT] __attribute__((section(".RxDecripSection"))); /* Ethernet Rx DMA Descriptors */: S: Z, m' e9 b9 ?" r+ f ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT] __attribute__((section(".TxDecripSection"))); /* Ethernet Tx DMA Descriptors */5 N/ ?$ T$ E- H, Z uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE] __attribute__((section(".RxArraySection"))); /* Ethernet Receive Buffers */ & a9 y" @7 F/ i3 {1 b #endif8 l+ _$ R4 J( `+ `! C4 Z ! X5 {7 T3 Q4 k5 o7 J 4、low_level_output中" p5 @0 e) B8 E SCB_CleanInvalidateDCache();" d4 p/ u6 Q7 s1 l; E4 l HAL_ETH_Transmit(&heth, &TxConfig, 5); 5、low_level_input中 . t$ z3 @7 B0 m- Z! @ /* Clean and Invalidate data cache */, S3 y: q* p h* a5 _, D8 W) o7 Y: [ SCB_CleanInvalidateDCache();! w4 M* i7 Q0 D% v! k 1 y4 @8 @$ j1 _3 B HAL_ETH_GetRxDataBuffer(&heth, &RxBuff);. I+ P, v* N, L0 E) W7 ?9 A; ^ HAL_ETH_GetRxDataLength(&heth, &framelength); 6 A4 a, k, J2 `( E) z5 ~: A7 R SCB_InvalidateDCache_by_Addr((uint32_t *)Rx_Buff, (ETH_RX_DESC_CNT*ETH_RX_BUFFER_SIZE)); / o% C8 [# h( k8 m+ ~6 n* C4 C3 l 8 {' y ~3 I2 B 6、lwipopts.h中,注意和MPU对比 /* USER CODE BEGIN 1 */* u$ ~+ W0 I* N, h #define LWIP_RAM_HEAP_POINTER (0x30044000) 7、ETH_RX_BUFFER_SIZE要一致 heth.Init.RxBuffLen = ETH_RX_BUFFER_SIZE;) G) |! r: \. `2 E- o4 t) O6 |! c% h __attribute__((at(0x30040200))) uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffer */2 Q. ]4 h/ z$ @2 k4 I* i6 T . X( h" L s! g! r SCB_InvalidateDCache_by_Addr((uint32_t *)Rx_Buff, (ETH_RX_DESC_CNT*ETH_RX_BUFFER_SIZE));# K% W5 w- q2 B1 @5 `" ~; m! y2 Q & ^8 M) w, z+ ~9 @ p = pbuf_alloced_custom(PBUF_RAW, framelength, PBUF_POOL, &rx_pbuf[current_pbuf_idx], RxBuff.buffer, ETH_RX_BUFFER_SIZE);+ G+ [6 \$ B8 z2 \4 z( \4 N ; v% N5 R: ]& ?3 O 8、keil配置RAM如下,勾线IRAM2,不勾选IRAM1 见附件。: M0 U* w' K$ L3 q, a0 E7 o , o/ `6 K9 H2 N( j: K4 c. R * U3 Y+ O' ?7 n6 r! y% ^ 二、不使能MPU、CACHE情况 ) N! n- e! i2 m3 E! |) o Z 上述1,4,5,6标红代码全部注释掉。 & M, O7 B* O9 k9 L6 f( o5 ` 三、注意事项 1、网络相关管脚配置成高速,cube默认是低速 2、可以先禁止MPU和cache,屏蔽掉相关代码,待网络测通后再开启MPU和cache,进行对应配置 3、H7目前官方库支持不到位,特别是有些examples完全没有经过验证,需特别注意( P( `, |7 W5 D. l( `! U4 \* G 4、使用MPU和cache时,多看看手册,弄懂机制避免入坑 C( K7 v$ _. ~: A% w4 U! Z8 E2 }$ I 5 L; }" @* h6 r: Q. A 9 H8 ]0 F9 I4 n/ ]7 ^ |
【2025·STM32峰会】GUI解决方案实训分享5-调通板载的NRF24L01 SPI接口并使用模块进行无线通信(发送和接收)
【2025·STM32峰会】GUI解决方案实训分享4-使用MVP架构从硬件外设读取数据并显示到图形界面、从图形界面发送指令控制硬件外设
【2025·STM32峰会】GUI解决方案实训分享3-搭建空白TouchGFX例程并实现简单的功能(含硬件部分的串口打印)
【2025·STM32峰会】GUI解决方案实训分享2-编译运行TouchGFX咖啡机例程(含桌面仿真)
【2025·STM32峰会】+TouchGFX实现动态进度显示以及界面切换
【2025·STM32峰会】+使用TouchGFX快速创建GUI
【2025·STM32峰会】GUI解决方案实训分享1-对LVGL咖啡机例程的牛刀小试以及问题排查
实战经验 | 关于STM32H7使用LL库生成ADC代码工作异常问题说明
实战经验 | 关于STM32H745的MC SDK电机控制工程问题的解决办法
【H745I GUI】1.GreenHouse 灯光控制
在大数据量通信交互时,会造成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的任务优先级提高
之前用的是F207+DP83848,很容易就调通了,这次换了H7之后,CubeMX里面配置完全不一样了,卡了2天,看到楼主发的注意事项,1个小时就调通了,非常感谢!
我再补充一点,在配置LWIP之前,需要先给PHY芯片一个硬复位,不然配置不成功,H7的RAM起始地址一定要是0x24000000,我用的是IAR,修改RAM起始地址的方法跟KEIL不太一样,ALT+F7打开“option”选项,然后选择“Linker”>"Config">"Edit">"Memory Regions"修改即可;
" b2 M) K7 V, j4 `6 T6 K
另外有点注意的就是 使用CubeMX生成的“ethernetif.c”里面,默认的heth.Init.RxBuffLen是1524,但是在"stm32h7xx_hal_eth.h"中,默认的ETH_MAX_PACKET_SIZE 大小是1528,这两个是不一样的,需要手动改成一样的数。1 }; u5 W8 ^# A: u6 h
要是早两天看到你的帖子我就告诉你这个问题出在cache上了,我也正在调试H743的ETH,也是碰到了cache问题。。。不过楼主也是蛮厉害的。不知道楼主有测速没有?我现在遇到的问题是Rx速度不堪入目。7 `. v/ a) O! K; J
netio:9 n! c8 V% J& B3 j0 l) h9 X$ O
楼主能加方式交流一下吗?
$ X$ \0 s7 @6 @0 e. S7 n' D
我耽搁了两周啊,后面被搞得没脾气了
https://www.stmcu.org.cn/module/forum/thread-615031-1-1.html
% f2 V3 J2 G r! u+ f1 M) k, ]4 Q
& G; E; O7 A8 u h/ [% P: J
你好,你的速度是多少?
815201002