STM32F207+DP83848+RT-THREAD 네트워크 플러그 재연결 시험 실현
                                            
 9338 단어  rt-thread 학습
                    
1. DP83848을 통해 링크의 상태 변화로 설정하면 해당 교회에 전기 평형 변화(구체적으로 보면 매뉴얼)가 있어 STM32의 외부 중단을 촉발하고 STM32 네트워크 상태를 알린다.다음은 PHY 구성
/************************************************************
**  DP83848                    MCU。
*************************************************************/
uint32_t Eth_Link_PHYITConfig(uint16_t PHYAddress)
{
/* PHY registers */
  uint32_t tmpreg = 0;
  tmpreg = ETH_ReadPHYRegister(PHYAddress, 2);
  tmpreg = ETH_ReadPHYRegister(PHYAddress, 3);
  /* Read MICR register */
  tmpreg = ETH_ReadPHYRegister(PHYAddress, PHY_MICR);
  /* Enable output interrupt events to signal via the INT pin */
  tmpreg |= (uint32_t)PHY_MICR_INT_EN | PHY_MICR_INT_OE;
  if(!(ETH_WritePHYRegister(PHYAddress, PHY_MICR, tmpreg)))
  {
    /* Return ERROR in case of write timeout */
    return ETH_ERROR;
  }
  /* Read MISR register */
  tmpreg = ETH_ReadPHYRegister(PHYAddress, PHY_MISR);
  /* Enable Interrupt on change of link status */
  tmpreg |= (uint32_t)PHY_MISR_LINK_INT_EN;
  if(!(ETH_WritePHYRegister(PHYAddress, PHY_MISR, tmpreg)))
  {
    /* Return ERROR in case of write timeout */
    return ETH_ERROR;
  }
  /* Return SUCCESS */
  return ETH_SUCCESS;   
}  2. 코드는 STM32를 구성하는 파이프라인이 내려가면서 터치 인터럽트를 일으킨다.
/***********************************************************
***  GPIOA3        ,  MCU        。
************************************************************/
void Eth_Link_EXTIConfig(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  EXTI_InitTypeDef EXTI_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
  /* Enable the INT (PB14) Clock */
  RCC_AHB1PeriphClockCmd(ETH_LINK_GPIO_CLK, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
  /* Configure INT pin as input */
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_InitStructure.GPIO_Pin = ETH_LINK_PIN;
  GPIO_Init(ETH_LINK_GPIO_PORT, &GPIO_InitStructure);
  /* Connect EXTI Line to INT Pin */
  SYSCFG_EXTILineConfig(ETH_LINK_EXTI_PORT_SOURCE, ETH_LINK_EXTI_PIN_SOURCE);
  /* Configure EXTI line */
  EXTI_InitStructure.EXTI_Line = ETH_LINK_EXTI_LINE;
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;  
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);
  /* Enable and set the EXTI interrupt to the highest priority */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  
  NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
} 3、 MAC
및
DMA
관련 초기화 코드(이 부분의 초기화는 우리가 시스템을 시작할 때 이미 초기화했다)
4
static void ETH_MACDMA_Config(void)
{
  ETH_InitTypeDef ETH_InitStructure;
  /* Enable ETHERNET clock  */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_ETH_MAC | RCC_AHB1Periph_ETH_MAC_Tx |
                        RCC_AHB1Periph_ETH_MAC_Rx, ENABLE);
                        
  /* Reset ETHERNET on AHB Bus */
  ETH_DeInit();
  /* Software reset */
  ETH_SoftwareReset();
  /* Wait for software reset */
  while (ETH_GetSoftwareResetStatus() == SET);
  /* ETHERNET Configuration --------------------------------------------------*/
  /* Call ETH_StructInit if you don't like to configure all ETH_InitStructure parameter */
  ETH_StructInit(Ð_InitStructure);
  /* Fill ETH_InitStructure parametrs */
  /*------------------------   MAC   -----------------------------------*/
  ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Enable;
  //ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Disable; 
  //  ETH_InitStructure.ETH_Speed = ETH_Speed_10M;
  //  ETH_InitStructure.ETH_Mode = ETH_Mode_FullDuplex;   
  ETH_InitStructure.ETH_LoopbackMode = ETH_LoopbackMode_Disable;
  ETH_InitStructure.ETH_RetryTransmission = ETH_RetryTransmission_Disable;
  ETH_InitStructure.ETH_AutomaticPadCRCStrip = ETH_AutomaticPadCRCStrip_Disable;
  ETH_InitStructure.ETH_ReceiveAll = ETH_ReceiveAll_Disable;
  ETH_InitStructure.ETH_BroadcastFramesReception = ETH_BroadcastFramesReception_Enable;
  ETH_InitStructure.ETH_PromiscuousMode = ETH_PromiscuousMode_Disable;
  ETH_InitStructure.ETH_MulticastFramesFilter = ETH_MulticastFramesFilter_Perfect;
  ETH_InitStructure.ETH_UnicastFramesFilter = ETH_UnicastFramesFilter_Perfect;
#ifdef CHECKSUM_BY_HARDWARE
  ETH_InitStructure.ETH_ChecksumOffload = ETH_ChecksumOffload_Enable;
#endif
  /*------------------------   DMA   -----------------------------------*/  
  /* When we use the Checksum offload feature, we need to enable the Store and Forward mode: 
  the store and forward guarantee that a whole frame is stored in the FIFO, so the MAC can insert/verify the checksum, 
  if the checksum is OK the DMA can handle the frame otherwise the frame is dropped */
  ETH_InitStructure.ETH_DropTCPIPChecksumErrorFrame = ETH_DropTCPIPChecksumErrorFrame_Enable; 
  ETH_InitStructure.ETH_ReceiveStoreForward = ETH_ReceiveStoreForward_Enable;         
  ETH_InitStructure.ETH_TransmitStoreForward = ETH_TransmitStoreForward_Enable;     
  ETH_InitStructure.ETH_ForwardErrorFrames = ETH_ForwardErrorFrames_Disable;       
  ETH_InitStructure.ETH_ForwardUndersizedGoodFrames = ETH_ForwardUndersizedGoodFrames_Disable;   
  ETH_InitStructure.ETH_SecondFrameOperate = ETH_SecondFrameOperate_Enable;
  ETH_InitStructure.ETH_AddressAlignedBeats = ETH_AddressAlignedBeats_Enable;      
  ETH_InitStructure.ETH_FixedBurst = ETH_FixedBurst_Enable;                
  ETH_InitStructure.ETH_RxDMABurstLength = ETH_RxDMABurstLength_32Beat;          
  ETH_InitStructure.ETH_TxDMABurstLength = ETH_TxDMABurstLength_32Beat;
  ETH_InitStructure.ETH_DMAArbitration = ETH_DMAArbitration_RoundRobin_RxTx_2_1;
  /* Configure Ethernet */
  if( ETH_Init(Ð_InitStructure, DP83848_PHY_ADDRESS) ==  ETH_ERROR )
    rt_kprintf("ETH init error, may be no link
");
  {
       /* Configure the PHY to generate an interrupt on change of link status */
      Eth_Link_PHYITConfig(DP83848_PHY_ADDRESS);
      /* Configure the EXTI for Ethernet link status. */
      Eth_Link_EXTIConfig();
  }
  /* Enable the Ethernet Rx Interrupt */
  ETH_DMAITConfig(ETH_DMA_IT_NIS | ETH_DMA_IT_R , ENABLE);
}4, NIC 및DMA
패브릭 초기화 및 ENIC:
static rt_err_t rt_stm32_eth_init(rt_device_t dev)
{
    int i;
    /* MAC address configuration */
    ETH_MACAddressConfig(ETH_MAC_Address0, (u8*)&stm32_eth_device.dev_addr[0]);
    
    /* Initialize Tx Descriptors list: Chain Mode */
    ETH_DMATxDescChainInit(DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB);
    /* Initialize Rx Descriptors list: Chain Mode  */
    ETH_DMARxDescChainInit(DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB);
     /* Enable Ethernet Rx interrrupt */
    { 
        for(i=0; i  이상의 코드는 모두 초기화 같은 것이고 아무것도 아니다. 다음은 네트워크 핫플러그 기능을 실현하는 주요 함수이다.
/**********************************************
**                      ,
**                 MAC DMA。
**********************************************/
void Eth_Link_ITHandler(uint16_t PHYAddress)
{
    /* Check whether the link interrupt has occurred or not */
    if(((ETH_ReadPHYRegister(PHYAddress, PHY_MISR)) & PHY_LINK_STATUS) != 0)
    {
        uint16_t status  = ETH_ReadPHYRegister(PHYAddress, PHY_BSR);
        if(status & (PHY_AutoNego_Complete | PHY_Linked_Status)){
        init_dma_mac();//   MAC DMA    
        rt_kprintf("qqx enter net_link is  connect.
\r");
        }
        else{
        rt_kprintf("qqx enter net_link is  out
\r");
        }
    }
}  //   MAC DMA    
void init_dma_mac(void)
{
    rt_device_t stm32_eth_device;
    ETH_MACDMA_Config();
    stm32_eth_device = rt_device_find("e0");
    rt_stm32_eth_init(stm32_eth_device);
}  /*************************************************
**MCU        , STM32          
**            。
*************************************************/
void EXTI3_IRQHandler(void)
{
  if(EXTI_GetITStatus(ETH_LINK_EXTI_LINE) != RESET)
  {
    Eth_Link_ITHandler(DP83848_PHY_ADDRESS);
    /* Clear interrupt pending bit */
    EXTI_ClearITPendingBit(ETH_LINK_EXTI_LINE);
  }
}  전체적인 단계는: 인터럽트에 들어간 후 Eth 호출Link_ITHandler(DP83848_PHY_ADDRESS); ->
(1)ETH_MACDMA_Config();
(2)rt_stm32_eth_init(stm32_eth_device);//장치 찾기 함수를 통해 "e0 (자신의 실제 이름에 따라)"장치를 찾아서 이 네트워크 장치를 초기화합니다.
이렇게 하면 케이블이 언제 꽂히든지 연결되어 핫플러그 문제를 완벽하게 해결할 수 있다.