使用STM32CubeMX创建基于FreeRTOS的lwIP工程

硬件平台:STM32F407VE+DP83848开发板
STM32CubeMX配置:

  1. 在Peripherals中ETH的模式选择RMII,在Middlewares中勾选FREERTOS和LWIP,见下图:
    在这里插入图片描述
  2. 依据硬件环境自行对时钟进行配置,此处略。在LWIP Configuration中对lwIP进行相应的配置,将LWIP_DHCP设为Disable,IP_ADDRESS设为192.168.1.7,NETMASK_ADDRESS设为255.255.255.0,GATEWAY_ADDRESS设为192.168.1.1,见下图:
    在这里插入图片描述
  3. 在FREERTOS Configuration中新建两个任务,myTaskLED用作控制LED灯的闪烁指示系统运行,myTaskTcpEcho用作TCP服务器,当接收到客户端发来的数据后,把接收到的数据原样返回。注意,myTaskTcpEcho的优先级需较低,以免堵塞其他任务的正常执行,在此Priority设为osPriorityLow,还有就是分配足够的空间以满足任务的执行,在此Stack Size设为1024。见下图:
    在这里插入图片描述
  4. 最后点击Generate Code生成工程,工程生成后需要将stm32f407xx.h中的宏定义__NVIC_PRIO_BITS由4U改为4,否则编译将会报错。
  5. 编译成功后将程序下载至开发板,开发板和电脑用网线直连,至此,在命令行中键入ping 192.168.1.7就可以测试开发板的以太网通讯连接是否正常。另外,参考LwIP TCP/IP stack demonstration for STM32F4x7 microcontrollers (AN3966)将开发板配置为TCP服务器,服务器IP为192.168.1.7,端口为7,当接收到客户端发来的数据后,把接收到的数据原样返回。测试效果,见下图:
    在这里插入图片描述
    通过将AN3966配套的例程代码添加至taskTcpEcho中即可实现上述功能,代码如下:
void taskTcpEcho(void const * argument)
{
  /* USER CODE BEGIN taskTcpEcho */
  struct netconn *conn, *newconn;
  err_t err, accept_err;
  struct netbuf *buf;
  void *data;
  u16_t len;
  err_t recv_err;

  LWIP_UNUSED_ARG(argument);

  /* Create a new connection identifier. */
  conn = netconn_new(NETCONN_TCP);

  if (conn!=NULL)
  {  
    /* Bind connection to well known port number 7. */
    err = netconn_bind(conn, NULL, 7);

    if (err == ERR_OK)
    {
      /* Tell connection to go into listening mode. */
      netconn_listen(conn);

      while (1) 
      {
        /* Grab new connection. */
        accept_err = netconn_accept(conn, &newconn);

        /* Process the new connection. */
        if (accept_err == ERR_OK) 
        {
          recv_err = netconn_recv(newconn, &buf);
          while ( recv_err == ERR_OK) 
          {
            do
            {
              netbuf_data(buf, &data, &len);
              netconn_write(newconn, data, len, NETCONN_COPY);
            }
            while (netbuf_next(buf) >= 0);

            netbuf_delete(buf);
            recv_err = netconn_recv(newconn, &buf);
          }

          /* Close connection and discard connection identifier. */
          netconn_close(newconn);
          netconn_delete(newconn);
        }
      }
    }
    else
    {
      netconn_delete(newconn);
      printf(" can not bind TCP netconn");
    }
  }
  else
  {
    printf("can not create TCP netconn");
  }
  /* USER CODE END taskTcpEcho */
}

最后,本文所述的工程已作为资源上传,点此下载

以下是一个基于STM32Cube HAL库的Modbus TCP程序实例: ```c #include "main.h" #include "lwip.h" #include "lwip/api.h" #include "lwip/tcp.h" #include "mbtcp.h" void modbus_tcp_task(void *arg) { struct netconn *conn, *newconn; struct netbuf *buf; uint8_t recv_data[MBTCP_MAX_PDU_LEN]; uint16_t len, pdu_len, err; /* Create a new connection identifier. */ conn = netconn_new(NETCONN_TCP); if (conn != NULL) { /* Bind to port 502 */ netconn_bind(conn, NULL, MBTCP_PORT); /* Put the connection into LISTEN state. */ netconn_listen(conn); while (1) { /* Wait for a new connection. */ err = netconn_accept(conn, &newconn); if (err == ERR_OK) { while ((err = netconn_recv(newconn, &buf)) == ERR_OK) { /* Process Modbus TCP PDU */ netbuf_copy(buf, recv_data, netbuf_len(buf)); pdu_len = mbtcp_process_pdu(recv_data, netbuf_len(buf)); /* Send response */ if (pdu_len > 0) { err = netconn_write(newconn, recv_data, pdu_len, NETCONN_COPY); } /* Deallocate memory */ netbuf_delete(buf); } /* Close connection */ netconn_close(newconn); /* Delete connection */ netconn_delete(newconn); } } } } int main(void) { /* Initialize lwIP stack */ MX_LWIP_Init(); /* Initialize Modbus TCP */ mbtcp_init(); /* Create Modbus TCP task */ osThreadDef(modbus_tcp, modbus_tcp_task, osPriorityNormal, 0, configMINIMAL_STACK_SIZE * 2); osThreadCreate(osThread(modbus_tcp), NULL); while (1) { } } ``` 上述代码使用lwIP网络栈实现了一个Modbus TCP服务器,并使用了一个名为`mbtcp_process_pdu()`的函数来处理Modbus TCP PDU。具体实现和`mbtcp_init()`函数实现可以参考Modbus TCP库的文档。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值