NetworkInterface.c:
~~~ /* Standard includes. */include <stdint.h>
include <stdio.h>
include <stdlib.h>
/* FreeRTOS includes. */include “FreeRTOS.h”
include “task.h”
include “queue.h”
include “semphr.h”
/* FreeRTOS+TCP includes. */include “FreeRTOS_IP.h”
include “FreeRTOS_Sockets.h”
include “FreeRTOSIPPrivate.h”
include “NetworkBufferManagement.h”
include “stm32f4x7_eth.h”
include “NetworkInterfaceDefs.h”
/* ST includes. */include “stm32f4xx.h”
/********************************************************************************** * prototypes **********************************************************************************/ static void prvEMACHandlerTask( void pvParameters ); /********************************************************************************** * vars **********************************************************************************/ static TaskHandle_t xEMACTaskHandle = NULL; / Ethernet Rx & Tx DMA Descriptors / extern ETH_DMADESCTypeDef DMARxDscrTab[ETH_RXBUFNB], DMATxDscrTab[ETH_TXBUFNB]; / Ethernet Driver Receive buffers / extern uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE]; / Ethernet Driver Transmit buffers / extern uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE]; / Global pointer for last received frame infos */ extern ETH_DMA_Rx_Frame_infos *DMA_RX_FRAME_infos; /********************************************************************************** * static funs **********************************************************************************/ static void resetPhy (void) { GPIO_InitTypeDef gpioInit; unsigned int some; gpioInit.GPIO_Mode = GPIO_Mode_OUT; gpioInit.GPIO_OType = GPIO_OType_PP; gpioInit.GPIO_Pin = GPIO_Pin_12; gpioInit.GPIO_PuPd = GPIO_PuPd_NOPULL; gpioInit.GPIO_Speed = GPIO_Low_Speed; GPIO_Init(GPIOH, &gpioInit); GPIO_WriteBit(GPIOH, GPIO_Pin_12, Bit_RESET); some=1000000; while (some) some–; GPIO_WriteBit(GPIOH, GPIO_Pin_12, Bit_SET); } static void initEthGpios (void) { GPIO_InitTypeDef gpioInit; unsigned int some;RCC->AHB1ENR |= 0x00000010; //GPIOE enable clock
RCC->AHB1ENR |= 0x00000001; //GPIOA enable clock
RCC->AHB1ENR |= 0x00000002; //GPIOB enable clock
RCC->AHB1ENR |= 0x00000004; //GPIOC enable clock
RCC->AHB1ENR |= 0x00000040; //GPIOG enable clock
RCC->AHB1ENR |= 0x00000080; //GPIOH enable clock
gpioInit.GPIO_Mode = GPIO_Mode_OUT;
gpioInit.GPIO_OType = GPIO_OType_PP;
gpioInit.GPIO_Pin = GPIO_Pin_12;
gpioInit.GPIO_PuPd = GPIO_PuPd_NOPULL;
gpioInit.GPIO_Speed = GPIO_Low_Speed;
GPIO_Init(GPIOH, &gpioInit);
GPIO_WriteBit(GPIOH, GPIO_Pin_12, Bit_RESET);
some=1000000;
while (some) some--;
GPIO_WriteBit(GPIOH, GPIO_Pin_12, Bit_SET);
/* Enable System configuration controller clock */
RCC->APB2ENR |= (1 << 14);
/* Reset Ethernet MAC */
RCC->AHB1RSTR |= 0x02000000;
SYSCFG->PMC |= (1 << 23);
RCC->AHB1RSTR &= ~0x02000000;
RCC->AHB1ENR |= 0x1E000047;
/* Configure Port A ethernet pins (PA.1, PA.2, PA.7) */
GPIOA->MODER &= ~0x0000C03C;
GPIOA->MODER |= 0x00008028; /* Pins to alternate function */
GPIOA->OTYPER &= ~0x00000086; /* Pins in push-pull mode */
GPIOA->OSPEEDR |= 0x0000C03C; /* Slew rate as 100MHz pin */
GPIOA->PUPDR &= ~0x0000C03C; /* No pull up, no pull down */
GPIOA->AFR[0] &= ~0xF0000FF0;
GPIOA->AFR[0] |= 0xB0000BB0; /* Pins to AF11 (Ethernet) */
/* Configure Port C ethernet pins (PC.1, PC.4, PC.5) */
GPIOC->MODER &= ~0x00000F0C;
GPIOC->MODER |= 0x00000A08; /* Pins to alternate function */
GPIOC->OTYPER &= ~0x00000032; /* Pins in push-pull mode */
GPIOC->OSPEEDR |= 0x00000F0C; /* Slew rate as 100MHz pin */
GPIOC->PUPDR &= ~0x00000F0C; /* No pull up, no pull down */
GPIOC->AFR[0] &= ~0x00FF00F0;
GPIOC->AFR[0] |= 0x00BB00B0; /* Pins to AF11 (Ethernet) */
/* Configure Port G ethernet pins (PB.12, PB.13) */
GPIOB->MODER &= ~0x0F000000;
GPIOB->MODER |= 0x0A000000; /* Pin to alternate function */
GPIOB->OTYPER &= ~0x00003000; /* Pin in push-pull mode */
GPIOB->OSPEEDR |= 0x0F000000; /* Slew rate as 100MHz pin */
GPIOB->PUPDR &= ~0x0F000000; /* No pull up, no pull down */
GPIOB->AFR[1] &= ~0x00FF0000;
GPIOB->AFR[1] |= 0x00BB0000; /* Pin to AF11 (Ethernet) */
/* Configure Port B ethernet pins (PB.11) */
GPIOB->MODER &= ~0x00C00000;
GPIOB->MODER |= 0x00800000; /* Pins to alternate function */
GPIOB->OTYPER &= ~0x00000800; /* Pins in push-pull mode */
GPIOB->OSPEEDR |= 0x00C00000; /* Slew rate as 100MHz pin */
GPIOB->PUPDR &= ~0x0FF00000; /* No pull up, no pull down */
GPIOB->AFR[1] &= ~0x0000F000;
GPIOB->AFR[1] |= 0x0000B000; /* Pins to AF11 (Ethernet) */
}
/**********************************************************************************
* global
**********************************************************************************/
/**
* @brief init ehternet controller
*
* @return
/
BaseType_t xNetworkInterfaceInitialise( void )
{
ETH_InitTypeDef ETH_InitStructure;
/ init randov function */
if( xEMACTaskHandle == NULL )
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
RCC->AHB1RSTR |= 0x02000000;
SYSCFG_ETH_MediaInterfaceConfig(SYSCFG_ETH_MediaInterface_RMII);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_ETH_MAC | RCC_AHB1Periph_ETH_MAC_Tx | RCC_AHB1Periph_ETH_MAC_Rx | RCC_AHB1Periph_ETH_MAC_PTP, ENABLE);
initEthGpios();
ETH_SoftwareReset();
while (ETH_GetSoftwareResetStatus() == SET);
ETH_StructInit(Ð_InitStructure);
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;
ETH_InitStructure.ETH_ChecksumOffload = ETH_ChecksumOffload_Enable;
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, PHYAddress);
//Eth_Link_PHYITConfig(0x01);
uint8_t macAdr[] = {0x1E, 0x30, 0x6C, 0xA2, 0x45, 0x5C};
ETH_MACAddressConfig(ETH_MAC_Address0, macAdr);
ETH_DMATxDescChainInit(DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB);
ETH_DMARxDescChainInit(DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB);
for(uint32_t i=0; i<ETH_TXBUFNB; i++)
{
ETH_DMATxDescChecksumInsertionConfig(&DMATxDscrTab[i], ETH_DMATxDesc_ChecksumTCPUDPICMPFull);
}
ETH_FlushTransmitFIFO();
ETH_DMATransmissionCmd(ENABLE);
ETH_DMAReceptionCmd(ENABLE);
ETH_MACTransmissionCmd(ENABLE);
ETH_MACReceptionCmd(ENABLE);
/* Reset all interrupts */
ETH->DMASR = 0xFFFFFFFF;
//ETH_DMA_IT_AIS | ETH_DMA_IT_RBU |
ETH_DMAITConfig(ETH_DMA_IT_NIS | ETH_DMA_IT_R, ENABLE);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = ETH_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0C;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0C;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
ETH_Start();
xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL,
configMAX_PRIORITIES - 1, &xEMACTaskHandle );
}
return pdPASS;
}
/**
* @brief output data processing
*
* @param pxDescriptor
* @param bReleaseAfterSend
*
* @return
*/
BaseType_t xNetworkInterfaceOutput( xNetworkBufferDescriptor_t * const pxDescriptor,
BaseType_t bReleaseAfterSend )
{
u32 ulTransmitSize = pxDescriptor->xDataLength;
if( ulTransmitSize > ETH_MAX_PACKET_SIZE )
{
ulTransmitSize = ETH_MAX_PACKET_SIZE;
}
/* Copy bytes to dma buffres */
memcpy( ( void * ) DMATxDscrTab->Buffer1Addr, pxDescriptor->pucEthernetBuffer,
ulTransmitSize );
/* Prepare transmit descriptors to give to DMA. */
ETH_Prepare_Transmit_Descriptors(ulTransmitSize);
iptraceNETWORK_INTERFACE_TRANSMIT();
if( bReleaseAfterSend != pdFALSE )
{
vReleaseNetworkBufferAndDescriptor( pxDescriptor );
}
return pdTRUE;
}
/**
* @brief Ethernet Irq
*/
void ETH_IRQHandler( void )
{
BaseType_t xHigherPriorityTaskWoken = 0;
if (ETH_GetDMAITStatus(ETH_DMA_IT_R) != RESET)
{
ETH_CheckFrameReceived();
ETH_DMAClearITPendingBit(ETH_DMA_IT_R);
vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
//portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
if (ETH_GetDMAITStatus(ETH_DMA_IT_NIS) != RESET)
{
ETH_DMAClearITPendingBit(ETH_DMA_IT_NIS);
}
if (ETH_GetDMAITStatus(ETH_DMA_IT_AIS) != RESET)
{
ETH_DMAClearITPendingBit(ETH_DMA_IT_AIS);
}
if (ETH_GetDMAITStatus(ETH_DMA_IT_RBU) != RESET)
{
ETH_DMAClearITPendingBit(ETH_DMA_IT_RBU);
}
}
define BUFFERSIZE ( ipTOTALETHERNETFRAMESIZE + ipBUFFER_PADDING )
define BUFFERSIZEROUNDEDUP ( ( BUFFERSIZE + 7 ) & ~0x07UL )
static uint8t ucBuffers[ ipconfigNUMNETWORKBUFFERDESCRIPTORS ][ BUFFERSIZEROUNDED_UP ]; /* Static allocation buffers for FreeRTOS+TCP */ void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] ) { BaseType_t x;for( x = 0; x < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; x++ )
{
pxNetworkBuffers[ x ].pucEthernetBuffer = &( ucBuffers[ x ][ ipBUFFER_PADDING ] );
*( ( uint32_t * ) &ucBuffers[ x ][ 0 ] ) = ( uint32_t ) &( pxNetworkBuffers[ x ] );
}
}
/**
* @brief ethernet driver handling task
*
* @param pvParameters
*/
static void prvEMACHandlerTask( void *pvParameters )
{
NetworkBufferDescriptor_t *pxBufferDescriptor;
size_t xBytesReceived;IPStackEvent_t xRxEvent; FrameTypeDef frame; __IO ETH_DMADESCTypeDef *DMARxNextDesc;
for( ;; )
{
ulTaskNotifyTake( pdFALSE, portMAX_DELAY );
while (ETH_CheckFrameReceived())
{
frame = ETH_Get_Received_Frame();
/* Release descriptors to DMA */
/* Check if frame with multiple DMA buffer segments */
if (DMA_RX_FRAME_infos->Seg_Count > 1)
{
DMARxNextDesc = DMA_RX_FRAME_infos->FS_Rx_Desc;
}
else
{
DMARxNextDesc = frame.descriptor;
}
/* Set Own bit in Rx descriptors: gives the buffers back to DMA */
for (u32 i=0; i<DMA_RX_FRAME_infos->Seg_Count; i++)
{
DMARxNextDesc->Status = ETH_DMARxDesc_OWN;
DMARxNextDesc = (ETH_DMADESCTypeDef *)(DMARxNextDesc->Buffer2NextDescAddr);
}
/* Clear Segment_Count */
DMA_RX_FRAME_infos->Seg_Count =0;
/* 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;
}
if ( frame.length > 0 )
{
pxBufferDescriptor = pxGetNetworkBufferWithDescriptor( xBytesReceived, 0 );
if( pxBufferDescriptor != NULL )
{
memcpy( pxBufferDescriptor->pucEthernetBuffer,
( uint8_t * ) frame.buffer, frame.length);
pxBufferDescriptor->xDataLength = frame.length;
if( eConsiderFrameForProcessing( pxBufferDescriptor->pucEthernetBuffer )
== eProcessBuffer )
{
/* The event about to be sent to the TCP/IP is an Rx event. */
xRxEvent.eEventType = eNetworkRxEvent;
/* pvData is used to point to the network buffer descriptor that
now references the received data. */
xRxEvent.pvData = ( void * ) pxBufferDescriptor;
/* Send the data to the TCP/IP stack. */
if( xSendEventStructToIPTask( &xRxEvent, 0 ) == pdFALSE )
{
/* The buffer could not be sent to the IP task so the buffer
must be released. */
vReleaseNetworkBufferAndDescriptor( pxBufferDescriptor );
/* Make a call to the standard trace macro to log the
occurrence. */
iptraceETHERNET_RX_EVENT_LOST();
}
else
{
/* The message was successfully sent to the TCP/IP stack.
Call the standard trace macro to log the occurrence. */
iptraceNETWORK_INTERFACE_RECEIVE();
}
}
else
{
/* The Ethernet frame can be dropped, but the Ethernet buffer
must be released. */
vReleaseNetworkBufferAndDescriptor( pxBufferDescriptor );
}
}
else
{
/* The event was lost because a network buffer was not available.
Call the standard trace macro to log the occurrence. */
iptraceETHERNET_RX_EVENT_LOST();
}
}
}
}
}
/**********************************************************************************
* eof
**********************************************************************************/
~~~
Creating freertos+tcp task
~~~ /** * @file tcpProcess.cpp * @brief tcp task and etc. * @author * @version * @date 2016-09-16 */include <stdio.h>
/* FreeRTOS includes. */include <FreeRTOS.h>
include “task.h”
include “timers.h”
include “queue.h”
include “semphr.h”
/* FreeRTOS+TCP includes. */include “FreeRTOS_IP.h”
include “FreeRTOS_Sockets.h”
include “FreeRTOS_DHCP.h”
include “stm32f4xx.h”
const uint8t ucIPAddress[ ipIPADDRESSLENGTHBYTES ] = {192, 168, 10, 50}; const uint8t ucNetMask[ ipIPADDRESSLENGTHBYTES ] = { 255, 255, 255, 0 }; const uint8t ucGatewayAddress[ ipIPADDRESSLENGTHBYTES ] = {192, 168, 10, 1}; const uint8t ucDNSServerAddress[ ipIPADDRESSLENGTHBYTES ] = { 208, 67, 222, 222 }; const uint8t ucMACAddress[ ipMACADDRESSLENGTHBYTES ] = { 0x1E, 0x30, 0x6C, 0xA2, 0x45, 0x5C }; /********************************************************************************** * static **********************************************************************************/ static void initRandomFunction (void) { /* Enable RNG clock source / RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE); / RNG Peripheral enable */ RNG_Cmd(ENABLE); } /********************************************************************************** * global **********************************************************************************/ /** * @brief random function * * @return */ UBaseType_t uxRand( void ) { const uint32_t ulMultiplier = 0x015a4e35UL, ulIncrement = 1UL; static BaseType_t xInitialised = pdFALSE; static UBaseType_t ulNextRand;/* Don't initialise until the scheduler is running, as the timeout in the
random number generator uses the tick count. */
if( xInitialised == pdFALSE )
{
uint32_t ulSeed;
/* Generate a random number with which to seed the local pseudo random
number generating function. */
while(RNG_GetFlagStatus(RNG_FLAG_DRDY)== RESET);
ulSeed = RNG_GetRandomNumber();
ulNextRand = ulSeed;
xInitialised = pdTRUE;
}
/* Utility function to generate a pseudo random number. */
ulNextRand = ( ulMultiplier * ulNextRand ) + ulIncrement;
return( ( int ) ( ulNextRand >> 16UL ) & 0x7fffUL );
}
/**
* @brief start FreeRTOS+TCP
*/
void initTcpProcess (void)
{
initRandomFunction();
FreeRTOS_IPInit( ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress );
}
void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent )
{
}
void vApplicationPingReplyHook( ePingReplyStatust eStatus, uint16t usIdentifier )
{
}
/**********************************************************************************
* eof
**********************************************************************************/
~~~