文章耗时两个月,原来写了一半,后来遇到其他项目,中间自己重新画了一块电路板。终于把初始化功能实现了,网上的教程能用的确实凤毛麟角!
一、MPU配置详解
个人对stm32H7的MPU属于新接触,为了弄懂,自己也查阅了资料,看视频讲解。结合这次配置LWIP,分享下个人的学习心得。
MPU(Memory Project uint)内部保护单元。简单理解,就是一个内存管理员。对内存添加访问权限和设置内存单元(region)访问属性。
1、访问权限包括:
MPU REGION NO ACCESS 无访问(特权级&用户级都不可访问)
MPU REGION PRIV RW 仅支持特权级读写访问
MIPU REGION PRIV RW URO 禁止用户写访问(特权可读写访问)
MPU REGION FULL ACCESS 全访问(特权级&用户级都可访问)
MPU REGION PRIV RO 仅支持特权读访问
MPU REGION PRIV RO URO 只读(特权&用户都不可以写
我们一般会选择 MPU REGION FULL ACCESS 全访问(特权级&用户级都可访问)
2、内存单元(region)访问属性
(1)Normal memory 性能最强
CPU以最高效的方式加载和存储字节、半字和字,CPU对于这种内存区的加载或存储不一定要按照程序代码的顺序执行
(2)Device memory
加载和存储要严格按照次序进行,确保寄存器按照正确顺序设置
(3)strongly ordered
程序完全按照代码顺序执行,CPU会等待当前加载存储执行完毕后才执行下一条指令,导致性能下降。
3、访问属性组成:
MPU TEX field level 内存类型
MPU Shareability Permission 是否共享
MPU Cacheable Permission 是否缓存
MPU Bufferable Permission 是否缓冲
可缓存作用是开启Cache,加速CPU访问SRAM。
可缓冲的作用是开启Buffer,把CPU和Cache从较低的SRAM操作摆脱出来。
可共享的作用是解决master的数据同步。不要开启。
我们一般选择是CPU+Cache+Buffer+SRAM模式。此时充分利用cortex—M7的性能。
如何实现。这里涉及到内核的架构。
下面是STM32H743ZIT6地址映射图!
我们查看上面的图和内存映射地址表。
挨个讲!
(1)cortex-m7的cpu内核集成了L1-cache,包含I-Cache和D-Cache,分别是指令缓存和数据缓存。大小都是16KB。
(2)TCM RAM分为ITCM RAM(64KB)和DTCM RAM(128KB)的速率能到480MHz,无需配置MPU。
(3)AXI SRAM(512KB)AXI SRAM( D1 域) :
– 映射基地址 0x2400 0000 的 AXI SRAM,速率是240MHz,若提升速率要配置MPU
(4)AHB SRAM( D2 域):一共288KB,速率是240MHz,若提升速率要配置MPU
分为三个区域:
– 映射基地址 0x3000 0000 到 0x3001 FFFF(128KB)的 AHB SRAM1,
– 映射基地址 0x3002 0000 到 0x3003 FFFF(128KB)的 AHB SRAM2.
– 映射基地址 0x3004 0000 到 0x3004 FFFF(64KB) AHB SRAM3。
(5)AHB SRAM( D3 域):
– 映射到地址 0x3800 0000 的 AHB SRAM4,速率是240MHz,若提升速率要配置MPU
我们一般会选择Normal memory
stm32H7支持管理最多16个单元region。随着序号(region number)的增加,优先级随着增加。
二、cubemx配置
看到教程常见用AHB D2的SRAM3,这次我们先跟着使用.
1、打开stm32cubemx,点击cortex-M7
(1)默认模式使能
CPU ICache 使能
CPU DCache 使能
MPU Control Mode 选择 Background Region Privileged accesses only + MPU Disabled during hard fault, NMl and FAULTMASK handlers
(2)下面是Region 0设置
MPU Region Enabled
MPU Region Base Address 0x30040000
MPU Region Size 256B
MPU SubRegion Disable 0x0
MPU TEX feld level level 1
MPU Access Permission ALL ACCESS PERMITTED
MPU Instruction Access ENABLE
MPU Shareability Permission DISABLE
MPU Cacheable Permission DISABLE
MPU Bufferable Permission ENABLE
0x30040000是 AHB SRAM3的基地址。
MPU Region Size 256B
这是用于eth的收发buffer256B
MPU SubRegion Disable 0x0 不配置Region 子单元
MPU TEX feld level 配置策略为level1,此时性能最强,配置为0也可以。
MPU Access Permission ALL ACCESS PERMITTED 所有权限打开
MPU Instruction Access ENABLE 指令访问权限打开
MPU Shareability Permission DISABLE 不可分享
MPU Cacheable Permission ENABLE 开启缓存
MPU Bufferable Permission ENABLE 开启缓冲
(3)下面是Region 1设置
MPU Region Enabled
MPU Region Base Address 0x3004 4000
MPU Region Size 16KB
MPU SubRegion Disable 0x0
MPU TEX feld level level 0
MPU Access Permission ALL ACCESS PERMITTED
MPU Instruction Access ENABLE
MPU Shareability Permission DISABLE
MPU Cacheable Permission ENABLE
MPU Bufferable Permission ENABLE
0x3004 4000落在映射基地址 0x3004 0000 到 0x3004 7FFF(32KB)的 AHB SRAM3中.(正好中间位置)
MPU Region Size 16KB ?
这是用于存放lwip协议栈开的内存.
MPU SubRegion Disable 0x0 不配置Region 子单元
MPU TEX feld level 配置策略为level1,此时性能最强,配置为0也可以。
MPU Access Permission ALL ACCESS PERMITTED 所有权限打开
MPU Instruction Access ENABLE 指令访问权限打开
MPU Shareability Permission DISABLE 不可分享
MPU Cacheable Permission ENABLE 开启缓存
MPU Bufferable Permission ENABLE 开启缓冲
2、时钟配置
3、ETH配置
(1)MODE :RMII
(2)设置TX/RX 描述符地址
(3)使能中断
(4)设置GPIO
除了标配的RMII有关的管脚,速度设置为Very High外。
再添加一个RESET_PHY 管脚。
控制PHY芯片复位。
4、LWIP配置
(1)选择PHY芯片
使能LWIP后,配置PHY 芯片,默认就是LAN8742,选择即可。
(2)、配置IP,
LWIP-DHCP不使能。
IP地址,掩码,网关自己设置。
(3)堆栈设置
堆栈大小设置大一些。
基地址还是0x3004 4000,落在AHB SRAM3内。
(4)、网卡设置
网卡状态回调函数,使能!
网卡连接回调函数,使能!
5、配置DEBUG
然后生成初始化代码!
三、代码
(1)main.c中添加PHY芯片硬件复位
MX_GPIO_Init();
HAL_Delay(20);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,GPIO_PIN_SET);
HAL_Delay(20);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,GPIO_PIN_RESET);
HAL_Delay(20);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,GPIO_PIN_SET);
HAL_Delay(20);
(2)使能D2SRAM3时钟
__HAL_RCC_D2SRAM3_CLK_ENABLE();
(3)ethernetif_inpu函数
为网卡数据接收任务。LwIP中是通过一个task(ethernetif_input)轮询检查DMA控制器的状态以判断是否有数据接收到。
ethernetif_input程序写到eth中断里是因为使用终端的方式接收网络通信数据,而原先的HAL_ETH_IRQHandler这里边在这个程序里边没有进行实际的应用。
这里的目的,触发ETH中断,直接调用ethernetif_input函数。
(4)添加MX_LWIP_Process();
该函数的作用是从以太网缓冲区读取接收到的数据包, 将其发送到 lwIP 堆栈进行处理
四、测试
烧录.
1 、Ping 包
2、用ATKKPing
测试一分钟。无丢失!
下一篇分享stm32H723+LWIP+cubemx完成以太网初始化。