一、外接的以太网物理层芯片一般都有 中断脚,系统上电初始化时 配置连接这个脚的MCU GPIO 使能中断,如下所示:
/* 配置物理层芯片中断输入脚 */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
RCC_AHB1PeriphClockCmd(ETH_PHY_INTERRUPT_GPIO_CLK, ENABLE);
GPIO_InitStructure.GPIO_Pin = ETH_PHY_INTERRUPT_PIN;
GPIO_Init(ETH_PHY_INTERRUPT_GPIO_PORT, &GPIO_InitStructure);
SYSCFG_EXTILineConfig(ETH_PHY_INTERRUPT_EXTI_PORT_SOURCE,
ETH_PHY_INTERRUPT_EXTI_PIN_SOURCE);
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_InitStructure.EXTI_Line = ETH_PHY_INTERRUPT_EXTI_LINE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannel = ETH_PHY_INTERRUPT_NVIC_IRQ_CHANNEL;
NVIC_Init(&NVIC_InitStructure);
二、最后在这个MCU GPIO的中断函数 实现如下:
/**
* @输入参数: 无
* @输出参数: 无
* @返 回 值: 无
* @说 明: 以太网物理层芯片输入中断处理
*/
void ETH_PHY_INTERRUPT_IRQHandler(void)
{
rt_uint16_t u16RegValue;
//通知OS已进入中断状态
rt_interrupt_enter();
//读中断控制状态寄存器
u16RegValue = ETH_ReadPHYRegister(stm32_eth_device.u8PhyAddr, 0x1B);
if(u16RegValue & (1ul << 2))
{
//Link Down中断
eth_device_linkchange(&(stm32_eth_device.parent), RT_FALSE);
}
if(u16RegValue & (1ul << 0))
{
//Link Up中断
eth_device_linkchange(&(stm32_eth_device.parent), RT_TRUE);
//获取自动协商结果
u16RegValue = ETH_ReadPHYRegister(stm32_eth_device.u8PhyAddr, 0x1F);
//设置EMAC控制器
switch((u16RegValue >> 2) & 0x07)
{
case 1:
LOG_ETH_EMAC_DUPLEX_SPEED(("\r\n10Mbps半双工"));
ETH->MACCR &= ~ETH_Mode_FullDuplex;
ETH->MACCR &= ~ETH_Speed_100M;
break;
case 2:
LOG_ETH_EMAC_DUPLEX_SPEED(("\r\n100Mbps半双工"));
ETH->MACCR &= ~ETH_Mode_FullDuplex;
ETH->MACCR |= ETH_Speed_100M;
break;
case 5:
LOG_ETH_EMAC_DUPLEX_SPEED(("\r\n10Mbps全双工"));
ETH->MACCR |= ETH_Mode_FullDuplex;
ETH->MACCR &= ~ETH_Speed_100M;
break;
case 6:
LOG_ETH_EMAC_DUPLEX_SPEED(("\r\n100Mbps全双工"));
ETH->MACCR |= ETH_Mode_FullDuplex;
ETH->MACCR |= ETH_Speed_100M;
break;
default:
LOG_ETH_EMAC_DUPLEX_SPEED(("\r\n错误的emac自动协商结果!"));
break;
}
}
//清除中断
EXTI->PR = ETH_PHY_INTERRUPT_EXTI_LINE;
//通知OS已离开中断状态
rt_interrupt_leave();
}
本文介绍了Linux系统下处理网线热插拔的工作原理,主要涉及外接以太网物理层芯片的中断配置和中断处理函数。在系统初始化时,配置中断脚并启用中断,当网线连接或断开时,MCU通过中断函数更新EMAC控制器的设置以适应链路状态变化。
2749

被折叠的 条评论
为什么被折叠?



