本帖最后由 Switcc 于 2018-3-14 17:40 编辑 3 H) T6 G6 l# r5 W( X6 m 上上周本人发帖询问stm32H7平台移植DP83848 PHY驱动的帖子,详见 https://www.stmcu.org.cn/module/forum/thread-614912-1-1.html, 按照回帖建议直接使用cube库里LAN8742里的驱动,然后对照不同PHY芯片寄存器查看,可以读到寄存器数据,但是网络一直没有调通,特别是gratuitous arp设备上线的广播都抓不到,更不谈能PING通设备了。 : B2 \* q" x7 T+ k 经过长达两周的反复测试和问题排查,直接问题出在MPU和CACHE处理上。现分享使能MPU、CACHE和不使能MPU、CACHE两种模式配置说明:5 |6 w. a8 @/ } : d6 c8 B! L9 E 一、使能MPU、CACHE情况( Q5 c9 C2 r6 G 1、main.c中 HAL_Init()上加上MPU和CACHE配置4 b2 J7 m, [0 R, @3 B. @ /* USER CODE BEGIN 1 */ MPU_Config();3 i, v! j# G8 U. I/ U+ _ CPU_CACHE_Enable(); /* USER CODE END 1 */ . l" `% O2 n) `8 f$ M; \ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */8 {% q- ^4 C5 ~1 J) d& ~ HAL_Init();$ s( G2 J L+ F, M8 R3 { $ y" i; i" n; u1 F3 } /* USER CODE BEGIN 4 */ /** * @brief Configure the MPU attributes * @param None/ ^$ i) r) r* a5 w) [8 }2 v' C * @retval None4 _6 H( K' A( b9 { */ static void MPU_Config(void) { MPU_Region_InitTypeDef MPU_InitStruct;1 L0 N" q8 j3 y: ~ /* Disable the MPU */0 c* J, r: n# P8 a6 i+ ^6 g2 \ HAL_MPU_Disable(); /* Configure the MPU attributes as Device not cacheable . o: ~* U M$ B& |1 G4 S for ETH DMA descriptors */7 i3 Z- C0 E: n3 Q- H MPU_InitStruct.Enable = MPU_REGION_ENABLE;. p( J: U- t/ O5 N5 F8 }) _+ @1 C MPU_InitStruct.BaseAddress = 0x30040000;) ?0 Z' [# D5 |2 C MPU_InitStruct.Size = MPU_REGION_SIZE_256B;. o9 A6 ^, Y0 Z" {/ P- Q0 A MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE; MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;+ C2 M# A; q9 Z" a0 X MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; MPU_InitStruct.Number = MPU_REGION_NUMBER0;; @4 a8 ]! q' P4 P$ V8 }3 w7 m6 } MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;; x' M' a8 F W- P# v MPU_InitStruct.SubRegionDisable = 0x00; MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); 4 p2 E; [- M7 `5 ] c, W /* Configure the MPU attributes as Cacheable write through for LwIP RAM heap which contains the Tx buffers */5 w7 s, f/ L4 Q! a MPU_InitStruct.Enable = MPU_REGION_ENABLE; MPU_InitStruct.BaseAddress = 0x30044000; MPU_InitStruct.Size = MPU_REGION_SIZE_16KB;+ N4 i4 I$ V( N9 v MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;! w' H' d$ q( @) \# M- [9 ^2 C( F MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;) M' n: t$ w& |* V) m/ _4 j1 q MPU_InitStruct.Number = MPU_REGION_NUMBER1; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;: ~) ^/ l( r2 D6 J& O' b: d+ O; Q# J MPU_InitStruct.SubRegionDisable = 0x00;6 c( t2 [6 R* ?& X n8 I MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;% F: @2 j! l+ \0 t) l" }* ~+ t $ n# t! Y9 i7 X HAL_MPU_ConfigRegion(&MPU_InitStruct);+ y7 M0 U# k+ Q! y( D 1 A& m) S. V' [! w+ q /* Enable the MPU */, U( C5 j! S+ a2 N7 L) j: I/ i HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);8 p2 L5 y) s7 u5 q' R! m4 I } /** * @brief CPU L1-Cache enable. * @param None * @retval None; ], T) Z" K) y5 E */( p4 ^) I) l9 w* [. @ static void CPU_CACHE_Enable(void) l* v& f0 c# p8 G* N5 X. Y. @ { /* Enable I-Cache */$ Z0 y; `0 E. L2 t SCB_EnableICache(); ! T' q0 ~8 w+ ^; F8 G /* Enable D-Cache */+ L5 A9 w! g8 V& M0 M SCB_EnableDCache(); } ! A" ]9 F- E4 N7 v+ G9 g 2、main.c中时钟配置中加上一句 使能SRAM3时钟- ]8 H( e* P, H' T7 S4 Q, U /* Enable D2 domain SRAM3 Clock (0x30040000 AXI)*/, p1 d: a! A% {6 I __HAL_RCC_D2SRAM3_CLK_ENABLE();; h0 Y8 x( ^4 ?5 x3 p 4 C7 ?0 f* Q, c! Q 3、ethernetif.c中DMARxDscrTab、DMATxDscrTab地址分配,注意和MPU对比 #if defined ( __ICCARM__ ) /*!< IAR Compiler */ #pragma location=0x300400002 Q; e+ p4 k( A# l9 _! M w5 @ ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */. k8 g/ Y- f6 Y; _' ^! W2 d# j @ #pragma location=0x30040060) Z0 T: y7 f* h7 O4 t2 B, | ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */: o/ o% i0 A$ J. u2 t* l) @ #pragma location=0x30040200 uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffers */% P1 n% Z( j: C- C+ Q: S #elif defined ( __CC_ARM ) /* MDK ARM Compiler */ 6 o$ Z* z- W s4 x" P __attribute__((at(0x30040000))) ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */+ w) r/ U$ t' a1 _6 q( z( b __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 */: \$ t1 O2 m) o. S- s #elif defined ( __GNUC__ ) /* GNU Compiler */ 3 w. Y' a. ]1 ]9 X7 j+ { ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT] __attribute__((section(".RxDecripSection"))); /* Ethernet Rx DMA Descriptors */ ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT] __attribute__((section(".TxDecripSection"))); /* Ethernet Tx DMA Descriptors */! N/ ^, `' c* s* s. h- S2 g uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE] __attribute__((section(".RxArraySection"))); /* Ethernet Receive Buffers */& A- ?( f1 h3 P8 B7 a- @" J4 d3 X5 M ) |8 n8 r0 h+ J$ |, X& C# i# F+ L #endif ! z: n9 R$ }+ O0 p- D 4、low_level_output中' g" O& L/ J$ E- o 7 D! u! A; [6 D: { SCB_CleanInvalidateDCache(); / [3 e9 x6 Z0 v) h$ c% o. s HAL_ETH_Transmit(&heth, &TxConfig, 5);' _' v" Y m" k# K! d 3 S& L' [- ~4 D! w" L3 L 5、low_level_input中 /* Clean and Invalidate data cache */( ^$ v( C3 f1 `. h7 T+ }+ P SCB_CleanInvalidateDCache(); % r% }) D" J/ z8 m HAL_ETH_GetRxDataBuffer(&heth, &RxBuff); HAL_ETH_GetRxDataLength(&heth, &framelength);' `$ K0 k+ Q- ^( D& ?+ I7 L 6 ?: F4 q; S- n( G SCB_InvalidateDCache_by_Addr((uint32_t *)Rx_Buff, (ETH_RX_DESC_CNT*ETH_RX_BUFFER_SIZE)); # P! p6 w& t& Q & {5 D7 f6 z9 Q6 A) W( k 6、lwipopts.h中,注意和MPU对比' _4 `. u: a7 @1 f) B /* USER CODE BEGIN 1 */' m4 d, k3 b' v1 ~8 ~ #define LWIP_RAM_HEAP_POINTER (0x30044000) 7、ETH_RX_BUFFER_SIZE要一致; H( L5 {! _0 V+ C* v$ s# Z heth.Init.RxBuffLen = ETH_RX_BUFFER_SIZE;% \8 Z: ?; ^6 c5 N/ f3 Y$ ?' m __attribute__((at(0x30040200))) uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffer */ `- D1 l# [6 E9 |, \% J; j' L+ w SCB_InvalidateDCache_by_Addr((uint32_t *)Rx_Buff, (ETH_RX_DESC_CNT*ETH_RX_BUFFER_SIZE));" y. R6 J5 l$ b; [ ( B8 J C: I0 M p = pbuf_alloced_custom(PBUF_RAW, framelength, PBUF_POOL, &rx_pbuf[current_pbuf_idx], RxBuff.buffer, ETH_RX_BUFFER_SIZE);" Q* }' @5 y+ _. J" t % B/ F/ w7 _) P 1 x O( @/ i9 w" `* @& F: d( ~ 8、keil配置RAM如下,勾线IRAM2,不勾选IRAM1; ]1 M/ E2 G3 Q. k 见附件。 二、不使能MPU、CACHE情况' w4 T; b& u1 M4 L& ` 上述1,4,5,6标红代码全部注释掉。; u+ ]6 X. ]% ]$ [ $ l1 |; c5 E1 r. v! F- N1 Y8 ^ 三、注意事项 1、网络相关管脚配置成高速,cube默认是低速) L& I" z3 l% U/ ^# T 2、可以先禁止MPU和cache,屏蔽掉相关代码,待网络测通后再开启MPU和cache,进行对应配置# S8 Z! {' w# g# ^4 c) H* X 3、H7目前官方库支持不到位,特别是有些examples完全没有经过验证,需特别注意' Z* `/ j2 \6 ^9 C3 t/ [6 V, p 4、使用MPU和cache时,多看看手册,弄懂机制避免入坑$ W2 c( D8 @# }0 A/ t' x3 o. j 5 J' i; h( F) P9 C F) h# ] 2 E! w* e8 F+ o9 N# r |
【经验分享】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的任务优先级提高
之前用的是F207+DP83848,很容易就调通了,这次换了H7之后,CubeMX里面配置完全不一样了,卡了2天,看到楼主发的注意事项,1个小时就调通了,非常感谢!4 P) S& |. C/ O/ g6 Y; _
我再补充一点,在配置LWIP之前,需要先给PHY芯片一个硬复位,不然配置不成功,H7的RAM起始地址一定要是0x24000000,我用的是IAR,修改RAM起始地址的方法跟KEIL不太一样,ALT+F7打开“option”选项,然后选择“Linker”>"Config">"Edit">"Memory Regions"修改即可;
2 ^9 Q- I6 z' r
另外有点注意的就是 使用CubeMX生成的“ethernetif.c”里面,默认的heth.Init.RxBuffLen是1524,但是在"stm32h7xx_hal_eth.h"中,默认的ETH_MAX_PACKET_SIZE 大小是1528,这两个是不一样的,需要手动改成一样的数。# l& R2 e1 d3 |( H& a
要是早两天看到你的帖子我就告诉你这个问题出在cache上了,我也正在调试H743的ETH,也是碰到了cache问题。。。不过楼主也是蛮厉害的。不知道楼主有测速没有?我现在遇到的问题是Rx速度不堪入目。3 }9 S0 f) s0 q& L& ~
netio:# _6 c& S5 u$ ~
楼主能加方式交流一下吗?4 T& L8 P. z* i$ P1 C P4 s
我耽搁了两周啊,后面被搞得没脾气了
https://www.stmcu.org.cn/module/forum/thread-615031-1-1.html
9 V* s! d6 D3 O
7 |, u6 L/ D0 Q, i% N; w3 `) x
你好,你的速度是多少?$ h* H! a! ^1 q5 m9 K* j! U
815201002