STM32CUBEMX+STM32H750VB+LWIP+LAN8720A+FREERTOS TCP服务器、UDP数据接收发送、网线热插拔、IAR-8.32开发

STM32CUBEMX+STM32H750VB+LWIP+LAN8720A+FREERTOS TCP服务器、UDP数据接收发送、网线热插拔、IAR-8.32开发

  • STM32H750VB
    • 使用STM32CUBEMX生成工程
    • IAR+J-LINK调试准备工作
    • CUBEMX生成的代码问题所在

STM32H750VB

这是一款比较新的Cortex-M7内核的MCU,因为项目原因,需要一款RAM大(1024KB),主频高(480M)的芯片,我司的硬件工程师选择了他。

使用STM32CUBEMX生成工程

需要注意的是为什么不使用标准库,而选用大多数嵌入式工程师不是很熟悉的STM32CUBEMX生成的HAL库完全是因为找不到标准库啊!啊!啊!,当然也有学习新开发工具的想法

我使用的是STM32CUBEMX_V5.6.1

1.首先选择芯片(STM32H750VB
STM32CUBEMX+STM32H750VB+LWIP+LAN8720A+FREERTOS TCP服务器、UDP数据接收发送、网线热插拔、IAR-8.32开发_第1张图片
2.配置时钟,选择HSE(根据实际PCB选择
STM32CUBEMX+STM32H750VB+LWIP+LAN8720A+FREERTOS TCP服务器、UDP数据接收发送、网线热插拔、IAR-8.32开发_第2张图片
3.配置HAL库时钟,选择TIM1,因为需要上FreeRTOS系统,而系统的节拍器通常会选择系统滴答定时器systick,所以我们这里选择TIM1作为库定时器而不是systick。

STM32CUBEMX+STM32H750VB+LWIP+LAN8720A+FREERTOS TCP服务器、UDP数据接收发送、网线热插拔、IAR-8.32开发_第3张图片
4.使能Cache和MPU内存保护单元
因为H7结构体的特殊,LWIP网络需要使用的RAM要MPU保护,并且地址也是定死的0x30040000开始,和F4随意定义不同
具体为何这么设置得去看H750的用户手册
STM32CUBEMX+STM32H750VB+LWIP+LAN8720A+FREERTOS TCP服务器、UDP数据接收发送、网线热插拔、IAR-8.32开发_第4张图片
5.PHY芯片设置,PCB选用的是LAN8720A,虽然STM32CUBEMX选用的是LAN8742,但其实并没有什么很大的区别(即使区别不大,CUBEMX直接生成的程序也并不能让你ping通网络,可能是芯片比较新,好多功能没有得到实际验证,具体如何修改,下面会进行详细描述)。
STM32CUBEMX+STM32H750VB+LWIP+LAN8720A+FREERTOS TCP服务器、UDP数据接收发送、网线热插拔、IAR-8.32开发_第5张图片
6.FREERTOS系统设置,需要注意的也就只有TOTAL_HEAP_SIZE,你需要根据实际需要设置大小,其他的就是用什么使能什么,譬如:使用信号量的话就使能SEMAPHORE 等等。
STM32CUBEMX+STM32H750VB+LWIP+LAN8720A+FREERTOS TCP服务器、UDP数据接收发送、网线热插拔、IAR-8.32开发_第6张图片
7.LWIP设置,主要设置3个地方,注重注意的就是LWIP_NETIF_LINK_CALLBACK需要使能
通用设置很常规,这里我不要DHCP,就除能设置成了静态IP
STM32CUBEMX+STM32H750VB+LWIP+LAN8720A+FREERTOS TCP服务器、UDP数据接收发送、网线热插拔、IAR-8.32开发_第7张图片
使能了LINK_CALLBACK之后,就多了一个网线插拔时会进入的回调函数,你就可以在里面处理一些事情,不做也可以,他会自动deinit-ETH
STM32CUBEMX+STM32H750VB+LWIP+LAN8720A+FREERTOS TCP服务器、UDP数据接收发送、网线热插拔、IAR-8.32开发_第8张图片

PHY芯片选择LAN8742ASTM32CUBEMX+STM32H750VB+LWIP+LAN8720A+FREERTOS TCP服务器、UDP数据接收发送、网线热插拔、IAR-8.32开发_第9张图片
8.随意设置一个运行灯添加在TASK里面,用来查看程序运行状态就结束可以生成程序了。

IAR+J-LINK调试准备工作

因为STM32H750是一款很新的芯片,所以会出现,J-LINK和IAR中都没有这款芯片的情况,这个时候就需要更新IDE和J-LIN了,我更新到了IAR8.32和J-LINK6.84。
这里要吐槽的一点是IAR8.32真的是个垃圾,调试的时候,只是把鼠标放在变量名字上都会闪退,更别说在watch中看数组了。

CUBEMX生成的代码问题所在

1.因为我task多,MX_LWIP_Init();这个LWIP初始化函数是在任务中,是开启了系统任务调度之后才初始化的,就导致了PHY芯片初始化没有完成的问题。

解决方法:
ethernetif.c中、

static void low_level_init(struct netif *netif)	
/* USER CODE BEGIN PHY_PRE_CONFIG */ 
  
  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_2,GPIO_PIN_RESET);
  HAL_Delay(50);
  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_2,GPIO_PIN_SET);     //LAN8720A复位
  
/* USER CODE END PHY_PRE_CONFIG */
  /* Set PHY IO functions */
  LAN8742_RegisterBusIO(&LAN8742, &LAN8742_IOCtx);

  /* Initialize the LAN8742 ETH PHY */
  while(LAN8742_Init(&LAN8742) != LAN8742_STATUS_OK)    //需要写一个while确保LAN8742_Init成功
        ;

添加一个复位功能和while等待初始化完成功能。

2.因为硬件上面没有硬件上拉采用的自动协商,所以在软件中也要完成自动协商,在初始化完成后添加

static void low_level_init(struct netif *netif)	
/* USER CODE BEGIN PHY_POST_CONFIG */ 
LAN8742_StartAutoNego(&LAN8742);      //启动自动协商
/* USER CODE END PHY_POST_CONFIG */

2.ETH_RX_BUFFER_SIZE的宏定义是 1536UL
而生成代码

heth.Init.RxBuffLen = 1528;

需要改成

heth.Init.RxBuffLen = ETH_RX_BUFFER_SIZE;

3.清除高速Cache

static err_t low_level_output(struct netif *netif, struct pbuf *p)
  TxConfig.Length = framelen;
  TxConfig.TxBuffer = Txbuffer;

  SCB_CleanInvalidateDCache();        //清除Cache缓冲区
  HAL_ETH_Transmit(&heth, &TxConfig, ETH_DMA_TRANSMIT_TIMEOUT);
  
  return errval;
static struct pbuf * low_level_input(struct netif *netif)
  if (HAL_ETH_GetRxDataBuffer(&heth, &RxBuff) == HAL_OK) 
  {
     
    SCB_CleanInvalidateDCache();        //清除Cache缓冲区
    
    HAL_ETH_GetRxDataLength(&heth, &framelength);
    
    /* Build Rx descriptor to be ready for next data reception */
    HAL_ETH_BuildRxDescriptors(&heth);
    
    SCB_InvalidateDCache_by_Addr((uint32_t *)Rx_Buff, (ETH_RX_DESC_CNT*ETH_RX_BUFFER_SIZE));
    
#if !defined(DUAL_CORE) || defined(CORE_CM7)
    /* Invalidate data cache for ETH Rx Buffers */
    SCB_InvalidateDCache_by_Addr((uint32_t *)RxBuff.buffer, framelength);
#endif

    custom_pbuf  = (struct pbuf_custom*)LWIP_MEMPOOL_ALLOC(RX_POOL);
    custom_pbuf->custom_free_function = pbuf_free_custom;

    p = pbuf_alloced_custom(PBUF_RAW, framelength, PBUF_REF, custom_pbuf, RxBuff.buffer, ETH_RX_BUFFER_SIZE);
  }

4.系统时钟初始化完成后需要初始化SRAM3的时钟

  /* USER CODE BEGIN SysInit */
  __HAL_RCC_D2SRAM3_CLK_ENABLE();       //启动SRAM3的时钟
  /* USER CODE END SysInit */

这样就差不多了,我会把里面的相关资源上传

J-LINK下载

不带FREERTOS的工程下载地址

IAR8.32由于安装包太大,传不上来

你可能感兴趣的:(STM32H750,LWIP,FREERTOS,嵌入式,stm32,网络,单片机)