赞
踩
- #include "stm32f4xx.h"
-
- #include "FreeRTOS.h"
-
- #include "task.h"
-
- #include "queue.h"
-
-
-
- int main(void)
-
- {
-
- while(1);
-
- }
-
- //空闲状态回调函数
- void vApplicationIdleHook( void )
- {
-
- }
-
- //时间片轮转回调函数
- void vApplicationTickHook( void )
- {
-
- }
-
- //堆栈溢出回调函数
- void vApplicationStackOverflowHook( TaskHandle_t xTask, char *pcTaskName )
- {
-
- }
-
- //内存分配失败回调函数
- void vApplicationMallocFailedHook( void )
- {
-
- }
- #include "bsp_eth.h"
-
-
-
- void LAN8720_Init(void)
-
- {
-
- GPIO_InitTypeDef GPIO_Init;
-
-
-
- __HAL_RCC_SYSCFG_CLK_ENABLE();
-
- __HAL_RCC_GPIOA_CLK_ENABLE();
-
- __HAL_RCC_GPIOC_CLK_ENABLE();
-
- __HAL_RCC_GPIOD_CLK_ENABLE();
-
- __HAL_RCC_GPIOG_CLK_ENABLE();
-
- __HAL_RCC_ETH_CLK_ENABLE();
-
-
-
-
-
- /*RMII接口引脚
-
- ETH_MDIO -------------------------> PA2
-
- ETH_MDC --------------------------> PC1
-
- ETH_RMII_REF_CLK------------------> PA1
-
- ETH_RMII_CRS_DV ------------------> PA7
-
- ETH_RMII_RXD0 --------------------> PC4
-
- ETH_RMII_RXD1 --------------------> PC5
-
- ETH_RMII_TX_EN -------------------> PG11
-
- ETH_RMII_TXD0 --------------------> PG13
-
- ETH_RMII_TXD1 --------------------> PG14
-
- ETH_RESET-------------------------> PD3*/
-
-
-
- GPIO_Init.Mode=GPIO_MODE_AF_PP;
-
- GPIO_Init.Pin=GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7;
-
- GPIO_Init.Pull=GPIO_NOPULL;
-
- GPIO_Init.Speed=GPIO_SPEED_FREQ_VERY_HIGH;
-
- GPIO_Init.Alternate=GPIO_AF11_ETH;
-
- HAL_GPIO_Init(GPIOA,&GPIO_Init);
-
-
-
-
-
- GPIO_Init.Pin=GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5;
-
- HAL_GPIO_Init(GPIOC,&GPIO_Init);
-
-
-
- GPIO_Init.Pin=GPIO_PIN_11 | GPIO_PIN_14 | GPIO_PIN_13;
-
- HAL_GPIO_Init(GPIOG,&GPIO_Init);
-
-
-
- GPIO_Init.Mode=GPIO_MODE_OUTPUT_PP;
-
- GPIO_Init.Pin=GPIO_PIN_3;
-
- GPIO_Init.Pull=GPIO_NOPULL;
-
- GPIO_Init.Speed=GPIO_SPEED_FREQ_VERY_HIGH;
-
- HAL_GPIO_Init(GPIOD,&GPIO_Init);
-
-
-
- //复位
-
- HAL_GPIO_WritePin(GPIOD,GPIO_PIN_3,GPIO_PIN_RESET);
-
- vTaskDelay(100/portTICK_PERIOD_MS);
-
- HAL_GPIO_WritePin(GPIOD,GPIO_PIN_3,GPIO_PIN_SET);
-
- vTaskDelay(100/portTICK_PERIOD_MS);
-
-
-
- HAL_NVIC_SetPriority(ETH_IRQn,6,0);
-
- HAL_NVIC_EnableIRQ(ETH_IRQn);
-
- }
-
- TCP协议里需要用到随机数,这个随机数需要用户提供。随机数的创建参考下面代码。
- #include "randomnum.h"
-
-
-
-
-
- /* RNG handler declaration */
-
- RNG_HandleTypeDef RngHandle;
-
-
-
- static void Error_Handler()
-
- {
-
- while(1)
-
- {
-
- }
-
- }
-
-
-
- void RNG_init(void)
-
- {
-
- __HAL_RCC_RNG_CLK_ENABLE();
-
-
-
- /*## Configure the RNG peripheral #######################################*/
-
- RngHandle.Instance = RNG;
-
-
-
- /* DeInitialize the RNG peripheral */
-
- if (HAL_RNG_DeInit(&RngHandle) != HAL_OK)
-
- {
-
- /* DeInitialization Error */
-
- Error_Handler();
-
- }
-
-
-
- /* Initialize the RNG peripheral */
-
- if (HAL_RNG_Init(&RngHandle) != HAL_OK)
-
- {
-
- /* Initialization Error */
-
- Error_Handler();
-
- }
-
- }
-
-
-
- uint32_t Random_GetNumber(){
-
- uint32_t num;
-
- if (HAL_RNG_GenerateRandomNumber(&RngHandle, &num) != HAL_OK)
-
- {
-
- /* Random number generation error */
-
- Error_Handler();
-
- }
-
- return num;
-
- }
-
-
-
- void getRandomNumTo(uint32_t * num){
-
-
-
- if (HAL_RNG_GenerateRandomNumber(&RngHandle, num) != HAL_OK)
-
- {
-
- /* Random number generation error */
-
- Error_Handler();
-
- }
-
- }
-
-
-
- 配置文件FreeRTOSIPConfig.h,参考下面代码。
- #ifndef FREERTOS_IP_CONFIG_H
-
- #define FREERTOS_IP_CONFIG_H
-
-
-
- #ifdef __cplusplus
-
- extern "C" {
-
- #endif
-
-
-
-
-
- #include "stm32f4xx.h"
-
-
-
- #define ipconfigBYTE_ORDER pdFREERTOS_LITTLE_ENDIAN
-
-
-
-
-
- #define ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM ( 1 )
-
- #define ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM ( 1 )
-
-
-
-
-
- #define ipconfigSOCK_DEFAULT_RECEIVE_BLOCK_TIME ( 1000 )
-
- #define ipconfigSOCK_DEFAULT_SEND_BLOCK_TIME ( 1000 )
-
-
-
- #define ipconfigZERO_COPY_RX_DRIVER ( 0 )
-
- #define ipconfigZERO_COPY_TX_DRIVER ( 0 )
-
-
-
-
-
- #define ipconfigUSE_LLMNR ( 1 )
-
-
-
-
-
- #define ipconfigUSE_NBNS ( 0 )
-
-
-
-
-
- #define ipconfigUSE_DNS_CACHE ( 1 )
-
- #define ipconfigDNS_CACHE_NAME_LENGTH ( 16 )
-
- #define ipconfigDNS_CACHE_ENTRIES ( 4 )
-
- #define ipconfigDNS_REQUEST_ATTEMPTS ( 4 )
-
-
-
-
-
- #define ipconfigIP_TASK_PRIORITY ( configMAX_PRIORITIES - 2 )
-
-
-
-
-
- #define ipconfigIP_TASK_STACK_SIZE_WORDS ( configMINIMAL_STACK_SIZE * 5 )
-
-
-
-
-
- extern uint32_t Random_GetNumber(void);
-
- #define ipconfigRAND32() Random_GetNumber()
-
-
-
-
-
- #define ipconfigUSE_NETWORK_EVENT_HOOK 1
-
-
-
-
-
- #define ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS ( 5000 / portTICK_PERIOD_MS )
-
-
-
-
-
- #define ipconfigUSE_DHCP 1
-
- #define ipconfigDHCP_REGISTER_HOSTNAME 1
-
- #define ipconfigDHCP_USES_UNICAST 1
-
-
-
- #define ipconfigMAXIMUM_DISCOVER_TX_PERIOD ( pdMS_TO_TICKS( 30000 ) )
-
-
-
- #define ipconfigARP_CACHE_ENTRIES 6
-
-
-
- #define ipconfigMAX_ARP_RETRANSMISSIONS ( 5 )
-
-
-
- #define ipconfigMAX_ARP_AGE 150
-
-
-
- #define ipconfigINCLUDE_FULL_INET_ADDR 1
-
-
-
- #if( ipconfigZERO_COPY_RX_DRIVER != 0 )
-
- #define ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ( 25 + 6 )
-
- #else
-
- #define ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS 25
-
- #endif
-
-
-
- #define ipconfigEVENT_QUEUE_LENGTH ( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS + 5 )
-
-
-
- #define ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND 1
-
-
-
- #define ipconfigUDP_TIME_TO_LIVE 128
-
- #define ipconfigTCP_TIME_TO_LIVE 128 /* also defined in FreeRTOSIPConfigDefaults.h */
-
-
-
- #define ipconfigUSE_TCP ( 1 )
-
-
-
- #define ipconfigUSE_TCP_WIN ( 0 )
-
-
-
-
-
- #define ipconfigNETWORK_MTU 1500
-
-
-
- #define ipconfigUSE_DNS 1
-
-
-
- #define ipconfigREPLY_TO_INCOMING_PINGS 1
-
-
-
- #define ipconfigSUPPORT_OUTGOING_PINGS 1
-
-
-
- #define ipconfigSUPPORT_SELECT_FUNCTION 1
-
-
-
- #define ipconfigFILTER_OUT_NON_ETHERNET_II_FRAMES 1
-
-
-
- #define ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES 1
-
-
-
- #define configWINDOWS_MAC_INTERRUPT_SIMULATOR_DELAY ( 2 / portTICK_PERIOD_MS )
-
-
-
- #define ipconfigPACKET_FILLER_SIZE 2
-
-
-
- #define ipconfigTCP_WIN_SEG_COUNT 64
-
-
-
- #define ipconfigTCP_RX_BUFFER_LENGTH ( 3 * 1460 )
-
-
-
- #define ipconfigTCP_TX_BUFFER_LENGTH ( 2 * 1460 )
-
-
-
- #define ipconfigIS_VALID_PROG_ADDRESS(x) ( (x) != NULL )
-
-
-
- #define ipconfigTCP_HANG_PROTECTION ( 1 )
-
- #define ipconfigTCP_HANG_PROTECTION_TIME ( 30 )
-
-
-
- #define ipconfigTCP_KEEP_ALIVE ( 1 )
-
- #define ipconfigTCP_KEEP_ALIVE_INTERVAL ( 20 ) /* in seconds */
-
-
-
- #define ipconfigUSE_FTP 0
-
- #define ipconfigUSE_HTTP 0
-
-
-
- #define ipconfigFTP_TX_BUFSIZE ( 4 * ipconfigTCP_MSS )
-
- #define ipconfigFTP_TX_WINSIZE ( 2 )
-
- #define ipconfigFTP_RX_BUFSIZE ( 8 * ipconfigTCP_MSS )
-
- #define ipconfigFTP_RX_WINSIZE ( 4 )
-
- #define ipconfigHTTP_TX_BUFSIZE ( 3 * ipconfigTCP_MSS )
-
- #define ipconfigHTTP_TX_WINSIZE ( 2 )
-
- #define ipconfigHTTP_RX_BUFSIZE ( 4 * ipconfigTCP_MSS )
-
- #define ipconfigHTTP_RX_WINSIZE ( 4 )
-
-
-
- extern int lUDPLoggingPrintf( const char *pcFormatString, ... );
-
-
-
- #define ipconfigHAS_DEBUG_PRINTF 0
-
- #if( ipconfigHAS_DEBUG_PRINTF == 1 )
-
- #define FreeRTOS_debug_printf(X) lUDPLoggingPrintf X
-
- #endif
-
-
-
- #define ipconfigHAS_PRINTF 0
-
- #if( ipconfigHAS_PRINTF == 1 )
-
- #define FreeRTOS_printf(X) lUDPLoggingPrintf X
-
- #endif
-
-
-
- #define ipconfigDNS_USE_CALLBACKS 1
-
- #define ipconfigSUPPORT_SIGNALS 0
-
-
-
- #define TCP_SERVER 0
-
- #define TCP_CLIENT 1
-
-
-
- #if( TCP_CLIENT == 1 )
-
- #define CLIENT_PORT 0
-
- #endif
-
-
-
- #define configMAC_ADDR0 0x00
-
- #define configMAC_ADDR1 0x51
-
- #define configMAC_ADDR2 0x51
-
- #define configMAC_ADDR3 0x51
-
- #define configMAC_ADDR4 0x51
-
-
-
- #ifdef TCP_CLIENT
-
- #define configMAC_ADDR5 0x50
-
- #else
-
- #define configMAC_ADDR5 (0x50+ CLIENT_PORT)
-
- #endif
-
-
-
- #define configIP_ADDR0 192
-
- #define configIP_ADDR1 168
-
- #define configIP_ADDR2 31
-
- #define configIP_ADDR3 130
-
-
-
- #define configGATEWAY_ADDR0 0
-
- #define configGATEWAY_ADDR1 0
-
- #define configGATEWAY_ADDR2 0
-
- #define configGATEWAY_ADDR3 0
-
-
-
- #define configDNS_SERVER_ADDR0 0
-
- #define configDNS_SERVER_ADDR1 0
-
- #define configDNS_SERVER_ADDR2 0
-
- #define configDNS_SERVER_ADDR3 0
-
-
-
- #define configNET_MASK0 0
-
- #define configNET_MASK1 0
-
- #define configNET_MASK2 0
-
- #define configNET_MASK3 0
-
-
-
- #define configECHO_SERVER_ADDR0 192
-
- #define configECHO_SERVER_ADDR1 168
-
- #define configECHO_SERVER_ADDR2 31
-
- #define configECHO_SERVER_ADDR3 237
-
-
-
- #define configHTTP_ROOT "/websrc"
-
-
-
- #define configINCLUDE_DEMO_DEBUG_STATS 0
-
-
-
- #define configINCLUDE_QUERY_HEAP_COMMAND 0
-
-
-
- #define configUDP_LOGGING_NEEDS_CR_LF ( 0 )
-
-
-
- #define configUDP_LOGGING_STRING_LENGTH ( 200 )
-
-
-
- #define configUDP_LOGGING_MAX_MESSAGES_IN_BUFFER ( 20 )
-
-
-
- #define configUDP_LOGGING_TASK_STACK_SIZE ( 512 )
-
-
-
- #define configUDP_LOGGING_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
-
-
-
- #define configUDP_LOGGING_PORT_LOCAL 1499
-
- #define configUDP_LOGGING_PORT_REMOTE 1500
-
-
-
- #define configUDP_LOGGING_ADDR0 192
-
- #define configUDP_LOGGING_ADDR1 168
-
- #define configUDP_LOGGING_ADDR2 0
-
- #define configUDP_LOGGING_ADDR3 100
-
-
-
-
-
- #ifdef __cplusplus
-
- } /* extern "C" */
-
- #endif
-
-
-
- #endif
- #include "NetworkInterface.h"
-
-
-
- BaseType_t xSTM32_PhyRead( BaseType_t xAddress, BaseType_t xRegister, uint32_t *pulValue );
-
-
-
-
-
- #ifndef BMSR_LINK_STATUS
-
- #define BMSR_LINK_STATUS 0x0004UL
-
- #endif
-
-
-
- #ifndef PHY_LS_HIGH_CHECK_TIME_MS
-
- #define PHY_LS_HIGH_CHECK_TIME_MS 15000
-
- #endif
-
-
-
- #ifndef PHY_LS_LOW_CHECK_TIME_MS
-
- #define PHY_LS_LOW_CHECK_TIME_MS 1000
-
- #endif
-
-
-
-
-
- #define EMAC_IF_RX_EVENT 1UL
-
- #define EMAC_IF_TX_EVENT 2UL
-
- #define EMAC_IF_ERR_EVENT 4UL
-
- #define EMAC_IF_ALL_EVENT ( EMAC_IF_RX_EVENT | EMAC_IF_TX_EVENT | EMAC_IF_ERR_EVENT )
-
-
-
- #define ETH_DMA_ALL_INTS \
- ( ETH_DMA_IT_TST | ETH_DMA_IT_PMT | ETH_DMA_IT_MMC | ETH_DMA_IT_NIS | ETH_DMA_IT_ER | \
-
- ETH_DMA_IT_FBE | ETH_DMA_IT_RWT | ETH_DMA_IT_RPS | ETH_DMA_IT_RBU | ETH_DMA_IT_R | \
-
- ETH_DMA_IT_TU | ETH_DMA_IT_RO | ETH_DMA_IT_TJT | ETH_DMA_IT_TPS | ETH_DMA_IT_T )
-
-
-
-
-
-
-
- #define ipFRAGMENT_OFFSET_BIT_MASK ( ( uint16_t ) 0x0fff ) /* The bits in the two byte IP header field that make up the fragment offset value. */
-
-
-
- #if !defined( ipconfigETHERNET_AN_ENABLE )
-
-
-
- #define ipconfigETHERNET_AN_ENABLE 1
-
- #endif
-
-
-
- #if !defined( ipconfigETHERNET_AUTO_CROSS_ENABLE )
-
- #define ipconfigETHERNET_AUTO_CROSS_ENABLE 1
-
- #endif
-
-
-
- #if( ipconfigETHERNET_AN_ENABLE == 0 )
-
- #if !defined( ipconfigETHERNET_CROSSED_LINK )
-
- #define ipconfigETHERNET_CROSSED_LINK 1
-
- #endif
-
-
-
- #if !defined( ipconfigETHERNET_USE_100MB )
-
- #define ipconfigETHERNET_USE_100MB 1
-
- #endif
-
-
-
- #if !defined( ipconfigETHERNET_USE_FULL_DUPLEX )
-
- #define ipconfigETHERNET_USE_FULL_DUPLEX 1
-
- #endif
-
- #endif /* ipconfigETHERNET_AN_ENABLE == 0 */
-
-
-
- #ifndef configEMAC_TASK_STACK_SIZE
-
- #define configEMAC_TASK_STACK_SIZE ( 2 * configMINIMAL_STACK_SIZE )
-
- #endif
-
-
-
- static void prvEMACHandlerTask( void *pvParameters );
-
- static void prvEthernetUpdateConfig( BaseType_t xForce );
-
- static BaseType_t prvNetworkInterfaceInput( void );
-
- static BaseType_t xMayAcceptPacket( uint8_t *pcBuffer );
-
- static void prvDMATxDescListInit( void );
-
- static void prvDMARxDescListInit( void );
-
- static void vClearTXBuffers( void );
-
-
-
- #if( ipconfigUSE_LLMNR != 0 )
-
- static void prvMACAddressConfig(ETH_HandleTypeDef *heth, uint32_t ulIndex, uint8_t *Addr);
-
- #endif
-
-
-
- volatile uint32_t ulISREvents;
-
- static EthernetPhy_t xPhyObject;
-
- static ETH_HandleTypeDef xETH;
-
- static SemaphoreHandle_t xTXDescriptorSemaphore = NULL;
-
-
-
- #if( ipconfigUSE_LLMNR == 1 )
-
- static const uint8_t xLLMNR_MACAddress[] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0xFC };
-
- #endif
-
-
-
- __attribute__ ((aligned (32)))
-
- __attribute__ ((section(".first_data")))
-
- ETH_DMADescTypeDef DMARxDscrTab[ ETH_RXBUFNB ];
-
-
-
- #if( ipconfigZERO_COPY_RX_DRIVER == 0 )
-
- __ALIGN_BEGIN uint8_t Rx_Buff[ ETH_RXBUFNB ][ ETH_RX_BUF_SIZE ] __ALIGN_END;
-
- #endif
-
-
-
- __attribute__ ((aligned (32)))
-
- __attribute__ ((section(".first_data")))
-
- ETH_DMADescTypeDef DMATxDscrTab[ ETH_TXBUFNB ];
-
-
-
- #if( ipconfigZERO_COPY_TX_DRIVER == 0 )
-
- __ALIGN_BEGIN uint8_t Tx_Buff[ ETH_TXBUFNB ][ ETH_TX_BUF_SIZE ] __ALIGN_END;
-
- #endif
-
-
-
- static __IO ETH_DMADescTypeDef *DMATxDescToClear;
-
- extern const uint8_t ucMACAddress[ 6 ];
-
- static TaskHandle_t xEMACTaskHandle = NULL;
-
- static uint32_t ulPHYLinkStatus = 0;
-
- const PhyProperties_t xPHYProperties =
-
- {
-
- #if( ipconfigETHERNET_AN_ENABLE != 0 )
-
- .ucSpeed = PHY_SPEED_AUTO,
-
- .ucDuplex = PHY_DUPLEX_AUTO,
-
- #else
-
- #if( ipconfigETHERNET_USE_100MB != 0 )
-
- .ucSpeed = PHY_SPEED_100,
-
- #else
-
- .ucSpeed = PHY_SPEED_10,
-
- #endif
-
-
-
- #if( ipconfigETHERNET_USE_FULL_DUPLEX != 0 )
-
- .duplex = PHY_DUPLEX_FULL,
-
- #else
-
- .duplex = PHY_DUPLEX_HALF,
-
- #endif
-
- #endif
-
-
-
- #if( ipconfigETHERNET_AN_ENABLE != 0 ) && ( ipconfigETHERNET_AUTO_CROSS_ENABLE != 0 )
-
- .ucMDI_X = PHY_MDIX_AUTO,
-
- #elif( ipconfigETHERNET_CROSSED_LINK != 0 )
-
- .ucMDI_X = PHY_MDIX_CROSSED,
-
- #else
-
- .ucMDI_X = PHY_MDIX_DIRECT,
-
- #endif
-
- };
-
-
-
- /*-----------------------------------------------------------*/
-
-
-
- void HAL_ETH_RxCpltCallback( ETH_HandleTypeDef *heth )
-
- {
-
- BaseType_t xHigherPriorityTaskWoken = pdFALSE;
-
- ulISREvents |= EMAC_IF_RX_EVENT;
-
- if( xEMACTaskHandle != NULL )
-
- {
-
- vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
-
- portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
-
- }
-
- }
-
- /*-----------------------------------------------------------*/
-
-
-
- void HAL_ETH_TxCpltCallback( ETH_HandleTypeDef *heth )
-
- {
-
- BaseType_t xHigherPriorityTaskWoken = pdFALSE;
-
-
-
- ulISREvents |= EMAC_IF_TX_EVENT;
-
- if( xEMACTaskHandle != NULL )
-
- {
-
- vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
-
- portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
-
- }
-
-
-
- }
-
- /*-----------------------------------------------------------*/
-
-
-
- static void vClearTXBuffers()
-
- {
-
- __IO ETH_DMADescTypeDef *txLastDescriptor = xETH.TxDesc;
-
- size_t uxCount = ( ( UBaseType_t ) ETH_TXBUFNB ) - uxSemaphoreGetCount( xTXDescriptorSemaphore );
-
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
-
- NetworkBufferDescriptor_t *pxNetworkBuffer;
-
- uint8_t *ucPayLoad;
-
- #endif
-
-
-
- while( ( uxCount > 0 ) && ( ( DMATxDescToClear->Status & ETH_DMATXDESC_OWN ) == 0 ) )
-
- {
-
- if( ( DMATxDescToClear == txLastDescriptor ) && ( uxCount != ETH_TXBUFNB ) )
-
- {
-
- break;
-
- }
-
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
-
- {
-
- ucPayLoad = ( uint8_t * )DMATxDescToClear->Buffer1Addr;
-
-
-
- if( ucPayLoad != NULL )
-
- {
-
- pxNetworkBuffer = pxPacketBuffer_to_NetworkBuffer( ucPayLoad );
-
- if( pxNetworkBuffer != NULL )
-
- {
-
- vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer ) ;
-
- }
-
- DMATxDescToClear->Buffer1Addr = ( uint32_t )0u;
-
- }
-
- }
-
- #endif /* ipconfigZERO_COPY_TX_DRIVER */
-
-
-
- DMATxDescToClear = ( ETH_DMADescTypeDef * )( DMATxDescToClear->Buffer2NextDescAddr );
-
-
-
- uxCount--;
-
- /* Tell the counting semaphore that one more TX descriptor is available. */
-
- xSemaphoreGive( xTXDescriptorSemaphore );
-
- }
-
- }
-
- /*-----------------------------------------------------------*/
-
-
-
- BaseType_t xNetworkInterfaceInitialise( void )
-
- {
-
- HAL_StatusTypeDef hal_eth_init_status;
-
- //BaseType_t xResult;
-
-
-
- if( xEMACTaskHandle == NULL )
-
- {
-
- if( xTXDescriptorSemaphore == NULL )
-
- {
-
- xTXDescriptorSemaphore = xSemaphoreCreateCounting( ( UBaseType_t ) ETH_TXBUFNB, ( UBaseType_t ) ETH_TXBUFNB );
-
- configASSERT( xTXDescriptorSemaphore );
-
- }
-
-
-
- /* Initialise ETH */
-
- LAN8720_Init();
-
-
-
- xETH.Instance = ETH;
-
- xETH.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;
-
- xETH.Init.Speed = ETH_SPEED_100M;
-
- xETH.Init.DuplexMode = ETH_MODE_FULLDUPLEX;
-
- /* Value of PhyAddress doesn't matter, will be probed for. */
-
- xETH.Init.PhyAddress = 0;
-
-
-
- xETH.Init.MACAddr = ( uint8_t *) ucMACAddress;
-
- xETH.Init.RxMode = ETH_RXINTERRUPT_MODE;
-
-
-
- xETH.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;
-
-
-
- xETH.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;
-
-
-
-
-
- hal_eth_init_status = HAL_ETH_Init( &xETH );
-
-
-
- /* Only for inspection by debugger. */
-
- ( void ) hal_eth_init_status;
-
-
-
- /* Set the TxDesc and RxDesc pointers. */
-
- xETH.TxDesc = DMATxDscrTab;
-
- xETH.RxDesc = DMARxDscrTab;
-
-
-
- /* Make sure that all unused fields are cleared. */
-
- memset( &DMATxDscrTab, '\0', sizeof( DMATxDscrTab ) );
-
- memset( &DMARxDscrTab, '\0', sizeof( DMARxDscrTab ) );
-
-
-
- /* Initialize Tx Descriptors list: Chain Mode */
-
- DMATxDescToClear = DMATxDscrTab;
-
-
-
- /* Initialise TX-descriptors. */
-
- prvDMATxDescListInit();
-
-
-
- /* Initialise RX-descriptors. */
-
- prvDMARxDescListInit();
-
-
-
- #if( ipconfigUSE_LLMNR != 0 )
-
- {
-
- prvMACAddressConfig( &xETH, ETH_MAC_ADDRESS1, ( uint8_t *) xLLMNR_MACAddress );
-
- }
-
- #endif
-
-
-
- prvEthernetUpdateConfig( pdTRUE );
-
-
-
- xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xEMACTaskHandle );
-
- } /* if( xEMACTaskHandle == NULL ) */
-
-
-
- //检查PHY连接状态
-
- xSTM32_PhyRead( 0x00,0x01, &ulPHYLinkStatus);
-
- xPhyObject.ulLinkStatusMask = ulPHYLinkStatus;
-
- return ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0;
-
-
-
- }
-
- /*-----------------------------------------------------------*/
-
-
-
- static void prvDMATxDescListInit()
-
- {
-
- ETH_DMADescTypeDef *pxDMADescriptor;
-
- BaseType_t xIndex;
-
-
-
- /* Get the pointer on the first member of the descriptor list */
-
- pxDMADescriptor = DMATxDscrTab;
-
-
-
- /* Fill each DMA descriptor with the right values */
-
- for( xIndex = 0; xIndex < ETH_TXBUFNB; xIndex++, pxDMADescriptor++ )
-
- {
-
- /* Set Second Address Chained bit */
-
- pxDMADescriptor->Status = ETH_DMATXDESC_TCH;
-
-
-
- #if( ipconfigZERO_COPY_TX_DRIVER == 0 )
-
- {
-
- /* Set Buffer1 address pointer */
-
- pxDMADescriptor->Buffer1Addr = ( uint32_t )( Tx_Buff[ xIndex ] );
-
- }
-
- #endif
-
-
-
- if( xETH.Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE )
-
- {
-
- /* Set the DMA Tx descriptors checksum insertion for TCP, UDP, and ICMP */
-
- pxDMADescriptor->Status |= ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL;
-
- }
-
-
-
- /* Initialize the next descriptor with the Next Descriptor Polling Enable */
-
- if( xIndex < ETH_TXBUFNB - 1 )
-
- {
-
- /* Set next descriptor address register with next descriptor base address */
-
- pxDMADescriptor->Buffer2NextDescAddr = ( uint32_t ) ( pxDMADescriptor + 1 );
-
- }
-
- else
-
- {
-
- /* For last descriptor, set next descriptor address register equal to the first descriptor base address */
-
- pxDMADescriptor->Buffer2NextDescAddr = ( uint32_t ) DMATxDscrTab;
-
- }
-
- }
-
-
-
- /* Set Transmit Descriptor List Address Register */
-
- xETH.Instance->DMATDLAR = ( uint32_t ) DMATxDscrTab;
-
- }
-
- /*-----------------------------------------------------------*/
-
-
-
- static void prvDMARxDescListInit()
-
- {
-
- ETH_DMADescTypeDef *pxDMADescriptor;
-
- BaseType_t xIndex;
-
- /*
- * RX-descriptors.
- */
-
-
-
- /* Get the pointer on the first member of the descriptor list */
-
- pxDMADescriptor = DMARxDscrTab;
-
-
-
- /* Fill each DMA descriptor with the right values */
-
- for( xIndex = 0; xIndex < ETH_RXBUFNB; xIndex++, pxDMADescriptor++ )
-
- {
-
-
-
- /* Set Buffer1 size and Second Address Chained bit */
-
- pxDMADescriptor->ControlBufferSize = ETH_DMARXDESC_RCH | (uint32_t)ETH_RX_BUF_SIZE;
-
-
-
- #if( ipconfigZERO_COPY_RX_DRIVER != 0 )
-
- {
-
- /* Set Buffer1 address pointer */
-
- NetworkBufferDescriptor_t *pxBuffer;
-
-
-
- pxBuffer = pxGetNetworkBufferWithDescriptor( ETH_RX_BUF_SIZE, 100ul );
-
- /* If the assert below fails, make sure that there are at least 'ETH_RXBUFNB'
- Network Buffers available during start-up ( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ) */
-
- configASSERT( pxBuffer != NULL );
-
- if( pxBuffer != NULL )
-
- {
-
- pxDMADescriptor->Buffer1Addr = (uint32_t)pxBuffer->pucEthernetBuffer;
-
- pxDMADescriptor->Status = ETH_DMARXDESC_OWN;
-
- }
-
- }
-
- #else
-
- {
-
- /* Set Buffer1 address pointer */
-
- pxDMADescriptor->Buffer1Addr = ( uint32_t )( Rx_Buff[ xIndex ] );
-
- /* Set Own bit of the Rx descriptor Status */
-
- pxDMADescriptor->Status = ETH_DMARXDESC_OWN;
-
- }
-
- #endif
-
-
-
- /* Initialize the next descriptor with the Next Descriptor Polling Enable */
-
- if( xIndex < ETH_RXBUFNB - 1 )
-
- {
-
- /* Set next descriptor address register with next descriptor base address */
-
- pxDMADescriptor->Buffer2NextDescAddr = ( uint32_t )( pxDMADescriptor + 1 );
-
- }
-
- else
-
- {
-
- /* For last descriptor, set next descriptor address register equal to the first descriptor base address */
-
- pxDMADescriptor->Buffer2NextDescAddr = ( uint32_t ) DMARxDscrTab;
-
- }
-
-
-
- }
-
- /* Set Receive Descriptor List Address Register */
-
- xETH.Instance->DMARDLAR = ( uint32_t ) DMARxDscrTab;
-
- }
-
- /*-----------------------------------------------------------*/
-
-
-
- static void prvMACAddressConfig(ETH_HandleTypeDef *heth, uint32_t ulIndex, uint8_t *Addr)
-
- {
-
- uint32_t ulTempReg;
-
-
-
- /* Calculate the selected MAC address high register. */
-
- ulTempReg = 0x80000000ul | ( ( uint32_t ) Addr[ 5 ] << 8 ) | ( uint32_t ) Addr[ 4 ];
-
-
-
- /* Load the selected MAC address high register. */
-
- ( *(__IO uint32_t *)( ( uint32_t ) ( ETH_MAC_ADDR_HBASE + ulIndex ) ) ) = ulTempReg;
-
-
-
- /* Calculate the selected MAC address low register. */
-
- ulTempReg = ( ( uint32_t ) Addr[ 3 ] << 24 ) | ( ( uint32_t ) Addr[ 2 ] << 16 ) | ( ( uint32_t ) Addr[ 1 ] << 8 ) | Addr[ 0 ];
-
-
-
- /* Load the selected MAC address low register */
-
- ( *(__IO uint32_t *) ( ( uint32_t ) ( ETH_MAC_ADDR_LBASE + ulIndex ) ) ) = ulTempReg;
-
- }
-
- /*-----------------------------------------------------------*/
-
-
-
- BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor, BaseType_t bReleaseAfterSend )
-
- {
-
- BaseType_t xReturn = pdFAIL;
-
- uint32_t ulTransmitSize = 0;
-
- __IO ETH_DMADescTypeDef *pxDmaTxDesc;
-
- /* Do not wait too long for a free TX DMA buffer. */
-
- const TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 50u );
-
-
-
- #if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM != 0 )
-
- {
-
- ProtocolPacket_t *pxPacket;
-
-
-
- #if( ipconfigZERO_COPY_RX_DRIVER != 0 )
-
- {
-
- configASSERT( bReleaseAfterSend != 0 );
-
- }
-
- #endif /* ipconfigZERO_COPY_RX_DRIVER */
-
-
-
- /* If the peripheral must calculate the checksum, it wants
- the protocol checksum to have a value of zero. */
-
- pxPacket = ( ProtocolPacket_t * ) ( pxDescriptor->pucEthernetBuffer );
-
-
-
- if( pxPacket->xICMPPacket.xIPHeader.ucProtocol == ipPROTOCOL_ICMP )
-
- {
-
- pxPacket->xICMPPacket.xICMPHeader.usChecksum = ( uint16_t )0u;
-
- }
-
- }
-
- #endif
-
-
-
- /* Open a do {} while ( 0 ) loop to be able to call break. */
-
- do
-
- {
-
- if( xPhyObject.ulLinkStatusMask != 0 )
-
- {
-
- if( xSemaphoreTake( xTXDescriptorSemaphore, xBlockTimeTicks ) != pdPASS )
-
- {
-
- /* Time-out waiting for a free TX descriptor. */
-
- break;
-
- }
-
-
-
- /* This function does the actual transmission of the packet. The packet is
- contained in 'pxDescriptor' that is passed to the function. */
-
- pxDmaTxDesc = xETH.TxDesc;
-
-
-
- /* Is this buffer available? */
-
- configASSERT ( ( pxDmaTxDesc->Status & ETH_DMATXDESC_OWN ) == 0 );
-
-
-
- {
-
- /* Is this buffer available? */
-
- /* Get bytes in current buffer. */
-
- ulTransmitSize = pxDescriptor->xDataLength;
-
-
-
- if( ulTransmitSize > ETH_TX_BUF_SIZE )
-
- {
-
- ulTransmitSize = ETH_TX_BUF_SIZE;
-
- }
-
-
-
- #if( ipconfigZERO_COPY_TX_DRIVER == 0 )
-
- {
-
- /* Copy the bytes. */
-
- memcpy( ( void * ) pxDmaTxDesc->Buffer1Addr, pxDescriptor->pucEthernetBuffer, ulTransmitSize );
-
- }
-
- #else
-
- {
-
- /* Move the buffer. */
-
- pxDmaTxDesc->Buffer1Addr = ( uint32_t )pxDescriptor->pucEthernetBuffer;
-
- /* The Network Buffer has been passed to DMA, no need to release it. */
-
- bReleaseAfterSend = pdFALSE_UNSIGNED;
-
- }
-
- #endif /* ipconfigZERO_COPY_TX_DRIVER */
-
-
-
- /* Ask to set the IPv4 checksum.
- Also need an Interrupt on Completion so that 'vClearTXBuffers()' will be called.. */
-
- pxDmaTxDesc->Status |= ETH_DMATXDESC_CIC_TCPUDPICMP_FULL | ETH_DMATXDESC_IC;
-
-
-
- /* Prepare transmit descriptors to give to DMA. */
-
-
-
- /* Set LAST and FIRST segment */
-
- pxDmaTxDesc->Status |= ETH_DMATXDESC_FS | ETH_DMATXDESC_LS;
-
- /* Set frame size */
-
- pxDmaTxDesc->ControlBufferSize = ( ulTransmitSize & ETH_DMATXDESC_TBS1 );
-
- /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
-
- pxDmaTxDesc->Status |= ETH_DMATXDESC_OWN;
-
-
-
- /* Point to next descriptor */
-
- xETH.TxDesc = ( ETH_DMADescTypeDef * ) ( xETH.TxDesc->Buffer2NextDescAddr );
-
- /* Ensure completion of memory access */
-
- __DSB();
-
- /* Resume DMA transmission*/
-
- xETH.Instance->DMATPDR = 0;
-
- iptraceNETWORK_INTERFACE_TRANSMIT();
-
- xReturn = pdPASS;
-
- }
-
- }
-
- else
-
- {
-
- /* The PHY has no Link Status, packet shall be dropped. */
-
- }
-
- }
-
- while( 0 );
-
- /* The buffer has been sent so can be released. */
-
- if( bReleaseAfterSend != pdFALSE )
-
- {
-
- vReleaseNetworkBufferAndDescriptor( pxDescriptor );
-
- }
-
-
-
- return xReturn;
-
- }
-
- /*-----------------------------------------------------------*/
-
-
-
- static BaseType_t xMayAcceptPacket( uint8_t *pcBuffer )
-
- {
-
- const ProtocolPacket_t *pxProtPacket = ( const ProtocolPacket_t * )pcBuffer;
-
-
-
- switch( pxProtPacket->xTCPPacket.xEthernetHeader.usFrameType )
-
- {
-
- case ipARP_FRAME_TYPE:
-
- /* Check it later. */
-
- return pdTRUE;
-
- case ipIPv4_FRAME_TYPE:
-
- /* Check it here. */
-
- break;
-
- default:
-
- /* Refuse the packet. */
-
- return pdFALSE;
-
- }
-
-
-
- #if( ipconfigETHERNET_DRIVER_FILTERS_PACKETS == 1 )
-
- {
-
- const IPHeader_t *pxIPHeader = &(pxProtPacket->xTCPPacket.xIPHeader);
-
- uint32_t ulDestinationIPAddress;
-
-
-
- /* Ensure that the incoming packet is not fragmented (only outgoing packets
- * can be fragmented) as these are the only handled IP frames currently. */
-
- if( ( pxIPHeader->usFragmentOffset & FreeRTOS_ntohs( ipFRAGMENT_OFFSET_BIT_MASK ) ) != 0U )
-
- {
-
- return pdFALSE;
-
- }
-
- /* HT: Might want to make the following configurable because
- * most IP messages have a standard length of 20 bytes */
-
-
-
- /* 0x45 means: IPv4 with an IP header of 5 x 4 = 20 bytes
- * 0x47 means: IPv4 with an IP header of 7 x 4 = 28 bytes */
-
- if( pxIPHeader->ucVersionHeaderLength < 0x45 || pxIPHeader->ucVersionHeaderLength > 0x4F )
-
- {
-
- return pdFALSE;
-
- }
-
-
-
- ulDestinationIPAddress = pxIPHeader->ulDestinationIPAddress;
-
- /* Is the packet for this node? */
-
- if( ( ulDestinationIPAddress != *ipLOCAL_IP_ADDRESS_POINTER ) &&
-
- /* Is it a broadcast address x.x.x.255 ? */
-
- ( ( FreeRTOS_ntohl( ulDestinationIPAddress ) & 0xff ) != 0xff ) &&
-
- #if( ipconfigUSE_LLMNR == 1 )
-
- ( ulDestinationIPAddress != ipLLMNR_IP_ADDR ) &&
-
- #endif
-
- ( *ipLOCAL_IP_ADDRESS_POINTER != 0 ) ) {
-
- FreeRTOS_printf( ( "Drop IP %lxip\n", FreeRTOS_ntohl( ulDestinationIPAddress ) ) );
-
- return pdFALSE;
-
- }
-
-
-
- if( pxIPHeader->ucProtocol == ipPROTOCOL_UDP )
-
- {
-
- uint16_t port = pxProtPacket->xUDPPacket.xUDPHeader.usDestinationPort;
-
-
-
- if( ( xPortHasUDPSocket( port ) == pdFALSE )
-
- #if ipconfigUSE_LLMNR == 1
-
- && ( port != FreeRTOS_ntohs( ipLLMNR_PORT ) )
-
- #endif
-
- #if ipconfigUSE_NBNS == 1
-
- && ( port != FreeRTOS_ntohs( ipNBNS_PORT ) )
-
- #endif
-
- #if ipconfigUSE_DNS == 1
-
- && ( pxProtPacket->xUDPPacket.xUDPHeader.usSourcePort != FreeRTOS_ntohs( ipDNS_PORT ) )
-
- #endif
-
- ) {
-
- /* Drop this packet, not for this device. */
-
- return pdFALSE;
-
- }
-
- }
-
- }
-
- #endif /* ipconfigETHERNET_DRIVER_FILTERS_PACKETS */
-
- return pdTRUE;
-
- }
-
- /*-----------------------------------------------------------*/
-
-
-
- static BaseType_t prvNetworkInterfaceInput( void )
-
- {
-
- NetworkBufferDescriptor_t *pxCurDescriptor;
-
- NetworkBufferDescriptor_t *pxNewDescriptor = NULL;
-
- BaseType_t xReceivedLength, xAccepted;
-
- __IO ETH_DMADescTypeDef *pxDMARxDescriptor;
-
- xIPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
-
- const TickType_t xDescriptorWaitTime = pdMS_TO_TICKS( 250 );
-
- uint8_t *pucBuffer;
-
-
-
- pxDMARxDescriptor = xETH.RxDesc;
-
-
-
- if( ( pxDMARxDescriptor->Status & ETH_DMARXDESC_OWN) == 0 )
-
- {
-
- /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */
-
- xReceivedLength = ( ( pxDMARxDescriptor->Status & ETH_DMARXDESC_FL ) >> ETH_DMARXDESC_FRAMELENGTHSHIFT ) - 4;
-
-
-
- pucBuffer = (uint8_t *) pxDMARxDescriptor->Buffer1Addr;
-
-
-
- /* Update the ETHERNET DMA global Rx descriptor with next Rx descriptor */
-
- /* Chained Mode */
-
- /* Selects the next DMA Rx descriptor list for next buffer to read */
-
- xETH.RxDesc = ( ETH_DMADescTypeDef* )pxDMARxDescriptor->Buffer2NextDescAddr;
-
- }
-
- else
-
- {
-
- xReceivedLength = 0;
-
- }
-
-
-
- /* Obtain the size of the packet and put it into the "usReceivedLength" variable. */
-
-
-
- /* get received frame */
-
- if( xReceivedLength > 0ul )
-
- {
-
- /* In order to make the code easier and faster, only packets in a single buffer
- will be accepted. This can be done by making the buffers large enough to
- hold a complete Ethernet packet (1536 bytes).
- Therefore, two sanity checks: */
-
- configASSERT( xReceivedLength <= ETH_RX_BUF_SIZE );
-
-
-
- if( ( pxDMARxDescriptor->Status & ( ETH_DMARXDESC_CE | ETH_DMARXDESC_IPV4HCE | ETH_DMARXDESC_FT ) ) != ETH_DMARXDESC_FT )
-
- {
-
- /* Not an Ethernet frame-type or a checmsum error. */
-
- xAccepted = pdFALSE;
-
- }
-
- else
-
- {
-
- /* See if this packet must be handled. */
-
- xAccepted = xMayAcceptPacket( pucBuffer );
-
- }
-
-
-
- if( xAccepted != pdFALSE )
-
- {
-
- /* The packet wil be accepted, but check first if a new Network Buffer can
- be obtained. If not, the packet will still be dropped. */
-
- pxNewDescriptor = pxGetNetworkBufferWithDescriptor( ETH_RX_BUF_SIZE, xDescriptorWaitTime );
-
-
-
- if( pxNewDescriptor == NULL )
-
- {
-
- /* A new descriptor can not be allocated now. This packet will be dropped. */
-
- xAccepted = pdFALSE;
-
- }
-
- }
-
- #if( ipconfigZERO_COPY_RX_DRIVER != 0 )
-
- {
-
- /* Find out which Network Buffer was originally passed to the descriptor. */
-
- pxCurDescriptor = pxPacketBuffer_to_NetworkBuffer( pucBuffer );
-
- configASSERT( pxCurDescriptor != NULL );
-
- }
-
- #else
-
- {
-
- /* In this mode, the two descriptors are the same. */
-
- pxCurDescriptor = pxNewDescriptor;
-
- if( pxNewDescriptor != NULL )
-
- {
-
- /* The packet is acepted and a new Network Buffer was created,
- copy data to the Network Bufffer. */
-
- memcpy( pxNewDescriptor->pucEthernetBuffer, pucBuffer, xReceivedLength );
-
- }
-
- }
-
- #endif
-
-
-
- if( xAccepted != pdFALSE )
-
- {
-
- pxCurDescriptor->xDataLength = xReceivedLength;
-
- xRxEvent.pvData = ( void * ) pxCurDescriptor;
-
-
-
- /* Pass the data to the TCP/IP task for processing. */
-
- if( xSendEventStructToIPTask( &xRxEvent, xDescriptorWaitTime ) == pdFALSE )
-
- {
-
- /* Could not send the descriptor into the TCP/IP stack, it
- must be released. */
-
- vReleaseNetworkBufferAndDescriptor( pxCurDescriptor );
-
- iptraceETHERNET_RX_EVENT_LOST();
-
- }
-
- else
-
- {
-
- iptraceNETWORK_INTERFACE_RECEIVE();
-
- }
-
- }
-
-
-
- /* Release descriptors to DMA */
-
- #if( ipconfigZERO_COPY_RX_DRIVER != 0 )
-
- {
-
- /* Set Buffer1 address pointer */
-
- if( pxNewDescriptor != NULL )
-
- {
-
- pxDMARxDescriptor->Buffer1Addr = (uint32_t)pxNewDescriptor->pucEthernetBuffer;
-
- }
-
- else
-
- {
-
- /* The packet was dropped and the same Network
- Buffer will be used to receive a new packet. */
-
- }
-
- }
-
- #endif /* ipconfigZERO_COPY_RX_DRIVER */
-
-
-
- /* Set Buffer1 size and Second Address Chained bit */
-
- pxDMARxDescriptor->ControlBufferSize = ETH_DMARXDESC_RCH | (uint32_t)ETH_RX_BUF_SIZE;
-
- pxDMARxDescriptor->Status = ETH_DMARXDESC_OWN;
-
-
-
- /* Ensure completion of memory access */
-
- __DSB();
-
- /* When Rx Buffer unavailable flag is set clear it and resume
- reception. */
-
- if( ( xETH.Instance->DMASR & ETH_DMASR_RBUS ) != 0 )
-
- {
-
- /* Clear RBUS ETHERNET DMA flag. */
-
- xETH.Instance->DMASR = ETH_DMASR_RBUS;
-
-
-
- /* Resume DMA reception. */
-
- xETH.Instance->DMARPDR = 0;
-
- }
-
- }
-
-
-
- return ( xReceivedLength > 0 );
-
- }
-
- /*-----------------------------------------------------------*/
-
-
-
-
-
- BaseType_t xSTM32_PhyRead( BaseType_t xAddress, BaseType_t xRegister, uint32_t *pulValue )
-
- {
-
- uint16_t usPrevAddress = xETH.Init.PhyAddress;
-
- BaseType_t xResult;
-
- HAL_StatusTypeDef xHALResult;
-
-
-
- xETH.Init.PhyAddress = xAddress;
-
- xHALResult = HAL_ETH_ReadPHYRegister( &xETH, ( uint16_t )xRegister, pulValue );
-
- xETH.Init.PhyAddress = usPrevAddress;
-
-
-
- if( xHALResult == HAL_OK )
-
- {
-
- xResult = 0;
-
- }
-
- else
-
- {
-
- xResult = -1;
-
- }
-
- return xResult;
-
- }
-
- /*-----------------------------------------------------------*/
-
-
-
- BaseType_t xSTM32_PhyWrite( BaseType_t xAddress, BaseType_t xRegister, uint32_t ulValue )
-
- {
-
- uint16_t usPrevAddress = xETH.Init.PhyAddress;
-
- BaseType_t xResult;
-
- HAL_StatusTypeDef xHALResult;
-
-
-
- xETH.Init.PhyAddress = xAddress;
-
- xHALResult = HAL_ETH_WritePHYRegister( &xETH, ( uint16_t )xRegister, ulValue );
-
- xETH.Init.PhyAddress = usPrevAddress;
-
-
-
- if( xHALResult == HAL_OK )
-
- {
-
- xResult = 0;
-
- }
-
- else
-
- {
-
- xResult = -1;
-
- }
-
- return xResult;
-
- }
-
- /*-----------------------------------------------------------*/
-
-
-
- void phy_test()
-
- {
-
- BaseType_t xPhyCount;
-
- BaseType_t xPhyIndex;
-
-
-
- vPhyInitialise( &xPhyObject, xSTM32_PhyRead, xSTM32_PhyWrite );
-
- xPhyCount = xPhyDiscover( &xPhyObject );
-
- FreeRTOS_printf( ( "PHY count %ld\n", xPhyCount ) );
-
- for( xPhyIndex = 0; xPhyIndex < xPhyCount; xPhyIndex++ )
-
- {
-
- FreeRTOS_printf( ( "PHY[%d] at address %d ( 0x%08X )\n",
-
- xPhyIndex,
-
- xPhyObject.ucPhyIndexes[ xPhyIndex ],
-
- xPhyObject.ulPhyIDs[ xPhyIndex ] ) );
-
-
-
- }
-
-
-
- }
-
-
-
- void vMACBProbePhy( void )
-
- {
-
- vPhyInitialise( &xPhyObject, xSTM32_PhyRead, xSTM32_PhyWrite );
-
- xPhyDiscover( &xPhyObject );
-
- xPhyConfigure( &xPhyObject, &xPHYProperties );
-
- }
-
- /*-----------------------------------------------------------*/
-
-
-
- static void prvEthernetUpdateConfig( BaseType_t xForce )
-
- {
-
- FreeRTOS_printf( ( "prvEthernetUpdateConfig: LS mask %02lX Force %d\n",
-
- xPhyObject.ulLinkStatusMask,
-
- ( int )xForce ) );
-
-
-
- if( ( xForce != pdFALSE ) || ( xPhyObject.ulLinkStatusMask != 0 ) )
-
- {
-
- /* Restart the auto-negotiation. */
-
- if( xETH.Init.AutoNegotiation != ETH_AUTONEGOTIATION_DISABLE )
-
- {
-
- xPhyStartAutoNegotiation( &xPhyObject, xPhyGetMask( &xPhyObject ) );
-
-
-
- /* Configure the MAC with the Duplex Mode fixed by the
- auto-negotiation process. */
-
- if( xPhyObject.xPhyProperties.ucDuplex == PHY_DUPLEX_FULL )
-
- {
-
- xETH.Init.DuplexMode = ETH_MODE_FULLDUPLEX;
-
- }
-
- else
-
- {
-
- xETH.Init.DuplexMode = ETH_MODE_HALFDUPLEX;
-
- }
-
-
-
- /* Configure the MAC with the speed fixed by the
- auto-negotiation process. */
-
- if( xPhyObject.xPhyProperties.ucSpeed == PHY_SPEED_10 )
-
- {
-
- xETH.Init.Speed = ETH_SPEED_10M;
-
- }
-
- else
-
- {
-
- xETH.Init.Speed = ETH_SPEED_100M;
-
- }
-
- }
-
- else /* AutoNegotiation Disable */
-
- {
-
- /* Check parameters */
-
- assert_param( IS_ETH_SPEED( xETH.Init.Speed ) );
-
- assert_param( IS_ETH_DUPLEX_MODE( xETH.Init.DuplexMode ) );
-
-
-
- if( xETH.Init.DuplexMode == ETH_MODE_FULLDUPLEX )
-
- {
-
- xPhyObject.xPhyPreferences.ucDuplex = PHY_DUPLEX_HALF;
-
- }
-
- else
-
- {
-
- xPhyObject.xPhyPreferences.ucDuplex = PHY_DUPLEX_FULL;
-
- }
-
-
-
- if( xETH.Init.Speed == ETH_SPEED_10M )
-
- {
-
- xPhyObject.xPhyPreferences.ucSpeed = PHY_SPEED_10;
-
- }
-
- else
-
- {
-
- xPhyObject.xPhyPreferences.ucSpeed = PHY_SPEED_100;
-
- }
-
-
-
- xPhyObject.xPhyPreferences.ucMDI_X = PHY_MDIX_AUTO;
-
-
-
- /* Use predefined (fixed) configuration. */
-
- xPhyFixedValue( &xPhyObject, xPhyGetMask( &xPhyObject ) );
-
- }
-
-
-
- /* ETHERNET MAC Re-Configuration */
-
- HAL_ETH_ConfigMAC( &xETH, (ETH_MACInitTypeDef *) NULL);
-
-
-
- /* Restart MAC interface */
-
- HAL_ETH_Start( &xETH);
-
- }
-
- else
-
- {
-
- /* Stop MAC interface */
-
- HAL_ETH_Stop( &xETH );
-
- }
-
- }
-
- /*-----------------------------------------------------------*/
-
-
-
- BaseType_t xGetPhyLinkStatus( void )
-
- {
-
- BaseType_t xReturn;
-
-
-
- if( xPhyObject.ulLinkStatusMask != 0 )
-
- {
-
- xReturn = pdPASS;
-
- }
-
- else
-
- {
-
- xReturn = pdFAIL;
-
- }
-
-
-
- return xReturn;
-
- }
-
-
-
- static void prvEMACHandlerTask( void *pvParameters )
-
- {
-
- TimeOut_t xPhyTime;
-
- UBaseType_t uxLastMinBufferCount = 0;
-
- #if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
-
- UBaseType_t uxLastMinQueueSpace = 0;
-
- #endif
-
- TickType_t xPhyRemTime;
-
- UBaseType_t uxCurrentCount;
-
- BaseType_t xResult;
-
- uint32_t xStatus;
-
- const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
-
-
-
- /* Remove compiler warnings about unused parameters. */
-
- ( void ) pvParameters;
-
-
-
- for( ;; )
-
- {
-
- xResult = 0;
-
- uxCurrentCount = uxGetMinimumFreeNetworkBuffers();
-
- if( uxLastMinBufferCount != uxCurrentCount )
-
- {
-
- /* The logging produced below may be helpful
- while tuning +TCP: see how many buffers are in use. */
-
- uxLastMinBufferCount = uxCurrentCount;
-
- FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",uxGetNumberOfFreeNetworkBuffers(), uxCurrentCount ) );
-
- }
-
-
-
- if( xTXDescriptorSemaphore != NULL )
-
- {
-
- static UBaseType_t uxLowestSemCount = ( UBaseType_t ) ETH_TXBUFNB - 1;
-
-
-
- uxCurrentCount = uxSemaphoreGetCount( xTXDescriptorSemaphore );
-
- if( uxLowestSemCount > uxCurrentCount )
-
- {
-
- uxLowestSemCount = uxCurrentCount;
-
- FreeRTOS_printf( ( "TX DMA buffers: lowest %lu\n", uxLowestSemCount ) );
-
- }
-
-
-
- }
-
-
-
- #if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
-
- {
-
- uxCurrentCount = uxGetMinimumIPQueueSpace();
-
- if( uxLastMinQueueSpace != uxCurrentCount )
-
- {
-
- /* The logging produced below may be helpful
- while tuning +TCP: see how many buffers are in use. */
-
- uxLastMinQueueSpace = uxCurrentCount;
-
- FreeRTOS_printf( ( "Queue space: lowest %lu\n", uxCurrentCount ) );
-
- }
-
- }
-
- #endif /* ipconfigCHECK_IP_QUEUE_SPACE */
-
-
-
- if( ( ulISREvents & EMAC_IF_ALL_EVENT ) == 0 )
-
- {
-
- /* No events to process now, wait for the next. */
-
- ulTaskNotifyTake( pdFALSE, ulMaxBlockTime );
-
- }
-
-
-
- if( ( ulISREvents & EMAC_IF_RX_EVENT ) != 0 )
-
- {
-
- ulISREvents &= ~EMAC_IF_RX_EVENT;
-
-
-
- xResult = prvNetworkInterfaceInput();
-
- if( xResult > 0 )
-
- {
-
- while( prvNetworkInterfaceInput() > 0 )
-
- {
-
- }
-
- }
-
- }
-
-
-
- if( ( ulISREvents & EMAC_IF_TX_EVENT ) != 0 )
-
- {
-
- /* Code to release TX buffers if zero-copy is used. */
-
- ulISREvents &= ~EMAC_IF_TX_EVENT;
-
- /* Check if DMA packets have been delivered. */
-
- vClearTXBuffers();
-
- }
-
-
-
- if( ( ulISREvents & EMAC_IF_ERR_EVENT ) != 0 )
-
- {
-
- /* Future extension: logging about errors that occurred. */
-
- ulISREvents &= ~EMAC_IF_ERR_EVENT;
-
- }
-
-
-
- if( xResult > 0 )
-
- {
-
- /* A packet was received. No need to check for the PHY status now,
- but set a timer to check it later on. */
-
- vTaskSetTimeOutState( &xPhyTime );
-
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
-
- xResult = 0;
-
- }
-
- else if( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE )
-
- {
-
- HAL_ETH_ReadPHYRegister( &xETH, 0x01,&xStatus );
-
- xPhyObject.ulLinkStatusMask = xStatus;
-
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != ( xStatus & BMSR_LINK_STATUS ) )
-
- {
-
- ulPHYLinkStatus = xStatus;
-
- FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ) );
-
- prvEthernetUpdateConfig( pdFALSE );
-
- }
-
-
-
- vTaskSetTimeOutState( &xPhyTime );
-
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
-
- {
-
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
-
- }
-
- else
-
- {
-
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
-
- }
-
- }
-
- }
-
- }
-
- /*-----------------------------------------------------------*/
-
-
-
- void ETH_IRQHandler( void )
-
- {
-
- HAL_ETH_IRQHandler( &xETH );
-
- }
- #include "netInfoConfig.h"
-
-
-
- const uint8_t ucIPAddress[ 4 ] = { configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 };
-
- const uint8_t ucNetMask[ 4 ] = { configNET_MASK0, configNET_MASK1, configNET_MASK2, configNET_MASK3 };
-
- const uint8_t ucGatewayAddress[ 4 ] = { configGATEWAY_ADDR0, configGATEWAY_ADDR1, configGATEWAY_ADDR2, configGATEWAY_ADDR3 };
-
- const uint8_t ucDNSServerAddress[ 4 ] = { configDNS_SERVER_ADDR0, configDNS_SERVER_ADDR1, configDNS_SERVER_ADDR2, configDNS_SERVER_ADDR3 };
-
- const uint8_t ucMACAddress[ 6 ] = { configMAC_ADDR0, configMAC_ADDR1, configMAC_ADDR2, configMAC_ADDR3, configMAC_ADDR4, configMAC_ADDR5 };
-
-
-
-
-
- //this queue should be create for vApplicationPingReplyHook()
-
- QueueHandle_t xPingReplyQueue;
-
-
-
-
-
- /* --------------------------FUNCTION MODULE----------------------------- */
-
- //return a rand num
-
- UBaseType_t uxRand(){
-
- return (UBaseType_t) getRandomNum();
-
- }
-
-
-
- //Use this name to request IP during DHCP call
-
- const char *pcApplicationHostnameHook( void )
-
- {
-
- return mainHOST_NAME;
-
- }
-
-
-
- /*
-
- * The following function should be provided by the user and return true if it
-
- * matches the domain name.
-
- *this func will be used to judge whether *pcName matche DNS request or LLMNR request.
-
- return pdTRUE if matching DNS request,
-
- return pdFALSE if matching LLMNR request.
-
- */
-
- BaseType_t xApplicationDNSQueryHook( const char *pcName )
-
- {
-
- BaseType_t xReturn;
-
-
-
- if( strcmp( pcName, pcApplicationHostnameHook() ) == 0 )
-
- {
-
- xReturn = pdPASS;
-
- }
-
- else if( strcmp( pcName, mainDEVICE_NICK_NAME ) == 0 )
-
- {
-
- xReturn = pdPASS;
-
- }
-
- else
-
- {
-
- xReturn = pdFAIL;
-
- }
-
- return xReturn;
-
- }
-
-
-
- void vApplicationPingReplyHook( ePingReplyStatus_t eStatus, uint16_t usIdentifier )
-
- {
-
- switch( eStatus )
-
- {
-
- case eSuccess:
-
- xQueueSend( xPingReplyQueue, &usIdentifier, 10 / portTICK_PERIOD_MS );
-
- break;
-
- case eInvalidChecksum :
-
- break;
-
- case eInvalidData :
-
- break;
-
- }
-
- }
-
-
-
- void xPingReplyQueueCreate(void)
-
- {
-
- xPingReplyQueue = xQueueCreate( 20, sizeof( uint16_t ) );
-
- }
-
-
-
- BaseType_t vSendPing( const char *pcIPAddress )
-
- {
-
- uint16_t usRequestSequenceNumber, usReplySequenceNumber;
-
- uint32_t ulIPAddress;
-
- ulIPAddress = FreeRTOS_inet_addr( pcIPAddress );
-
-
-
- if(xPingReplyQueue == NULL)
-
- xPingReplyQueueCreate();
-
- usRequestSequenceNumber = FreeRTOS_SendPingRequest( ulIPAddress, 8, 100 / portTICK_PERIOD_MS );
-
- if( usRequestSequenceNumber == pdFAIL )
-
- {
-
- }
-
- else
-
- {
-
- if( xQueueReceive( xPingReplyQueue, &usReplySequenceNumber, 200 / portTICK_PERIOD_MS ) == pdPASS )
-
- {
-
- if( usRequestSequenceNumber == usReplySequenceNumber )
-
- {
-
- }
-
- }
-
- }
-
- return ulIPAddress;
-
- }
-
-
-
- BaseType_t IP_init( void )
-
- {
-
- return FreeRTOS_IPInit( ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress );
-
- }
-
-
-
-
-
- /*---------------------------DEBUG ONLY-------------------------------------*/
-
-
-
- int lUDPLoggingPrintf( const char *fmt, ... )
-
- {
-
- return 0;
-
- }
-
-
-
- void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent )
-
- {
-
- uint32_t ulIPAddress, ulNetMask, ulGatewayAddress, ulDNSServerAddress;
-
- char cBuffer[ 16 ];
-
- static BaseType_t xTasksAlreadyCreated = pdFALSE;
-
-
-
- FreeRTOS_printf( ( "vApplicationIPNetworkEventHook: event %ld\n", eNetworkEvent ) );
-
- if( eNetworkEvent == eNetworkUp )
-
- {
-
- if( xTasksAlreadyCreated == pdFALSE )
-
- {
-
- #if( mainCREATE_UDP_LOGGING_TASK == 1 )
-
- {
-
- vUDPLoggingTaskCreate();
-
- }
-
- #endif
-
-
-
- #if( ( mainCREATE_FTP_SERVER == 1 ) || ( mainCREATE_HTTP_SERVER == 1 ) )
-
- {
-
- /* Let the server work task now it can now create the servers. */
-
- xTaskNotifyGive( xServerWorkTaskHandle );
-
- }
-
- #endif
-
-
-
- #if( TCP_CLIENT == 1 )
-
- {
-
- // vStartTCPEchoClientTasks_SingleTasks( mainECHO_CLIENT_TASK_STACK_SIZE, mainECHO_CLIENT_TASK_PRIORITY );
-
- }
-
- #endif
-
-
-
- #if( TCP_SERVER == 1 )
-
- {
-
- // vStartSimpleTCPServerTasks( mainECHO_SERVER_STACK_SIZE, mainECHO_SERVER_TASK_PRIORITY );
-
- }
-
- #endif
-
-
-
- #if( mainCREATE_UDP_CLI_TASKS == 1 )
-
- {
-
- vRegisterSampleCLICommands();
-
- vRegisterTCPCLICommands();
-
- vStartUDPCommandInterpreterTask( mainUDP_CLI_TASK_STACK_SIZE, mainUDP_CLI_PORT_NUMBER, mainUDP_CLI_TASK_PRIORITY );
-
- }
-
- #endif
-
- xTasksAlreadyCreated = pdTRUE;
-
- }
-
-
-
- /* Print out the network configuration, which may have come from a DHCP
-
- server. */
-
- FreeRTOS_GetAddressConfiguration( &ulIPAddress, &ulNetMask, &ulGatewayAddress, &ulDNSServerAddress );
-
- FreeRTOS_inet_ntoa( ulIPAddress, cBuffer );
-
- FreeRTOS_printf( ( "IP Address: %s\n", cBuffer ) );
-
-
-
- FreeRTOS_inet_ntoa( ulNetMask, cBuffer );
-
- FreeRTOS_printf( ( "Subnet Mask: %s\n", cBuffer ) );
-
-
-
- FreeRTOS_inet_ntoa( ulGatewayAddress, cBuffer );
-
- FreeRTOS_printf( ( "Gateway Address: %s\n", cBuffer ) );
-
-
-
- FreeRTOS_inet_ntoa( ulDNSServerAddress, cBuffer );
-
- FreeRTOS_printf( ( "DNS Server Address: %s\n", cBuffer ) );
-
- }
-
- }
-
-
-
- 在main.c文件中引用头文件netInfoConfig.h,在main函数中调用初始化函数。参考如下代码。
- #include "bsp_clock.h"
-
- #include "randomnum.h"
-
- #include "netInfoConfig.h"
-
-
-
-
-
- int main(void)
-
- {
-
- HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
-
-
-
- CLOCLK_Init();
-
-
-
- RNG_init();
-
- IP_init();
-
- vTaskStartScheduler();
-
- while(1);
-
- }
- void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth)
-
- {
-
- /* Frame received */
-
- if (__HAL_ETH_DMA_GET_FLAG(heth, ETH_DMA_FLAG_R))
-
- {
-
- /* Receive complete callback */
-
- HAL_ETH_RxCpltCallback(heth);
-
-
-
- /* Clear the Eth DMA Rx IT pending bits */
-
- __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_IT_R);
-
-
-
- /* Set HAL State to Ready */
-
- heth->State = HAL_ETH_STATE_READY;
-
-
-
- /* Process Unlocked */
-
- __HAL_UNLOCK(heth);
-
-
-
- }
-
- /* Frame transmitted */
-
- if (__HAL_ETH_DMA_GET_FLAG(heth, ETH_DMA_FLAG_T))
-
- {
-
- /* Transfer complete callback */
-
- HAL_ETH_TxCpltCallback(heth);
-
-
-
- /* Clear the Eth DMA Tx IT pending bits */
-
- __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_IT_T);
-
-
-
- /* Set HAL State to Ready */
-
- heth->State = HAL_ETH_STATE_READY;
-
-
-
- /* Process Unlocked */
-
- __HAL_UNLOCK(heth);
-
- }
-
-
-
- /* Clear the interrupt flags */
-
- __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_IT_NIS);
-
-
-
- /* ETH DMA Error */
-
- if(__HAL_ETH_DMA_GET_FLAG(heth, ETH_DMA_FLAG_AIS))
-
- {
-
- /* Ethernet Error callback */
-
- HAL_ETH_ErrorCallback(heth);
-
-
-
- /* Clear the interrupt flags */
-
- __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_FLAG_AIS);
-
-
-
- /* Set HAL State to Ready */
-
- heth->State = HAL_ETH_STATE_READY;
-
-
-
- /* Process Unlocked */
-
- __HAL_UNLOCK(heth);
-
- }
-
- }
- void SysTick_Handler()
-
- {
-
- HAL_IncTick();
-
- xPortSysTickHandler();
-
- }
本文为个人爱好所做,欢迎各位大佬指点,如有错误之处还请见谅。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。