网络通信模型
PHY层:
物理层位于OSI最底层,物理层协议定义电气信号、线的状态、时钟要求、数据编码和数据传输用的连接器。 物理层的器件称为PHY。
功能:PHY层负责信号的转换,如将数字信号转换为适合在以太网线上传输的模拟信号,并实现数据的物理传输。
STM32H7系列微控制器并未集成PHY层。因此,在使用STM32H7进行以太网通信时,需要外部连接一个PHY芯片。
MAC层
功能:MAC层负责数据帧的封装和解封装,以及处理以太网的访问控制。
集成情况:STM32H7RS的MAC外设支持多种以太网接口标准,MII(媒体独立接口)和RMII(精简媒体独立接口),使其能够灵活地与外部PHY芯片连接。
STM32H7以太网通信的过程:
MAC与PHY的连接:STM32H7内部的MAC外设会通过MII(媒体独立接口)或RMII(精简媒体独立接口)等接口来连接外部的PHY芯片。这些接口用于传输网络数据。PHY的配置与控制:为了配置或读取PHY芯片的状态,STM32H7还需要通过MDIO(管理数据输入输出)接口与PHY芯片进行通信。MDIO接口类似于IIC接口,包括一根数据线MDIO和一根时钟线MDC。
原理图:
SDK LwIP_TFTP_Server demo案例:STM32H7S78-DK\Applications\LwIP\LwIP_TFTP_Server
J6跳线,板子上默认是跳到PB2,换到PC1可以正常运行。
LWIP 配置
启动IPv6
void HAL_ETH_MspInit(ETH_HandleTypeDef* ethHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
if(ethHandle->Instance==ETH)
{
/* USER CODE BEGIN ETH_MspInit 0 */
/* USER CODE END ETH_MspInit 0 */
/** Initializes the peripherals clock
*/
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ETH1REF|RCC_PERIPHCLK_ETH1PHY;
PeriphClkInit.Eth1RefClockSelection = RCC_ETH1REFCLKSOURCE_PHY;
PeriphClkInit.Eth1PhyClockSelection = RCC_ETH1PHYCLKSOURCE_PLL3S;
/* USER CODE BEGIN MACADDRESS */
/* USER CODE END MACADDRESS */
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
/* Enable Peripheral clock */
__HAL_RCC_ETH1MAC_CLK_ENABLE();
__HAL_RCC_ETH1TX_CLK_ENABLE();
__HAL_RCC_ETH1RX_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**ETH GPIO Configuration
PD7 ------> ETH_RMII_REF_CLK
PD4 ------> ETH_PHY_INTN
PG11 ------> ETH_RMII_TX_EN
PC1 ------> ETH_MDC
PA2 ------> ETH_MDIO
PC4 ------> ETH_RMII_RXD0
PA7 ------> ETH_RMII_CRS_DV
PC5 ------> ETH_RMII_RXD1
PB0 ------> ETH_RMII_TXD0
PB1 ------> ETH_RMII_TXD1
*/
GPIO_InitStruct.Pin = GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF4_ETH;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF11_ETH;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF11_ETH;
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF11_ETH;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF11_ETH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF11_ETH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* USER CODE BEGIN ETH_MspInit 1 */
/* USER CODE END ETH_MspInit 1 */
}
}
void HAL_ETH_MspDeInit(ETH_HandleTypeDef* ethHandle)
{
if(ethHandle->Instance==ETH)
{
/* USER CODE BEGIN ETH_MspDeInit 0 */
/* USER CODE END ETH_MspDeInit 0 */
/* Disable Peripheral clock */
__HAL_RCC_ETH1MAC_CLK_DISABLE();
__HAL_RCC_ETH1TX_CLK_DISABLE();
__HAL_RCC_ETH1RX_CLK_DISABLE();
/**ETH GPIO Configuration
PD7 ------> ETH_RMII_REF_CLK
PD4 ------> ETH_PHY_INTN
PG11 ------> ETH_RMII_TX_EN
PC1 ------> ETH_MDC
PA2 ------> ETH_MDIO
PC4 ------> ETH_RMII_RXD0
PA7 ------> ETH_RMII_CRS_DV
PC5 ------> ETH_RMII_RXD1
PB0 ------> ETH_RMII_TXD0
PB1 ------> ETH_RMII_TXD1
*/
HAL_GPIO_DeInit(GPIOD, GPIO_PIN_7|GPIO_PIN_4);
HAL_GPIO_DeInit(GPIOG, GPIO_PIN_11);
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5);
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_7);
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_0|GPIO_PIN_1);
/* USER CODE BEGIN ETH_MspDeInit 1 */
/* USER CODE END ETH_MspDeInit 1 */
}
}
/*******************************************************************************
PHI IO Functions
*******************************************************************************/
/**
* [url=home.php?mod=space&uid=247401]@brief[/url] Initializes the MDIO interface GPIO and clocks.
* @param None
* @retval 0 if OK, -1 if ERROR
*/
int32_t ETH_PHY_IO_Init(void)
{
/* We assume that MDIO GPIO configuration is already done
in the ETH_MspInit() else it should be done here
*/
/* Configure the MDIO Clock */
HAL_ETH_SetMDIOClockRange(&heth);
return 0;
}
IPv4 & V6 双栈,同时支持IPv4和IPv6两种协议栈。这意味着这些设备既能处理IPv4数据包,也能处理IPv6数据包。当设备接收到一个数据包时,它会检查数据包的IP版本号,然后根据版本号选择相应的协议栈进行处理。在双栈网络中,设备可以同时拥有IPv4和IPv6两种地址。这些地址可以通过手动配置、DHCP(动态主机配置协议)或其他地址分配机制进行分配。
开发板和电脑在同一个网关下分配不同Ip,成功通信。
|