本帖最后由 Switcc 于 2018-3-14 17:40 编辑 " H3 w/ L% B& j1 G; i 上上周本人发帖询问stm32H7平台移植DP83848 PHY驱动的帖子,详见5 j. ?8 w4 s+ w/ L p+ F https://www.stmcu.org.cn/module/forum/thread-614912-1-1.html, [! |8 G4 D2 C- S 按照回帖建议直接使用cube库里LAN8742里的驱动,然后对照不同PHY芯片寄存器查看,可以读到寄存器数据,但是网络一直没有调通,特别是gratuitous arp设备上线的广播都抓不到,更不谈能PING通设备了。 5 @2 @7 ]% U# Z0 I$ k 经过长达两周的反复测试和问题排查,直接问题出在MPU和CACHE处理上。现分享使能MPU、CACHE和不使能MPU、CACHE两种模式配置说明: 8 W6 v& f# O3 x* D 一、使能MPU、CACHE情况+ g* t2 f, l# ?) d3 M 1、main.c中 HAL_Init()上加上MPU和CACHE配置 /* USER CODE BEGIN 1 */" l/ L0 F, {4 Y! |1 p MPU_Config(); CPU_CACHE_Enable();1 B, E! U, A8 g2 U5 o /* USER CODE END 1 */ % @9 I S+ u: d2 ^2 n9 b) w2 M /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init();$ h4 W# l' M3 m* f /* USER CODE BEGIN 4 */ /** * @brief Configure the MPU attributes * @param None# i% n( Z0 l' ?) A) i * @retval None$ v1 h* K4 M9 |' [% T3 m' S */5 \, h9 t4 ^; ]9 @* `( Y static void MPU_Config(void) { MPU_Region_InitTypeDef MPU_InitStruct;7 B" R) O* W: Y, x2 w# F 3 U' a# J# o! I- u8 J /* Disable the MPU */ HAL_MPU_Disable(); /* Configure the MPU attributes as Device not cacheable ; M p& C5 m8 M2 `/ C) t5 K5 i for ETH DMA descriptors */, Y4 g( { r- \9 x MPU_InitStruct.Enable = MPU_REGION_ENABLE; MPU_InitStruct.BaseAddress = 0x30040000;, t( _; H5 U1 r3 P* D5 ?( d- n MPU_InitStruct.Size = MPU_REGION_SIZE_256B;: [% p, M1 U2 V# d4 D MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;) } Q3 Q# f5 Y9 s! f MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;2 u3 M4 {+ {1 l5 W8 r/ {7 R MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;9 Y. p# J1 n! o$ i3 z7 T MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; MPU_InitStruct.Number = MPU_REGION_NUMBER0;$ d; Q' }9 J$ q8 Q MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;& @7 F" v" F) k" w8 D" ]) J D MPU_InitStruct.SubRegionDisable = 0x00;1 a0 \" H3 d' f' y3 U. W; m& }' _ MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); ; K" _" l3 p; [; B, e /* Configure the MPU attributes as Cacheable write through ! ` A. Q3 [+ x4 s' }9 B7 a# T for LwIP RAM heap which contains the Tx buffers */ MPU_InitStruct.Enable = MPU_REGION_ENABLE;) _0 i9 k) ~4 [! J) } MPU_InitStruct.BaseAddress = 0x30044000; MPU_InitStruct.Size = MPU_REGION_SIZE_16KB; MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;3 x" V3 o3 v6 {" l5 K MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;8 ]. [1 D8 |, m5 v5 f" M MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; MPU_InitStruct.Number = MPU_REGION_NUMBER1; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; MPU_InitStruct.SubRegionDisable = 0x00; MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;& s' Z' h8 a+ w: B! L& ` HAL_MPU_ConfigRegion(&MPU_InitStruct);' N/ N. A& I! v1 { /* Enable the MPU */ HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);. r$ p/ t! \0 H! @ I/ t } /**( g3 O7 Y7 X9 n9 g7 V; M * @brief CPU L1-Cache enable.4 p$ f/ _# y2 t4 w* D * @param None * @retval None5 X* g; a- d$ f! i */. o! s6 M, N1 m; T' { static void CPU_CACHE_Enable(void) {% w$ x; S! w/ e9 m* E# R' W7 T /* Enable I-Cache */ SCB_EnableICache();6 `) f. U6 d. B3 ` / X$ S. G& ?7 `8 L /* Enable D-Cache */ SCB_EnableDCache();; L+ t1 V: o- q$ D! E3 q6 `1 ^- F1 z }! ~' J) ], t* f G9 A9 T* v+ t 6 S: J; s7 r2 V) _/ B, n x: V; K' u* o; a* m5 Q$ n 2、main.c中时钟配置中加上一句 使能SRAM3时钟; o- \2 s' c8 C3 V /* Enable D2 domain SRAM3 Clock (0x30040000 AXI)*/- P: E! ^6 ?: I: p5 @. Z __HAL_RCC_D2SRAM3_CLK_ENABLE(); 2 q3 a( b& G: Q: H* {3 Z/ U : y4 ^6 I! E" W 3、ethernetif.c中DMARxDscrTab、DMATxDscrTab地址分配,注意和MPU对比 G) @- D' r' x E7 K 9 k8 u5 `9 j3 ~/ x( h" s1 Z& \) b* G( A #if defined ( __ICCARM__ ) /*!< IAR Compiler */3 |& k8 C! T# w4 X! D #pragma location=0x30040000 ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */ #pragma location=0x30040060 ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */8 K' D6 D, m/ t6 W/ G# ]8 O( { #pragma location=0x30040200 uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffers */ 2 d8 z% m. t. m, |& T: w #elif defined ( __CC_ARM ) /* MDK ARM Compiler */! x& I' u9 f2 c# ] __attribute__((at(0x30040000))) ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */) [. e3 K( N, {& ~; C1 v __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 */$ H3 f& b H& F3 X6 M0 I# n #elif defined ( __GNUC__ ) /* GNU Compiler */ * W2 P6 I# ]- c& L 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 */2 |% h6 b* `- o uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE] __attribute__((section(".RxArraySection"))); /* Ethernet Receive Buffers */( _) Q+ }0 z- D9 z$ P0 F& F2 J #endif+ H, L5 K. }3 J7 C+ m1 b9 \ 1 t3 M$ T, y! X. S) W1 \ 2 n& t7 h; T* k: T% z/ L 4、low_level_output中 J3 K/ T( f# h SCB_CleanInvalidateDCache();8 X9 l& r& V! S/ x5 d1 w / J+ C( p( P, M HAL_ETH_Transmit(&heth, &TxConfig, 5); " {6 e- ~: D. c 5、low_level_input中2 F" w8 d% t- ]* w' U' h " R% ^+ z; \' t- G! w 7 v0 w1 ?( i& B; v. b a9 N; d /* Clean and Invalidate data cache */ SCB_CleanInvalidateDCache(); HAL_ETH_GetRxDataBuffer(&heth, &RxBuff); HAL_ETH_GetRxDataLength(&heth, &framelength);+ J9 d# X5 L/ H Y8 c" _/ k! C ) T2 v+ M! \7 Z7 {+ J& F" w SCB_InvalidateDCache_by_Addr((uint32_t *)Rx_Buff, (ETH_RX_DESC_CNT*ETH_RX_BUFFER_SIZE));& k. k2 ]6 r) n, ]; {1 @/ {6 H 3 `5 m- o" @% J7 @ L& Z9 ]& d* j/ J 6、lwipopts.h中,注意和MPU对比/ J$ r2 |' k2 F2 m1 [# O0 s! f /* USER CODE BEGIN 1 */ z" S8 Z$ `) \8 j& S$ ^ #define LWIP_RAM_HEAP_POINTER (0x30044000)5 Y: \6 b" |6 c& H- o- a* n2 c 7、ETH_RX_BUFFER_SIZE要一致 heth.Init.RxBuffLen = ETH_RX_BUFFER_SIZE;* g. w8 N0 }3 O* _ ; V" J& G j- V" l& d" ~ ^7 | __attribute__((at(0x30040200))) uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffer */ 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);( S: A7 u3 s! P 1 H' Y, K" V* ]/ a* e: L$ x3 T- a 8、keil配置RAM如下,勾线IRAM2,不勾选IRAM1 见附件。1 b% N$ N" p l5 D5 Q$ B0 f 二、不使能MPU、CACHE情况 上述1,4,5,6标红代码全部注释掉。 ) I% g$ E* y# ~2 u0 M 三、注意事项! P" v+ o/ M; b: {" s2 r6 F0 J- f3 V 1、网络相关管脚配置成高速,cube默认是低速7 v- m. W0 x# ^# ~; r, X 2、可以先禁止MPU和cache,屏蔽掉相关代码,待网络测通后再开启MPU和cache,进行对应配置 3、H7目前官方库支持不到位,特别是有些examples完全没有经过验证,需特别注意0 r! O- q. M$ R- L. x 4、使用MPU和cache时,多看看手册,弄懂机制避免入坑$ ?, f' N% q: O' P5 c1 W* e # W. a# ^0 O! z, d ' e; e) }' l: k |
【经验分享】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个小时就调通了,非常感谢!0 {4 @. N# @6 Z2 h% J* n5 j }+ W
我再补充一点,在配置LWIP之前,需要先给PHY芯片一个硬复位,不然配置不成功,H7的RAM起始地址一定要是0x24000000,我用的是IAR,修改RAM起始地址的方法跟KEIL不太一样,ALT+F7打开“option”选项,然后选择“Linker”>"Config">"Edit">"Memory Regions"修改即可;# f# R# x$ p- d! Z: g
s7 {; C/ C9 q1 X2 ^+ L6 h
另外有点注意的就是 使用CubeMX生成的“ethernetif.c”里面,默认的heth.Init.RxBuffLen是1524,但是在"stm32h7xx_hal_eth.h"中,默认的ETH_MAX_PACKET_SIZE 大小是1528,这两个是不一样的,需要手动改成一样的数。5 ], W9 v; F {! j! i* `4 \$ M
要是早两天看到你的帖子我就告诉你这个问题出在cache上了,我也正在调试H743的ETH,也是碰到了cache问题。。。不过楼主也是蛮厉害的。不知道楼主有测速没有?我现在遇到的问题是Rx速度不堪入目。
netio:
楼主能加方式交流一下吗?
4 h% T! d z0 ?5 g
我耽搁了两周啊,后面被搞得没脾气了
https://www.stmcu.org.cn/module/forum/thread-615031-1-1.html
. C, ^. K# D; Q% j7 g& l
: X0 ^8 f0 U* |# V
( Q! k% }& f+ O4 s$ H; e4 ^1 z
你好,你的速度是多少? n @2 B! k$ A) W6 x9 }
815201002