1. 程式人生 > >使用STM32CubeMX建立基於FreeRTOS的lwIP工程

使用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 */
}