本帖最后由 Switcc 于 2018-3-14 17:40 编辑 . t8 C9 I* J3 H/ u4 B! ~* } 上上周本人发帖询问stm32H7平台移植DP83848 PHY驱动的帖子,详见/ O' l Q3 D, N. E https://www.stmcu.org.cn/module/forum/thread-614912-1-1.html,: E& V+ }) Q/ Y( n5 q4 v. s : `2 ]( o- I# t% n- X 按照回帖建议直接使用cube库里LAN8742里的驱动,然后对照不同PHY芯片寄存器查看,可以读到寄存器数据,但是网络一直没有调通,特别是gratuitous arp设备上线的广播都抓不到,更不谈能PING通设备了。 经过长达两周的反复测试和问题排查,直接问题出在MPU和CACHE处理上。现分享使能MPU、CACHE和不使能MPU、CACHE两种模式配置说明:( v% j" g: k) {! K/ ? 一、使能MPU、CACHE情况3 \, U' s, a1 h( C 1、main.c中 HAL_Init()上加上MPU和CACHE配置 /* USER CODE BEGIN 1 */8 G) z& \! w* d8 P/ e/ c, G MPU_Config(); CPU_CACHE_Enable(); /* USER CODE END 1 */* I+ n0 g2 N6 K3 m4 \5 f: n5 | /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); ( _; ?$ q0 S, C1 h( o9 |$ b6 _4 L 6 F; |; n1 R" n7 R, Y- z- x /* USER CODE BEGIN 4 */ /**4 d) v. s' F. a/ l1 P% P) K: p; a * @brief Configure the MPU attributes * @param None * @retval None( Y. y/ s/ H9 |( M+ W */1 D$ t* u; B+ }* U- U, I static void MPU_Config(void). C. t9 O7 y* H8 P2 c: _$ } { MPU_Region_InitTypeDef MPU_InitStruct; 7 C" u8 X5 }" {( ~0 o: ~ /* Disable the MPU */ HAL_MPU_Disable();! e5 c. f. P$ A- I) n 3 C! L% q( I" }+ m /* Configure the MPU attributes as Device not cacheable * T9 j* b/ P: o8 }6 }! y for ETH DMA descriptors */9 F1 b3 q% X! v MPU_InitStruct.Enable = MPU_REGION_ENABLE; MPU_InitStruct.BaseAddress = 0x30040000; MPU_InitStruct.Size = MPU_REGION_SIZE_256B;! {; F2 D$ O4 \$ ]6 `; U MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE; MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;8 A: f* j. z* W) y! K( C. G MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; MPU_InitStruct.Number = MPU_REGION_NUMBER0; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;4 a. P" U5 k2 {' g* p' a MPU_InitStruct.SubRegionDisable = 0x00; MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); 5 v) O4 m" X) j6 K( J- L /* Configure the MPU attributes as Cacheable write through for LwIP RAM heap which contains the Tx buffers */( R7 m' N& I$ {8 H. k: v: J7 A8 Q MPU_InitStruct.Enable = MPU_REGION_ENABLE;* E. V9 i* O3 @. R! e; | C, X6 X! a MPU_InitStruct.BaseAddress = 0x30044000; MPU_InitStruct.Size = MPU_REGION_SIZE_16KB;! p: F. [& q" l MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;5 l' [5 W# F) u) L MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;9 c* Z( G1 B, E6 }. X MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;5 A/ n3 W1 D/ X5 J! m& a$ q8 t MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; MPU_InitStruct.Number = MPU_REGION_NUMBER1; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; MPU_InitStruct.SubRegionDisable = 0x00;+ _, k# V9 J( F( ` MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); 4 E+ d; ]' K- `5 {$ v /* Enable the MPU */ HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT); }; L7 b' i0 |. W/ _/ n" a $ d1 x! D* z+ N /** * @brief CPU L1-Cache enable.7 ^8 `2 |( O9 ? V' H7 u, { * @param None6 q; _# O2 A: r- | * @retval None */% X# {, D0 s+ d7 H3 ^ static void CPU_CACHE_Enable(void) { /* Enable I-Cache */8 W# c& H7 w3 W: E# ~' W0 K7 F# b SCB_EnableICache();1 u+ x8 {+ o* R6 W3 u # w2 X v3 c) z, g3 }2 W /* Enable D-Cache */ SCB_EnableDCache();+ t$ q+ m, R3 p2 { I } " I3 ?7 R' `& D- Q 2、main.c中时钟配置中加上一句 使能SRAM3时钟1 [+ S/ n+ s5 R( z3 i* n /* Enable D2 domain SRAM3 Clock (0x30040000 AXI)*/5 Q, e0 i6 F- w; a __HAL_RCC_D2SRAM3_CLK_ENABLE();! Q+ Y; L1 C: @3 F# V / J/ d; V2 E+ } - t+ E2 _, C8 d% x: u+ S 3、ethernetif.c中DMARxDscrTab、DMATxDscrTab地址分配,注意和MPU对比* G/ |, A5 l; s2 R/ Y5 } ' g5 k% Y$ V4 K/ d( _8 a #if defined ( __ICCARM__ ) /*!< IAR Compiler */ #pragma location=0x30040000* U1 \3 n/ A. ]1 `$ v! P+ ? ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */& x4 s3 O( Q( S4 n9 ~9 S b #pragma location=0x30040060' B1 s7 y2 Y" ^( ?; N G# y ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */; A8 V& ^% q. y2 J8 l6 X2 F* w# x #pragma location=0x30040200 uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffers */. v. O J0 T- Z& h2 w* s+ S" @ 9 H6 F0 b) X1 I1 M #elif defined ( __CC_ARM ) /* MDK ARM Compiler */9 l6 O) `: r0 q$ E/ C __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 */ 5 r w/ t. z/ q' P #elif defined ( __GNUC__ ) /* GNU Compiler */ ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT] __attribute__((section(".RxDecripSection"))); /* Ethernet Rx DMA Descriptors */9 a& t8 _# G0 B4 f* Y n5 U+ g ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT] __attribute__((section(".TxDecripSection"))); /* Ethernet Tx DMA Descriptors */ uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE] __attribute__((section(".RxArraySection"))); /* Ethernet Receive Buffers */5 S% c4 |+ g1 [- c7 f2 j #endif% K# d' i, S, H4 b2 O6 W \5 }$ {% i / }* g) _* {+ \. l: G 4、low_level_output中, M% F J9 _4 L* S c# q 1 Y o! i0 w) Y+ R. m# L/ p: l SCB_CleanInvalidateDCache();: w9 V) ~8 i3 y/ g: z9 { HAL_ETH_Transmit(&heth, &TxConfig, 5);# V! ^# u9 [0 U7 W8 T% a% M 5、low_level_input中 / [0 \' R7 J1 W+ _2 U" @# p( r2 ? $ @7 Q- O, h4 d$ R /* Clean and Invalidate data cache */ SCB_CleanInvalidateDCache(); ( g9 @- Z. _, D0 S" \+ H1 I, r" [ HAL_ETH_GetRxDataBuffer(&heth, &RxBuff); HAL_ETH_GetRxDataLength(&heth, &framelength);8 o" l/ R& u( _ - r" b# K+ U4 {! b( \ SCB_InvalidateDCache_by_Addr((uint32_t *)Rx_Buff, (ETH_RX_DESC_CNT*ETH_RX_BUFFER_SIZE));( n2 v/ M$ i5 B0 T3 ^6 L % {1 _2 x3 E! m* E; [- t 6 ?( d$ b$ z9 ]/ ^ a8 r5 A . N1 J' d |) o" B( {) X5 F& t& r 6、lwipopts.h中,注意和MPU对比 /* USER CODE BEGIN 1 */ #define LWIP_RAM_HEAP_POINTER (0x30044000) 7、ETH_RX_BUFFER_SIZE要一致 ' r2 k: l0 A, V+ u heth.Init.RxBuffLen = ETH_RX_BUFFER_SIZE;6 k" I; E( {8 O. e% g9 k __attribute__((at(0x30040200))) uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffer */ # G0 u% q+ L! F9 R4 V! v SCB_InvalidateDCache_by_Addr((uint32_t *)Rx_Buff, (ETH_RX_DESC_CNT*ETH_RX_BUFFER_SIZE));! C: Y5 h4 \, \7 b$ F8 f6 ^) B / j' `" w5 c/ |' y" B2 |) a3 T p = pbuf_alloced_custom(PBUF_RAW, framelength, PBUF_POOL, &rx_pbuf[current_pbuf_idx], RxBuff.buffer, ETH_RX_BUFFER_SIZE); 8、keil配置RAM如下,勾线IRAM2,不勾选IRAM1 见附件。5 M% H+ Q: O: d* Y- n 3 [, w3 q S" } T4 Y 二、不使能MPU、CACHE情况) r8 o/ p$ ^/ O0 K 上述1,4,5,6标红代码全部注释掉。 三、注意事项 1、网络相关管脚配置成高速,cube默认是低速 2、可以先禁止MPU和cache,屏蔽掉相关代码,待网络测通后再开启MPU和cache,进行对应配置 3、H7目前官方库支持不到位,特别是有些examples完全没有经过验证,需特别注意( Z4 i+ G H b! Q 4、使用MPU和cache时,多看看手册,弄懂机制避免入坑' R1 G7 ~9 l& Z9 T; f % u5 {/ e, X; S- F9 P 5 R# U! l) [4 }. \- h |
兔哥的杂谈【002】——如何性价比更高地去编译STM32
【Wio Lite AI视觉开发套件】+简单刷个屏
工程师笔记 | STM32H7 RAMECC功能及应用
stm32使用定时器触发dma传输,启动dma没反应的几种情况的解决方法
【Wio Lite AI视觉开发套件】+cube.ai与食物识别
【STM32H7S78-DK】汽车仪表系统
【STM32H7S78-DK】基于 rtthread 适配 lcd 驱动移植 lvgl
【STM32H7S78-DK评测】TouchGFX (QR Code)二维码生成器
【STM32H7S78-DK】rtthread 增加 psram 内存管理
【STM32H7S78-DK】开箱与rtthread工程初体验
在大数据量通信交互时,会造成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的任务优先级提高
/ j( o. h" [# f/ Z; S
之前用的是F207+DP83848,很容易就调通了,这次换了H7之后,CubeMX里面配置完全不一样了,卡了2天,看到楼主发的注意事项,1个小时就调通了,非常感谢!8 E: t/ H8 A! s
我再补充一点,在配置LWIP之前,需要先给PHY芯片一个硬复位,不然配置不成功,H7的RAM起始地址一定要是0x24000000,我用的是IAR,修改RAM起始地址的方法跟KEIL不太一样,ALT+F7打开“option”选项,然后选择“Linker”>"Config">"Edit">"Memory Regions"修改即可;2 |7 E, C5 B; V- t
另外有点注意的就是 使用CubeMX生成的“ethernetif.c”里面,默认的heth.Init.RxBuffLen是1524,但是在"stm32h7xx_hal_eth.h"中,默认的ETH_MAX_PACKET_SIZE 大小是1528,这两个是不一样的,需要手动改成一样的数。, f Q5 J0 \% b" @! E( y3 G9 s
要是早两天看到你的帖子我就告诉你这个问题出在cache上了,我也正在调试H743的ETH,也是碰到了cache问题。。。不过楼主也是蛮厉害的。不知道楼主有测速没有?我现在遇到的问题是Rx速度不堪入目。0 o ]5 ~9 T* `- r+ I" O
netio:
, h. j: _+ G$ U& f" h* @1 Y* |
楼主能加方式交流一下吗?
0 m! j: L1 L+ |# ]9 T; o
我耽搁了两周啊,后面被搞得没脾气了
https://www.stmcu.org.cn/module/forum/thread-615031-1-1.html
1 V5 d# Q1 z4 L: ~' s
' [! n3 X4 _' v0 k
你好,你的速度是多少?
815201002