ST意法半导体
直播中

陈霞

7年用户 936经验值
私信 关注
[问答]

在NUCLEO-H743ZI板上通过STM32CubeMX生成的代码有问题求助

你好,
我在 NUCLEO-H743ZI 开发板上通过 STM32CubeMX 生成的代码似乎有一些问题。我想将其配置为在 LwIP/RAW API 上运行。我可以为它的近亲 NUCLEO F767ZI 开发板创建这样的配置。在后一种情况下,我采取以下步骤:


  • 将 HCLK 设置为 216 MHz(从 HSI 获取时钟);
  • 使能ETH外设,设置为RMII模式,将ETH_TXD0和ETH_TX_EN引脚分别设置为PG13和PG11(其他适当映射);
  • 在 ETH Configuration>General: Ethernet Configuration 中将 PHY 地址设置为 0
  • 启用 LwIP 中间件;
  • 启用 ICMP(在 LwIP Key Options>IPMP Options 中的 LWIP_BROADCAST_PING 和 LWIP_MULTICAST_PING)。此步骤不是必需的,但它有助于确定设备是否一切正常。

生成代码后,我将一个外部变量添加到我的 main.c 中,以便能够跟踪设备是否已获得 IP 地址:

  • /* USER CODE BEGIN PV */
  • /* Private variables ---------------------------------------------------------*/
  • extern struct netif gnetif;
  • /* USER CODE END PV */

此外,我在主循环中添加了标准的 LwIP/RAW IP 回调:


  • /* Infinite loop */
  • /* USER CODE BEGIN WHILE */
  • while (1)
  • {
  • /* USER CODE END WHILE */
  • /* USER CODE BEGIN 3 */
  • ethernetif_input(&gnetif);
  • sys_check_timeouts();
  • }
  • /* USER CODE END 3 */

此代码运行良好,我能够获得 IP 地址(我可以从 gnetif->ip_addr 字段确定它),我可以在 WireShark 中看到所有正确的 ARP 请求,并且我能够 ping 设备:


在此,我仅过滤来自/至适当 (STM32) MAC 地址 00:80:E1:00:00:00 的流量。

对于 NUCLEO-H7432ZI 板,我基本上遵循相同的步骤,但有一些小差异:

  • 将 HCLK 设置为 400 MHz(从 HSI 获取时钟);
  • 使能ETH外设,设置为RMII模式,将ETH_TXD0和ETH_TX_EN引脚分别设置为PG13和PG11(其他适当映射);
  • 启用 CPU DCache(在 Cortex_M7 配置下)
  • 启用 LWIP 中间件
  • 选择 LAN8742/LAN8742 作为 Driver_PHY(在 LwIP>Platform Settings 下)
  • 启用 ICMP(在 LwIP Key Options>IPMP Options 中的 LWIP_BROADCAST_PING 和 LWIP_MULTICAST_PING)。
对于 F7 示例,我适当地更改了 main.c 中的代码。此外,我编辑链接器文件以将 RAM 从 0x24000000 分区到 0x2407FFFF(在 ETH>Parameter Setting 中有一条指令这样做是为了让 ETH 外设工作)。
如果我将这个(几乎相同的)版本上传到 NUCLEAO-H743ZI 板,我将没有网络活动(没有 ARP 请求获取 IP 地址。
现在我知道问题出在 STM32CubeMX 生成的配置中。硬件本身是好的。STM32Cube_FW_H7_V1.1.0 中有一个 LwIP HTTP 服务器示例,如果我将其上传到威廉希尔官方网站 板,它就可以正常工作。STM32Cube_FW_H7_V1.1.0 中的 LwIP_HTTP_Server_Netconn_RTOS 示例有些不同:它使用 RTOS 和 Netconn API。对于我的应用程序,我想坚持使用 Raw API(而不是 RTOS)。所以我的问题是,我的微控制器配置中缺少什么?


回帖(1)

刘宇

2022-12-27 11:41:26
抱歉耽搁了。这些建议没有用,但现在我已经在不使用 RTOS 的情况下管理了它:

我更改为没有 RTOS(原始 API)的 LwiP TCP/IP 堆栈,因为这对我们有用。

使用 Raw API 效果很好,但如果触发了太多 Ajax 请求,也会出现一些崩溃
一次,LwIP 服务器不得不接收和发送过多的数据,没有任何空闲时间。

问题似乎是指令 - 缓存!数据缓存不是问题。

最后,我在模块“ethernetif.c”(LwIP Raw API)中做了以下更改:

static err_t low_level_output(struct netif *netif, struct pbuf *p)
{
SCB_DisableICache(); // 在函数开始时禁用指令缓存
为了 (....)
...
SCB_EnableICache(); // 在函数结束时启用指令缓存
返回错误;
}

静态结构 pbuf * low_level_input(struct netif *netif)
{
(HAL_ETH_IsRxDataAvailable(&heth))
{
   SCB_DisableICache(); // 如果成功,在函数开始时禁用指令缓存!
   ...

   SCB_EnableICache(); // 在函数结束时启用指令缓存
   返回 p;
}
别的
  {
   返回空值;
  }
}


我不使用主循环进行 Lwip-Process 轮询。

// 而 (1)
// {
// MX_LWIP_Process(); // 在 lwip.c 中,此函数调用:ethernetif.c 中的 ethernetif_input()
// }

我只是使用以太网 - Lwip-Process 的中断而不是包含在“stm32h7xx_it.c”中:

void ETH_IRQHandler(void)
{
uint32_t 休息;

{
    rest = ethernetif_input(&gnetif);                     
} 而(休息);

// -------------- 完成后清除标志 ----------------------
  __HAL_ETH_DMA_CLEAR_IT(&heth, ETH_DMACSR_RI | ETH_DMACSR_NIS);
  __HAL_ETH_DMA_CLEAR_IT(&heth, ETH_DMACSR_TI | ETH_DMACSR_NIS);
  __HAL_ETH_DMA_CLEAR_IT(&heth, (ETH_DMACSR_CDE | ETH_DMACSR_ETI | ETH_DMACSR_RWT |
                         ETH_DMACSR_RBU | ETH_DMACSR_AIS));
  __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG(ETH_WAKEUP_EXTI_LINE);
}

这给人一种更舒适的“RTOS”感觉,现在可以完美运行。
在主循环中可以执行其他操作。


举报

更多回帖

发帖
×
20
完善资料,
赚取积分