
本帖最后由 Switcc 于 2018-3-14 17:40 编辑 " C% ?" ?! L$ j0 x" p0 E/ O9 v' Z / k8 k3 q1 h2 i5 m 上上周本人发帖询问stm32H7平台移植DP83848 PHY驱动的帖子,详见9 }9 I7 a/ d- G( O% {3 | https://www.stmcu.org.cn/module/forum/thread-614912-1-1.html, . I: ]5 y( ^( X# N# E 按照回帖建议直接使用cube库里LAN8742里的驱动,然后对照不同PHY芯片寄存器查看,可以读到寄存器数据,但是网络一直没有调通,特别是gratuitous arp设备上线的广播都抓不到,更不谈能PING通设备了。 3 ^: a7 H& j* K+ W# ^1 C 经过长达两周的反复测试和问题排查,直接问题出在MPU和CACHE处理上。现分享使能MPU、CACHE和不使能MPU、CACHE两种模式配置说明:! M4 O# W+ n; g' A" _. l+ U; x+ S 1 b$ h5 ~; H1 b- q# d% t) t 一、使能MPU、CACHE情况& ~: [( W3 [& _% j/ D( x0 s 1、main.c中 HAL_Init()上加上MPU和CACHE配置- K( I# B9 x- D& B$ T+ M" v; C /* USER CODE BEGIN 1 */ MPU_Config(); CPU_CACHE_Enable(); /* USER CODE END 1 */ - s# C! y$ a2 i /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); : {, x3 \2 y- X U5 m' s% `0 b /* USER CODE BEGIN 4 */+ R: s9 m ~0 v4 k' i% F) X4 _ /**% M$ C0 a- r; t3 [6 K2 y3 Q" E4 f * @brief Configure the MPU attributes * @param None) w. C/ o: C8 R( l/ r& ~ * @retval None0 c2 Y$ d3 U* v5 @ */9 K+ v: b9 l2 t7 x( J; u# P static void MPU_Config(void) {) v/ j* l+ Q1 E' ]# w+ _* w; y. H MPU_Region_InitTypeDef MPU_InitStruct; ' j% V0 q1 x/ J4 }+ h1 p5 J5 R /* Disable the MPU */, S8 G! v* g/ M. B9 e' @# q HAL_MPU_Disable(); / \# K! d, P( S+ s& X" g$ _ /* Configure the MPU attributes as Device not cacheable for ETH DMA descriptors */6 m: y- {6 D4 l MPU_InitStruct.Enable = MPU_REGION_ENABLE;. B* M# ], a8 w7 y6 b/ |+ k MPU_InitStruct.BaseAddress = 0x30040000;% m; ^! W# W5 H, J" \9 C" p/ ]" g MPU_InitStruct.Size = MPU_REGION_SIZE_256B;% @$ X1 S) m( Y2 N6 x+ ^/ S4 N MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;$ S) ]: {# x8 n MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE; MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; MPU_InitStruct.Number = MPU_REGION_NUMBER0;* R T/ g0 B, D. Q+ @ MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;5 R- d1 |) y$ D! O V MPU_InitStruct.SubRegionDisable = 0x00; MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;% l( J- I0 T: T0 d" ?3 B. R* t) ? # [1 p- l6 ~" y( K' v- d. c HAL_MPU_ConfigRegion(&MPU_InitStruct); ; L5 P, E% H [6 ]7 d /* Configure the MPU attributes as Cacheable write through for LwIP RAM heap which contains the Tx buffers */ MPU_InitStruct.Enable = MPU_REGION_ENABLE;, Z9 r' c z2 {" e& v/ Y MPU_InitStruct.BaseAddress = 0x30044000; MPU_InitStruct.Size = MPU_REGION_SIZE_16KB; MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;5 {9 N* N. i, w) U" J# U3 i+ y, f M MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;8 H6 Q f4 Q, w5 q& y MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;( E8 e. P, ?# |0 d MPU_InitStruct.Number = MPU_REGION_NUMBER1; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; MPU_InitStruct.SubRegionDisable = 0x00; MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;( J9 Y5 l3 k9 c z! B " u0 L5 t, r; G' t. ` L, O) ] HAL_MPU_ConfigRegion(&MPU_InitStruct); ; _, G. s ~: s* S/ p7 ^4 Y* v3 X/ X- l /* Enable the MPU */$ j$ _' d% E0 F2 ?$ s9 W# I HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT); }4 Z9 d- s! O6 z: ?0 x' \ # W( ?" | Q, d+ F& \ /**3 t/ Z7 M# g0 l * @brief CPU L1-Cache enable. * @param None * @retval None8 H+ f9 h b" \, D: G6 ]1 L$ n- n */+ S% ^6 s" f* l2 z% a/ o0 b static void CPU_CACHE_Enable(void)3 ~: O+ U' g: |& S9 m# M {3 i1 r& G+ j( L0 c /* Enable I-Cache */6 ~: @) Y* U9 n" S/ p# Y8 H SCB_EnableICache(); . e* ?3 h* a7 U1 d6 h( q8 j T0 M1 b /* Enable D-Cache */0 S9 t, O4 }+ ~3 i/ Q* f SCB_EnableDCache(); } 3 f6 K+ {& E; [5 O2 r4 S 2、main.c中时钟配置中加上一句 使能SRAM3时钟 /* Enable D2 domain SRAM3 Clock (0x30040000 AXI)*/ __HAL_RCC_D2SRAM3_CLK_ENABLE();0 }9 Q! F/ |! _2 | 1 W3 m$ o$ G1 [$ M* E / z, p8 a( g" K/ V& d 3、ethernetif.c中DMARxDscrTab、DMATxDscrTab地址分配,注意和MPU对比2 W& x* d O# _2 S4 M 2 @" q3 s: B- c/ Y- L #if defined ( __ICCARM__ ) /*!< IAR Compiler */( U' m: _3 Y4 l! I) ?/ k + U& U/ u/ A0 d, V1 Y #pragma location=0x30040000+ p. h1 ~7 h9 _$ P. z+ T. g8 X ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */. c5 o3 {& c. r7 m2 y #pragma location=0x30040060# A- V, N* u, W/ Z; Q ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */ #pragma location=0x30040200" \; L4 E" o# G( a; N7 Z: ] uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffers */ #elif defined ( __CC_ARM ) /* MDK ARM Compiler */ # j4 |' W: N4 \- n8 U5 V' A __attribute__((at(0x30040000))) ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */% }5 j. m" b5 C: }& C% B) K: ~ __attribute__((at(0x30040060))) ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */ __attribute__((at(0x30040200))) uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffer */. \* C2 E3 D8 P9 U# y+ z5 y , c4 } ]4 H- V9 u2 b4 t% {' h( [ #elif defined ( __GNUC__ ) /* GNU Compiler */ ; \- i/ w$ |& g5 X ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT] __attribute__((section(".RxDecripSection"))); /* Ethernet Rx DMA Descriptors */ A% c6 Z6 O6 w8 a- R2 x, M3 [7 Z/ s ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT] __attribute__((section(".TxDecripSection"))); /* Ethernet Tx DMA Descriptors */2 m$ [$ f$ F, Z% b& e uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE] __attribute__((section(".RxArraySection"))); /* Ethernet Receive Buffers */' Z$ q3 E+ j. Y0 N2 J! e9 B Z7 T5 E: i" [+ \1 A #endif3 s% n. |$ ]) n7 t+ B2 } 6 W. m* Y# a9 P4 C! ~( l8 v9 @1 I 4、low_level_output中$ n( d6 O- H0 J# C0 v1 L! o 9 j3 p1 X' h8 y4 X# @( A+ y SCB_CleanInvalidateDCache(); HAL_ETH_Transmit(&heth, &TxConfig, 5);7 B0 |/ g8 |9 _! a2 ~ 9 U2 g. T; p9 r7 [; w0 A 5、low_level_input中 /* Clean and Invalidate data cache */0 a3 a: s/ I* O9 s$ ] SCB_CleanInvalidateDCache(); HAL_ETH_GetRxDataBuffer(&heth, &RxBuff);( T: |, r! B) M5 |: j% l HAL_ETH_GetRxDataLength(&heth, &framelength); SCB_InvalidateDCache_by_Addr((uint32_t *)Rx_Buff, (ETH_RX_DESC_CNT*ETH_RX_BUFFER_SIZE));# C- S) H# ]% |" M7 M9 A5 } d % e& z( M1 q, L7 A" t - \4 g+ L8 D, [1 A$ r" h) J7 w, x 8 S) |. n) J2 g/ c( z2 x8 a9 M' g 6、lwipopts.h中,注意和MPU对比 /* USER CODE BEGIN 1 */" o$ O' l$ N% A9 [; x #define LWIP_RAM_HEAP_POINTER (0x30044000) 7、ETH_RX_BUFFER_SIZE要一致 heth.Init.RxBuffLen = ETH_RX_BUFFER_SIZE; __attribute__((at(0x30040200))) uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffer */' f1 `% L- j# B; c SCB_InvalidateDCache_by_Addr((uint32_t *)Rx_Buff, (ETH_RX_DESC_CNT*ETH_RX_BUFFER_SIZE)); p = pbuf_alloced_custom(PBUF_RAW, framelength, PBUF_POOL, &rx_pbuf[current_pbuf_idx], RxBuff.buffer, ETH_RX_BUFFER_SIZE);5 H( ?! @! \* x + I* _: t: J$ I, B 8、keil配置RAM如下,勾线IRAM2,不勾选IRAM1( R6 z; X" I; ]! T' f; i 见附件。 r) a5 h7 x- K9 Z8 W- L 二、不使能MPU、CACHE情况 3 `0 U2 ^/ B p) Z! S& U) ~ 上述1,4,5,6标红代码全部注释掉。 三、注意事项 1、网络相关管脚配置成高速,cube默认是低速6 N( [( D) @9 U, f/ l6 L8 A3 c) Z 2、可以先禁止MPU和cache,屏蔽掉相关代码,待网络测通后再开启MPU和cache,进行对应配置! V, f" Q: a8 N: d; { 3、H7目前官方库支持不到位,特别是有些examples完全没有经过验证,需特别注意. q& F$ r) P* X" x5 Z, Y 4、使用MPU和cache时,多看看手册,弄懂机制避免入坑8 x7 v3 d O" B$ Z7 l. h ! ]& g6 _7 H$ p( i: r3 L5 W 2 S9 S6 L5 @( E {' i7 p |
拷打cubemx【003】——找不到的芯片包
【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电机控制工程问题的解决办法
在大数据量通信交互时,会造成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"修改即可;2 H5 z6 w. j/ f7 Y1 w/ L* d3 ]
另外有点注意的就是 使用CubeMX生成的“ethernetif.c”里面,默认的heth.Init.RxBuffLen是1524,但是在"stm32h7xx_hal_eth.h"中,默认的ETH_MAX_PACKET_SIZE 大小是1528,这两个是不一样的,需要手动改成一样的数。' {5 E* H1 v' ^! B X" m( f/ g
要是早两天看到你的帖子我就告诉你这个问题出在cache上了,我也正在调试H743的ETH,也是碰到了cache问题。。。不过楼主也是蛮厉害的。不知道楼主有测速没有?我现在遇到的问题是Rx速度不堪入目。& a$ V7 g# m, ^) r" T4 F6 ~6 G
netio:1 K2 A* h0 q( \ R" e
! z$ `7 a( \& p4 l( W" W- b+ n, c) ?
楼主能加方式交流一下吗?
我耽搁了两周啊,后面被搞得没脾气了
https://www.stmcu.org.cn/module/forum/thread-615031-1-1.html
你好,你的速度是多少?4 P. W# C, h4 g u" ^3 T
815201002