|
本帖最后由 Switcc 于 2018-3-14 17:40 编辑 , H6 i1 M- C1 p" x $ M8 |5 b7 I. ]1 J- A) x: E+ o) `2 {, w 上上周本人发帖询问stm32H7平台移植DP83848 PHY驱动的帖子,详见 https://www.stmcu.org.cn/module/forum/thread-614912-1-1.html,. G( d8 b( z2 i, x8 ~! O 按照回帖建议直接使用cube库里LAN8742里的驱动,然后对照不同PHY芯片寄存器查看,可以读到寄存器数据,但是网络一直没有调通,特别是gratuitous arp设备上线的广播都抓不到,更不谈能PING通设备了。 ^* x& G! z! ]' w U 经过长达两周的反复测试和问题排查,直接问题出在MPU和CACHE处理上。现分享使能MPU、CACHE和不使能MPU、CACHE两种模式配置说明:* {3 W- g0 `4 W$ K. | ' n$ P( K! l" _' A$ `& c; e' ? 一、使能MPU、CACHE情况 1、main.c中 HAL_Init()上加上MPU和CACHE配置, t+ d9 _0 b2 V( E1 L& i+ Y /* USER CODE BEGIN 1 */ MPU_Config(); CPU_CACHE_Enable();, D* y) H# ~- Q /* USER CODE END 1 */ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */6 R: K: C- G" n7 b1 U HAL_Init();8 g, C+ z$ y+ ~: P ' h+ X, {$ K- U /* USER CODE BEGIN 4 */ ^9 R4 W3 e5 i2 o- Y /**" B. }1 i; R1 s6 a * @brief Configure the MPU attributes : f% [. N6 z2 L. P7 D) V * @param None * @retval None! K2 M& e: A' h( W */ static void MPU_Config(void)/ \9 k( J; L9 x `" L8 {: V3 c& ~7 T* ~ { MPU_Region_InitTypeDef MPU_InitStruct;& J! j; S* m! {& B( p: Y" x! x : k; x7 g) K" H! \ /* Disable the MPU */ HAL_MPU_Disable();6 N! ^" f4 v4 @8 u* d /* Configure the MPU attributes as Device not cacheable for ETH DMA descriptors */ MPU_InitStruct.Enable = MPU_REGION_ENABLE;0 u- C! f5 O' C- w& J MPU_InitStruct.BaseAddress = 0x30040000;0 F9 ^' b' r7 z$ r$ \ MPU_InitStruct.Size = MPU_REGION_SIZE_256B; MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;% |. H6 A8 j' s/ n0 t* @ MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;! s, J: E& W6 T4 Z; z 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;+ j, u6 E" e& J9 C* T+ u 4 k. M( J% m* |; n5 [8 h- w% O HAL_MPU_ConfigRegion(&MPU_InitStruct);) t7 C' T& c' E# Y6 \ r 2 c8 r! a% z5 N: M) @ /* Configure the MPU attributes as Cacheable write through for LwIP RAM heap which contains the Tx buffers */ MPU_InitStruct.Enable = MPU_REGION_ENABLE; MPU_InitStruct.BaseAddress = 0x30044000; MPU_InitStruct.Size = MPU_REGION_SIZE_16KB;$ X& M% u5 o& |2 S- Y' ` MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;/ a8 @+ B+ H0 h3 N( W0 F MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;6 z& F1 C' g9 x8 e- W& \/ B0 A MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;, J$ x( |9 K2 P/ i3 ^: [ J: Q0 B MPU_InitStruct.Number = MPU_REGION_NUMBER1; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;. c& ~. ?8 ^% n7 M: x MPU_InitStruct.SubRegionDisable = 0x00;' t: Y3 c+ C; l2 {( O y( C F MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;3 |' z$ Q' O( d% ~; J2 T! I HAL_MPU_ConfigRegion(&MPU_InitStruct);+ i: |" h2 V5 ~! }6 j& } / l6 d; B( d: L2 A$ y. i /* Enable the MPU */ HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);) i6 b( W& R1 ?, D3 K# v } ) s0 P9 W4 h* Y% N- C) i3 W /** * @brief CPU L1-Cache enable.5 X/ Y8 u6 L* ^* \ Q. Y' H * @param None# m! O/ k2 s# @3 w * @retval None+ |7 l2 l! h3 |( M1 f4 h */ static void CPU_CACHE_Enable(void); h4 ^' q$ J6 |! r3 g6 U { /* Enable I-Cache */ SCB_EnableICache();% g& {% q. }; Y% ~! n8 B- l5 X* T /* Enable D-Cache */ SCB_EnableDCache(); }3 G6 C) f& F3 D- ~5 b z8 E* z9 J 2、main.c中时钟配置中加上一句 使能SRAM3时钟( t5 x& n |! o: G1 ? /* Enable D2 domain SRAM3 Clock (0x30040000 AXI)*/ __HAL_RCC_D2SRAM3_CLK_ENABLE(); 5 z' b+ o, K/ u3 X/ A! g 3、ethernetif.c中DMARxDscrTab、DMATxDscrTab地址分配,注意和MPU对比 }7 i2 B- Z) G #if defined ( __ICCARM__ ) /*!< IAR Compiler */ 7 r( e$ Y! ~- t0 b0 y* d #pragma location=0x30040000" O: x7 q' _+ g% \ [, d ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */0 l6 R+ e; ? ^2 S. W0 v #pragma location=0x300400604 D) l% v3 N* m0 Y" L; i ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */: ], t6 Y, O" f$ j W; j #pragma location=0x30040200 uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffers */ ! W; t- m/ i1 I. {9 I# B$ g #elif defined ( __CC_ARM ) /* MDK ARM Compiler */* x: l0 X% F. t' h/ M __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 */8 S# `3 S& D5 X __attribute__((at(0x30040200))) uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffer */ #elif defined ( __GNUC__ ) /* GNU Compiler */ 5 P, N3 x! d$ l3 Z 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 *// W* S3 X0 \+ H9 }8 c* f0 k- j0 M+ T ) l6 N; y3 s% W* S: M7 _+ X+ G #endif 4、low_level_output中 SCB_CleanInvalidateDCache();, R+ n& o8 Z* {3 j8 l 5 L: p/ E7 j9 P0 Z& A5 I# \ HAL_ETH_Transmit(&heth, &TxConfig, 5); 5、low_level_input中3 e( y) E6 ^! j0 V 1 V4 q' v& H/ y& i+ X# ^ 7 Y, ~+ W' T! c# Y# }- z /* Clean and Invalidate data cache */ SCB_CleanInvalidateDCache(); HAL_ETH_GetRxDataBuffer(&heth, &RxBuff);/ I( H- ~% O% u6 W HAL_ETH_GetRxDataLength(&heth, &framelength); ; t- T+ L7 A) ~* X0 Z& S' S# L SCB_InvalidateDCache_by_Addr((uint32_t *)Rx_Buff, (ETH_RX_DESC_CNT*ETH_RX_BUFFER_SIZE));3 @. y6 g3 S: M$ R0 { % r4 m" r g0 g2 N6 F8 X! E. B5 L 6、lwipopts.h中,注意和MPU对比' q* D: F4 z* f /* USER CODE BEGIN 1 */ #define LWIP_RAM_HEAP_POINTER (0x30044000) D! O. N. A& b/ g4 X2 q9 w/ a 7、ETH_RX_BUFFER_SIZE要一致 heth.Init.RxBuffLen = ETH_RX_BUFFER_SIZE; __attribute__((at(0x30040200))) uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffer */( b1 e( X' B5 C ; K [ G2 N& F' l- } SCB_InvalidateDCache_by_Addr((uint32_t *)Rx_Buff, (ETH_RX_DESC_CNT*ETH_RX_BUFFER_SIZE));/ \8 ]) j3 Z" | p = pbuf_alloced_custom(PBUF_RAW, framelength, PBUF_POOL, &rx_pbuf[current_pbuf_idx], RxBuff.buffer, ETH_RX_BUFFER_SIZE); : ], w8 y# @+ p% p6 t ]1 h 8、keil配置RAM如下,勾线IRAM2,不勾选IRAM1( `: O7 [& }" `# T5 w: p 见附件。- b+ D. R; u( v* x( |! ` 二、不使能MPU、CACHE情况 1 E, M3 v6 j6 d; k& ~ 上述1,4,5,6标红代码全部注释掉。 [0 H d0 i$ A% B" n& o 三、注意事项; `, M) v6 S) i; T 1、网络相关管脚配置成高速,cube默认是低速 2、可以先禁止MPU和cache,屏蔽掉相关代码,待网络测通后再开启MPU和cache,进行对应配置9 `' [8 l8 _5 R 3、H7目前官方库支持不到位,特别是有些examples完全没有经过验证,需特别注意 4、使用MPU和cache时,多看看手册,弄懂机制避免入坑 - v4 @2 u4 Y' w0 V9 C7 c ' _. {9 i2 F, z# g |
【 逢7发帖赢大礼】1、利用CubeMX生成正点原子H7R7开发板的STM32CubeIDE工程
【STM32H735G-DK测评】ADC3+TIMER1+DMA 采样模拟信号
【STM32H735DK测评】Ethernet+lwip DHCP获取IP地址
STM32H743基于CubeMx5.0配置手册
【STM32H735G-DK测评】lvgl移植
【STM32H735G-DK 测评】STM32H735G-DK External Loder 编译和测试
【福利三:逢7发帖赢大礼】使用MPU6050模块、img_dsc、img_btn机制实现一些简单有趣的动画效果
【福利三:逢7发帖赢大礼】使用arc弧形拉条控件控制PWM舵机及使用SPI3接口操作NRF24L01模块进行无线通信
【福利三:逢7发帖赢大礼】调试nucleo-WBA65RI工程测试样板的一些心得
【福利三:逢7发帖赢大礼】lv_timer和BME680实现温度、湿度、气压数据读取
微信公众号
手机版
在大数据量通信交互时,会造成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个小时就调通了,非常感谢!
我再补充一点,在配置LWIP之前,需要先给PHY芯片一个硬复位,不然配置不成功,H7的RAM起始地址一定要是0x24000000,我用的是IAR,修改RAM起始地址的方法跟KEIL不太一样,ALT+F7打开“option”选项,然后选择“Linker”>"Config">"Edit">"Memory Regions"修改即可;' h. q6 S; ~+ K' _8 ~
7 K5 g. Z; X/ J# Y9 J% E
另外有点注意的就是 使用CubeMX生成的“ethernetif.c”里面,默认的heth.Init.RxBuffLen是1524,但是在"stm32h7xx_hal_eth.h"中,默认的ETH_MAX_PACKET_SIZE 大小是1528,这两个是不一样的,需要手动改成一样的数。8 ]' v" M5 `! S6 }; `- e( y7 x# T
4 F* L) W1 s6 B, ?
要是早两天看到你的帖子我就告诉你这个问题出在cache上了,我也正在调试H743的ETH,也是碰到了cache问题。。。不过楼主也是蛮厉害的。不知道楼主有测速没有?我现在遇到的问题是Rx速度不堪入目。
netio:
楼主能加方式交流一下吗?
6 l9 J K; l$ Y* k
' e, O4 x: C( [- H4 { Z3 k
我耽搁了两周啊,后面被搞得没脾气了
https://www.stmcu.org.cn/module/forum/thread-615031-1-1.html
1 q5 K3 f$ h9 u: }
4 S9 L# F$ j/ f% p; ~$ k+ T
你好,你的速度是多少?$ o2 o% P, \! p9 V2 i+ {
815201002