当前位置:   article > 正文

stm32f407探索者+HAL库+FreeRTOS +FreeRTOS_TCP/IP 移植_探索者407tcp客户端

探索者407tcp客户端
  • 在stm32f4空工程文件夹下创建FreeRTOS文件夹用来存放FreeRTOS源码,将FreeRTOS文件源码中FreeRTOS\Source路径下的全部文件拷贝到新建的FreeRTOS文件夹中。
  • 打开stm32f4空工程,添加分组FreeRTOS/Source,用来存放FreeRTOS源码。添加分组FreeRTOS/Ports,用来存放端口和内存分配方案。将FreeRTOS路径下的文件timers.c、croutine.c、list.c、queue.c、event_groups.c、task.c添加到FreeRTOS/Source中。将FreeRTOS\portable\MemMang路径下的内存管理文件heap_4.c和FreeRTOS\portable\RVDS\ARM_CM4F路径下的接口文件port.c添加到FreeRTOS/Ports中。
  • 将路径FreeRTOS\ include和 FreeRTOS\portable\RVDS\ARM_CM4F添加到工程头文件路径中 。
  • 将FreeRTOS\Demo\CORTEX_M4F_STM32F407ZG-SKl路径下的配置文件FreeRTOSConfig.h复制到User文件夹下,并在工程中添加到User分组中。
  • 在main.c中添加FreeRTOS.h、task.h、queue.h三个头文件,编译。出现一个错误,提示SystemCoreClock没有定义,如下图。

  • 因为__ICCARM__是IAR编译工具链的相关宏定义,而这个工程使用的ARM编译工具链,所以将FreeRTOSConfig.h文件将宏定义__ICCARM__改为__CC_ARM,再次编译,发现出现四个错误。如下图。

  • 这四个错误是没有相关回调函数定义,vApplicationIdleHook()是空闲状态回调函数,vApplicationTickHook()是时间片轮转回调函数,vApplicationStackOverflowHook()是堆栈溢出回调函数,vApplicationMallocFailedHook()是内存分配失败回调函数。在main.c中定义这四个回调函数。
  1. #include "stm32f4xx.h"
  2. #include "FreeRTOS.h"
  3. #include "task.h"
  4. #include "queue.h"
  5. int main(void)
  6. {
  7. while(1);
  8. }
  9. //空闲状态回调函数
  10. void vApplicationIdleHook( void )
  11. {
  12. }
  13. //时间片轮转回调函数
  14. void vApplicationTickHook( void )
  15. {
  16. }
  17. //堆栈溢出回调函数
  18. void vApplicationStackOverflowHook( TaskHandle_t xTask, char *pcTaskName )
  19. {
  20. }
  21. //内存分配失败回调函数
  22. void vApplicationMallocFailedHook( void )
  23. {
  24. }

 

  • 再次编译发现没有错误了,移植完成。
  • 创建FreeRTOS-TCP文件夹用来存放TCP源码,将FreeRTOS-Plus文件源码中FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP路径下的全部文件拷贝到新建的FreeRTOS-TCP文件夹中。
  • 打开工程,添加分组FreeRTOS_TCP,用来存放TCP源码。添加分组FreeRTOS_TCP/Ports,用来存放端口和内存分配方案。将FreeRTOS_TCP路径下的C文件添加到FreeRTOS_TCP分组中。将FreeRTOS-TCP\portable\BufferManagement路径下的内存管理文件BufferAllocation_2.c、FreeRTOS-TCP\portable\NetworkInterface\STM32Fxx路径下的接口文件NetworkInterface.c和FreeRTOS-TCP\portable\NetworkInterface\Common路径下的物理层处理文件添加到FreeRTOS_TCP/Ports中。
  • 将路径FreeRTOS-TCP\include和 FreeRTOS-TCP\portable\NetworkInterface\include添加到工程头文件路径中 。
  • 将FreeRTOS-Plus\Demo\FreeRTOS_Plus_TCP_Minimal_Windows_Simulator路径下的配置文件FreeRTOSIPConfig.h复制到User文件夹下,并在工程中添加到User分组中。
  • 联网需要用到以太网物理层芯片,此案例采用LAN8720,用户需要编写LAN8720驱动函数。这里我们创建bsp_eth.c和bsp_eth.h两个文件,在文件里完成LAN8720驱动。将文件添加到工程中。参考下面代码。
  1. #include "bsp_eth.h"
  2. void LAN8720_Init(void)
  3. {
  4.   GPIO_InitTypeDef GPIO_Init;
  5.   __HAL_RCC_SYSCFG_CLK_ENABLE();
  6.   __HAL_RCC_GPIOA_CLK_ENABLE();
  7.   __HAL_RCC_GPIOC_CLK_ENABLE();
  8.   __HAL_RCC_GPIOD_CLK_ENABLE();
  9.   __HAL_RCC_GPIOG_CLK_ENABLE();
  10.   __HAL_RCC_ETH_CLK_ENABLE();
  11.  
  12.   /*RMII接口引脚
  13.   ETH_MDIO -------------------------> PA2
  14.   ETH_MDC --------------------------> PC1
  15.   ETH_RMII_REF_CLK------------------> PA1
  16.   ETH_RMII_CRS_DV ------------------> PA7
  17.   ETH_RMII_RXD0 --------------------> PC4
  18.   ETH_RMII_RXD1 --------------------> PC5
  19.   ETH_RMII_TX_EN -------------------> PG11
  20.   ETH_RMII_TXD0 --------------------> PG13
  21.   ETH_RMII_TXD1 --------------------> PG14
  22.   ETH_RESET-------------------------> PD3*/
  23.  
  24.   GPIO_Init.Mode=GPIO_MODE_AF_PP;
  25.   GPIO_Init.Pin=GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7;
  26.   GPIO_Init.Pull=GPIO_NOPULL;
  27.   GPIO_Init.Speed=GPIO_SPEED_FREQ_VERY_HIGH;
  28.   GPIO_Init.Alternate=GPIO_AF11_ETH;
  29.   HAL_GPIO_Init(GPIOA,&GPIO_Init);
  30.  
  31.  
  32.   GPIO_Init.Pin=GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5;
  33.   HAL_GPIO_Init(GPIOC,&GPIO_Init); 
  34.  
  35.   GPIO_Init.Pin=GPIO_PIN_11 | GPIO_PIN_14 | GPIO_PIN_13;
  36.   HAL_GPIO_Init(GPIOG,&GPIO_Init); 
  37.  
  38.   GPIO_Init.Mode=GPIO_MODE_OUTPUT_PP;
  39.   GPIO_Init.Pin=GPIO_PIN_3;
  40.   GPIO_Init.Pull=GPIO_NOPULL;
  41.   GPIO_Init.Speed=GPIO_SPEED_FREQ_VERY_HIGH;
  42.   HAL_GPIO_Init(GPIOD,&GPIO_Init);
  43.   //复位
  44.   HAL_GPIO_WritePin(GPIOD,GPIO_PIN_3,GPIO_PIN_RESET);  
  45.   vTaskDelay(100/portTICK_PERIOD_MS);
  46.   HAL_GPIO_WritePin(GPIOD,GPIO_PIN_3,GPIO_PIN_SET);
  47.   vTaskDelay(100/portTICK_PERIOD_MS);
  48.  
  49.   HAL_NVIC_SetPriority(ETH_IRQn,6,0);
  50.   HAL_NVIC_EnableIRQ(ETH_IRQn);
  51. }
  52. TCP协议里需要用到随机数,这个随机数需要用户提供。随机数的创建参考下面代码。
  53. #include "randomnum.h"
  54. /* RNG handler declaration */
  55. RNG_HandleTypeDef RngHandle;
  56. static void Error_Handler()
  57. {
  58.       while(1)
  59.       {
  60.       }
  61. }
  62. void RNG_init(void)
  63. {
  64.   __HAL_RCC_RNG_CLK_ENABLE();
  65.  
  66.   /*## Configure the RNG peripheral #######################################*/
  67.   RngHandle.Instance = RNG;
  68.  
  69.   /* DeInitialize the RNG peripheral */
  70.   if (HAL_RNG_DeInit(&RngHandle) != HAL_OK)
  71.   {
  72.     /* DeInitialization Error */
  73.     Error_Handler();
  74.   }   
  75.   /* Initialize the RNG peripheral */
  76.   if (HAL_RNG_Init(&RngHandle) != HAL_OK)
  77.   {
  78.     /* Initialization Error */
  79.     Error_Handler();
  80.   }
  81. }
  82. uint32_t Random_GetNumber(){
  83.   uint32_t num;
  84.   if (HAL_RNG_GenerateRandomNumber(&RngHandle, &num) != HAL_OK)
  85.       {
  86.         /* Random number generation error */
  87.         Error_Handler();     
  88.       }
  89.   return num;
  90. }
  91. void getRandomNumTo(uint32_t * num){
  92.   if (HAL_RNG_GenerateRandomNumber(&RngHandle, num) != HAL_OK)
  93.       {
  94.         /* Random number generation error */
  95.         Error_Handler();     
  96.       }
  97. }
  98. 配置文件FreeRTOSIPConfig.h,参考下面代码。
  99. #ifndef FREERTOS_IP_CONFIG_H
  100. #define FREERTOS_IP_CONFIG_H
  101. #ifdef __cplusplus
  102. extern "C" {
  103. #endif
  104.  
  105.  
  106. #include "stm32f4xx.h"
  107. #define ipconfigBYTE_ORDER pdFREERTOS_LITTLE_ENDIAN
  108. #define ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM      ( 1 )
  109. #define ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM      ( 1 )
  110. #define ipconfigSOCK_DEFAULT_RECEIVE_BLOCK_TIME ( 1000 )
  111. #define   ipconfigSOCK_DEFAULT_SEND_BLOCK_TIME  ( 1000 )
  112. #define ipconfigZERO_COPY_RX_DRIVER          ( 0 )
  113. #define ipconfigZERO_COPY_TX_DRIVER          ( 0 )
  114. #define ipconfigUSE_LLMNR                    ( 1 )
  115. #define ipconfigUSE_NBNS                 ( 0 )
  116. #define ipconfigUSE_DNS_CACHE                ( 1 )
  117. #define ipconfigDNS_CACHE_NAME_LENGTH       ( 16 )
  118. #define ipconfigDNS_CACHE_ENTRIES            ( 4 )
  119. #define ipconfigDNS_REQUEST_ATTEMPTS     ( 4 )
  120. #define ipconfigIP_TASK_PRIORITY         ( configMAX_PRIORITIES - 2 )
  121. #define ipconfigIP_TASK_STACK_SIZE_WORDS ( configMINIMAL_STACK_SIZE * 5 )
  122. extern uint32_t Random_GetNumber(void);
  123. #define ipconfigRAND32() Random_GetNumber()
  124. #define ipconfigUSE_NETWORK_EVENT_HOOK 1
  125. #define ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS ( 5000 / portTICK_PERIOD_MS )
  126. #define ipconfigUSE_DHCP                             1
  127. #define ipconfigDHCP_REGISTER_HOSTNAME  1
  128. #define ipconfigDHCP_USES_UNICAST       1
  129. #define ipconfigMAXIMUM_DISCOVER_TX_PERIOD      ( pdMS_TO_TICKS( 30000 ) )
  130. #define ipconfigARP_CACHE_ENTRIES        6
  131. #define ipconfigMAX_ARP_RETRANSMISSIONS ( 5 )
  132. #define ipconfigMAX_ARP_AGE          150
  133. #define ipconfigINCLUDE_FULL_INET_ADDR  1
  134. #if( ipconfigZERO_COPY_RX_DRIVER != 0 )
  135.   #define ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS        ( 25 + 6 )
  136. #else
  137.   #define ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS        25
  138. #endif
  139. #define ipconfigEVENT_QUEUE_LENGTH       ( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS + 5 )
  140. #define ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND 1
  141. #define ipconfigUDP_TIME_TO_LIVE     128
  142. #define ipconfigTCP_TIME_TO_LIVE     128 /* also defined in FreeRTOSIPConfigDefaults.h */
  143. #define ipconfigUSE_TCP              ( 1 )
  144. #define ipconfigUSE_TCP_WIN          ( 0 )
  145. #define ipconfigNETWORK_MTU                  1500
  146. #define ipconfigUSE_DNS                              1
  147. #define ipconfigREPLY_TO_INCOMING_PINGS             1
  148. #define ipconfigSUPPORT_OUTGOING_PINGS              1
  149. #define ipconfigSUPPORT_SELECT_FUNCTION             1
  150. #define ipconfigFILTER_OUT_NON_ETHERNET_II_FRAMES  1
  151. #define ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES 1
  152. #define configWINDOWS_MAC_INTERRUPT_SIMULATOR_DELAY ( 2 / portTICK_PERIOD_MS )
  153. #define ipconfigPACKET_FILLER_SIZE 2
  154. #define ipconfigTCP_WIN_SEG_COUNT 64
  155. #define ipconfigTCP_RX_BUFFER_LENGTH         ( 3 * 1460 )
  156. #define ipconfigTCP_TX_BUFFER_LENGTH         ( 2 * 1460 )
  157. #define ipconfigIS_VALID_PROG_ADDRESS(x) ( (x) != NULL )
  158. #define ipconfigTCP_HANG_PROTECTION              ( 1 )
  159. #define ipconfigTCP_HANG_PROTECTION_TIME    ( 30 )
  160. #define ipconfigTCP_KEEP_ALIVE               ( 1 )
  161. #define ipconfigTCP_KEEP_ALIVE_INTERVAL     ( 20 ) /* in seconds */
  162. #define ipconfigUSE_FTP                      0
  163. #define ipconfigUSE_HTTP                 0
  164. #define ipconfigFTP_TX_BUFSIZE               ( 4 * ipconfigTCP_MSS )
  165. #define ipconfigFTP_TX_WINSIZE               ( 2 )
  166. #define ipconfigFTP_RX_BUFSIZE               ( 8 * ipconfigTCP_MSS )
  167. #define ipconfigFTP_RX_WINSIZE               ( 4 )
  168. #define ipconfigHTTP_TX_BUFSIZE              ( 3 * ipconfigTCP_MSS )
  169. #define ipconfigHTTP_TX_WINSIZE              ( 2 )
  170. #define ipconfigHTTP_RX_BUFSIZE              ( 4 * ipconfigTCP_MSS )
  171. #define ipconfigHTTP_RX_WINSIZE              ( 4 )
  172. extern int lUDPLoggingPrintf( const char *pcFormatString, ... );
  173. #define ipconfigHAS_DEBUG_PRINTF 0
  174. #if( ipconfigHAS_DEBUG_PRINTF == 1 )
  175.   #define FreeRTOS_debug_printf(X)   lUDPLoggingPrintf X
  176. #endif
  177. #define ipconfigHAS_PRINTF           0
  178. #if( ipconfigHAS_PRINTF == 1 )
  179.   #define FreeRTOS_printf(X)         lUDPLoggingPrintf X
  180. #endif
  181. #define ipconfigDNS_USE_CALLBACKS            1
  182. #define ipconfigSUPPORT_SIGNALS              0
  183. #define   TCP_SERVER              0
  184. #define TCP_CLIENT           1
  185. #if(  TCP_CLIENT == 1 )
  186.   #define CLIENT_PORT 0
  187. #endif
  188. #define configMAC_ADDR0      0x00
  189. #define configMAC_ADDR1      0x51
  190. #define configMAC_ADDR2      0x51
  191. #define configMAC_ADDR3      0x51
  192. #define configMAC_ADDR4      0x51
  193. #ifdef TCP_CLIENT
  194.   #define configMAC_ADDR5        0x50
  195. #else
  196.   #define configMAC_ADDR5        (0x50+ CLIENT_PORT)
  197. #endif
  198. #define configIP_ADDR0       192
  199. #define configIP_ADDR1       168
  200. #define configIP_ADDR2       31
  201. #define configIP_ADDR3       130
  202. #define configGATEWAY_ADDR0  0
  203. #define configGATEWAY_ADDR1  0
  204. #define configGATEWAY_ADDR2  0
  205. #define configGATEWAY_ADDR3  0
  206. #define configDNS_SERVER_ADDR0   0
  207. #define configDNS_SERVER_ADDR1   0
  208. #define configDNS_SERVER_ADDR2   0
  209. #define configDNS_SERVER_ADDR3   0
  210. #define configNET_MASK0      0
  211. #define configNET_MASK1      0
  212. #define configNET_MASK2      0
  213. #define configNET_MASK3      0
  214. #define configECHO_SERVER_ADDR0  192
  215. #define configECHO_SERVER_ADDR1 168
  216. #define configECHO_SERVER_ADDR2 31
  217. #define configECHO_SERVER_ADDR3 237
  218. #define configHTTP_ROOT "/websrc"
  219. #define configINCLUDE_DEMO_DEBUG_STATS      0
  220. #define configINCLUDE_QUERY_HEAP_COMMAND 0
  221. #define configUDP_LOGGING_NEEDS_CR_LF  ( 0 )
  222. #define configUDP_LOGGING_STRING_LENGTH ( 200 )
  223. #define   configUDP_LOGGING_MAX_MESSAGES_IN_BUFFER  ( 20 )
  224. #define   configUDP_LOGGING_TASK_STACK_SIZE      ( 512 )
  225. #define configUDP_LOGGING_TASK_PRIORITY      ( tskIDLE_PRIORITY + 1 )
  226. #define configUDP_LOGGING_PORT_LOCAL 1499
  227. #define configUDP_LOGGING_PORT_REMOTE   1500
  228. #define configUDP_LOGGING_ADDR0  192
  229. #define configUDP_LOGGING_ADDR1  168
  230. #define configUDP_LOGGING_ADDR2  0
  231. #define configUDP_LOGGING_ADDR3  100
  232.  
  233. #ifdef __cplusplus
  234. } /* extern "C" */
  235. #endif
  236. #endif

 

  • 修改接口文件NetworkInterface.c。具体修改请参考如下代码。
  1. #include "NetworkInterface.h"
  2. BaseType_t xSTM32_PhyRead( BaseType_t xAddress, BaseType_t xRegister, uint32_t *pulValue );
  3. #ifndef   BMSR_LINK_STATUS
  4.   #define BMSR_LINK_STATUS            0x0004UL
  5. #endif
  6. #ifndef   PHY_LS_HIGH_CHECK_TIME_MS
  7.   #define PHY_LS_HIGH_CHECK_TIME_MS  15000
  8. #endif
  9. #ifndef   PHY_LS_LOW_CHECK_TIME_MS
  10.   #define PHY_LS_LOW_CHECK_TIME_MS   1000
  11. #endif
  12. #define EMAC_IF_RX_EVENT        1UL
  13. #define EMAC_IF_TX_EVENT        2UL
  14. #define EMAC_IF_ERR_EVENT       4UL
  15. #define EMAC_IF_ALL_EVENT       ( EMAC_IF_RX_EVENT | EMAC_IF_TX_EVENT | EMAC_IF_ERR_EVENT )
  16. #define ETH_DMA_ALL_INTS \
  17.   ( ETH_DMA_IT_TST | ETH_DMA_IT_PMT | ETH_DMA_IT_MMC | ETH_DMA_IT_NIS | ETH_DMA_IT_ER | \
  18.     ETH_DMA_IT_FBE | ETH_DMA_IT_RWT | ETH_DMA_IT_RPS | ETH_DMA_IT_RBU | ETH_DMA_IT_R | \
  19.     ETH_DMA_IT_TU | ETH_DMA_IT_RO | ETH_DMA_IT_TJT | ETH_DMA_IT_TPS | ETH_DMA_IT_T )
  20. #define ipFRAGMENT_OFFSET_BIT_MASK       ( ( uint16_t ) 0x0fff ) /* The bits in the two byte IP header field that make up the fragment offset value. */
  21. #if !defined( ipconfigETHERNET_AN_ENABLE )
  22.   #define ipconfigETHERNET_AN_ENABLE            1
  23. #endif
  24. #if !defined( ipconfigETHERNET_AUTO_CROSS_ENABLE )
  25.   #define ipconfigETHERNET_AUTO_CROSS_ENABLE    1
  26. #endif
  27. #if( ipconfigETHERNET_AN_ENABLE == 0 )
  28.   #if !defined( ipconfigETHERNET_CROSSED_LINK )
  29.       #define ipconfigETHERNET_CROSSED_LINK          1
  30.   #endif
  31.   #if !defined( ipconfigETHERNET_USE_100MB )
  32.       #define ipconfigETHERNET_USE_100MB            1
  33.   #endif
  34.   #if !defined( ipconfigETHERNET_USE_FULL_DUPLEX )
  35.       #define ipconfigETHERNET_USE_FULL_DUPLEX      1
  36.   #endif
  37. #endif /* ipconfigETHERNET_AN_ENABLE == 0 */
  38. #ifndef configEMAC_TASK_STACK_SIZE
  39.   #define configEMAC_TASK_STACK_SIZE ( 2 * configMINIMAL_STACK_SIZE )
  40. #endif
  41. static void prvEMACHandlerTask( void *pvParameters );
  42. static void prvEthernetUpdateConfig( BaseType_t xForce );
  43. static BaseType_t prvNetworkInterfaceInput( void );
  44. static BaseType_t xMayAcceptPacket( uint8_t *pcBuffer );
  45. static void prvDMATxDescListInit( void );
  46. static void prvDMARxDescListInit( void );
  47. static void vClearTXBuffers( void );
  48. #if( ipconfigUSE_LLMNR != 0 )
  49.   static void prvMACAddressConfig(ETH_HandleTypeDef *heth, uint32_t ulIndex, uint8_t *Addr);
  50. #endif
  51. volatile uint32_t ulISREvents;
  52. static EthernetPhy_t xPhyObject;
  53. static ETH_HandleTypeDef xETH;
  54. static SemaphoreHandle_t xTXDescriptorSemaphore = NULL;
  55. #if( ipconfigUSE_LLMNR == 1 )
  56.   static const uint8_t xLLMNR_MACAddress[] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0xFC };
  57. #endif
  58. __attribute__ ((aligned (32)))
  59. __attribute__ ((section(".first_data")))
  60.   ETH_DMADescTypeDef  DMARxDscrTab[ ETH_RXBUFNB ];
  61. #if( ipconfigZERO_COPY_RX_DRIVER == 0 )
  62.   __ALIGN_BEGIN uint8_t Rx_Buff[ ETH_RXBUFNB ][ ETH_RX_BUF_SIZE ] __ALIGN_END;
  63. #endif
  64. __attribute__ ((aligned (32)))
  65. __attribute__ ((section(".first_data")))
  66.   ETH_DMADescTypeDef  DMATxDscrTab[ ETH_TXBUFNB ];
  67. #if( ipconfigZERO_COPY_TX_DRIVER == 0 )
  68.   __ALIGN_BEGIN uint8_t Tx_Buff[ ETH_TXBUFNB ][ ETH_TX_BUF_SIZE ] __ALIGN_END;
  69. #endif
  70. static __IO ETH_DMADescTypeDef  *DMATxDescToClear;
  71. extern const uint8_t ucMACAddress[ 6 ];
  72. static TaskHandle_t xEMACTaskHandle = NULL;
  73. static uint32_t ulPHYLinkStatus = 0;
  74. const PhyProperties_t xPHYProperties =
  75. {
  76.   #if( ipconfigETHERNET_AN_ENABLE != 0 )
  77.       .ucSpeed = PHY_SPEED_AUTO,
  78.       .ucDuplex = PHY_DUPLEX_AUTO,
  79.   #else
  80.       #if( ipconfigETHERNET_USE_100MB != 0 )
  81.           .ucSpeed = PHY_SPEED_100,
  82.       #else
  83.           .ucSpeed = PHY_SPEED_10,
  84.       #endif
  85.       #if( ipconfigETHERNET_USE_FULL_DUPLEX != 0 )
  86.           .duplex = PHY_DUPLEX_FULL,
  87.       #else
  88.           .duplex = PHY_DUPLEX_HALF,
  89.       #endif
  90.   #endif
  91.   #if( ipconfigETHERNET_AN_ENABLE != 0 ) && ( ipconfigETHERNET_AUTO_CROSS_ENABLE != 0 )
  92.       .ucMDI_X = PHY_MDIX_AUTO,
  93.   #elif( ipconfigETHERNET_CROSSED_LINK != 0 )
  94.       .ucMDI_X = PHY_MDIX_CROSSED,
  95.   #else
  96.       .ucMDI_X = PHY_MDIX_DIRECT,
  97.   #endif
  98. };
  99. /*-----------------------------------------------------------*/
  100. void HAL_ETH_RxCpltCallback( ETH_HandleTypeDef *heth )
  101. {
  102. BaseType_t xHigherPriorityTaskWoken = pdFALSE;
  103.     ulISREvents |= EMAC_IF_RX_EVENT;
  104.   if( xEMACTaskHandle != NULL )
  105.   {
  106.       vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
  107.       portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
  108.   }
  109. }
  110. /*-----------------------------------------------------------*/
  111. void HAL_ETH_TxCpltCallback( ETH_HandleTypeDef *heth )
  112. {
  113.   BaseType_t xHigherPriorityTaskWoken = pdFALSE;
  114.  
  115.   ulISREvents |= EMAC_IF_TX_EVENT;
  116.   if( xEMACTaskHandle != NULL )
  117.   {
  118.       vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
  119.       portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
  120.   }
  121. }
  122. /*-----------------------------------------------------------*/
  123. static void vClearTXBuffers()
  124. {
  125. __IO ETH_DMADescTypeDef  *txLastDescriptor = xETH.TxDesc;
  126. size_t uxCount = ( ( UBaseType_t ) ETH_TXBUFNB ) - uxSemaphoreGetCount( xTXDescriptorSemaphore );
  127. #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
  128.   NetworkBufferDescriptor_t *pxNetworkBuffer;
  129.   uint8_t *ucPayLoad;
  130. #endif
  131.   while( ( uxCount > 0 ) && ( ( DMATxDescToClear->Status & ETH_DMATXDESC_OWN ) == 0 ) )
  132.   {
  133.       if( ( DMATxDescToClear == txLastDescriptor ) && ( uxCount != ETH_TXBUFNB ) )
  134.       {
  135.           break;
  136.       }
  137.       #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
  138.       {
  139.           ucPayLoad = ( uint8_t * )DMATxDescToClear->Buffer1Addr;
  140.           if( ucPayLoad != NULL )
  141.           {
  142.               pxNetworkBuffer = pxPacketBuffer_to_NetworkBuffer( ucPayLoad );
  143.               if( pxNetworkBuffer != NULL )
  144.               {
  145.                   vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer ) ;
  146.               }
  147.               DMATxDescToClear->Buffer1Addr = ( uint32_t )0u;
  148.           }
  149.       }
  150.       #endif /* ipconfigZERO_COPY_TX_DRIVER */
  151.       DMATxDescToClear = ( ETH_DMADescTypeDef * )( DMATxDescToClear->Buffer2NextDescAddr );
  152.       uxCount--;
  153.       /* Tell the counting semaphore that one more TX descriptor is available. */
  154.       xSemaphoreGive( xTXDescriptorSemaphore );
  155.   }
  156. }
  157. /*-----------------------------------------------------------*/
  158. BaseType_t xNetworkInterfaceInitialise( void )
  159. {
  160. HAL_StatusTypeDef hal_eth_init_status;
  161. //BaseType_t xResult;
  162.   if( xEMACTaskHandle == NULL )
  163.   {
  164.       if( xTXDescriptorSemaphore == NULL )
  165.       {
  166.           xTXDescriptorSemaphore = xSemaphoreCreateCounting( ( UBaseType_t ) ETH_TXBUFNB, ( UBaseType_t ) ETH_TXBUFNB );
  167.           configASSERT( xTXDescriptorSemaphore );
  168.       }
  169.       /* Initialise ETH */
  170.       LAN8720_Init();
  171.      
  172.       xETH.Instance = ETH;
  173.       xETH.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;
  174.       xETH.Init.Speed = ETH_SPEED_100M;
  175.       xETH.Init.DuplexMode = ETH_MODE_FULLDUPLEX;
  176.       /* Value of PhyAddress doesn't matter, will be probed for. */
  177.       xETH.Init.PhyAddress = 0;
  178.       xETH.Init.MACAddr = ( uint8_t *) ucMACAddress;
  179.       xETH.Init.RxMode = ETH_RXINTERRUPT_MODE;
  180.       xETH.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;
  181.       xETH.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;
  182.       hal_eth_init_status = HAL_ETH_Init( &xETH );
  183.       /* Only for inspection by debugger. */
  184.       ( void ) hal_eth_init_status;
  185.       /* Set the TxDesc and RxDesc pointers. */
  186.       xETH.TxDesc = DMATxDscrTab;
  187.       xETH.RxDesc = DMARxDscrTab;
  188.       /* Make sure that all unused fields are cleared. */
  189.       memset( &DMATxDscrTab, '\0', sizeof( DMATxDscrTab ) );
  190.       memset( &DMARxDscrTab, '\0', sizeof( DMARxDscrTab ) );
  191.       /* Initialize Tx Descriptors list: Chain Mode */
  192.       DMATxDescToClear = DMATxDscrTab;
  193.       /* Initialise TX-descriptors. */
  194.       prvDMATxDescListInit();
  195.       /* Initialise RX-descriptors. */
  196.       prvDMARxDescListInit();
  197.       #if( ipconfigUSE_LLMNR != 0 )
  198.       {
  199.           prvMACAddressConfig( &xETH, ETH_MAC_ADDRESS1, ( uint8_t *) xLLMNR_MACAddress );
  200.       }
  201.       #endif
  202.       prvEthernetUpdateConfig( pdTRUE );
  203.       xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xEMACTaskHandle );
  204.   } /* if( xEMACTaskHandle == NULL ) */
  205.   //检查PHY连接状态
  206.   xSTM32_PhyRead( 0x00,0x01, &ulPHYLinkStatus);
  207.   xPhyObject.ulLinkStatusMask = ulPHYLinkStatus;
  208.   return ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0;
  209.  
  210. }
  211. /*-----------------------------------------------------------*/
  212. static void prvDMATxDescListInit()
  213. {
  214. ETH_DMADescTypeDef *pxDMADescriptor;
  215. BaseType_t xIndex;
  216.   /* Get the pointer on the first member of the descriptor list */
  217.   pxDMADescriptor = DMATxDscrTab;
  218.   /* Fill each DMA descriptor with the right values */
  219.   for( xIndex = 0; xIndex < ETH_TXBUFNB; xIndex++, pxDMADescriptor++ )
  220.   {
  221.       /* Set Second Address Chained bit */
  222.       pxDMADescriptor->Status = ETH_DMATXDESC_TCH;
  223.       #if( ipconfigZERO_COPY_TX_DRIVER == 0 )
  224.       {
  225.           /* Set Buffer1 address pointer */
  226.           pxDMADescriptor->Buffer1Addr = ( uint32_t )( Tx_Buff[ xIndex ] );
  227.       }
  228.       #endif
  229.       if( xETH.Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE )
  230.       {
  231.           /* Set the DMA Tx descriptors checksum insertion for TCP, UDP, and ICMP */
  232.           pxDMADescriptor->Status |= ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL;
  233.       }
  234.       /* Initialize the next descriptor with the Next Descriptor Polling Enable */
  235.       if( xIndex < ETH_TXBUFNB - 1 )
  236.       {
  237.           /* Set next descriptor address register with next descriptor base address */
  238.           pxDMADescriptor->Buffer2NextDescAddr = ( uint32_t ) ( pxDMADescriptor + 1 );
  239.       }
  240.       else
  241.       {
  242.           /* For last descriptor, set next descriptor address register equal to the first descriptor base address */
  243.           pxDMADescriptor->Buffer2NextDescAddr = ( uint32_t ) DMATxDscrTab;
  244.       }
  245.   }
  246.   /* Set Transmit Descriptor List Address Register */
  247.   xETH.Instance->DMATDLAR = ( uint32_t ) DMATxDscrTab;
  248. }
  249. /*-----------------------------------------------------------*/
  250. static void prvDMARxDescListInit()
  251. {
  252. ETH_DMADescTypeDef *pxDMADescriptor;
  253. BaseType_t xIndex;
  254.   /*
  255.    * RX-descriptors.
  256.    */
  257.   /* Get the pointer on the first member of the descriptor list */
  258.   pxDMADescriptor = DMARxDscrTab;
  259.   /* Fill each DMA descriptor with the right values */
  260.   for( xIndex = 0; xIndex < ETH_RXBUFNB; xIndex++, pxDMADescriptor++ )
  261.   {
  262.       /* Set Buffer1 size and Second Address Chained bit */
  263.       pxDMADescriptor->ControlBufferSize = ETH_DMARXDESC_RCH | (uint32_t)ETH_RX_BUF_SIZE; 
  264.       #if( ipconfigZERO_COPY_RX_DRIVER != 0 )
  265.       {
  266.       /* Set Buffer1 address pointer */
  267.       NetworkBufferDescriptor_t *pxBuffer;
  268.           pxBuffer = pxGetNetworkBufferWithDescriptor( ETH_RX_BUF_SIZE, 100ul );
  269.           /* If the assert below fails, make sure that there are at least 'ETH_RXBUFNB'
  270.           Network Buffers available during start-up ( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ) */
  271.           configASSERT( pxBuffer != NULL );
  272.           if( pxBuffer != NULL )
  273.           {
  274.               pxDMADescriptor->Buffer1Addr = (uint32_t)pxBuffer->pucEthernetBuffer;
  275.               pxDMADescriptor->Status = ETH_DMARXDESC_OWN;
  276.           }
  277.       }
  278.       #else
  279.       {
  280.           /* Set Buffer1 address pointer */
  281.           pxDMADescriptor->Buffer1Addr = ( uint32_t )( Rx_Buff[ xIndex ] );
  282.           /* Set Own bit of the Rx descriptor Status */
  283.           pxDMADescriptor->Status = ETH_DMARXDESC_OWN;
  284.       }
  285.       #endif
  286.       /* Initialize the next descriptor with the Next Descriptor Polling Enable */
  287.       if( xIndex < ETH_RXBUFNB - 1 )
  288.       {
  289.           /* Set next descriptor address register with next descriptor base address */
  290.           pxDMADescriptor->Buffer2NextDescAddr = ( uint32_t )( pxDMADescriptor + 1 );
  291.       }
  292.       else
  293.       {
  294.           /* For last descriptor, set next descriptor address register equal to the first descriptor base address */
  295.           pxDMADescriptor->Buffer2NextDescAddr = ( uint32_t ) DMARxDscrTab;
  296.       }
  297.   }
  298.   /* Set Receive Descriptor List Address Register */
  299.   xETH.Instance->DMARDLAR = ( uint32_t ) DMARxDscrTab;
  300. }
  301. /*-----------------------------------------------------------*/
  302. static void prvMACAddressConfig(ETH_HandleTypeDef *heth, uint32_t ulIndex, uint8_t *Addr)
  303. {
  304. uint32_t ulTempReg;
  305.   /* Calculate the selected MAC address high register. */
  306.   ulTempReg = 0x80000000ul | ( ( uint32_t ) Addr[ 5 ] << 8 ) | ( uint32_t ) Addr[ 4 ];
  307.   /* Load the selected MAC address high register. */
  308.   ( *(__IO uint32_t *)( ( uint32_t ) ( ETH_MAC_ADDR_HBASE + ulIndex ) ) ) = ulTempReg;
  309.   /* Calculate the selected MAC address low register. */
  310.   ulTempReg = ( ( uint32_t ) Addr[ 3 ] << 24 ) | ( ( uint32_t ) Addr[ 2 ] << 16 ) | ( ( uint32_t ) Addr[ 1 ] << 8 ) | Addr[ 0 ];
  311.   /* Load the selected MAC address low register */
  312.   ( *(__IO uint32_t *) ( ( uint32_t ) ( ETH_MAC_ADDR_LBASE + ulIndex ) ) ) = ulTempReg;
  313. }
  314. /*-----------------------------------------------------------*/
  315. BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor, BaseType_t bReleaseAfterSend )
  316. {
  317.   BaseType_t xReturn = pdFAIL;
  318.   uint32_t ulTransmitSize = 0;
  319.   __IO ETH_DMADescTypeDef *pxDmaTxDesc;
  320.   /* Do not wait too long for a free TX DMA buffer. */
  321.   const TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 50u );
  322.   #if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM != 0 )
  323.   {
  324.       ProtocolPacket_t *pxPacket;
  325.       #if( ipconfigZERO_COPY_RX_DRIVER != 0 )
  326.       {
  327.           configASSERT( bReleaseAfterSend != 0 );
  328.       }
  329.       #endif /* ipconfigZERO_COPY_RX_DRIVER */
  330.       /* If the peripheral must calculate the checksum, it wants
  331.       the protocol checksum to have a value of zero. */
  332.       pxPacket = ( ProtocolPacket_t * ) ( pxDescriptor->pucEthernetBuffer );
  333.       if( pxPacket->xICMPPacket.xIPHeader.ucProtocol == ipPROTOCOL_ICMP )
  334.       {
  335.           pxPacket->xICMPPacket.xICMPHeader.usChecksum = ( uint16_t )0u;
  336.       }
  337.   }
  338.   #endif
  339.   /* Open a do {} while ( 0 ) loop to be able to call break. */
  340.   do
  341.   {
  342.       if( xPhyObject.ulLinkStatusMask != 0 )
  343.       {
  344.           if( xSemaphoreTake( xTXDescriptorSemaphore, xBlockTimeTicks ) != pdPASS )
  345.           {
  346.               /* Time-out waiting for a free TX descriptor. */
  347.               break;
  348.           }
  349.           /* This function does the actual transmission of the packet. The packet is
  350.           contained in 'pxDescriptor' that is passed to the function. */
  351.           pxDmaTxDesc = xETH.TxDesc;
  352.           /* Is this buffer available? */
  353.           configASSERT ( ( pxDmaTxDesc->Status & ETH_DMATXDESC_OWN ) == 0 );
  354.           {
  355.               /* Is this buffer available? */
  356.               /* Get bytes in current buffer. */
  357.               ulTransmitSize = pxDescriptor->xDataLength;
  358.               if( ulTransmitSize > ETH_TX_BUF_SIZE )
  359.               {
  360.                   ulTransmitSize = ETH_TX_BUF_SIZE;
  361.               }
  362.               #if( ipconfigZERO_COPY_TX_DRIVER == 0 )
  363.               {
  364.                   /* Copy the bytes. */
  365.                   memcpy( ( void * ) pxDmaTxDesc->Buffer1Addr, pxDescriptor->pucEthernetBuffer, ulTransmitSize );
  366.               }
  367.               #else
  368.               {
  369.                   /* Move the buffer. */
  370.                   pxDmaTxDesc->Buffer1Addr = ( uint32_t )pxDescriptor->pucEthernetBuffer;
  371.                   /* The Network Buffer has been passed to DMA, no need to release it. */
  372.                   bReleaseAfterSend = pdFALSE_UNSIGNED;
  373.               }
  374.               #endif /* ipconfigZERO_COPY_TX_DRIVER */
  375.               /* Ask to set the IPv4 checksum.
  376.               Also need an Interrupt on Completion so that 'vClearTXBuffers()' will be called.. */
  377.               pxDmaTxDesc->Status |= ETH_DMATXDESC_CIC_TCPUDPICMP_FULL | ETH_DMATXDESC_IC;
  378.               /* Prepare transmit descriptors to give to DMA. */
  379.               /* Set LAST and FIRST segment */
  380.               pxDmaTxDesc->Status |= ETH_DMATXDESC_FS | ETH_DMATXDESC_LS;
  381.               /* Set frame size */
  382.               pxDmaTxDesc->ControlBufferSize = ( ulTransmitSize & ETH_DMATXDESC_TBS1 );
  383.               /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
  384.               pxDmaTxDesc->Status |= ETH_DMATXDESC_OWN;
  385.               /* Point to next descriptor */
  386.               xETH.TxDesc = ( ETH_DMADescTypeDef * ) ( xETH.TxDesc->Buffer2NextDescAddr );
  387.               /* Ensure completion of memory access */
  388.               __DSB();
  389.               /* Resume DMA transmission*/
  390.               xETH.Instance->DMATPDR = 0;
  391.               iptraceNETWORK_INTERFACE_TRANSMIT();
  392.               xReturn = pdPASS;
  393.           }
  394.       }
  395.       else
  396.       {
  397.           /* The PHY has no Link Status, packet shall be dropped. */
  398.       }
  399.   }
  400.   while( 0 );
  401.   /* The buffer has been sent so can be released. */
  402.   if( bReleaseAfterSend != pdFALSE )
  403.   {
  404.       vReleaseNetworkBufferAndDescriptor( pxDescriptor );
  405.   }
  406.   return xReturn;
  407. }
  408. /*-----------------------------------------------------------*/
  409. static BaseType_t xMayAcceptPacket( uint8_t *pcBuffer )
  410. {
  411. const ProtocolPacket_t *pxProtPacket = ( const ProtocolPacket_t * )pcBuffer;
  412.   switch( pxProtPacket->xTCPPacket.xEthernetHeader.usFrameType )
  413.   {
  414.   case ipARP_FRAME_TYPE:
  415.       /* Check it later. */
  416.       return pdTRUE;
  417.   case ipIPv4_FRAME_TYPE:
  418.       /* Check it here. */
  419.       break;
  420.   default:
  421.       /* Refuse the packet. */
  422.       return pdFALSE;
  423.   }
  424.   #if( ipconfigETHERNET_DRIVER_FILTERS_PACKETS == 1 )
  425.   {
  426.       const IPHeader_t *pxIPHeader = &(pxProtPacket->xTCPPacket.xIPHeader);
  427.       uint32_t ulDestinationIPAddress;
  428.       /* Ensure that the incoming packet is not fragmented (only outgoing packets
  429.        * can be fragmented) as these are the only handled IP frames currently. */
  430.       if( ( pxIPHeader->usFragmentOffset & FreeRTOS_ntohs( ipFRAGMENT_OFFSET_BIT_MASK ) ) != 0U )
  431.       {
  432.           return pdFALSE;
  433.       }
  434.       /* HT: Might want to make the following configurable because
  435.        * most IP messages have a standard length of 20 bytes */
  436.       /* 0x45 means: IPv4 with an IP header of 5 x 4 = 20 bytes
  437.        * 0x47 means: IPv4 with an IP header of 7 x 4 = 28 bytes */
  438.       if( pxIPHeader->ucVersionHeaderLength < 0x45 || pxIPHeader->ucVersionHeaderLength > 0x4F )
  439.       {
  440.           return pdFALSE;
  441.       }
  442.       ulDestinationIPAddress = pxIPHeader->ulDestinationIPAddress;
  443.       /* Is the packet for this node? */
  444.       if( ( ulDestinationIPAddress != *ipLOCAL_IP_ADDRESS_POINTER ) &&
  445.           /* Is it a broadcast address x.x.x.255 ? */
  446.           ( ( FreeRTOS_ntohl( ulDestinationIPAddress ) & 0xff ) != 0xff ) &&
  447.       #if( ipconfigUSE_LLMNR == 1 )
  448.           ( ulDestinationIPAddress != ipLLMNR_IP_ADDR ) &&
  449.       #endif
  450.           ( *ipLOCAL_IP_ADDRESS_POINTER != 0 ) ) {
  451.           FreeRTOS_printf( ( "Drop IP %lxip\n", FreeRTOS_ntohl( ulDestinationIPAddress ) ) );
  452.           return pdFALSE;
  453.       }
  454.       if( pxIPHeader->ucProtocol == ipPROTOCOL_UDP )
  455.       {
  456.           uint16_t port = pxProtPacket->xUDPPacket.xUDPHeader.usDestinationPort;
  457.           if( ( xPortHasUDPSocket( port ) == pdFALSE )
  458.           #if ipconfigUSE_LLMNR == 1
  459.               && ( port != FreeRTOS_ntohs( ipLLMNR_PORT ) )
  460.           #endif
  461.           #if ipconfigUSE_NBNS == 1
  462.               && ( port != FreeRTOS_ntohs( ipNBNS_PORT ) )
  463.           #endif
  464.           #if ipconfigUSE_DNS == 1
  465.               && ( pxProtPacket->xUDPPacket.xUDPHeader.usSourcePort != FreeRTOS_ntohs( ipDNS_PORT ) )
  466.           #endif
  467.               ) {
  468.               /* Drop this packet, not for this device. */
  469.               return pdFALSE;
  470.           }
  471.       }
  472.   }
  473.   #endif  /* ipconfigETHERNET_DRIVER_FILTERS_PACKETS */
  474.   return pdTRUE;
  475. }
  476. /*-----------------------------------------------------------*/
  477. static BaseType_t prvNetworkInterfaceInput( void )
  478. {
  479. NetworkBufferDescriptor_t *pxCurDescriptor;
  480. NetworkBufferDescriptor_t *pxNewDescriptor = NULL;
  481. BaseType_t xReceivedLength, xAccepted;
  482. __IO ETH_DMADescTypeDef *pxDMARxDescriptor;
  483. xIPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
  484. const TickType_t xDescriptorWaitTime = pdMS_TO_TICKS( 250 );
  485. uint8_t *pucBuffer;
  486.   pxDMARxDescriptor = xETH.RxDesc;
  487.   if( ( pxDMARxDescriptor->Status & ETH_DMARXDESC_OWN) == 0 )
  488.   {
  489.       /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */
  490.       xReceivedLength = ( ( pxDMARxDescriptor->Status & ETH_DMARXDESC_FL ) >> ETH_DMARXDESC_FRAMELENGTHSHIFT ) - 4;
  491.       pucBuffer = (uint8_t *) pxDMARxDescriptor->Buffer1Addr;
  492.       /* Update the ETHERNET DMA global Rx descriptor with next Rx descriptor */
  493.       /* Chained Mode */   
  494.       /* Selects the next DMA Rx descriptor list for next buffer to read */
  495.       xETH.RxDesc = ( ETH_DMADescTypeDef* )pxDMARxDescriptor->Buffer2NextDescAddr;
  496.   }
  497.   else
  498.   {
  499.       xReceivedLength = 0;
  500.   }
  501.   /* Obtain the size of the packet and put it into the "usReceivedLength" variable. */
  502.   /* get received frame */
  503.   if( xReceivedLength > 0ul )
  504.   {
  505.       /* In order to make the code easier and faster, only packets in a single buffer
  506.       will be accepted.  This can be done by making the buffers large enough to
  507.       hold a complete Ethernet packet (1536 bytes).
  508.       Therefore, two sanity checks: */
  509.       configASSERT( xReceivedLength <= ETH_RX_BUF_SIZE );
  510.       if( ( pxDMARxDescriptor->Status & ( ETH_DMARXDESC_CE | ETH_DMARXDESC_IPV4HCE | ETH_DMARXDESC_FT ) ) != ETH_DMARXDESC_FT )
  511.       {
  512.           /* Not an Ethernet frame-type or a checmsum error. */
  513.           xAccepted = pdFALSE;
  514.       }
  515.       else
  516.       {
  517.           /* See if this packet must be handled. */
  518.           xAccepted = xMayAcceptPacket( pucBuffer );
  519.       }
  520.       if( xAccepted != pdFALSE )
  521.       {
  522.           /* The packet wil be accepted, but check first if a new Network Buffer can
  523.           be obtained. If not, the packet will still be dropped. */
  524.           pxNewDescriptor = pxGetNetworkBufferWithDescriptor( ETH_RX_BUF_SIZE, xDescriptorWaitTime );
  525.           if( pxNewDescriptor == NULL )
  526.           {
  527.               /* A new descriptor can not be allocated now. This packet will be dropped. */
  528.               xAccepted = pdFALSE;
  529.           }
  530.       }
  531.       #if( ipconfigZERO_COPY_RX_DRIVER != 0 )
  532.       {
  533.           /* Find out which Network Buffer was originally passed to the descriptor. */
  534.           pxCurDescriptor = pxPacketBuffer_to_NetworkBuffer( pucBuffer );
  535.           configASSERT( pxCurDescriptor != NULL );
  536.       }
  537.       #else
  538.       {
  539.           /* In this mode, the two descriptors are the same. */
  540.           pxCurDescriptor = pxNewDescriptor;
  541.           if( pxNewDescriptor != NULL )
  542.           {
  543.               /* The packet is acepted and a new Network Buffer was created,
  544.               copy data to the Network Bufffer. */
  545.               memcpy( pxNewDescriptor->pucEthernetBuffer, pucBuffer, xReceivedLength );
  546.           }
  547.       }
  548.       #endif
  549.       if( xAccepted != pdFALSE )
  550.       {
  551.           pxCurDescriptor->xDataLength = xReceivedLength;
  552.           xRxEvent.pvData = ( void * ) pxCurDescriptor;
  553.           /* Pass the data to the TCP/IP task for processing. */
  554.           if( xSendEventStructToIPTask( &xRxEvent, xDescriptorWaitTime ) == pdFALSE )
  555.           {
  556.               /* Could not send the descriptor into the TCP/IP stack, it
  557.               must be released. */
  558.               vReleaseNetworkBufferAndDescriptor( pxCurDescriptor );
  559.               iptraceETHERNET_RX_EVENT_LOST();
  560.           }
  561.           else
  562.           {
  563.               iptraceNETWORK_INTERFACE_RECEIVE();
  564.           }
  565.       }
  566.       /* Release descriptors to DMA */
  567.       #if( ipconfigZERO_COPY_RX_DRIVER != 0 )
  568.       {
  569.           /* Set Buffer1 address pointer */
  570.           if( pxNewDescriptor != NULL )
  571.           {
  572.               pxDMARxDescriptor->Buffer1Addr = (uint32_t)pxNewDescriptor->pucEthernetBuffer;
  573.           }
  574.           else
  575.           {
  576.               /* The packet was dropped and the same Network
  577.               Buffer will be used to receive a new packet. */
  578.           }
  579.       }
  580.       #endif /* ipconfigZERO_COPY_RX_DRIVER */
  581.       /* Set Buffer1 size and Second Address Chained bit */
  582.       pxDMARxDescriptor->ControlBufferSize = ETH_DMARXDESC_RCH | (uint32_t)ETH_RX_BUF_SIZE; 
  583.       pxDMARxDescriptor->Status = ETH_DMARXDESC_OWN;
  584.       /* Ensure completion of memory access */
  585.       __DSB();
  586.       /* When Rx Buffer unavailable flag is set clear it and resume
  587.       reception. */
  588.       if( ( xETH.Instance->DMASR & ETH_DMASR_RBUS ) != 0 )
  589.       {
  590.           /* Clear RBUS ETHERNET DMA flag. */
  591.           xETH.Instance->DMASR = ETH_DMASR_RBUS;
  592.           /* Resume DMA reception. */
  593.           xETH.Instance->DMARPDR = 0;
  594.       }
  595.   }
  596.   return ( xReceivedLength > 0 );
  597. }
  598. /*-----------------------------------------------------------*/
  599. BaseType_t xSTM32_PhyRead( BaseType_t xAddress, BaseType_t xRegister, uint32_t *pulValue )
  600. {
  601. uint16_t usPrevAddress = xETH.Init.PhyAddress;
  602. BaseType_t xResult;
  603. HAL_StatusTypeDef xHALResult;
  604.   xETH.Init.PhyAddress = xAddress;
  605.   xHALResult = HAL_ETH_ReadPHYRegister( &xETH, ( uint16_t )xRegister, pulValue );
  606.   xETH.Init.PhyAddress = usPrevAddress;
  607.   if( xHALResult == HAL_OK )
  608.   {
  609.       xResult = 0;
  610.   }
  611.   else
  612.   {
  613.       xResult = -1;
  614.   }
  615.   return xResult;
  616. }
  617. /*-----------------------------------------------------------*/
  618. BaseType_t xSTM32_PhyWrite( BaseType_t xAddress, BaseType_t xRegister, uint32_t ulValue )
  619. {
  620. uint16_t usPrevAddress = xETH.Init.PhyAddress;
  621. BaseType_t xResult;
  622. HAL_StatusTypeDef xHALResult;
  623.   xETH.Init.PhyAddress = xAddress;
  624.   xHALResult = HAL_ETH_WritePHYRegister( &xETH, ( uint16_t )xRegister, ulValue );
  625.   xETH.Init.PhyAddress = usPrevAddress;
  626.   if( xHALResult == HAL_OK )
  627.   {
  628.       xResult = 0;
  629.   }
  630.   else
  631.   {
  632.       xResult = -1;
  633.   }
  634.   return xResult;
  635. }
  636. /*-----------------------------------------------------------*/
  637. void phy_test()
  638. {
  639. BaseType_t xPhyCount;
  640. BaseType_t xPhyIndex;
  641.   vPhyInitialise( &xPhyObject, xSTM32_PhyRead, xSTM32_PhyWrite );
  642.   xPhyCount = xPhyDiscover( &xPhyObject );
  643.   FreeRTOS_printf( ( "PHY count %ld\n", xPhyCount ) );
  644.   for( xPhyIndex = 0; xPhyIndex < xPhyCount; xPhyIndex++ )
  645.   {
  646.       FreeRTOS_printf( ( "PHY[%d] at address %d ( 0x%08X )\n",
  647.           xPhyIndex,
  648.           xPhyObject.ucPhyIndexes[ xPhyIndex ],
  649.           xPhyObject.ulPhyIDs[ xPhyIndex ] ) );
  650.   }
  651.  
  652. }
  653. void vMACBProbePhy( void )
  654. {
  655.   vPhyInitialise( &xPhyObject, xSTM32_PhyRead, xSTM32_PhyWrite );
  656.   xPhyDiscover( &xPhyObject );
  657.   xPhyConfigure( &xPhyObject, &xPHYProperties );
  658. }
  659. /*-----------------------------------------------------------*/
  660. static void prvEthernetUpdateConfig( BaseType_t xForce )
  661. {
  662.   FreeRTOS_printf( ( "prvEthernetUpdateConfig: LS mask %02lX Force %d\n",
  663.       xPhyObject.ulLinkStatusMask,
  664.       ( int )xForce ) );
  665.   if( ( xForce != pdFALSE ) || ( xPhyObject.ulLinkStatusMask != 0 ) )
  666.   {
  667.       /* Restart the auto-negotiation. */
  668.       if( xETH.Init.AutoNegotiation != ETH_AUTONEGOTIATION_DISABLE )
  669.       {
  670.           xPhyStartAutoNegotiation( &xPhyObject, xPhyGetMask( &xPhyObject ) );
  671.           /* Configure the MAC with the Duplex Mode fixed by the
  672.           auto-negotiation process. */
  673.           if( xPhyObject.xPhyProperties.ucDuplex == PHY_DUPLEX_FULL )
  674.           {
  675.               xETH.Init.DuplexMode = ETH_MODE_FULLDUPLEX;
  676.           }
  677.           else
  678.           {
  679.               xETH.Init.DuplexMode = ETH_MODE_HALFDUPLEX;
  680.           }
  681.           /* Configure the MAC with the speed fixed by the
  682.           auto-negotiation process. */
  683.           if( xPhyObject.xPhyProperties.ucSpeed == PHY_SPEED_10 )
  684.           {
  685.               xETH.Init.Speed = ETH_SPEED_10M;
  686.           }
  687.           else
  688.           {
  689.               xETH.Init.Speed = ETH_SPEED_100M;
  690.           }
  691.       }
  692.       else /* AutoNegotiation Disable */
  693.       {
  694.           /* Check parameters */
  695.           assert_param( IS_ETH_SPEED( xETH.Init.Speed ) );
  696.           assert_param( IS_ETH_DUPLEX_MODE( xETH.Init.DuplexMode ) );
  697.           if( xETH.Init.DuplexMode == ETH_MODE_FULLDUPLEX )
  698.           {
  699.               xPhyObject.xPhyPreferences.ucDuplex = PHY_DUPLEX_HALF;
  700.           }
  701.           else
  702.           {
  703.               xPhyObject.xPhyPreferences.ucDuplex = PHY_DUPLEX_FULL;
  704.           }
  705.           if( xETH.Init.Speed == ETH_SPEED_10M )
  706.           {
  707.               xPhyObject.xPhyPreferences.ucSpeed = PHY_SPEED_10;
  708.           }
  709.           else
  710.           {
  711.               xPhyObject.xPhyPreferences.ucSpeed = PHY_SPEED_100;
  712.           }
  713.           xPhyObject.xPhyPreferences.ucMDI_X = PHY_MDIX_AUTO;
  714.           /* Use predefined (fixed) configuration. */
  715.           xPhyFixedValue( &xPhyObject, xPhyGetMask( &xPhyObject ) );
  716.       }
  717.       /* ETHERNET MAC Re-Configuration */
  718.       HAL_ETH_ConfigMAC( &xETH, (ETH_MACInitTypeDef *) NULL);
  719.       /* Restart MAC interface */
  720.       HAL_ETH_Start( &xETH);
  721.   }
  722.   else
  723.   {
  724.       /* Stop MAC interface */
  725.       HAL_ETH_Stop( &xETH );
  726.   }
  727. }
  728. /*-----------------------------------------------------------*/
  729. BaseType_t xGetPhyLinkStatus( void )
  730. {
  731. BaseType_t xReturn;
  732.   if( xPhyObject.ulLinkStatusMask != 0 )
  733.   {
  734.       xReturn = pdPASS;
  735.   }
  736.   else
  737.   {
  738.       xReturn = pdFAIL;
  739.   }
  740.   return xReturn;
  741. }
  742. static void prvEMACHandlerTask( void *pvParameters )
  743. {
  744.   TimeOut_t xPhyTime;
  745.   UBaseType_t uxLastMinBufferCount = 0;
  746.   #if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
  747.   UBaseType_t uxLastMinQueueSpace = 0;
  748.   #endif
  749.   TickType_t xPhyRemTime;
  750.   UBaseType_t uxCurrentCount;
  751.   BaseType_t xResult;
  752.   uint32_t xStatus;
  753.   const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
  754.       /* Remove compiler warnings about unused parameters. */
  755.       ( void ) pvParameters;
  756.       for( ;; )
  757.       {
  758.           xResult = 0;
  759.           uxCurrentCount = uxGetMinimumFreeNetworkBuffers();
  760.           if( uxLastMinBufferCount != uxCurrentCount )
  761.           {
  762.               /* The logging produced below may be helpful
  763.               while tuning +TCP: see how many buffers are in use. */
  764.               uxLastMinBufferCount = uxCurrentCount;
  765.               FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",uxGetNumberOfFreeNetworkBuffers(), uxCurrentCount ) );
  766.           }
  767.           if( xTXDescriptorSemaphore != NULL )
  768.           {
  769.           static UBaseType_t uxLowestSemCount = ( UBaseType_t ) ETH_TXBUFNB - 1;
  770.               uxCurrentCount = uxSemaphoreGetCount( xTXDescriptorSemaphore );
  771.               if( uxLowestSemCount > uxCurrentCount )
  772.               {
  773.                   uxLowestSemCount = uxCurrentCount;
  774.                   FreeRTOS_printf( ( "TX DMA buffers: lowest %lu\n", uxLowestSemCount ) );
  775.               }
  776.           }
  777.           #if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
  778.           {
  779.               uxCurrentCount = uxGetMinimumIPQueueSpace();
  780.               if( uxLastMinQueueSpace != uxCurrentCount )
  781.               {
  782.                   /* The logging produced below may be helpful
  783.                   while tuning +TCP: see how many buffers are in use. */
  784.                   uxLastMinQueueSpace = uxCurrentCount;
  785.                   FreeRTOS_printf( ( "Queue space: lowest %lu\n", uxCurrentCount ) );
  786.               }
  787.           }
  788.           #endif /* ipconfigCHECK_IP_QUEUE_SPACE */
  789.           if( ( ulISREvents & EMAC_IF_ALL_EVENT ) == 0 )
  790.           {
  791.               /* No events to process now, wait for the next. */
  792.               ulTaskNotifyTake( pdFALSE, ulMaxBlockTime );
  793.           }
  794.           if( ( ulISREvents & EMAC_IF_RX_EVENT ) != 0 )
  795.           {
  796.               ulISREvents &= ~EMAC_IF_RX_EVENT;
  797.               xResult = prvNetworkInterfaceInput();
  798.               if( xResult > 0 )
  799.               {
  800.                       while( prvNetworkInterfaceInput() > 0 )
  801.                   {
  802.                   }
  803.               }
  804.           }
  805.           if( ( ulISREvents & EMAC_IF_TX_EVENT ) != 0 )
  806.           {
  807.               /* Code to release TX buffers if zero-copy is used. */
  808.               ulISREvents &= ~EMAC_IF_TX_EVENT;
  809.               /* Check if DMA packets have been delivered. */
  810.               vClearTXBuffers();
  811.           }
  812.           if( ( ulISREvents & EMAC_IF_ERR_EVENT ) != 0 )
  813.           {
  814.               /* Future extension: logging about errors that occurred. */
  815.               ulISREvents &= ~EMAC_IF_ERR_EVENT;
  816.           }
  817.           if( xResult > 0 )
  818.           {
  819.               /* A packet was received. No need to check for the PHY status now,
  820.               but set a timer to check it later on. */
  821.               vTaskSetTimeOutState( &xPhyTime );
  822.               xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
  823.               xResult = 0;
  824.           }
  825.           else if( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE )
  826.           {
  827.               HAL_ETH_ReadPHYRegister( &xETH, 0x01,&xStatus );
  828.               xPhyObject.ulLinkStatusMask = xStatus;
  829.               if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != ( xStatus & BMSR_LINK_STATUS ) )
  830.               {
  831.                   ulPHYLinkStatus = xStatus;
  832.                   FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ) );
  833.                   prvEthernetUpdateConfig( pdFALSE );
  834.               }
  835.               vTaskSetTimeOutState( &xPhyTime );
  836.               if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
  837.               {
  838.                   xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
  839.               }
  840.               else
  841.               {
  842.                   xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
  843.               }
  844.           }
  845.       }
  846. }
  847. /*-----------------------------------------------------------*/
  848. void ETH_IRQHandler( void )
  849. {
  850.   HAL_ETH_IRQHandler( &xETH );
  851. }

 

  1. TCP还有一些配置函数在接口文件中没有实现,需要用户自己实现。创建netInfoConfig.c和netInfoConfig.h文件来实现TCP需要的一些接口配置函数参考如下代码。
  1. #include "netInfoConfig.h" 
  2. const uint8_t ucIPAddress[ 4 ] = { configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 }; 
  3. const uint8_t ucNetMask[ 4 ] = { configNET_MASK0, configNET_MASK1, configNET_MASK2, configNET_MASK3 }; 
  4. const uint8_t ucGatewayAddress[ 4 ] = { configGATEWAY_ADDR0, configGATEWAY_ADDR1, configGATEWAY_ADDR2, configGATEWAY_ADDR3 }; 
  5. const uint8_t ucDNSServerAddress[ 4 ] = { configDNS_SERVER_ADDR0, configDNS_SERVER_ADDR1, configDNS_SERVER_ADDR2, configDNS_SERVER_ADDR3 }; 
  6. const uint8_t ucMACAddress[ 6 ] = { configMAC_ADDR0, configMAC_ADDR1, configMAC_ADDR2, configMAC_ADDR3, configMAC_ADDR4, configMAC_ADDR5 };
  7. //this queue should be create for vApplicationPingReplyHook()
  8. QueueHandle_t xPingReplyQueue;
  9. /* --------------------------FUNCTION MODULE----------------------------- */
  10. //return a rand num
  11. UBaseType_t uxRand(){ 
  12.     return (UBaseType_t) getRandomNum(); 
  13. //Use this name to request IP during DHCP call
  14. const char *pcApplicationHostnameHook( void )
  15. {
  16.   return mainHOST_NAME;
  17. }
  18. /*
  19.  * The following function should be provided by the user and return true if it
  20.  * matches the domain name.
  21.  *this func will be used to judge whether *pcName matche DNS request or LLMNR request.
  22.     return pdTRUE if matching DNS request,
  23.     return pdFALSE if matching LLMNR request.
  24.  */ 
  25. BaseType_t xApplicationDNSQueryHook( const char *pcName )
  26.   BaseType_t xReturn; 
  27.   if( strcmp( pcName, pcApplicationHostnameHook() ) == 0
  28.   { 
  29.           xReturn = pdPASS; 
  30.   } 
  31.   else if( strcmp( pcName, mainDEVICE_NICK_NAME ) == 0
  32.   { 
  33.           xReturn = pdPASS; 
  34.   } 
  35.   else 
  36.   { 
  37.           xReturn = pdFAIL; 
  38.   } 
  39.   return xReturn; 
  40. void vApplicationPingReplyHook( ePingReplyStatus_t eStatus, uint16_t usIdentifier ) 
  41.   switch( eStatus ) 
  42.   { 
  43.       case eSuccess: 
  44.               xQueueSend( xPingReplyQueue, &usIdentifier, 10 / portTICK_PERIOD_MS ); 
  45.               break; 
  46.       case eInvalidChecksum :
  47.               break;
  48.       case eInvalidData :   
  49.               break; 
  50.   } 
  51. }
  52. void xPingReplyQueueCreate(void)
  53.     xPingReplyQueue = xQueueCreate( 20, sizeof( uint16_t ) ); 
  54. }
  55. BaseType_t vSendPing( const char *pcIPAddress )
  56. {
  57.   uint16_t usRequestSequenceNumber, usReplySequenceNumber;
  58.   uint32_t ulIPAddress;
  59.   ulIPAddress = FreeRTOS_inet_addr( pcIPAddress );
  60.      
  61.   if(xPingReplyQueue == NULL)
  62.       xPingReplyQueueCreate();
  63.     usRequestSequenceNumber = FreeRTOS_SendPingRequest( ulIPAddress, 8, 100 / portTICK_PERIOD_MS );
  64.     if( usRequestSequenceNumber == pdFAIL )
  65.     {
  66.     }
  67.     else
  68.     {
  69.           if( xQueueReceive( xPingReplyQueue, &usReplySequenceNumber, 200 / portTICK_PERIOD_MS ) == pdPASS )
  70.           {
  71.               if( usRequestSequenceNumber == usReplySequenceNumber )
  72.               {
  73.               }
  74.           }
  75.     }
  76.       return ulIPAddress;
  77. }
  78. BaseType_t IP_init( void )
  79. {  
  80.    return FreeRTOS_IPInit( ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress ); 
  81. /*---------------------------DEBUG ONLY-------------------------------------*/ 
  82. int lUDPLoggingPrintf( const char *fmt, ... )
  83. {   
  84.   return 0;
  85. void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent )
  86. {
  87.   uint32_t ulIPAddress, ulNetMask, ulGatewayAddress, ulDNSServerAddress;
  88.   char cBuffer[ 16 ];
  89.   static BaseType_t xTasksAlreadyCreated = pdFALSE;
  90.   FreeRTOS_printf( ( "vApplicationIPNetworkEventHook: event %ld\n", eNetworkEvent ) );
  91.   if( eNetworkEvent == eNetworkUp )
  92.   {
  93.       if( xTasksAlreadyCreated == pdFALSE )
  94.       {
  95.           #if( mainCREATE_UDP_LOGGING_TASK == 1 )
  96.           {
  97.               vUDPLoggingTaskCreate();
  98.           }
  99.           #endif
  100.           #if( ( mainCREATE_FTP_SERVER == 1 ) || ( mainCREATE_HTTP_SERVER == 1 ) )
  101.           {
  102.               /* Let the server work task now it can now create the servers. */
  103.               xTaskNotifyGive( xServerWorkTaskHandle );
  104.           }
  105.           #endif
  106.           #if( TCP_CLIENT == 1 )
  107.           {
  108. //                vStartTCPEchoClientTasks_SingleTasks( mainECHO_CLIENT_TASK_STACK_SIZE, mainECHO_CLIENT_TASK_PRIORITY );
  109.           }
  110.           #endif
  111.           #if( TCP_SERVER == 1 )
  112.           {
  113. //                vStartSimpleTCPServerTasks( mainECHO_SERVER_STACK_SIZE, mainECHO_SERVER_TASK_PRIORITY );
  114.           }
  115.           #endif
  116.           #if( mainCREATE_UDP_CLI_TASKS == 1 )
  117.           {
  118.               vRegisterSampleCLICommands();
  119.               vRegisterTCPCLICommands();
  120.               vStartUDPCommandInterpreterTask( mainUDP_CLI_TASK_STACK_SIZE, mainUDP_CLI_PORT_NUMBER, mainUDP_CLI_TASK_PRIORITY );
  121.           }
  122.           #endif
  123.           xTasksAlreadyCreated = pdTRUE;
  124.       }
  125.       /* Print out the network configuration, which may have come from a DHCP
  126.       server. */
  127.       FreeRTOS_GetAddressConfiguration( &ulIPAddress, &ulNetMask, &ulGatewayAddress, &ulDNSServerAddress );
  128.       FreeRTOS_inet_ntoa( ulIPAddress, cBuffer );
  129.       FreeRTOS_printf( ( "IP Address: %s\n", cBuffer ) );
  130.       FreeRTOS_inet_ntoa( ulNetMask, cBuffer );
  131.       FreeRTOS_printf( ( "Subnet Mask: %s\n", cBuffer ) );
  132.       FreeRTOS_inet_ntoa( ulGatewayAddress, cBuffer );
  133.       FreeRTOS_printf( ( "Gateway Address: %s\n", cBuffer ) );
  134.       FreeRTOS_inet_ntoa( ulDNSServerAddress, cBuffer );
  135.       FreeRTOS_printf( ( "DNS Server Address: %s\n", cBuffer ) );
  136.   }
  137. }
  138. 在main.c文件中引用头文件netInfoConfig.h,在main函数中调用初始化函数。参考如下代码。
  139. #include "bsp_clock.h"
  140. #include "randomnum.h"
  141. #include "netInfoConfig.h"
  142. int main(void)
  143. {
  144.   HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
  145.  
  146.   CLOCLK_Init();
  147.  
  148.   RNG_init();                                           
  149.   IP_init();
  150.   vTaskStartScheduler();
  151.   while(1);
  152. }

 

  • 编译工程,有14个错误。这里是要提供两个编译器内置的命令以取消结构体自动字节对齐,如果用的IDE是keil,那么默认编译器是armcc,需要pack_struct_start.h文件内添加#pragma pack(1),并在pack_struct_end.h文件内添加#pragma pack(),在FreeRTOS-TCP\include路径下创建这两个文件,并将代码添加进去。再次编译。
  • 工程编译,有216个错误,报错类型说明符的无效组合,在报错的结构体后面加上“;”。再次编译。
  • 工程编译,有35个错误,在FreeRTOS_IP.h文件中引用FreeRTOS.h和list.h头文件
  • 工程编译,有1个错误。注释掉phyHandling.c文件下eventLogging.h的引用。再次编译。
  • 工程编译,有1个错误,eventLogAdd()函数没被定义。注释掉相关引用。再次编译。无错误。
  • 修改stm32f4xx_hal_eth.c文件下函数HAL_ETH_IRQHandler()里的else if,改成if。参考如下代码。
  1. void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth)
  2. {
  3.   /* Frame received */
  4.   if (__HAL_ETH_DMA_GET_FLAG(heth, ETH_DMA_FLAG_R))
  5.   {
  6.     /* Receive complete callback */
  7.     HAL_ETH_RxCpltCallback(heth);
  8.     
  9.      /* Clear the Eth DMA Rx IT pending bits */
  10.     __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_IT_R);
  11.     /* Set HAL State to Ready */
  12.     heth->State = HAL_ETH_STATE_READY;
  13.    
  14.     /* Process Unlocked */
  15.     __HAL_UNLOCK(heth);
  16.   }
  17.   /* Frame transmitted */
  18.   if (__HAL_ETH_DMA_GET_FLAG(heth, ETH_DMA_FLAG_T))
  19.   {
  20.     /* Transfer complete callback */
  21.     HAL_ETH_TxCpltCallback(heth);
  22.    
  23.     /* Clear the Eth DMA Tx IT pending bits */
  24.     __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_IT_T);
  25.     /* Set HAL State to Ready */
  26.     heth->State = HAL_ETH_STATE_READY;
  27.    
  28.     /* Process Unlocked */
  29.     __HAL_UNLOCK(heth);
  30.   }
  31.  
  32.   /* Clear the interrupt flags */
  33.   __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_IT_NIS);
  34.  
  35.   /* ETH DMA Error */
  36.   if(__HAL_ETH_DMA_GET_FLAG(heth, ETH_DMA_FLAG_AIS))
  37.   {
  38.     /* Ethernet Error callback */
  39.     HAL_ETH_ErrorCallback(heth);
  40.     /* Clear the interrupt flags */
  41.     __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_FLAG_AIS);
  42.  
  43.     /* Set HAL State to Ready */
  44.     heth->State = HAL_ETH_STATE_READY;
  45.    
  46.     /* Process Unlocked */
  47.     __HAL_UNLOCK(heth);
  48.   }
  49. }
  • 屏蔽FreeRTOSConfig.h文件下的#define xPortSysTickHandler SysTick_Handler,创建prot.h文件,文件放在FreeRTOS\portable\RVDS\ARM_CM4F路径下。文件内声明xPortSysTickHandler()函数。
  • 修改bsp_clock.c文件,加入以下函数。
  1. void SysTick_Handler()
  2. {
  3.   HAL_IncTick();
  4.   xPortSysTickHandler();
  5. }
  • 编译运行,无错误,下载到开发板,连接网线到路由器,登录路由器查看ip地址,ping 开发板IP,正常ping通。

 

本文为个人爱好所做,欢迎各位大佬指点,如有错误之处还请见谅。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/518362
推荐阅读
相关标签
  

闽ICP备14008679号