阅读STM32F107的lwip移植后的一个项目工程 我不是女神ヾ 2022-07-21 01:08 74阅读 0赞 网络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); \}
还没有评论,来说两句吧...