LwIP移植到FreeRTOS(STM32F107+DP83848)
1.創(chuàng)建工程
?
2.移植庫(kù)文件
將STM32F107_ETH_LwIP_V1.0.0中的庫(kù)文件拷貝到工程中
添加文件和路徑
創(chuàng)建main.c
將STM32F107_ETH_LwIP_V1.0.0中的中斷入口文件和配置文件拷貝到工程中
刪除stm32f10x_it.h和stm32f10x_it.c中不需要的內(nèi)容
#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) {}添加路徑
設(shè)置預(yù)編譯符號(hào)
編譯,無(wú)錯(cuò)誤無(wú)警告
?
3.移植FreeRTOS
將FreeRTOSv10.3.1中的源碼拷貝到工程中
?
刪除不需要的架構(gòu)文件
?
?
添加文件和路徑
?
將FreeRTOSv10.3.1中demo中配置文件拷貝到工程中
修改異常向量入口
創(chuàng)建rcc.h、rcc.c、nvic.h、nvic.c、freertos.c五個(gè)文件
#ifndef __RCC_H_ #define __RCC_H_/* 功能: RCC時(shí)鐘配置參數(shù): 無(wú)返回值:無(wú)*/ void rcc_config(void);#endif #include "stm32f10x.h" #include "stm32f10x_flash.h" #include "rcc.h"/* 功能: RCC時(shí)鐘配置參數(shù): 無(wú)返回值:無(wú)*/ void rcc_config(void) { ErrorStatus HSEStartUpStatus;/* RCC寄存器設(shè)置為默認(rèn)配置 */RCC_DeInit();/* 打開(kāi)外部高速時(shí)鐘 */RCC_HSEConfig(RCC_HSE_ON);/* 等待外部高速時(shí)鐘穩(wěn)定 */HSEStartUpStatus = RCC_WaitForHSEStartUp();if(HSEStartUpStatus == SUCCESS) {/* 設(shè)置HCLK = SYSCLK */RCC_HCLKConfig(RCC_SYSCLK_Div1);/* 設(shè)置PCLK2 = HCLK */RCC_PCLK2Config(RCC_HCLK_Div1);/* 設(shè)置PCLK1 = HCLK / 2 */RCC_PCLK1Config(RCC_HCLK_Div2);/* 設(shè)置FLASH代碼延時(shí) */FLASH_SetLatency(FLASH_Latency_2);/* 使能預(yù)取址緩存 */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穩(wěn)定 */while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);/* 設(shè)置PLL為系統(tǒng)時(shí)鐘源 */RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);/* 等待系統(tǒng)時(shí)鐘源切換到PLL */while(RCC_GetSYSCLKSource() != 0x08);/* 設(shè)置系統(tǒng)節(jié)拍器時(shí)鐘源為FCLK */SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);} } #ifndef __NVIC_H_ #define __NVIC_H_/* 功能: 中斷嵌套控制器配置參數(shù): 無(wú)返回值:無(wú)*/ void nvic_config(void);#endif #include "stm32f10x.h" #include "nvic.h"/* 功能: 中斷嵌套控制器配置參數(shù): 無(wú)返回值:無(wú)*/ void nvic_config(void) {/* 選擇中斷分組4 */NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); } #include "FreeRTOS.h" #include "task.h"void lwip_task(void *argument);/* 功能: freertos初始化參數(shù): 無(wú)返回值:無(wú)*/ void freertos_init(void) {/* 按鍵任務(wù) */xTaskCreate(lwip_task, "lwip_task", 128, NULL, 4, NULL); }/* lwip任務(wù) */ 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);/* 主函數(shù) */ int main(void) {/* 硬件初始化 */prvSetupHardware();/* freertos初始化 */freertos_init();/* 啟動(dòng)調(diào)度器 */vTaskStartScheduler(); }/* 硬件初始化 */ static void prvSetupHardware(void) { /* 時(shí)鐘配置 */rcc_config();/* 中斷嵌套控制器配置 */nvic_config(); }使用j-link調(diào)試,在任務(wù)中打上斷點(diǎn),系統(tǒng)調(diào)度正常
?
4.移植庫(kù)文件LwIP
將lwip-2.1.2中的源碼拷貝到工程中
添加文件和路徑
將STM32F2x7_ETH_LwIP_V1.1.0中配置文件拷貝到工程中
將STM32F2x7_ETH_LwIP_V1.1.0中架構(gòu)相關(guān)文件拷貝到工程中,并添加路徑
編譯發(fā)現(xiàn)部分變量類型重復(fù)定義,將cc.h中重復(fù)的部分注釋掉
將contrib-2.1.0中FreeRTOS架構(gòu)文件拷貝并覆蓋到工程中
將sys_arch.c添加到工程中
編譯發(fā)現(xiàn),FreeRTOS部分功能未開(kāi)啟,修改FreeRTOS配置文件
編譯發(fā)現(xiàn),LwIP配置文件中configMAX_PRIORITIES未定義,修改
編譯發(fā)現(xiàn),不允許TCP_SNDQUEUELOWAT >= TCP_SND_QUEUELEN,修改
編譯發(fā)現(xiàn),errno未定義,定義
?
5.移植DP83848網(wǎng)卡驅(qū)動(dòng)
將STM32F2x7_ETH_LwIP_V1.1.0網(wǎng)卡驅(qū)動(dòng)拷貝到工程中
將網(wǎng)卡驅(qū)動(dòng)文件添加到工程,并結(jié)合STM32F107_ETH_LwIP_V1.0.0工程進(jìn)行適當(dāng)修改
/*** @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 );} }編譯發(fā)現(xiàn),FreeRTOS部分功能未開(kāi)啟,修改FreeRTOS配置文件
創(chuàng)建eth.h和eth.c文件
#ifndef __ETH_H_ #define __ETH_H_/* 功能: ETH配置參數(shù): 無(wú)返回值:無(wú)*/ void eth_config(void);#endif #include "stm32_eth.h" #include "eth.h"#define PHY_ADDRESS 0x01/* 功能: ETH配置參數(shù): 無(wú)返回值:無(wú)*/ 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(Ð_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(Ð_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);/* 主函數(shù) */ int main(void) {/* 硬件初始化 */prvSetupHardware();/* freertos初始化 */freertos_init();/* 啟動(dòng)調(diào)度器 */vTaskStartScheduler(); }/* 硬件初始化 */ static void prvSetupHardware(void) { /* 時(shí)鐘配置 */rcc_config();/* 中斷嵌套控制器配置 */nvic_config();/* ETH配置 */eth_config(); }創(chuàng)建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, ðernetif_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初始化參數(shù): 無(wú)返回值:無(wú)*/ void freertos_init(void) {/* 按鍵任務(wù) */xTaskCreate(lwip_task, "lwip_task", 128, NULL, 4, NULL); }int errno;/* lwip任務(wù) */ void lwip_task(void *argument) {LwIP_Init();while(1){vTaskDelay(1000);} }編譯運(yùn)行,ping不通。仿真發(fā)現(xiàn)是ICMP校驗(yàn)問(wèn)題。修改lwip配置文件
編譯運(yùn)行,ping成功
總結(jié)
以上是生活随笔為你收集整理的LwIP移植到FreeRTOS(STM32F107+DP83848)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: FreeModbus源码获取
- 下一篇: uboot启动内核