本帖最后由 Switcc 于 2018-3-14 17:40 编辑 0 \5 ?# ?0 D/ @6 p 上上周本人发帖询问stm32H7平台移植DP83848 PHY驱动的帖子,详见 https://www.stmcu.org.cn/module/forum/thread-614912-1-1.html,* m" A! v$ P" h$ m( M 按照回帖建议直接使用cube库里LAN8742里的驱动,然后对照不同PHY芯片寄存器查看,可以读到寄存器数据,但是网络一直没有调通,特别是gratuitous arp设备上线的广播都抓不到,更不谈能PING通设备了。 经过长达两周的反复测试和问题排查,直接问题出在MPU和CACHE处理上。现分享使能MPU、CACHE和不使能MPU、CACHE两种模式配置说明:; x/ t) E$ T' g6 l 一、使能MPU、CACHE情况$ h* m, ~5 r. o2 [ 1、main.c中 HAL_Init()上加上MPU和CACHE配置- _' [! p9 c: w+ @$ x0 B5 y' m. s /* USER CODE BEGIN 1 */ MPU_Config(); CPU_CACHE_Enable(); /* USER CODE END 1 */8 _3 y [- m9 H4 L- ~ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */2 m0 \, Q) s. q$ w3 D. u& C HAL_Init();/ l& z9 z" }& C9 o4 U- G , O" z$ `6 O% u: g5 @- U/ G ' B' f7 M! m& D' `( Z, }- H5 K7 f /* USER CODE BEGIN 4 */ /** * @brief Configure the MPU attributes * @param None5 T y1 z1 B7 J6 r1 I8 i * @retval None */& V7 T; o1 m1 }3 ~/ F) U" e static void MPU_Config(void) { MPU_Region_InitTypeDef MPU_InitStruct; /* Disable the MPU */ HAL_MPU_Disable();0 K" M: ~1 G, } /* Configure the MPU attributes as Device not cacheable for ETH DMA descriptors */8 k& @, l6 `/ I0 M Y MPU_InitStruct.Enable = MPU_REGION_ENABLE; MPU_InitStruct.BaseAddress = 0x30040000;* l' y v$ [% |6 U$ v MPU_InitStruct.Size = MPU_REGION_SIZE_256B; MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;3 V4 F2 _8 }- _3 ~ MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;5 {! }( ]- R1 M: P1 O$ o3 K MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;& G' {2 Z, o( ^: A MPU_InitStruct.Number = MPU_REGION_NUMBER0;: D; \& F" {1 O U' a+ O3 G MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; MPU_InitStruct.SubRegionDisable = 0x00;5 f/ x$ l% [& @* p$ O MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; 9 v/ k. u0 p0 i7 _/ u" i6 G; | HAL_MPU_ConfigRegion(&MPU_InitStruct);' P l9 Z- a; Z3 } /* Configure the MPU attributes as Cacheable write through for LwIP RAM heap which contains the Tx buffers */8 f3 _4 Z% D# K* P MPU_InitStruct.Enable = MPU_REGION_ENABLE;( r6 e9 v7 [+ p" ^* M' H MPU_InitStruct.BaseAddress = 0x30044000;9 p2 ~' S& ?2 B MPU_InitStruct.Size = MPU_REGION_SIZE_16KB; MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;6 W: |# [0 v8 e& _3 Z; M, U5 \* ^ MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;9 t5 O2 d4 c' H! D3 C' L MPU_InitStruct.Number = MPU_REGION_NUMBER1;: z. l; v+ ]0 \5 Z+ V( p5 `6 V MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; MPU_InitStruct.SubRegionDisable = 0x00;$ e1 u3 J5 x1 ~7 j- n MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; 4 i9 f* }4 r* m, P HAL_MPU_ConfigRegion(&MPU_InitStruct); /* Enable the MPU */ HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT); } : `3 D4 ]! L5 v$ ~6 @2 {$ D /** * @brief CPU L1-Cache enable. * @param None- Q, h+ j8 A& t7 R& h8 |- v9 y * @retval None( x) O) n {, _6 a */% h+ I8 j, K7 l. B0 a6 U static void CPU_CACHE_Enable(void) {! j k9 l" v+ I1 }; @$ F /* Enable I-Cache */ SCB_EnableICache(); * I7 N: u! g" B /* Enable D-Cache */! G3 G* q+ [* }5 h$ L E8 d SCB_EnableDCache(); } & }' U. C. Y; T9 c9 M5 N6 D" Z* o 2、main.c中时钟配置中加上一句 使能SRAM3时钟 /* Enable D2 domain SRAM3 Clock (0x30040000 AXI)*/! |8 W) J6 D2 x8 _0 z$ Z! G7 d __HAL_RCC_D2SRAM3_CLK_ENABLE(); 8 E7 i3 X& j% c* b& E8 e 3 ?' ~. z! s8 p; @1 J$ | 3、ethernetif.c中DMARxDscrTab、DMATxDscrTab地址分配,注意和MPU对比* o$ e1 e9 x3 R #if defined ( __ICCARM__ ) /*!< IAR Compiler */ |! E6 m: Q2 ], p' ?% k6 X #pragma location=0x30040000 ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */, P$ Y8 l/ o( p #pragma location=0x30040060; |# i1 u: C( \5 r0 v1 m ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */ #pragma location=0x30040200 uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffers */ #elif defined ( __CC_ARM ) /* MDK ARM Compiler */ __attribute__((at(0x30040000))) ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */' ~* q8 [. D. ^ __attribute__((at(0x30040060))) ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */ q- ?! w& k/ e C) M# V0 |- [ __attribute__((at(0x30040200))) uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffer */% {- I8 X* w5 G# w6 ^( [/ e, q* \ #elif defined ( __GNUC__ ) /* GNU Compiler */ , M& c# U4 P7 O 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 */ uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE] __attribute__((section(".RxArraySection"))); /* Ethernet Receive Buffers */ 6 e0 @& D! [: _9 h #endif & O. W t) a5 y4 `2 Y: L 4、low_level_output中 2 a* ^/ [! c) q' j$ k) K- ?* m SCB_CleanInvalidateDCache();, M! _! y, n3 o, D% e/ d HAL_ETH_Transmit(&heth, &TxConfig, 5); 5、low_level_input中2 D. C3 g* Y6 x; x; I , u8 `- D) ]$ N. ]6 r B; h . \) l, E& m8 p9 J7 M8 h4 I /* Clean and Invalidate data cache */8 t4 J. U: Z5 \" a SCB_CleanInvalidateDCache();: y% v6 Y0 n8 q3 } ) `0 f' d2 Y; `: m9 B+ m5 z HAL_ETH_GetRxDataBuffer(&heth, &RxBuff);4 Q3 y: g% r& T6 f! l" d; G6 U+ t HAL_ETH_GetRxDataLength(&heth, &framelength);* c( D' ] e m2 ~8 B; R& v . i, T: `: ?' N3 ~! c SCB_InvalidateDCache_by_Addr((uint32_t *)Rx_Buff, (ETH_RX_DESC_CNT*ETH_RX_BUFFER_SIZE)); , d7 l$ j5 m! P ( k( _8 d5 C' k' n) r, U* i2 ^ 6、lwipopts.h中,注意和MPU对比9 G# q' Q! V) }. ]2 f1 D7 a /* USER CODE BEGIN 1 */. o+ p) E5 H% Y/ ` [. ? #define LWIP_RAM_HEAP_POINTER (0x30044000)4 q- ^8 i. {0 n$ E 3 H( o% |/ m! Q( b 7、ETH_RX_BUFFER_SIZE要一致* i, K2 y6 t# w0 ~- |: t n ) g/ A( L! a, x+ N( z% C2 Q! t heth.Init.RxBuffLen = ETH_RX_BUFFER_SIZE;; Q/ W& W3 f6 m9 T' O s2 K4 R, S2 n" N. h __attribute__((at(0x30040200))) uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffer */ ; U+ f9 V9 }/ e0 j SCB_InvalidateDCache_by_Addr((uint32_t *)Rx_Buff, (ETH_RX_DESC_CNT*ETH_RX_BUFFER_SIZE));7 `3 T" f8 H% X5 j a. g . b% e i. @2 e; p3 n+ M5 i p = pbuf_alloced_custom(PBUF_RAW, framelength, PBUF_POOL, &rx_pbuf[current_pbuf_idx], RxBuff.buffer, ETH_RX_BUFFER_SIZE);. j8 \! W* v1 x0 p6 g 8、keil配置RAM如下,勾线IRAM2,不勾选IRAM1 见附件。) X# ]: q8 U% g2 p) r) u $ C; |0 P6 d+ c8 P/ y, J 1 f: @0 f: j1 U4 ?" |+ c 二、不使能MPU、CACHE情况 ; R$ h1 j; g9 ?' d8 U 上述1,4,5,6标红代码全部注释掉。 三、注意事项 1、网络相关管脚配置成高速,cube默认是低速 g' V+ j: a% X% W4 W9 p Q' a8 ~7 D 2、可以先禁止MPU和cache,屏蔽掉相关代码,待网络测通后再开启MPU和cache,进行对应配置 3、H7目前官方库支持不到位,特别是有些examples完全没有经过验证,需特别注意 4、使用MPU和cache时,多看看手册,弄懂机制避免入坑 # r2 O& v2 ?; Y x( ?3 {3 ~1 D. I& ?0 l |
【STM32H7S78-DK评测】XIP项目源码分析
【STM32H7S78-DK评测】步进电机控制介绍一与tensorflow安装与测试
【STM32H7S78-DK】rtthread 增加 psram 内存管理
【STM32H7S78-DK评测】-4 LTDC&DMA2D 基本测试
【STM32H7S78-DK】基于 rtthread 适配 sdcard 文件系统
【STM32H7S78-DK】开箱与rtthread工程初体验
【STM32H7S78-DK评测】简单开箱和Demo体验
【STM32H7S78-DK评测】XIP模板问题处理与电机控制
【STM32H7S78-DK评测】CoreMark移植和优化--兼记printf重定向实现方法及常见问题
【STM32H7S78-DK评测】开发板初识与工程模板创建
在大数据量通信交互时,会造成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个小时就调通了,非常感谢!" ?" X# s# v/ {( h: K7 y8 f7 M
我再补充一点,在配置LWIP之前,需要先给PHY芯片一个硬复位,不然配置不成功,H7的RAM起始地址一定要是0x24000000,我用的是IAR,修改RAM起始地址的方法跟KEIL不太一样,ALT+F7打开“option”选项,然后选择“Linker”>"Config">"Edit">"Memory Regions"修改即可;6 v" H. q9 A$ u* N! k
, c% y% T( |2 Q* @: A
另外有点注意的就是 使用CubeMX生成的“ethernetif.c”里面,默认的heth.Init.RxBuffLen是1524,但是在"stm32h7xx_hal_eth.h"中,默认的ETH_MAX_PACKET_SIZE 大小是1528,这两个是不一样的,需要手动改成一样的数。
要是早两天看到你的帖子我就告诉你这个问题出在cache上了,我也正在调试H743的ETH,也是碰到了cache问题。。。不过楼主也是蛮厉害的。不知道楼主有测速没有?我现在遇到的问题是Rx速度不堪入目。
netio:
; O, f6 L) O b' q+ |0 Z
楼主能加方式交流一下吗?" I& ~, O2 R7 f! w
4 p5 K/ N9 G6 w @0 G; f
我耽搁了两周啊,后面被搞得没脾气了
https://www.stmcu.org.cn/module/forum/thread-615031-1-1.html
, `4 O/ K& O$ `+ T- c9 k
) D& K0 N: N1 u
& t5 g' q% n$ v9 [
你好,你的速度是多少?
815201002