1.创建工程

2.移植库文件

将STM32F107_ETH_LwIP_V1.0.0中的库文件拷贝到工程中

添加文件和路径

创建main.c

将STM32F107_ETH_LwIP_V1.0.0中的中断入口文件和配置文件拷贝到工程中

删除stm32f10x_it.h和stm32f10x_it.c中不需要的内容

#ifndef __STM32F10x_IT_H
#define __STM32F10x_IT_H#ifdef __cplusplusextern "C" {
#endif #include "stm32f10x.h"void NMI_Handler(void);
void HardFault_Handler(void);
void MemManage_Handler(void);
void BusFault_Handler(void);
void UsageFault_Handler(void);
void SVC_Handler(void);
void DebugMon_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);#ifdef __cplusplus
}
#endif#endif
#include "stm32f10x_it.h"void NMI_Handler(void)
{}void HardFault_Handler(void)
{while(1){}
}void MemManage_Handler(void)
{while(1){}
}void BusFault_Handler(void)
{while(1){}
}void UsageFault_Handler(void)
{while(1){}
}void SVC_Handler(void)
{}void DebugMon_Handler(void)
{}void PendSV_Handler(void)
{}void SysTick_Handler(void)
{}

添加路径

设置预编译符号

编译,无错误无警告

3.移植FreeRTOS

将FreeRTOSv10.3.1中的源码拷贝到工程中

删除不需要的架构文件

添加文件和路径

将FreeRTOSv10.3.1中demo中配置文件拷贝到工程中

修改异常向量入口

创建rcc.h、rcc.c、nvic.h、nvic.c、freertos.c五个文件

#ifndef __RCC_H_
#define __RCC_H_/* 功能:  RCC时钟配置参数:  无返回值:无*/
void rcc_config(void);#endif
#include "stm32f10x.h"
#include "stm32f10x_flash.h"
#include "rcc.h"/* 功能:    RCC时钟配置参数:  无返回值:无*/
void rcc_config(void)
{ ErrorStatus HSEStartUpStatus;/* RCC寄存器设置为默认配置 */RCC_DeInit();/* 打开外部高速时钟 */RCC_HSEConfig(RCC_HSE_ON);/* 等待外部高速时钟稳定 */HSEStartUpStatus = RCC_WaitForHSEStartUp();if(HSEStartUpStatus == SUCCESS) {/* 设置HCLK = SYSCLK */RCC_HCLKConfig(RCC_SYSCLK_Div1);/* 设置PCLK2 = HCLK */RCC_PCLK2Config(RCC_HCLK_Div1);/* 设置PCLK1 = HCLK / 2 */RCC_PCLK1Config(RCC_HCLK_Div2);/* 设置FLASH代码延时 */FLASH_SetLatency(FLASH_Latency_2);/* 使能预取址缓存 */FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);RCC_PREDIV2Config(RCC_PREDIV2_Div5);RCC_PLL2Config(RCC_PLL2Mul_8);RCC_PLL2Cmd(ENABLE);while(RCC_GetFlagStatus(RCC_FLAG_PLL2RDY)== RESET){}RCC_PREDIV1Config(RCC_PREDIV1_Source_PLL2, RCC_PREDIV1_Div5);RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_9);/* 使能PLL */RCC_PLLCmd(ENABLE);/* 等待PLL稳定 */while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);/* 设置PLL为系统时钟源 */RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);/* 等待系统时钟源切换到PLL */while(RCC_GetSYSCLKSource() != 0x08);/* 设置系统节拍器时钟源为FCLK */SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);}
}
#ifndef __NVIC_H_
#define __NVIC_H_/* 功能: 中断嵌套控制器配置参数:    无返回值:无*/
void nvic_config(void);#endif
#include "stm32f10x.h"
#include "nvic.h"/* 功能:   中断嵌套控制器配置参数:    无返回值:无*/
void nvic_config(void)
{/* 选择中断分组4 */NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
}
#include "FreeRTOS.h"
#include "task.h"void lwip_task(void *argument);/* 功能:    freertos初始化参数:  无返回值:无*/
void freertos_init(void)
{/* 按键任务 */xTaskCreate(lwip_task, "lwip_task", 128, NULL, 4, NULL);
}/* lwip任务 */
void lwip_task(void *argument)
{while(1){vTaskDelay(1000);}
}

修改main.c

#include "stm32f10x.h"
#include "rcc.h"
#include "nvic.h"
#include "FreeRTOS.h"
#include "task.h"/* 硬件初始化 */
static void prvSetupHardware(void);
/* freertos初始化 */
void freertos_init(void);/* 主函数 */
int main(void)
{/* 硬件初始化 */prvSetupHardware();/* freertos初始化 */freertos_init();/* 启动调度器 */vTaskStartScheduler();
}/* 硬件初始化 */
static void prvSetupHardware(void)
{   /* 时钟配置 */rcc_config();/* 中断嵌套控制器配置 */nvic_config();
}

使用j-link调试,在任务中打上断点,系统调度正常

4.移植库文件LwIP

将lwip-2.1.2中的源码拷贝到工程中

添加文件和路径

将STM32F2x7_ETH_LwIP_V1.1.0中配置文件拷贝到工程中

将STM32F2x7_ETH_LwIP_V1.1.0中架构相关文件拷贝到工程中,并添加路径

编译发现部分变量类型重复定义,将cc.h中重复的部分注释掉

将contrib-2.1.0中FreeRTOS架构文件拷贝并覆盖到工程中

将sys_arch.c添加到工程中

编译发现,FreeRTOS部分功能未开启,修改FreeRTOS配置文件

编译发现,LwIP配置文件中configMAX_PRIORITIES未定义,修改

编译发现,不允许TCP_SNDQUEUELOWAT >= TCP_SND_QUEUELEN,修改

编译发现,errno未定义,定义

5.移植DP83848网卡驱动

将STM32F2x7_ETH_LwIP_V1.1.0网卡驱动拷贝到工程中

将网卡驱动文件添加到工程,并结合STM32F107_ETH_LwIP_V1.0.0工程进行适当修改

/*** @file* Ethernet Interface Skeleton**//** Copyright (c) 2001-2004 Swedish Institute of Computer Science.* All rights reserved.** Redistribution and use in source and binary forms, with or without modification,* are permitted provided that the following conditions are met:** 1. Redistributions of source code must retain the above copyright notice,*    this list of conditions and the following disclaimer.* 2. Redistributions in binary form must reproduce the above copyright notice,*    this list of conditions and the following disclaimer in the documentation*    and/or other materials provided with the distribution.* 3. The name of the author may not be used to endorse or promote products*    derived from this software without specific prior written permission.** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY* OF SUCH DAMAGE.** This file is part of the lwIP TCP/IP stack.** Author: Adam Dunkels <adam@sics.se>**//** This file is a skeleton for developing Ethernet network interface* drivers for lwIP. Add code to the low_level functions and do a* search-and-replace for the word "ethernetif" to replace it with* something that better describes your network interface.*/#include "lwip/opt.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/pbuf.h"
#include "lwip/sys.h"
#include "netif/etharp.h"
#include "ethernetif.h"
#include "stm32_eth.h"
#include <string.h>
#include "FreeRTOS.h"
#include "semphr.h"#define netifMTU                                (1500)
#define netifINTERFACE_TASK_STACK_SIZE      ( 350 )
#define netifINTERFACE_TASK_PRIORITY        ( configMAX_PRIORITIES - 1 )
#define netifGUARD_BLOCK_TIME           ( 250 )
/* The time to block waiting for input. */
#define emacBLOCK_TIME_WAITING_FOR_INPUT    ( ( portTickType ) 100 )/* Define those to better describe your network interface. */
#define IFNAME0 's'
#define IFNAME1 't'static struct netif *s_pxNetIf = NULL;
xSemaphoreHandle s_xSemaphore = NULL;#define ETH_RXBUFNB        4
#define ETH_TXBUFNB        2#define  ETH_DMARxDesc_FrameLengthShift           16
#define  ETH_ERROR              ((u32)0)
#define  ETH_SUCCESS            ((u32)1)/* Ethernet Rx & Tx DMA Descriptors */
ETH_DMADESCTypeDef  DMARxDscrTab[ETH_RXBUFNB], DMATxDscrTab[ETH_TXBUFNB];/* Ethernet Receive buffers  */
uint8_t Rx_Buff[ETH_RXBUFNB][ETH_MAX_PACKET_SIZE]; /* Ethernet Transmit buffers */
uint8_t Tx_Buff[ETH_TXBUFNB][ETH_MAX_PACKET_SIZE]; /* Global pointers to track current transmit and receive descriptors */
extern ETH_DMADESCTypeDef  *DMATxDescToSet;
extern ETH_DMADESCTypeDef  *DMARxDescToGet;typedef struct
{u32 length;u32 buffer;ETH_DMADESCTypeDef *descriptor;
}FrameTypeDef;FrameTypeDef ETH_RxPkt_ChainMode(void);
u32 ETH_GetCurrentTxBuffer(void);
u32 ETH_TxPkt_ChainMode(u16 FrameLength);static void ethernetif_input( void * pvParameters );/*** In this function, the hardware should be initialized.* Called from ethernetif_init().** @param netif the already initialized lwip network interface structure*        for this ethernetif*/
static void low_level_init(struct netif *netif)
{uint32_t i;/* set netif MAC hardware address length */netif->hwaddr_len = ETHARP_HWADDR_LEN;/* set netif MAC hardware address */netif->hwaddr[0] = 0x00;netif->hwaddr[1] = 0x80;netif->hwaddr[2] = 0xE1;netif->hwaddr[3] = 0x00;netif->hwaddr[4] = 0x00;netif->hwaddr[5] = 0x00;/* set netif maximum transfer unit */netif->mtu = 1500;/* Accept broadcast address and ARP traffic */netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;s_pxNetIf =netif;/* create binary semaphore used for informing ethernetif of frame reception */if (s_xSemaphore == NULL){s_xSemaphore= xSemaphoreCreateCounting(20,0);}/* initialize MAC address in ethernet MAC */ ETH_MACAddressConfig(ETH_MAC_Address0, netif->hwaddr); /* 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<ETH_RXBUFNB; i++){ETH_DMARxDescReceiveITConfig(&DMARxDscrTab[i], ENABLE);}}#ifdef CHECKSUM_BY_HARDWARE/* Enable the checksum insertion for the Tx frames */{for(i=0; i<ETH_TXBUFNB; i++){ETH_DMATxDescChecksumInsertionConfig(&DMATxDscrTab[i], ETH_DMATxDesc_ChecksumTCPUDPICMPFull);}}
#endif/* create the task that handles the ETH_MAC */xTaskCreate(ethernetif_input, "Eth_if", netifINTERFACE_TASK_STACK_SIZE, NULL,netifINTERFACE_TASK_PRIORITY,NULL);/* Enable MAC and DMA transmission and reception */ETH_Start();
}/*** This function should do the actual transmission of the packet. The packet is* contained in the pbuf that is passed to the function. This pbuf* might be chained.** @param netif the lwip network interface structure for this ethernetif* @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)* @return ERR_OK if the packet could be sent*         an err_t value if the packet couldn't be sent** @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to*       strange results. You might consider waiting for space in the DMA queue*       to become availale since the stack doesn't retry to send a packet*       dropped because of memory failure (except for the TCP timers).*/static err_t low_level_output(struct netif *netif, struct pbuf *p)
{static xSemaphoreHandle xTxSemaphore = NULL;struct pbuf *q;uint32_t l = 0;u8 *buffer ;if (xTxSemaphore == NULL){vSemaphoreCreateBinary (xTxSemaphore);} if (xSemaphoreTake(xTxSemaphore, netifGUARD_BLOCK_TIME)){buffer =  (u8 *)(DMATxDescToSet->Buffer1Addr);for(q = p; q != NULL; q = q->next) {memcpy((u8_t*)&buffer[l], q->payload, q->len);l = l + q->len;}ETH_TxPkt_ChainMode(l);xSemaphoreGive(xTxSemaphore);}return ERR_OK;
}/*** Should allocate a pbuf and transfer the bytes of the incoming* packet from the interface into the pbuf.** @param netif the lwip network interface structure for this ethernetif* @return a pbuf filled with the received packet (including MAC header)*         NULL on memory error*/
static struct pbuf * low_level_input(struct netif *netif)
{struct pbuf *p, *q;u16_t len;uint32_t l=0;FrameTypeDef frame;u8 *buffer;p = NULL;/* Get received frame */frame = ETH_RxPkt_ChainMode();/* check that frame has no error */if ((frame.descriptor->Status & ETH_DMARxDesc_ES) == (uint32_t)RESET){/* Obtain the size of the packet and put it into the "len" variable. */len = frame.length;buffer = (u8 *)frame.buffer;/* We allocate a pbuf chain of pbufs from the pool. */p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);/* Copy received frame from ethernet driver buffer to stack buffer */if (p != NULL){ for (q = p; q != NULL; q = q->next){memcpy((u8_t*)q->payload, (u8_t*)&buffer[l], q->len);l = l + q->len;} }}/* Set Own bit of the Rx descriptor Status: gives the buffer back to ETHERNET DMA */frame.descriptor->Status = ETH_DMARxDesc_OWN; /* When Rx Buffer unavailable flag is set: clear it and resume reception */if ((ETH->DMASR & ETH_DMASR_RBUS) != (u32)RESET)  {/* Clear RBUS ETHERNET DMA flag */ETH->DMASR = ETH_DMASR_RBUS;/* Resume DMA reception */ETH->DMARPDR = 0;}return p;
}/*** This function is the ethernetif_input task, it is processed when a packet * is ready to be read from the interface. It uses the function low_level_input() * that should handle the actual reception of bytes from the network* interface. Then the type of the received packet is determined and* the appropriate input function is called.** @param netif the lwip network interface structure for this ethernetif*/
void ethernetif_input( void * pvParameters )
{struct pbuf *p;for( ;; ){if (xSemaphoreTake( s_xSemaphore, emacBLOCK_TIME_WAITING_FOR_INPUT)==pdTRUE){p = low_level_input( s_pxNetIf );if (ERR_OK != s_pxNetIf->input( p, s_pxNetIf)){pbuf_free(p);p=NULL;}}}
}  /*** Should be called at the beginning of the program to set up the* network interface. It calls the function low_level_init() to do the* actual setup of the hardware.** This function should be passed as a parameter to netif_add().** @param netif the lwip network interface structure for this ethernetif* @return ERR_OK if the loopif is initialized*         ERR_MEM if private data couldn't be allocated*         any other err_t on error*/
err_t ethernetif_init(struct netif *netif)
{LWIP_ASSERT("netif != NULL", (netif != NULL));#if LWIP_NETIF_HOSTNAME/* Initialize interface hostname */netif->hostname = "lwip";
#endif /* LWIP_NETIF_HOSTNAME */netif->name[0] = IFNAME0;netif->name[1] = IFNAME1;netif->output = etharp_output;netif->linkoutput = low_level_output;/* initialize the hardware */low_level_init(netif);return ERR_OK;
}/*******************************************************************************
* Function Name  : ETH_RxPkt_ChainMode
* Description    : Receives a packet.
* Input          : None
* Output         : None
* Return         : frame: farme size and location
*******************************************************************************/
FrameTypeDef ETH_RxPkt_ChainMode(void)
{ u32 framelength = 0;FrameTypeDef frame = {0,0}; /* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */if((DMARxDescToGet->Status & ETH_DMARxDesc_OWN) != (u32)RESET){    frame.length = ETH_ERROR;if ((ETH->DMASR & ETH_DMASR_RBUS) != (u32)RESET)  {/* Clear RBUS ETHERNET DMA flag */ETH->DMASR = ETH_DMASR_RBUS;/* Resume DMA reception */ETH->DMARPDR = 0;}/* Return error: OWN bit set */return frame; }if(((DMARxDescToGet->Status & ETH_DMARxDesc_ES) == (u32)RESET) && ((DMARxDescToGet->Status & ETH_DMARxDesc_LS) != (u32)RESET) &&  ((DMARxDescToGet->Status & ETH_DMARxDesc_FS) != (u32)RESET))  {      /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */framelength = ((DMARxDescToGet->Status & ETH_DMARxDesc_FL) >> ETH_DMARxDesc_FrameLengthShift) - 4;/* Get the addrees of the actual buffer */frame.buffer = DMARxDescToGet->Buffer1Addr;   }else{/* Return ERROR */framelength = ETH_ERROR;}frame.length = framelength;frame.descriptor = DMARxDescToGet;/* Update the ETHERNET DMA global Rx descriptor with next Rx decriptor */      /* Chained Mode */    /* Selects the next DMA Rx descriptor list for next buffer to read */ DMARxDescToGet = (ETH_DMADESCTypeDef*) (DMARxDescToGet->Buffer2NextDescAddr);    /* Return Frame */return (frame);
}/*******************************************************************************
* Function Name  : ETH_TxPkt_ChainMode
* Description    : Transmits a packet, from application buffer, pointed by ppkt.
* Input          : - FrameLength: Tx Packet size.
* Output         : None
* Return         : ETH_ERROR: in case of Tx desc owned by DMA
*                  ETH_SUCCESS: for correct transmission
*******************************************************************************/
u32 ETH_TxPkt_ChainMode(u16 FrameLength)
{   /* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */if((DMATxDescToSet->Status & ETH_DMATxDesc_OWN) != (u32)RESET){  /* Return ERROR: OWN bit set */return ETH_ERROR;}/* Setting the Frame Length: bits[12:0] */DMATxDescToSet->ControlBufferSize = (FrameLength & ETH_DMATxDesc_TBS1);/* Setting the last segment and first segment bits (in this case a frame is transmitted in one descriptor) */    DMATxDescToSet->Status |= ETH_DMATxDesc_LS | ETH_DMATxDesc_FS;/* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */DMATxDescToSet->Status |= ETH_DMATxDesc_OWN;/* When Tx Buffer unavailable flag is set: clear it and resume transmission */if ((ETH->DMASR & ETH_DMASR_TBUS) != (u32)RESET){/* Clear TBUS ETHERNET DMA flag */ETH->DMASR = ETH_DMASR_TBUS;/* Resume DMA transmission*/ETH->DMATPDR = 0;}/* Update the ETHERNET DMA global Tx descriptor with next Tx decriptor */  /* Chained Mode *//* Selects the next DMA Tx descriptor list for next buffer to send */ DMATxDescToSet = (ETH_DMADESCTypeDef*) (DMATxDescToSet->Buffer2NextDescAddr);    /* Return SUCCESS */return ETH_SUCCESS;
}/*******************************************************************************
* Function Name  : ETH_GetCurrentTxBuffer
* Description    : Return the address of the buffer pointed by the current descritor.
* Input          : None
* Output         : None
* Return         : Buffer address
*******************************************************************************/
u32 ETH_GetCurrentTxBuffer(void)
{ /* Return Buffer address */return (DMATxDescToSet->Buffer1Addr);
}/*** @brief  This function handles ETH interrupt request.* @param  None* @retval None*/
void ETH_IRQHandler(void)
{portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;/* Frame received */if ( ETH_GetDMAFlagStatus(ETH_DMA_FLAG_R) == SET) {/* Give the semaphore to wakeup LwIP task */xSemaphoreGiveFromISR( s_xSemaphore, &xHigherPriorityTaskWoken );   }/* Clear the interrupt flags. *//* Clear the Eth DMA Rx IT pending bits */ETH_DMAClearITPendingBit(ETH_DMA_IT_R);ETH_DMAClearITPendingBit(ETH_DMA_IT_NIS);/* Switch tasks if necessary. */ if( xHigherPriorityTaskWoken != pdFALSE ){portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );}
}

编译发现,FreeRTOS部分功能未开启,修改FreeRTOS配置文件

创建eth.h和eth.c文件

#ifndef __ETH_H_
#define __ETH_H_/* 功能:  ETH配置参数:    无返回值:无*/
void eth_config(void);#endif
#include "stm32_eth.h"
#include "eth.h"#define PHY_ADDRESS       0x01/* 功能:  ETH配置参数:    无返回值:无*/
void eth_config(void)
{
////* Enable ETHERNET clock  */RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ETH_MAC | RCC_AHBPeriph_ETH_MAC_Tx |RCC_AHBPeriph_ETH_MAC_Rx, ENABLE);/* Enable GPIOs and ADC1 clocks */RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC |RCC_APB2Periph_GPIOD | RCC_APB2Periph_AFIO, ENABLE);///GPIO_InitTypeDef GPIO_InitStructure;/* SWJ重映射 */GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);  /* ETH重映射 */GPIO_PinRemapConfig(GPIO_Remap_ETH, ENABLE);/* MCO输出 */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_Init(GPIOA, &GPIO_InitStructure);/* ETHERNET pins configuration- ETH_MII_MDIO / ETH_RMII_MDIO: PA2- ETH_MII_MDC / ETH_RMII_MDC: PC1- ETH_MII_TX_EN / ETH_RMII_TX_EN: PB11- ETH_MII_TXD0 / ETH_RMII_TXD0: PB12- ETH_MII_TXD1 / ETH_RMII_TXD1: PB13- ETH_MII_RX_CLK / ETH_RMII_REF_CLK: PA1- ETH_MII_RX_DV / ETH_RMII_CRS_DV: PD8- ETH_MII_RXD0 / ETH_RMII_RXD0: PD9- ETH_MII_RXD1 / ETH_RMII_RXD1: PD10 */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_Init(GPIOC, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13;                              GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOD, &GPIO_InitStructure);////* NVIC configuration */NVIC_InitTypeDef NVIC_InitStructure;/* Enable the Ethernet global Interrupt */NVIC_InitStructure.NVIC_IRQChannel = ETH_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure); ///ETH_InitTypeDef ETH_InitStructure;/* RMII Media interface selection ------------------------------------------*/GPIO_ETH_MediaInterfaceConfig(GPIO_ETH_MediaInterface_RMII);/* Set PLL3 clock output to 50MHz (25MHz /5 *10 =50MHz) */RCC_PLL3Config(RCC_PLL3Mul_10);/* Enable PLL3 */RCC_PLL3Cmd(ENABLE);/* Wait till PLL3 is ready */while(RCC_GetFlagStatus(RCC_FLAG_PLL3RDY) == RESET){}/* Get PLL3 clock on PA8 pin (MCO) */RCC_MCOConfig(RCC_MCO_PLL3CLK); /* 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(&ETH_InitStructure);/* Fill ETH_InitStructure parametrs *//*------------------------   MAC   -----------------------------------*/ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Enable  ;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_HARDWAREETH_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 */ETH_Init(&ETH_InitStructure, PHY_ADDRESS);/* Enable the Ethernet Rx Interrupt */ETH_DMAITConfig(ETH_DMA_IT_NIS | ETH_DMA_IT_R, ENABLE);
}

修改main.c

#include "stm32f10x.h"
#include "rcc.h"
#include "nvic.h"
#include "eth.h"
#include "FreeRTOS.h"
#include "task.h"/* 硬件初始化 */
static void prvSetupHardware(void);
/* freertos初始化 */
void freertos_init(void);/* 主函数 */
int main(void)
{/* 硬件初始化 */prvSetupHardware();/* freertos初始化 */freertos_init();/* 启动调度器 */vTaskStartScheduler();
}/* 硬件初始化 */
static void prvSetupHardware(void)
{   /* 时钟配置 */rcc_config();/* 中断嵌套控制器配置 */nvic_config();/* ETH配置 */eth_config();
}

创建lwip.h和lwip.c

#ifndef __LWIP_H_
#define __LWIP_H_void LwIP_Init(void);#endif
#include "lwip.h"
#include "lwip/tcpip.h"
#include "ethernetif.h"struct netif xnetif; /* network interface structure *//*** @brief  Initializes the lwIP stack* @param  None* @retval None*/
void LwIP_Init(void)
{ip4_addr_t ipaddr, netmask, gw;/* Create tcp_ip stack thread */tcpip_init( NULL, NULL );   /* IP address setting & display on STM32_evalboard LCD*/IP4_ADDR(&ipaddr, 192, 168, 1, 10);IP4_ADDR(&netmask, 255, 255 , 255, 0);IP4_ADDR(&gw, 192, 168, 1, 1);/* - netif_add(struct netif *netif, struct ip_addr *ipaddr,struct ip_addr *netmask, struct ip_addr *gw,void *state, err_t (* init)(struct netif *netif),err_t (* input)(struct pbuf *p, struct netif *netif))Adds your network interface to the netif_list. Allocate a structnetif and pass a pointer to this structure as the first argument.Give pointers to cleared ip_addr structures when using DHCP,or fill them with sane numbers otherwise. The state pointer may be NULL.The init function pointer must point to a initialization function foryour ethernet netif interface. The following code illustrates it's use.*/netif_add(&xnetif, &ipaddr, &netmask, &gw, NULL, &ethernetif_init, &tcpip_input);/*  Registers the default network interface. */netif_set_default(&xnetif);/*  When the netif is fully configured this function must be called.*/netif_set_up(&xnetif);
}

修改freertos.c

#include "FreeRTOS.h"
#include "task.h"
#include "lwip.h"void lwip_task(void *argument);/* 功能:    freertos初始化参数:  无返回值:无*/
void freertos_init(void)
{/* 按键任务 */xTaskCreate(lwip_task, "lwip_task", 128, NULL, 4, NULL);
}int errno;/* lwip任务 */
void lwip_task(void *argument)
{LwIP_Init();while(1){vTaskDelay(1000);}
}

编译运行,ping不通。仿真发现是ICMP校验问题。修改lwip配置文件

编译运行,ping成功

LwIP移植到FreeRTOS(STM32F107+DP83848)相关推荐

  1. STM32F407+FreeRTOS+LwIP移植问题汇总

    1.移植环境为STM32F407标准库+FreeRTOS v9.00+LwIP1.4.1.LwIP移植可分为带操作系统和不带操作系统两种移植方式.本次移植采用了带操作系统,但是只移植了LwIP的内核( ...

  2. 构建一个轻量级的嵌入式虚拟平台,开发工程用板stm32 picoc解释器,大量自定义函数,sarm拓展,lwip移植,nes模拟器移植,系统优化,等等技术的融合

    让嵌入式想java一样一处编写到处运行 第一次写博客,其实接触嵌入式已经快两年了,从开始学51单片机的时候,怀着满腔的热情.写出了点亮第一个流水灯代码的时候那个无比的激动,到后面自己做许多有趣的东西( ...

  3. linux模块移植到freertos,FATFS在嵌入式操作系统FreeRTOS中的移植与应用

    摘 要: FreeRTOS作为一款免费的实时操作系统,系统内核小.裁剪方便.移植性好,广泛应用于对成本敏感的小型嵌入式系统中,但是FreeRTOS本身不带文件管理功能,不便于很多需要经常进行文件存储与 ...

  4. 为LWIP移植DM9000驱动

    以前设计了一个stm32F407+DM9000的板子,跑的是UIP网络协议栈,但在使用中遇到了各种问题,经过很多次补丁才算稳定,但性能还是不尽如人意.现在转来研究下LWIP,正好开发板有个freeRT ...

  5. LwIP移植准备工作

    1.下载LwIP源码 进入官网https://savannah.nongnu.org/projects/lwip/ 进入下载页面,下载最新的LwIP源码和例程 2.下载FreeRTOS源码 进入官网: ...

  6. freertos zynq 移植_Zynq-7000 FreeRTOS(一)系统移植配置

    软件版本:VIvado HLx 2018.2 从FreeRTOS的官网中下载源代码: https://www.freertos.org/a00104.html 图:FreeRTOS的官网 上图中,点击 ...

  7. CH32V307 LwIP移植使用

    CH32V307是沁恒推出的通用单片机系列,功能很强,集成片上的10M以太网PHY芯片,官方提供的以太网并没有公开源码,只是以一个SOCKET以太网库的形式提供.目前也没有多少移植LWIP的例程公布. ...

  8. linux模块移植到freertos,opus移植到freertos系统

    硬件平台:cortex-M4F 200MHZ平台(RTL8721DM) 软件系统:FREERTOS 编译器: Using built-in specs. COLLECT_GCC=/home/kuili ...

  9. 来吧展示!以太网配合FreeRTOS实现socket通信!实战STM32F4以太网DP83848配合LWIP

    目的:实现STM32F407+FreeRTOS+Ethernet(DP83848)+Lwip实现socket通信,在实现之前我们先来了解下几点储备知识 一. 以太网行业标准MII/RMII 1 以太网 ...

最新文章

  1. linux c 编译警告 warning: this decimal constant is unsigned only in ISO C90
  2. mkisofs简单定制linux iso
  3. laravel 导出导入excel和csv文件的 使用
  4. Mixing ASP.NET MVC and Webforms
  5. iOS-多线程 ,整理集锦,多种线程的创建
  6. spoolsv.exe占cpu 99%的解决方法(转)
  7. 偶也要去上海Tech一把了
  8. 在Windows XP中轻松发传真
  9. 初识用.NET Remoting来开发分布式应用
  10. openssl做HMAC实例(C++)
  11. 2021免费注册TK域名使用一年的方法
  12. python输入数组_python读入数组
  13. [禅悟人生]有自知之明, 在深浅之间权衡做人
  14. [联想 ThinkPad E450c 怎么进入BIOS]
  15. 儿童学习桌有哪些升降方式
  16. 数据分析 常见异常及解决办法(一)
  17. Udacity 自动驾驶工程师学习笔记(二)——深度学习(1)
  18. 计算机的一级基础知识
  19. 怎么更改计算机用户名网络密码怎么办,怎么改wifi密码和名称(电脑修改wifi密码步骤)...
  20. PAT A1141 PAT Ranking of Institutions ——昨夜西风凋碧树

热门文章

  1. Qt文档阅读笔记|Qt工作笔记-setupUi官方解析与实例(widgets中界面与业务分离)
  2. 大四课程设计之基于RFID技术的考勤管理系统(二)读取COM口数据
  3. matlab数学建模可应用到第几章,《MATLAB在数学建模中的应用(第2版)》
  4. java 8 java demo_Java 8 中的 Streams API Demo
  5. bash mysql 循环输出_Bash实用技巧:同时循环两个列表
  6. php mysql mvc_超简洁PHPMVC
  7. CentOS 安装Python 3.52
  8. 计组之中央处理器:8、五段式指令流水线
  9. 操作系统之文件管理:2、文件的逻辑结构(有结构文件、无结构文件、顺序文件、索引文件、索引顺序文件)
  10. linux 高级IO函数之sendfile splice tee