阅读STM32F107的lwip移植后的一个项目工程

网络MAC地址从哪里获得?可以获取mcu的CPU ID,然后从CPU ID获取MAC地址

unsigned char _eth_phy_mac[6] = {0x8, 0x2e,0,0,0,0};

void Eth_GenMAC(){
       /*
    SerialID[0] = *(unsigned int*)(0x1FFFF7E8);
    SerialID[1] = *(unsigned int*)(0x1FFFF7EC);
    SerialID[2] = *(unsigned int*)(0x1FFFF7F0);
    */
    unsigned char *cpu_id = (unsigned char *)0x1FFFF7E8;
    unsigned int crc32_value;
    
    crc32_value = crc32(cpu_id, 12);
    _eth_phy_mac[2] = (char)(crc32_value >> 0);
    _eth_phy_mac[3] = (char)(crc32_value >> 8);
    _eth_phy_mac[4] = (char)(crc32_value >> 16);
    _eth_phy_mac[5] = (char)(crc32_value >> 24);
};

stm32的ethernet 初始化,主要是PHY的驱动,

void stm32f107_eth_init(void)
{
RCC_ClocksTypeDef RCC_Clocks;

Eth_GenMAC();
eth_phy_clk_init();
eth_phy_gpio_init();
eth_phy_nvic_init();
eth_phy_mco_init();
eth_phy_confugration();
RCC_GetClocksFreq(&RCC_Clocks);
SysTick_Config(RCC_Clocks.SYSCLK_Frequency / 100);
NVIC_SetPriority (SysTick_IRQn, 1);
}

然后Lwip初始化操作

int Eth_LwipRegisterWithDHCP(){

    struct ip_addr ipaddr;
    struct ip_addr netmask;
    struct ip_addr gw;

    setIsDHCP();
    mem_init();
    memp_init();

    ipaddr.addr = 0;
    netmask.addr = 0;
    gw.addr = 0;

    Set_MAC_Address(_eth_phy_mac);
    netif_add(ð_phy_netif, &ipaddr, &netmask, &gw, NULL, ðernetif_init, ðernet_input);
    netif_set_default(ð_phy_netif);

    dhcp_start(ð_phy_netif);
    netif_set_up(ð_phy_netif);
    return 0;
}

移植LWIP到stm32上无操作系统时,注意不同的phy芯片,网卡驱动不同,所以,第一步应该是网卡驱动的改写,然后时候网络数据收发使用DMA的两个描述符,收和发,采用环形链表的数据结构。DMA的描述符结构如下:

typedef struct  {
  __IO uint32_t   Status;                /*!< Status */
  uint32_t   ControlBufferSize;     /*!< Control and Buffer1, Buffer2 lengths */
  uint32_t   Buffer1Addr;           /*!< Buffer1 address pointer */
  uint32_t   Buffer2NextDescAddr;   /*!< Buffer2 or next descriptor address pointer */
/* Enhanced ETHERNET DMA PTP Descriptors */
#ifdef USE_ENHANCED_DMA_DESCRIPTORS
  uint32_t   ExtendedStatus;        /* Extended status for PTP receive descriptor */
  uint32_t   Reserved1;             /* Reserved */
  uint32_t   TimeStampLow;          /* Time Stamp Low value for transmit and receive */
  uint32_t   TimeStampHigh;         /* Time Stamp High value for transmit and receive */
#endif /* USE_ENHANCED_DMA_DESCRIPTORS */
} ETH_DMADESCTypeDef;

如果定义的是接收结构体数组类型可以使用函数ETH_DMARxDescChainInit()ETH_DMATxDescChainInit()完成链表的构成。

使用结构体指针完成对两个TX和RX的描述符跟踪

__IO ETH_DMADESCTypeDef  *DMATxDescToSet;
__IO ETH_DMADESCTypeDef  *DMARxDescToGet;

注意对收发数据的内存管理,通常使用动态的分配内容空间,并且接收数据是使用中断接收的方式处理

void ETH_IRQHandler(void)
{
while(ETH_GetRxPktSize(DMARxDescToGet)!=0) //¼ì²âÊÇ·ñÊÕµ½Êý¾Ý°ü

lwip_pkt_handle();
}
ETH_DMAClearITPendingBit(ETH_DMA_IT_R);
ETH_DMAClearITPendingBit(ETH_DMA_IT_NIS);
}  



你可能感兴趣的:(MCU)