STM32F207+DP83848+RT-THREAD 네트워크 플러그 재연결 시험 실현

9338 단어 rt-thread 학습
나는 처음에 이 문제에 부딪혔을 때 인터넷에 검색해 보았지만 모두 분명하게 말하지 못했다."재초기화", "재초기화 MAC"가 아니라 모두 텍스트 표면에 있습니다. 아래에 직접 코드를 붙이고 첨부된 코드는 스스로 테스트하여 통과했습니다.
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 (자신의 실제 이름에 따라)"장치를 찾아서 이 네트워크 장치를 초기화합니다.
이렇게 하면 케이블이 언제 꽂히든지 연결되어 핫플러그 문제를 완벽하게 해결할 수 있다.

좋은 웹페이지 즐겨찾기