STM32F767ZI-NUCLEO移植LWIP

    技术2022-07-10  133

    ###一、生成stm32工程

    1、选择STM32F767ZI芯片 2、配置时钟源

    3、配置外设(串口及网卡)

    4、生成代码


    ###二、下载LWIP源码(http://savannah.nongnu.org/projects/lwip/) 1.下载最新版本2.1.2,其他版本亦可。 2.在STM32的工程目录下新建一个文件夹并命名为LWIP 3.将lwip的src目录下的 /api /apps /core /include /netif 拷贝到当前文件夹下 4.在keil工程新建以下文件目录,并将代码添加进去 5.添加源码路径 6.在main.c新增MPU配置及使能缓存函数

    static void MPU_Config(void) { MPU_Region_InitTypeDef MPU_InitStruct; /* Disable the MPU */ HAL_MPU_Disable(); /* Configure the MPU attributes as WT for SRAM */ MPU_InitStruct.Enable = MPU_REGION_ENABLE; MPU_InitStruct.BaseAddress = 0x20020000; MPU_InitStruct.Size = MPU_REGION_SIZE_512KB; MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE; MPU_InitStruct.Number = MPU_REGION_NUMBER0; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; MPU_InitStruct.SubRegionDisable = 0x00; MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; /* Configure the MPU as Normal Non Cacheable for Ethernet Buffers in the SRAM2 */ MPU_InitStruct.Enable = MPU_REGION_ENABLE; MPU_InitStruct.BaseAddress = 0x2007C000; MPU_InitStruct.Size = MPU_REGION_SIZE_16KB; MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE; MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE; MPU_InitStruct.Number = MPU_REGION_NUMBER1; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1; MPU_InitStruct.SubRegionDisable = 0x00; MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); /* Configure the MPU as Device for Ethernet Descriptors in the SRAM2 */ MPU_InitStruct.Enable = MPU_REGION_ENABLE; MPU_InitStruct.BaseAddress = 0x2007C000; MPU_InitStruct.Size = MPU_REGION_SIZE_256B; MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE; MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE; MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE; MPU_InitStruct.Number = MPU_REGION_NUMBER2; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; MPU_InitStruct.SubRegionDisable = 0x00; MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); /* Enable the MPU */ HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT); } /** * @brief CPU L1-Cache enable. * @param None * @retval None */ static void CPU_CACHE_Enable(void) { /* Enable I-Cache */ SCB_EnableICache(); /* Enable D-Cache */ SCB_EnableDCache(); }

    7.由于生成代码中网卡RMII引脚不对,需自行修改

    void HAL_ETH_MspInit(ETH_HandleTypeDef* ethHandle) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(ethHandle->Instance==ETH) { __HAL_RCC_ETH_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOG_CLK_ENABLE(); /**ETH GPIO Configuration RMII_REF_CLK ----------------------> PA1 RMII_MDIO -------------------------> PA2 RMII_MDC --------------------------> PC1 RMII_MII_CRS_DV -------------------> PA7 RMII_MII_RXD0 ---------------------> PC4 RMII_MII_RXD1 ---------------------> PC5 RMII_MII_RXER ---------------------> PG2 RMII_MII_TX_EN --------------------> PG11 RMII_MII_TXD0 ---------------------> PG13 RMII_MII_TXD1 ---------------------> PB13 */ GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF11_ETH; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_7; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF11_ETH; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_13;//GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF11_ETH; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* Configure PG2, PG11, PG13 and PG14 */ GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_11 | GPIO_PIN_13; HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); /* Output HSE clock (25MHz) on MCO pin (PA8) to clock the PHY */ HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_PLLCLK, RCC_MCODIV_4); } }

    8.在ethernetif.c添加以下代码

    #if defined ( __CC_ARM ) ETH_DMADescTypeDef DMARxDscrTab[ETH_RXBUFNB] __attribute__((at(0x2007C000)));/* Ethernet Rx DMA Descriptors */ ETH_DMADescTypeDef DMATxDscrTab[ETH_TXBUFNB] __attribute__((at(0x2007C080)));/* Ethernet Tx DMA Descriptors */ uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE] __attribute__((at(0x2007C100))); /* Ethernet Receive Buffers */ uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE] __attribute__((at(0x2007D8D0))); /* Ethernet Transmit Buffers */ #elif defined ( __ICCARM__ ) /*!< IAR Compiler */ #pragma data_alignment=4 #pragma location=0x2007C000 __no_init ETH_DMADescTypeDef DMARxDscrTab[ETH_RXBUFNB];/* Ethernet Rx DMA Descriptors */ #pragma location=0x2007C080 __no_init ETH_DMADescTypeDef DMATxDscrTab[ETH_TXBUFNB];/* Ethernet Tx DMA Descriptors */ #pragma location=0x2007C100 __no_init uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE]; /* Ethernet Receive Buffers */ #pragma location=0x2007D8D0 __no_init uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE]; /* Ethernet Transmit Buffers */ #elif defined ( __GNUC__ ) /*!< GNU Compiler */ ETH_DMADescTypeDef DMARxDscrTab[ETH_RXBUFNB] __attribute__((section(".RxDecripSection")));/* Ethernet Rx DMA Descriptors */ ETH_DMADescTypeDef DMATxDscrTab[ETH_TXBUFNB] __attribute__((section(".TxDescripSection")));/* Ethernet Tx DMA Descriptors */ uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE] __attribute__((section(".RxarraySection"))); /* Ethernet Receive Buffers */ uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE] __attribute__((section(".TxarraySection"))); /* Ethernet Transmit Buffers */ #endif static void low_level_init(struct netif *netif) { uint8_t macaddress[6]= { MAC_ADDR0, MAC_ADDR1, MAC_ADDR2, MAC_ADDR3, MAC_ADDR4, MAC_ADDR5 }; heth.Instance = ETH; heth.Init.MACAddr = macaddress; heth.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;//使能自协商模式 heth.Init.Speed = ETH_SPEED_100M;//网速100M heth.Init.DuplexMode = ETH_MODE_FULLDUPLEX;//全双工 heth.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;//RMII接口 heth.Init.RxMode = ETH_RXPOLLING_MODE;//轮询接收 heth.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;//硬件帧校验 heth.Init.PhyAddress = LAN8742A_PHY_ADDRESS;//PHY都中 /* 配置以太网外设(GPIOs, clocks, MAC, DMA) */ if (HAL_ETH_Init(&heth) == HAL_OK) { /* 设置NETIF连接标志*/ netif->flags |= NETIF_FLAG_LINK_UP; } /* 设置netif连接标志 */ netif->flags |= NETIF_FLAG_LINK_UP; /* 初始化tx描述符列表:链接模式 */ HAL_ETH_DMATxDescListInit(&heth, DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB); /* 初始化rx描述符列表:链接模式 */ HAL_ETH_DMARxDescListInit(&heth, DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB); /*设置netif MAC硬件地址长度*/ netif->hwaddr_len = ETHARP_HWADDR_LEN; /* 设置MAC硬件地址 */ netif->hwaddr[0] = MAC_ADDR0; netif->hwaddr[1] = MAC_ADDR1; netif->hwaddr[2] = MAC_ADDR2; netif->hwaddr[3] = MAC_ADDR3; netif->hwaddr[4] = MAC_ADDR4; netif->hwaddr[5] = MAC_ADDR5; /* 设置netif最大传输单位*/ netif->mtu = 1500; /* 接收广播地址和ARP流量 */ netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP; /* 使能MAC和DMA发送接收 */ HAL_ETH_Start(&heth); } /** * @brief Returns the current time in milliseconds * when LWIP_TIMERS == 1 and NO_SYS == 1 * @param None * @retval Current Time value */ u32_t sys_now(void) { return HAL_GetTick(); }

    9.调用函数

    int main(void) { /* USER CODE BEGIN 1 */ /* Configure the MPU attributes as Device memory for ETH DMA descriptors */ MPU_Config(); /* Enable the CPU Cache */ CPU_CACHE_Enable(); /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); //MX_ETH_Init(); MX_USART3_UART_Init(); /* USER CODE BEGIN 2 */ /*初始化lwip*/ lwip_init(); printf("LAN8742A Ethernet Demo\n"); printf("LwIP版本%s\n",LWIP_VERSION_STRING); printf("ping实验\n"); //IP地址和端口可在main.h修改 printf("IP: %d.%d.%d.%d\n",IP_ADDR0,IP_ADDR1,IP_ADDR2,IP_ADDR3); /* 网络接口配置 */ Netif_Config(); /* 报告用户网络连接状态*/ User_notification(&gnetif); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* 从以太网中读取数据包,交给lwip处理 */ ethernetif_input(&gnetif); /* 处理lwip超时 */ sys_check_timeouts(); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ }

    ###三、烧录验证 1、打开终端,输入ping + IP 验证成功!!!

    Processed: 0.013, SQL: 9