本帖最后由 Switcc 于 2018-3-14 17:40 编辑 上上周本人发帖询问stm32H7平台移植DP83848 PHY驱动的帖子,详见 https://www.stmcu.org.cn/module/forum/thread-614912-1-1.html,- V6 E) P7 a) N- } 5 B* S& g' w) F& h# H 按照回帖建议直接使用cube库里LAN8742里的驱动,然后对照不同PHY芯片寄存器查看,可以读到寄存器数据,但是网络一直没有调通,特别是gratuitous arp设备上线的广播都抓不到,更不谈能PING通设备了。8 o; V* E9 g! m, W! d: H # H/ o5 A$ k; y( P" K0 R 经过长达两周的反复测试和问题排查,直接问题出在MPU和CACHE处理上。现分享使能MPU、CACHE和不使能MPU、CACHE两种模式配置说明: 一、使能MPU、CACHE情况! b; S1 a" ^1 C4 f3 K6 H4 m 1、main.c中 HAL_Init()上加上MPU和CACHE配置9 e- r7 N/ z* F$ q# p /* USER CODE BEGIN 1 */ MPU_Config(); CPU_CACHE_Enable();. g0 t5 p( V K2 m /* USER CODE END 1 */7 K1 j1 x5 ]* P- d$ F! z /* Reset of all peripherals, Initializes the Flash interface and the Systick. */1 V/ y! I& c* k# U: x HAL_Init();$ d6 F0 S$ Y0 W9 |# L /* USER CODE BEGIN 4 */, L) T& B0 G8 j$ }; ?/ M7 Z /**# h0 x7 f9 m2 \% U8 z: ~ * @brief Configure the MPU attributes ! ]# D, t4 H& D9 [/ ~ * @param None * @retval None */- O: R" ~9 s3 W# u: S4 p static void MPU_Config(void) { MPU_Region_InitTypeDef MPU_InitStruct; a9 r9 j+ v- d3 q7 N 6 |% a/ P# q+ S8 ^0 A2 ? /* Disable the MPU */2 j }0 @8 I, m2 K* e HAL_MPU_Disable();6 R; [2 [6 J( R( ?7 @5 w 0 Z! I& z( l! C4 Q# n" T" r /* Configure the MPU attributes as Device not cacheable for ETH DMA descriptors */8 v8 x9 E, z9 R$ V" P) e MPU_InitStruct.Enable = MPU_REGION_ENABLE; MPU_InitStruct.BaseAddress = 0x30040000; MPU_InitStruct.Size = MPU_REGION_SIZE_256B; MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;: o0 A0 {, i5 m$ b% A" J MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;2 @% q: H, i# I% m 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;- f& W% ~8 e& ~ Z6 y, ], i0 `* b MPU_InitStruct.SubRegionDisable = 0x00; MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;- g d! {/ k8 K$ k# [: U! T 2 R/ R8 G% D d# c HAL_MPU_ConfigRegion(&MPU_InitStruct);/ R' L' Q) G/ g2 [0 D; S * `5 ` V' v _2 ]/ {% c/ h+ u+ f# U /* Configure the MPU attributes as Cacheable write through 4 |. l, `; Y: m/ ^+ } for LwIP RAM heap which contains the Tx buffers */, o) W- A# K$ o* r Z& p; h MPU_InitStruct.Enable = MPU_REGION_ENABLE; MPU_InitStruct.BaseAddress = 0x30044000;/ ?9 i& b1 {% e- j# H* q, G MPU_InitStruct.Size = MPU_REGION_SIZE_16KB;+ r6 e; H! h6 y/ X8 O3 i0 W; {% s MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;+ m8 V( ]& A" p. z$ H MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; MPU_InitStruct.Number = MPU_REGION_NUMBER1; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;: }3 R+ I9 v/ g* S8 Z MPU_InitStruct.SubRegionDisable = 0x00;7 ]7 ^3 M, Z/ F* W* a MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;5 r$ Z" K8 I4 \6 a & ]9 Z1 L2 s- M; r, O8 e1 ^ HAL_MPU_ConfigRegion(&MPU_InitStruct);" Y( T: N1 d( i& { 1 v9 A/ k# z% |: S9 X3 g! w /* Enable the MPU */ HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT); } /** u; m# i0 w2 M- Q1 k6 @ * @brief CPU L1-Cache enable.! k. |# G: n n/ v * @param None * @retval None* k) ^6 J6 e4 p. i) w */ static void CPU_CACHE_Enable(void) { /* Enable I-Cache */( j; C* B! t% E q% A* S SCB_EnableICache(); /* Enable D-Cache */) c2 i1 B/ n8 l2 v" L5 B4 o SCB_EnableDCache(); } 9 b+ q/ s0 v2 \; T" G9 z( g 2、main.c中时钟配置中加上一句 使能SRAM3时钟 /* Enable D2 domain SRAM3 Clock (0x30040000 AXI)*/5 f; A% w1 D$ `: u* g __HAL_RCC_D2SRAM3_CLK_ENABLE(); % ] g9 q1 w9 s4 U# A9 m 3、ethernetif.c中DMARxDscrTab、DMATxDscrTab地址分配,注意和MPU对比 #if defined ( __ICCARM__ ) /*!< IAR Compiler */% f3 g% a$ h1 {/ W# o/ e; T 2 d% d* V' Z: U) F8 { #pragma location=0x30040000 H- \( a: |$ J" ]5 ? 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 */$ I7 ]: [' X j+ k+ ]: t #pragma location=0x30040200' i8 a" r! d9 }% R- e uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffers */4 ~, Y( i" t. ` #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 */ __attribute__((at(0x30040200))) uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffer */ #elif defined ( __GNUC__ ) /* GNU Compiler */ / S6 O: H2 P! t N1 \8 m1 C- @5 J ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT] __attribute__((section(".RxDecripSection"))); /* Ethernet Rx DMA Descriptors */: \/ i* r4 d( c# ]# i1 L+ O ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT] __attribute__((section(".TxDecripSection"))); /* Ethernet Tx DMA Descriptors */* p, s1 \9 k! x% w& \ {# J7 H uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE] __attribute__((section(".RxArraySection"))); /* Ethernet Receive Buffers */6 n4 t' `0 B) R; n! M& n Y , @3 F( @8 S0 _4 t& q8 X #endif; k* L+ x D' d' a 4、low_level_output中6 V# l' R* l' _8 b% ? SCB_CleanInvalidateDCache(); , j6 X; V' o J1 b HAL_ETH_Transmit(&heth, &TxConfig, 5); 5、low_level_input中7 ~6 D, E8 e d+ N 7 e% V0 h( o; g0 q( k; y /* Clean and Invalidate data cache */ SCB_CleanInvalidateDCache();6 D2 i* J. S5 z; w1 x. E HAL_ETH_GetRxDataBuffer(&heth, &RxBuff); HAL_ETH_GetRxDataLength(&heth, &framelength);% f0 w5 m) Y( S. R. K i0 p0 E+ o( ?# y, f" j, c: S: w0 w SCB_InvalidateDCache_by_Addr((uint32_t *)Rx_Buff, (ETH_RX_DESC_CNT*ETH_RX_BUFFER_SIZE)); / ~6 O6 X! H1 g9 l* u; X 6、lwipopts.h中,注意和MPU对比5 a9 ?9 ]: }5 k* @ /* USER CODE BEGIN 1 */ #define LWIP_RAM_HEAP_POINTER (0x30044000)% G, z5 D) F2 C8 p 1 N# H& b9 {- b5 s 7、ETH_RX_BUFFER_SIZE要一致 heth.Init.RxBuffLen = ETH_RX_BUFFER_SIZE; R# D p2 H. M( V! X# L' A __attribute__((at(0x30040200))) uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffer */ 7 Q, E6 K. P! F g8 Z SCB_InvalidateDCache_by_Addr((uint32_t *)Rx_Buff, (ETH_RX_DESC_CNT*ETH_RX_BUFFER_SIZE)); 8 y! G+ I/ A5 p& u9 D p = pbuf_alloced_custom(PBUF_RAW, framelength, PBUF_POOL, &rx_pbuf[current_pbuf_idx], RxBuff.buffer, ETH_RX_BUFFER_SIZE); + q0 `% K; n& v) a ; N- a+ w' `- F& }' ]) y 8、keil配置RAM如下,勾线IRAM2,不勾选IRAM10 Y% [1 v9 @' B( a- ~: B 见附件。0 [# T3 s8 e0 }+ f/ k: D. L6 q 二、不使能MPU、CACHE情况7 o& t% L/ C% g9 |* o ; H+ u9 V5 V' c6 U" F 上述1,4,5,6标红代码全部注释掉。 三、注意事项 1、网络相关管脚配置成高速,cube默认是低速 2、可以先禁止MPU和cache,屏蔽掉相关代码,待网络测通后再开启MPU和cache,进行对应配置7 n+ x% w* f1 _1 j; B1 z 3、H7目前官方库支持不到位,特别是有些examples完全没有经过验证,需特别注意 4、使用MPU和cache时,多看看手册,弄懂机制避免入坑8 S0 d/ z( t& S- j& ^ , k, \" ^+ s2 T+ B ! m6 z P. l' t8 k1 ] 5 y% J' x: z c. f5 M& r& 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的任务优先级提高
: `$ r( u4 A, N4 h7 |
之前用的是F207+DP83848,很容易就调通了,这次换了H7之后,CubeMX里面配置完全不一样了,卡了2天,看到楼主发的注意事项,1个小时就调通了,非常感谢!8 n; Z) ?, f6 ~
我再补充一点,在配置LWIP之前,需要先给PHY芯片一个硬复位,不然配置不成功,H7的RAM起始地址一定要是0x24000000,我用的是IAR,修改RAM起始地址的方法跟KEIL不太一样,ALT+F7打开“option”选项,然后选择“Linker”>"Config">"Edit">"Memory Regions"修改即可;
2 c; o' J1 h2 B! a9 Z) ]
另外有点注意的就是 使用CubeMX生成的“ethernetif.c”里面,默认的heth.Init.RxBuffLen是1524,但是在"stm32h7xx_hal_eth.h"中,默认的ETH_MAX_PACKET_SIZE 大小是1528,这两个是不一样的,需要手动改成一样的数。5 a; A3 @- f4 h0 K- p: U9 V
_* P3 c; W/ }8 l: q. U
要是早两天看到你的帖子我就告诉你这个问题出在cache上了,我也正在调试H743的ETH,也是碰到了cache问题。。。不过楼主也是蛮厉害的。不知道楼主有测速没有?我现在遇到的问题是Rx速度不堪入目。
netio:
楼主能加方式交流一下吗?) z4 W8 a8 G$ j
_" |0 T2 R* h! D: T5 s1 K T
9 f9 W& _. n* {1 X/ O
& f. _" x8 I r; C- o: ~$ A
我耽搁了两周啊,后面被搞得没脾气了
https://www.stmcu.org.cn/module/forum/thread-615031-1-1.html
1 S9 _# d3 O5 |9 C3 ]
你好,你的速度是多少?: w* a* @+ s/ C
815201002