|
本帖最后由 Switcc 于 2018-3-14 17:40 编辑 上上周本人发帖询问stm32H7平台移植DP83848 PHY驱动的帖子,详见 https://www.stmcu.org.cn/module/forum/thread-614912-1-1.html, ! U, z& A' b7 p/ s# y9 ~: v 按照回帖建议直接使用cube库里LAN8742里的驱动,然后对照不同PHY芯片寄存器查看,可以读到寄存器数据,但是网络一直没有调通,特别是gratuitous arp设备上线的广播都抓不到,更不谈能PING通设备了。( G* G$ ?( G! d- \3 D 2 y$ ^, S9 D, ~3 s& n9 ^ 经过长达两周的反复测试和问题排查,直接问题出在MPU和CACHE处理上。现分享使能MPU、CACHE和不使能MPU、CACHE两种模式配置说明: N, {. a) k% E" F3 e! q: K: l% o1 |1 S 一、使能MPU、CACHE情况( ?2 \# B% ~% k2 l 1、main.c中 HAL_Init()上加上MPU和CACHE配置 /* USER CODE BEGIN 1 */: s1 O0 e6 n% a8 [. R( Y MPU_Config();' M9 K$ J* \# u" h3 B CPU_CACHE_Enable(); /* USER CODE END 1 */7 n$ O, }3 ]1 m+ b0 Y7 R* w F 4 X. X/ Z# ^2 J$ u2 \0 p /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init();; C, V& ~& i: \ 1 w1 R6 U$ l0 t8 c5 [- }) R) G /* USER CODE BEGIN 4 */ /**0 L) Y( u$ [% O# D+ W" D! r" X5 ] * @brief Configure the MPU attributes + i$ B4 l8 v' ?, b6 _( p * @param None% L) Q8 M/ V) f% R * @retval None */ static void MPU_Config(void)! o' @2 d) i, H% h: v4 B- Q { MPU_Region_InitTypeDef MPU_InitStruct; ! g) y4 L. q& H* A# \1 m3 d R /* Disable the MPU */ HAL_MPU_Disable(); 1 b D4 p8 U; V3 O; v /* Configure the MPU attributes as Device not cacheable * c8 B2 ^4 N1 ~# h1 h+ G! U for ETH DMA descriptors */ MPU_InitStruct.Enable = MPU_REGION_ENABLE; MPU_InitStruct.BaseAddress = 0x30040000;0 P# E8 J* u' |, S MPU_InitStruct.Size = MPU_REGION_SIZE_256B; MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;" [9 p0 [ `. `8 Y0 A* h3 F MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE; MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;6 ` M% u1 B+ C MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; MPU_InitStruct.Number = MPU_REGION_NUMBER0; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; MPU_InitStruct.SubRegionDisable = 0x00;- Z9 ^1 r& U1 g; e' Y' f# i% V# W2 c K MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); / m2 Y5 Q4 G9 u4 O6 Q1 T* y+ ^ /* 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;4 O: t& l8 k4 K* p MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;2 q" d1 ~8 r- P6 Z& h X y MPU_InitStruct.Number = MPU_REGION_NUMBER1;! N# [1 | ]1 a8 \. E" f8 \ MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; MPU_InitStruct.SubRegionDisable = 0x00;1 X6 @( L& [: K, w0 l. ~+ H" Z! b MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; ; ]$ D* D6 j K; i2 w3 q, H HAL_MPU_ConfigRegion(&MPU_InitStruct);' I, S5 a9 o" z3 d8 h( W- m3 k 6 e- a1 D7 K: v' C0 j /* Enable the MPU */, ]1 Q/ j5 b" A& ] HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT); }- z1 k# c2 e5 U6 _- H" ?# y+ D, Z /**/ [' P U0 Q# {( S; w7 `' [8 p3 E * @brief CPU L1-Cache enable. * @param None * @retval None */ static void CPU_CACHE_Enable(void)5 s) \. e) o4 i& `& L- \ {: j- J6 a5 a) b, M /* Enable I-Cache */ SCB_EnableICache();* g, C) g4 D2 d8 ]2 @+ I; E. W) _( l 9 c/ K# z" ~( c' f# [; A /* Enable D-Cache */ SCB_EnableDCache(); } 2、main.c中时钟配置中加上一句 使能SRAM3时钟9 ~% Y% W5 u% M) p. ~" x /* Enable D2 domain SRAM3 Clock (0x30040000 AXI)*/ __HAL_RCC_D2SRAM3_CLK_ENABLE();" f9 h- o+ v. c! X# |! Z . E0 ?% I, ^; s O) a8 i( s2 X0 |! ^- d 1 H9 r c# c; ^2 B1 u' S " C8 `) W- V( Z3 j& a6 p0 j$ ` 3、ethernetif.c中DMARxDscrTab、DMATxDscrTab地址分配,注意和MPU对比) j$ S: f0 N' o* z #if defined ( __ICCARM__ ) /*!< IAR Compiler */ #pragma location=0x30040000 ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */! h, m: \# Z* K) P! X8 j& Z8 Z #pragma location=0x300400604 v$ E7 M- Y& j8 o# \ ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */( X ]3 q+ \+ r/ f6 O0 Q #pragma location=0x30040200 uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffers */4 }( O$ y$ T0 r/ o4 S8 b ; {0 U7 ?7 B! |, n #elif defined ( __CC_ARM ) /* MDK ARM Compiler */ ' X8 d" o- d$ k __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 */( T3 I6 C8 _! p* e, W __attribute__((at(0x30040200))) uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffer */ , S' G) P! ?; O/ L. B #elif defined ( __GNUC__ ) /* GNU Compiler */ $ p% D4 S" X, P( `: ? ? ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT] __attribute__((section(".RxDecripSection"))); /* Ethernet Rx DMA Descriptors */' ]$ F [. I6 G& v; b+ M& D 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 _0 s6 R/ d1 J/ l #endif 6 ]9 b1 B# f Q) F; D( a, M% { 4、low_level_output中 SCB_CleanInvalidateDCache();( u0 J+ D0 c# ]" v HAL_ETH_Transmit(&heth, &TxConfig, 5);, t$ }! ^$ Z" p8 @ 5、low_level_input中 9 O/ g9 \/ X. e9 j+ s% r6 p+ J * {& a( F) }+ l _6 h/ T2 Y /* Clean and Invalidate data cache */% _% E- { G7 m SCB_CleanInvalidateDCache();4 V7 P% }8 d: F# ^- q 6 a9 n! D& {: k- G | HAL_ETH_GetRxDataBuffer(&heth, &RxBuff); HAL_ETH_GetRxDataLength(&heth, &framelength);, Z" U z: M/ N" N SCB_InvalidateDCache_by_Addr((uint32_t *)Rx_Buff, (ETH_RX_DESC_CNT*ETH_RX_BUFFER_SIZE)); ) x/ w8 D R0 |! D4 _' l 9 }- E8 c* V1 K6 e5 D 6、lwipopts.h中,注意和MPU对比 /* USER CODE BEGIN 1 *// |: G! f$ }( f- C #define LWIP_RAM_HEAP_POINTER (0x30044000) ) w3 W+ I+ S+ t* ?$ b* B, d2 d % |4 w4 q n" p. g; b1 U 7、ETH_RX_BUFFER_SIZE要一致$ [( N0 H, F; _. H% q' G u& S* {9 J% @ 0 ^3 P+ `6 S6 D J( W( N heth.Init.RxBuffLen = ETH_RX_BUFFER_SIZE; 3 f, }3 F+ t( q9 i$ e# d$ ^3 E __attribute__((at(0x30040200))) uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffer */. C0 P" O* o. E SCB_InvalidateDCache_by_Addr((uint32_t *)Rx_Buff, (ETH_RX_DESC_CNT*ETH_RX_BUFFER_SIZE)); 8 Y7 s4 ~& a/ T1 U) I 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 见附件。 2 V4 i" f' y. r) N 二、不使能MPU、CACHE情况- m/ I+ @7 Z4 M6 O1 P+ k " D. ^! z) u% Z; j& k+ ^6 q3 ` 上述1,4,5,6标红代码全部注释掉。5 P. i: D2 s$ c @/ e) h 三、注意事项7 _) O3 m' E9 C9 Y& `$ o 1、网络相关管脚配置成高速,cube默认是低速 2、可以先禁止MPU和cache,屏蔽掉相关代码,待网络测通后再开启MPU和cache,进行对应配置! l) U g' s4 E/ w9 p9 [ 3、H7目前官方库支持不到位,特别是有些examples完全没有经过验证,需特别注意# }- \. G- Z! q) R) ~ 4、使用MPU和cache时,多看看手册,弄懂机制避免入坑* s; |! q8 @, M- x) I! e5 T : _: V: f3 ~0 H$ a) N |
【 逢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"修改即可; P8 y, A" P r) f; R
2 q5 c: ]& s- y; J s/ C
另外有点注意的就是 使用CubeMX生成的“ethernetif.c”里面,默认的heth.Init.RxBuffLen是1524,但是在"stm32h7xx_hal_eth.h"中,默认的ETH_MAX_PACKET_SIZE 大小是1528,这两个是不一样的,需要手动改成一样的数。+ x' `& ]4 f. H. e7 F9 g2 F4 a. Q! s1 y: P
: `% |" n9 f% f5 @6 X
要是早两天看到你的帖子我就告诉你这个问题出在cache上了,我也正在调试H743的ETH,也是碰到了cache问题。。。不过楼主也是蛮厉害的。不知道楼主有测速没有?我现在遇到的问题是Rx速度不堪入目。
netio:3 R0 o. ]6 a3 v6 ^8 M4 u4 h O
楼主能加方式交流一下吗?
/ a6 r# k' k. X4 i
我耽搁了两周啊,后面被搞得没脾气了
https://www.stmcu.org.cn/module/forum/thread-615031-1-1.html
) {) o( x5 C& H# `* P
, I, N- O/ F; l9 \/ H9 D+ L5 u
2 ^: \/ \8 N# ^, v
你好,你的速度是多少?
815201002