{"id":123681,"date":"2026-11-08T01:40:46","date_gmt":"2026-11-07T17:40:46","guid":{"rendered":"https:\/\/www.wsisp.com\/helps\/123681.html"},"modified":"2026-11-08T01:40:46","modified_gmt":"2026-11-07T17:40:46","slug":"freertos-stm32-lwip-%e8%b6%85%e6%97%b6%e7%bd%91%e7%bb%9c-i-o-%e5%ae%8c%e6%95%b4%e7%a4%ba%e4%be%8b","status":"publish","type":"post","link":"https:\/\/www.wsisp.com\/helps\/123681.html","title":{"rendered":"FreeRTOS + STM32 + LwIP \u8d85\u65f6\u7f51\u7edc I\/O \u5b8c\u6574\u793a\u4f8b"},"content":{"rendered":"<p>        \/* MD \/ \u5bcc\u6587\u672c\u4e2d\u7684 .toc\uff08\u542b\u535a\u5ba2\u56ed\u642c\u5bb6\u7b49\u5d4c\u5957\u7ed3\u6784\uff09\uff1b.toc-box \u5728\u4fa7\u680f\uff0c\u4e0d\u53d7\u5f71\u54cd *\/<br \/>\n        #content_views .toc,<br \/>\n        \/* \u7f16\u8f91\u5668\u5e38\u5728\u76ee\u5f55\u524d\u540e\u63d2\u5165\u7a7a p\uff08:empty \u4ecd\u5360 20px\uff09\uff0c\u4e00\u5e76\u53bb\u6389\u907f\u514d\u9876\u7a7a\u9699 *\/<br \/>\n        #content_views.markdown_views &gt; p:empty:has(+ .toc),<br \/>\n        #content_views.markdown_views &gt; .toc + p:empty,<br \/>\n        \/* \u5bcc\u6587\u672c\u65e7\u7248\u76ee\u5f55\u6807\u8bb0 *\/<br \/>\n        #content_views.htmledit_views #main-toc,<br \/>\n        #content_views.htmledit_views #hr-toc,<br \/>\n        #content_views.htmledit_views p[id*=\\&#8221;-toc\\&#8221;] {<br \/>\n          display: none !important;<br \/>\n        }<br \/>\n        \/* \u76ee\u5f55\u53bb\u6389\u540e\uff0c\u7d27\u8ddf\u7684\u9996\u4e2a\u6807\u9898\u4e0d\u518d\u591a\u51fa\u4e00\u5757\u4e0a\u8fb9\u8ddd *\/<br \/>\n        #content_views.markdown_views &gt; .toc + h1,<br \/>\n        #content_views.markdown_views &gt; .toc + h2,<br \/>\n        #content_views.markdown_views &gt; .toc + h3,<br \/>\n        #content_views.markdown_views &gt; .toc + h4,<br \/>\n        #content_views.markdown_views &gt; .toc + p:empty + h1,<br \/>\n        #content_views.markdown_views &gt; .toc + p:empty + h2,<br \/>\n        #content_views.markdown_views &gt; .toc + p:empty + h3,<br \/>\n        #content_views.markdown_views &gt; .toc + p:empty + h4 {<br \/>\n          margin-top: 0 !important;<br \/>\n        }<\/p>\n<p>\u4e0b\u9762\u662f\u4e00\u4e2a\u5b8c\u6574\u7684\u3001\u53ef\u76f4\u63a5\u53c2\u8003\u79fb\u690d\u7684\u5b9e\u73b0\u3002\u6838\u5fc3\u601d\u8def&#xff1a;LwIP socket \u9ed8\u8ba4\u662f\u963b\u585e\u7684&#xff0c;\u914d\u5408\u00a0SO_RCVTIMEO\/SO_SNDTIMEO\u00a0\u6216\u975e\u963b\u585e &#043;\u00a0select\/poll\u00a0\u5b9e\u73b0\u8d85\u65f6\u3002\u8fd9\u91cc\u7ed9\u51fa\u57fa\u4e8e\u00a0select()\u00a0\u7684\u53ef\u79fb\u690d\u65b9\u6848&#xff08;LwIP \u652f\u6301\u00a0select&#xff09;&#xff0c;\u5e76\u5904\u7406\u00a0EINTR\u3001\u90e8\u5206\u6536\u53d1\u7b49\u8fb9\u754c\u3002<\/p>\n<hr \/>\n<h3>1. \u5934\u6587\u4ef6\u4e0e\u914d\u7f6e<\/h3>\n<p>\/* net_io_task.h *\/<br \/>\n#ifndef NET_IO_TASK_H<br \/>\n#define NET_IO_TASK_H<\/p>\n<p>#include &#034;FreeRTOS.h&#034;<br \/>\n#include &#034;task.h&#034;<br \/>\n#include &#034;lwip\/sockets.h&#034;<br \/>\n#include &#034;lwip\/inet.h&#034;<br \/>\n#include &#034;lwip\/errno.h&#034;<\/p>\n<p>\/* \u4efb\u52a1\u914d\u7f6e *\/<br \/>\n#define NET_TASK_STACK_SIZE      (512 * 4)      \/* \u5b57\u8282&#xff0c;\u89c6 LwIP \u914d\u7f6e\u653e\u5927 *\/<br \/>\n#define NET_TASK_PRIO            (tskIDLE_PRIORITY &#043; 3)<br \/>\n#define NET_SERVER_PORT          8080<br \/>\n#define NET_CONNECT_TIMEOUT_MS   5000<br \/>\n#define NET_RECV_TIMEOUT_MS      3000<br \/>\n#define NET_SEND_TIMEOUT_MS      3000<br \/>\n#define NET_RECV_BUF_LEN         512<\/p>\n<p>void net_io_task(void *arg);<\/p>\n<p>#endif<\/p>\n<hr \/>\n<h3>2. \u6838\u5fc3\u5de5\u5177\u51fd\u6570&#xff1a;\u5e26\u8d85\u65f6\u7684 send \/ recv<\/h3>\n<p>\/* net_io_util.c *\/<br \/>\n#include &#034;net_io_task.h&#034;<br \/>\n#include &lt;string.h&gt;<\/p>\n<p>\/* \u8fd4\u56de &gt;&#061;0: \u5b9e\u9645\u53d1\u9001\u5b57\u8282\u6570; -1: \u9519\u8bef(\u542b\u8d85\u65f6) *\/<br \/>\nstatic int sock_send_timeout(int s, const void *buf, size_t len, uint32_t timeout_ms)<br \/>\n{<br \/>\n    const uint8_t *p   &#061; (const uint8_t *)buf;<br \/>\n    size_t         sent &#061; 0;<br \/>\n    uint32_t       start &#061; xTaskGetTickCount();<\/p>\n<p>    while (sent &lt; len) {<br \/>\n        fd_set wfds;<br \/>\n        FD_ZERO(&amp;wfds);<br \/>\n        FD_SET(s, &amp;wfds);<\/p>\n<p>        \/* \u8ba1\u7b97\u5269\u4f59\u65f6\u95f4 *\/<br \/>\n        uint32_t elapsed &#061; (xTaskGetTickCount() &#8211; start) * portTICK_PERIOD_MS;<br \/>\n        if (elapsed &gt;&#061; timeout_ms) {<br \/>\n            errno &#061; EWOULDBLOCK;<br \/>\n            return -1;<br \/>\n        }<br \/>\n        struct timeval tv;<br \/>\n        uint32_t remain_ms &#061; timeout_ms &#8211; elapsed;<br \/>\n        tv.tv_sec  &#061; remain_ms \/ 1000;<br \/>\n        tv.tv_usec &#061; (remain_ms % 1000) * 1000;<\/p>\n<p>        int rc &#061; lwip_select(s &#043; 1, NULL, &amp;wfds, NULL, &amp;tv);<br \/>\n        if (rc &lt; 0) {<br \/>\n            if (errno &#061;&#061; EINTR) continue;       \/* \u88ab\u4fe1\u53f7\/\u5176\u5b83\u4e2d\u65ad\u6253\u65ad&#xff0c;\u91cd\u8bd5 *\/<br \/>\n            return -1;<br \/>\n        }<br \/>\n        if (rc &#061;&#061; 0) {                          \/* \u8d85\u65f6 *\/<br \/>\n            errno &#061; EWOULDBLOCK;<br \/>\n            return -1;<br \/>\n        }<\/p>\n<p>        ssize_t n &#061; lwip_send(s, p &#043; sent, len &#8211; sent, 0 \/* \u6216 MSG_DONTWAIT *\/);<br \/>\n        if (n &lt; 0) {<br \/>\n            if (errno &#061;&#061; EINTR)  continue;<br \/>\n            if (errno &#061;&#061; EWOULDBLOCK || errno &#061;&#061; EAGAIN) continue; \/* \u518d\u7b49 *\/<br \/>\n            return -1;<br \/>\n        }<br \/>\n        sent &#043;&#061; (size_t)n;<br \/>\n    }<br \/>\n    return (int)sent;<br \/>\n}<\/p>\n<p>\/* \u8fd4\u56de &gt;0: \u6536\u5230\u5b57\u8282\u6570; 0: \u5bf9\u7aef\u5173\u95ed; -1: \u9519\u8bef(\u542b\u8d85\u65f6) *\/<br \/>\nstatic int sock_recv_timeout(int s, void *buf, size_t len, uint32_t timeout_ms)<br \/>\n{<br \/>\n    uint32_t start &#061; xTaskGetTickCount();<\/p>\n<p>    for (;;) {<br \/>\n        fd_set rfds;<br \/>\n        FD_ZERO(&amp;rfds);<br \/>\n        FD_SET(s, &amp;rfds);<\/p>\n<p>        uint32_t elapsed &#061; (xTaskGetTickCount() &#8211; start) * portTICK_PERIOD_MS;<br \/>\n        if (elapsed &gt;&#061; timeout_ms) { errno &#061; EWOULDBLOCK; return -1; }<\/p>\n<p>        struct timeval tv;<br \/>\n        uint32_t remain_ms &#061; timeout_ms &#8211; elapsed;<br \/>\n        tv.tv_sec  &#061; remain_ms \/ 1000;<br \/>\n        tv.tv_usec &#061; (remain_ms % 1000) * 1000;<\/p>\n<p>        int rc &#061; lwip_select(s &#043; 1, &amp;rfds, NULL, NULL, &amp;tv);<br \/>\n        if (rc &lt; 0) {<br \/>\n            if (errno &#061;&#061; EINTR) continue;<br \/>\n            return -1;<br \/>\n        }<br \/>\n        if (rc &#061;&#061; 0) { errno &#061; EWOULDBLOCK; return -1; }<\/p>\n<p>        ssize_t n &#061; lwip_recv(s, buf, len, 0);<br \/>\n        if (n &lt; 0) {<br \/>\n            if (errno &#061;&#061; EINTR || errno &#061;&#061; EWOULDBLOCK || errno &#061;&#061; EAGAIN)<br \/>\n                continue;<br \/>\n            return -1;<br \/>\n        }<br \/>\n        return (int)n;   \/* n&#061;&#061;0 \u8868\u793a\u5bf9\u7aef\u5173\u95ed *\/<br \/>\n    }<br \/>\n}<\/p>\n<p>\u4e3a\u4ec0\u4e48\u8981\u7528\u00a0select\u00a0\u800c\u4e0d\u662f\u5355\u7eaf\u00a0SO_RCVTIMEO&#xff1f;<br \/>\nLwIP \u7684\u00a0SO_RCVTIMEO\/SO_SNDTIMEO\u00a0\u5728\u4e0d\u540c\u79fb\u690d\u7248\u672c\u91cc\u884c\u4e3a\u4e0d\u5b8c\u5168\u4e00\u81f4&#xff08;\u90e8\u5206\u7248\u672c\u00a0setsockopt\u00a0\u540e\u4ec5\u5bf9\u540e\u7eed\u8c03\u7528\u751f\u6548\u3001\u4e14\u4e0d\u540c lwipopts \u4e0b\u652f\u6301\u4e0d\u540c&#xff09;\u3002select\u00a0\u662f LwIP \u6807\u51c6\u652f\u6301\u3001\u884c\u4e3a\u6700\u7a33\u7684\u8def\u5f84&#xff0c;\u4e14\u80fd\u540c\u65f6\u7edf\u4e00\u7ba1\u7406\u6536\u53d1\u8d85\u65f6\u3002\u82e5\u4f60\u7684 LwIP \u7248\u672c\u00a0SO_RCVTIMEO\u00a0\u5b8c\u6574\u53ef\u7528&#xff0c;\u4e5f\u53ef\u7528&#xff0c;\u89c1\u6587\u672b\u8bf4\u660e\u3002<\/p>\n<hr \/>\n<h3>3. \u5e26\u8d85\u65f6\u7684 connect<\/h3>\n<p>\/* \u8fd4\u56de 0 \u6210\u529f, -1 \u5931\u8d25\/\u8d85\u65f6 *\/<br \/>\nstatic int sock_connect_timeout(const char *ip, uint16_t port, uint32_t timeout_ms)<br \/>\n{<br \/>\n    int s &#061; lwip_socket(AF_INET, SOCK_STREAM, 0);<br \/>\n    if (s &lt; 0) return -1;<\/p>\n<p>    \/* \u5148\u8bbe\u4e3a\u975e\u963b\u585e\u4ee5\u652f\u6301 connect \u8d85\u65f6 *\/<br \/>\n    int flags &#061; lwip_fcntl(s, F_GETFL, 0);<br \/>\n    lwip_fcntl(s, F_SETFL, flags | O_NONBLOCK);<\/p>\n<p>    struct sockaddr_in addr;<br \/>\n    memset(&amp;addr, 0, sizeof(addr));<br \/>\n    addr.sin_family      &#061; AF_INET;<br \/>\n    addr.sin_port        &#061; htons(port);<br \/>\n    addr.sin_addr.s_addr &#061; inet_addr(ip);<\/p>\n<p>    int rc &#061; lwip_connect(s, (struct sockaddr *)&amp;addr, sizeof(addr));<br \/>\n    if (rc &lt; 0 &amp;&amp; errno !&#061; EINPROGRESS) {<br \/>\n        lwip_close(s);<br \/>\n        return -1;<br \/>\n    }<\/p>\n<p>    if (rc &lt; 0) { \/* EINPROGRESS: \u7b49\u5f85\u53ef\u5199 *\/<br \/>\n        fd_set wfds, efds;<br \/>\n        FD_ZERO(&amp;wfds); FD_ZERO(&amp;efds);<br \/>\n        FD_SET(s, &amp;wfds); FD_SET(s, &amp;efds);<\/p>\n<p>        struct timeval tv;<br \/>\n        tv.tv_sec  &#061; timeout_ms \/ 1000;<br \/>\n        tv.tv_usec &#061; (timeout_ms % 1000) * 1000;<\/p>\n<p>        rc &#061; lwip_select(s &#043; 1, NULL, &amp;wfds, &amp;efds, &amp;tv);<br \/>\n        if (rc &lt;&#061; 0) {                 \/* \u8d85\u65f6\u6216\u9519\u8bef *\/<br \/>\n            lwip_close(s);<br \/>\n            return -1;<br \/>\n        }<br \/>\n        \/* \u68c0\u67e5 connect \u662f\u5426\u771f\u7684\u6210\u529f *\/<br \/>\n        int soerr &#061; 0;<br \/>\n        socklen_t slen &#061; sizeof(soerr);<br \/>\n        lwip_getsockopt(s, SOL_SOCKET, SO_ERROR, &amp;soerr, &amp;slen);<br \/>\n        if (soerr !&#061; 0) {<br \/>\n            lwip_close(s);<br \/>\n            return -1;<br \/>\n        }<br \/>\n    }<\/p>\n<p>    \/* \u6062\u590d\u963b\u585e\u6a21\u5f0f&#xff0c;\u4fbf\u4e8e\u540e\u7eed recv\/send \u8bed\u4e49\u6e05\u6670 *\/<br \/>\n    lwip_fcntl(s, F_SETFL, flags);<br \/>\n    return s;<br \/>\n}<\/p>\n<hr \/>\n<h3>4. \u5b8c\u6574\u4efb\u52a1\u793a\u4f8b<\/h3>\n<p>\/* net_io_task.c *\/<br \/>\n#include &#034;net_io_task.h&#034;<br \/>\n#include &lt;string.h&gt;<br \/>\n#include &lt;stdio.h&gt;<\/p>\n<p>static const char *kServerIP &#061; &#034;192.168.1.100&#034;;<\/p>\n<p>void net_io_task(void *arg)<br \/>\n{<br \/>\n    (void)arg;<br \/>\n    uint8_t rxbuf[NET_RECV_BUF_LEN];<\/p>\n<p>    for (;;) {<br \/>\n        \/* &#8212;- 1. \u5efa\u8fde&#xff08;\u5e26\u8d85\u65f6&#xff09; &#8212;- *\/<br \/>\n        int s &#061; sock_connect_timeout(kServerIP, NET_SERVER_PORT, NET_CONNECT_TIMEOUT_MS);<br \/>\n        if (s &lt; 0) {<br \/>\n            printf(&#034;[NET] connect failed\/timeout, retry in 2s\\\\r\\\\n&#034;);<br \/>\n            vTaskDelay(pdMS_TO_TICKS(2000));<br \/>\n            continue;<br \/>\n        }<br \/>\n        printf(&#034;[NET] connected\\\\r\\\\n&#034;);<\/p>\n<p>        \/* &#8212;- 2. \u53d1\u9001\u8bf7\u6c42&#xff08;\u5e26\u8d85\u65f6&#xff09; &#8212;- *\/<br \/>\n        const char *req &#061; &#034;GET \/status HTTP\/1.0\\\\r\\\\nHost: dev\\\\r\\\\n\\\\r\\\\n&#034;;<br \/>\n        if (sock_send_timeout(s, req, strlen(req), NET_SEND_TIMEOUT_MS) &lt; 0) {<br \/>\n            printf(&#034;[NET] send timeout\/err, close\\\\r\\\\n&#034;);<br \/>\n            lwip_close(s);<br \/>\n            vTaskDelay(pdMS_TO_TICKS(1000));<br \/>\n            continue;<br \/>\n        }<\/p>\n<p>        \/* &#8212;- 3. \u63a5\u6536\u54cd\u5e94&#xff08;\u5e26\u8d85\u65f6&#xff0c;\u5faa\u73af\u6536\u76f4\u5230\u5bf9\u7aef\u5173\u95ed\u6216\u8d85\u65f6&#xff09; &#8212;- *\/<br \/>\n        int total &#061; 0;<br \/>\n        for (;;) {<br \/>\n            int n &#061; sock_recv_timeout(s, rxbuf, sizeof(rxbuf), NET_RECV_TIMEOUT_MS);<br \/>\n            if (n &gt; 0) {<br \/>\n                \/* \u5904\u7406\u6570\u636e&#xff1a;\u6b64\u5904\u4ec5\u6253\u5370\u957f\u5ea6&#xff0c;\u5b9e\u9645\u53ef\u89e3\u6790\/\u5165\u961f *\/<br \/>\n                total &#043;&#061; n;<br \/>\n                \/* fwrite \/ \u89e3\u6790 &#8230; *\/<br \/>\n            } else if (n &#061;&#061; 0) {<br \/>\n                printf(&#034;[NET] peer closed, total&#061;%d\\\\r\\\\n&#034;, total);<br \/>\n                break;                       \/* \u5bf9\u7aef\u5173\u95ed&#xff0c;\u6b63\u5e38\u7ed3\u675f *\/<br \/>\n            } else {<br \/>\n                if (errno &#061;&#061; EWOULDBLOCK)<br \/>\n                    printf(&#034;[NET] recv timeout, total&#061;%d\\\\r\\\\n&#034;, total);<br \/>\n                else<br \/>\n                    printf(&#034;[NET] recv error\\\\r\\\\n&#034;);<br \/>\n                break;                       \/* \u8d85\u65f6\u6216\u9519\u8bef&#xff0c;\u7ed3\u675f\u672c\u6b21\u4f1a\u8bdd *\/<br \/>\n            }<br \/>\n        }<\/p>\n<p>        \/* &#8212;- 4. \u5173\u95ed\u5e76\u5ef6\u65f6\u91cd\u8fde &#8212;- *\/<br \/>\n        lwip_close(s);<br \/>\n        vTaskDelay(pdMS_TO_TICKS(3000));<br \/>\n    }<br \/>\n}<\/p>\n<hr \/>\n<h3>5. \u521b\u5efa\u4efb\u52a1&#xff08;main \u6216\u521d\u59cb\u5316\u5904&#xff09;<\/h3>\n<p>#include &#034;net_io_task.h&#034;<\/p>\n<p>void app_start(void)<br \/>\n{<br \/>\n    \/* \u524d\u7f6e&#xff1a;\u7f51\u5361\u5df2 up&#xff0c;DHCP \u5b8c\u6210\u6216\u9759\u6001 IP \u5df2\u8bbe\u7f6e&#xff0c;LwIP \u5df2\u521d\u59cb\u5316 *\/<br \/>\n    xTaskCreate(net_io_task,<br \/>\n                &#034;net_io&#034;,<br \/>\n                NET_TASK_STACK_SIZE \/ sizeof(StackType_t),  \/* FreeRTOS \u7528 word *\/<br \/>\n                NULL,<br \/>\n                NET_TASK_PRIO,<br \/>\n                NULL);<br \/>\n}<\/p>\n<p>\u6ce8\u610f&#xff1a;xTaskCreate\u00a0\u7684\u6808\u5927\u5c0f\u5728\u591a\u6570 FreeRTOS \u79fb\u690d\u91cc\u4ee5\u00a0word&#xff08;4 \u5b57\u8282&#xff09;\u00a0\u4e3a\u5355\u4f4d&#xff1b;\u4e0a\u9762\u00a0NET_TASK_STACK_SIZE\u00a0\u6211\u6309\u5b57\u8282\u7ed9\u4e86\u5b8f&#xff0c;\u521b\u5efa\u65f6\u9664\u4ee5\u00a0sizeof(StackType_t)\u3002\u82e5\u4f60\u76f4\u63a5\u4e60\u60ef\u7528 word \u6570&#xff0c;\u628a\u5b8f\u6539\u6210 word \u6570\u5e76\u53bb\u6389\u9664\u6cd5\u5373\u53ef\u3002<\/p>\n<hr \/>\n<h3>6.\u00a0lwipopts.h\u00a0\u5173\u952e\u914d\u7f6e<\/h3>\n<p>\/* lwipopts.h \u7247\u6bb5 \u2014\u2014 \u5fc5\u987b\u786e\u4fdd select \u4e0e socket \u76f8\u5173\u5f00\u542f *\/<br \/>\n#define LWIP_SOCKET                 1<br \/>\n#define LWIP_NETCONN                1<br \/>\n#define LWIP_SO_RCVTIMEO            1   \/* \u82e5\u60f3\u7528 SO_RCVTIMEO \u65b9\u5f0f *\/<br \/>\n#define LWIP_SO_SNDTIMEO            1<br \/>\n#define LWIP_SO_RCVBUF              1<br \/>\n#define LWIP_SELECT                 1   \/* LwIP 1.4&#043; \u5185\u90e8\u7531 LWIP_SOCKET \u63d0\u4f9b *\/<\/p>\n<p>#define MEMP_NUM_NETCONN            8   \/* \u6bcf socket \u5360\u4e00\u4e2a netconn *\/<br \/>\n#define MEMP_NUM_NETBUF             16<br \/>\n#define MEMP_NUM_TCP_SEG            32<br \/>\n#define TCP_SND_BUF                 (4 * TCP_MSS)<br \/>\n#define TCP_WND                     (4 * TCP_MSS)<\/p>\n<p>\/* \u82e5\u7528 select&#xff0c;\u786e\u4fdd\u4ee5\u4e0b\u5f00\u542f&#xff08;\u90e8\u5206\u7248\u672c&#xff09; *\/<br \/>\n#define LWIP_TIMEVAL_PRIVATE        0   \/* \u7528\u7cfb\u7edf\u7684 struct timeval&#xff0c;\u6216 1 \u7528 LwIP \u81ea\u5e26 *\/<\/p>\n<hr \/>\n<h3>7. \u8fb9\u754c\u4e0e\u5e38\u89c1\u5751&#xff08;\u52a1\u5fc5\u770b&#xff09;<\/h3>\n<table>\n<tr>\u573a\u666f\u5904\u7406<\/tr>\n<tbody>\n<tr>\n<td>select\u00a0\u8fd4\u56de\u503c<\/td>\n<td>0&#061;\u8d85\u65f6&#xff0c;&gt;0&#061;\u5c31\u7eea\u6570&#xff0c;&lt;0&#061;\u9519\u8bef\u3002\u8d85\u65f6\u8981\u663e\u5f0f\u5224\u5b9a&#xff0c;\u4e0d\u80fd\u5f53\u9519\u8bef\u4e00\u5f8b\u5173\u95ed<\/td>\n<\/tr>\n<tr>\n<td>EINTR<\/td>\n<td>FreeRTOS \u4e0b LwIP\u00a0select\u00a0\u4e00\u822c\u4e0d\u4f1a\u8fd4\u56de EINTR&#xff08;\u65e0\u4fe1\u53f7\u673a\u5236&#xff09;&#xff0c;\u4f46\u4fdd\u7559\u91cd\u8bd5\u903b\u8f91\u65e0\u5bb3&#xff1b;EWOULDBLOCK\/EAGAIN\u00a0\u5fc5\u987b\u91cd\u8bd5\u800c\u975e\u76f4\u63a5\u5931\u8d25<\/td>\n<\/tr>\n<tr>\n<td>\u90e8\u5206\u6536\u53d1<\/td>\n<td>TCP \u662f\u5b57\u8282\u6d41&#xff0c;send\u00a0\u53ef\u80fd\u53ea\u53d1\u4e00\u90e8\u5206\u3001recv\u00a0\u53ef\u80fd\u5c11\u4e8e\u8bf7\u6c42\u957f\u5ea6&#xff0c;\u5fc5\u987b\u7528\u5faa\u73af\u7d2f\u8ba1&#xff08;\u4e0a\u9762\u5df2\u5904\u7406&#xff09;<\/td>\n<\/tr>\n<tr>\n<td>recv\u00a0\u8fd4\u56de 0<\/td>\n<td>\u8868\u793a\u5bf9\u7aef\u6709\u5e8f\u5173\u95ed&#xff0c;\u662f\u6b63\u5e38\u7ec8\u6b62&#xff0c;\u4e0d\u662f\u9519\u8bef<\/td>\n<\/tr>\n<tr>\n<td>connect \u8d85\u65f6<\/td>\n<td>\u5fc5\u987b\u7528\u975e\u963b\u585e &#043;\u00a0select\u00a0&#043;\u00a0SO_ERROR\u00a0\u68c0\u67e5&#xff0c;\u5426\u5219\u00a0connect\u00a0\u53ef\u80fd\u957f\u65f6\u95f4\u963b\u585e\u4efb\u52a1<\/td>\n<\/tr>\n<tr>\n<td>\u4efb\u52a1\u4f18\u5148\u7ea7<\/td>\n<td>\u7f51\u7edc\u4efb\u52a1\u4f18\u5148\u7ea7\u4e0d\u8981\u9ad8\u4e8e LwIP \u7684\u00a0tcpip_thread&#xff08;\u901a\u5e38\u00a0LWIP_TCPIP_CORE_LOCKING\u00a0\u6216\u72ec\u7acb\u7ebf\u7a0b&#xff0c;\u4e00\u822c\u4e3a\u4e2d\u9ad8\u4f18\u5148\u7ea7&#xff09;&#xff1b;\u8fc7\u4f4e\u53ef\u80fd\u997f\u6b7b<\/td>\n<\/tr>\n<tr>\n<td>\u6808\u5927\u5c0f<\/td>\n<td>LwIP &#043; \u5b57\u7b26\u4e32\u5904\u7406 &#043; printf \u5f88\u5403\u6808&#xff0c;\u5efa\u8bae \u2265 2 KB&#xff0c;\u542b printf \u65f6\u66f4\u5927<\/td>\n<\/tr>\n<tr>\n<td>printf\u00a0\u963b\u585e<\/td>\n<td>\u82e5\u5e95\u5c42 UART \u963b\u585e&#xff0c;\u957f\u65f6\u95f4\u6253\u5370\u4f1a\u5f71\u54cd\u8d85\u65f6\u7cbe\u5ea6&#xff1b;\u91cf\u4ea7\u5efa\u8bae\u7528 RTT\/\u961f\u5217<\/td>\n<\/tr>\n<tr>\n<td>\u8d85\u65f6\u7cbe\u5ea6<\/td>\n<td>\u57fa\u4e8e\u00a0xTaskGetTickCount()&#xff0c;\u53d7\u00a0configTICK_RATE_HZ\u00a0\u9650\u5236&#xff1b;1 ms tick \u4e0b\u6beb\u79d2\u7ea7\u8db3\u591f&#xff0c;\u82e5\u8981\u6c42\u66f4\u7cbe\u786e\u7528\u00a0xTaskGetTickCountFromISR\/\u9ad8\u7cbe\u5ea6\u5b9a\u65f6\u5668<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<hr \/>\n<h3>8. \u5907\u9009\u65b9\u6848&#xff1a;\u76f4\u63a5\u7528\u00a0SO_RCVTIMEO \/ SO_SNDTIMEO<\/h3>\n<p>\u82e5\u4f60\u7684 LwIP \u7248\u672c\u5b8c\u6574\u652f\u6301\u8fd9\u4e24\u4e2a\u9009\u9879&#xff08;LWIP_SO_RCVTIMEO&#061;1,\u00a0LWIP_SO_SNDTIMEO&#061;1&#xff09;&#xff0c;\u4ee3\u7801\u53ef\u66f4\u77ed&#xff1a;<\/p>\n<p>struct timeval tv &#061; { .tv_sec &#061; NET_RECV_TIMEOUT_MS \/ 1000,<br \/>\n                      .tv_usec &#061; (NET_RECV_TIMEOUT_MS % 1000) * 1000 };<br \/>\nlwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &amp;tv, sizeof(tv));<\/p>\n<p>ssize_t n &#061; lwip_recv(s, buf, len, 0);<br \/>\nif (n &lt; 0 &amp;&amp; (errno &#061;&#061; EWOULDBLOCK || errno &#061;&#061; EAGAIN)) {<br \/>\n    \/* \u8d85\u65f6 *\/<br \/>\n}<\/p>\n<p>\u6743\u8861&#xff1a;SO_*TIMEO\u00a0\u7b80\u6d01&#xff0c;\u4f46\u90e8\u5206 LwIP \u79fb\u690d\u7248\u672c\u5bf9\u00a0send\u00a0\u8d85\u65f6\u4e0d\u652f\u6301\u6216\u8bed\u4e49\u4e0d\u4e00\u81f4&#xff1b;select\u00a0\u65b9\u6848\u8de8\u7248\u672c\u6700\u7a33&#xff0c;\u4e14\u80fd\u7edf\u4e00\u7ba1\u7406\u591a socket\u3002\u91cf\u4ea7\/\u591a\u8fde\u63a5\u5efa\u8bae\u7528\u00a0select\u00a0\u65b9\u6848\u3002<\/p>\n<hr \/>\n<h3>9. \u6d41\u7a0b\u603b\u7ed3<\/h3>\n<p>text<\/p>\n<p>connect(\u975e\u963b\u585e) \u2192 select \u7b49\u53ef\u5199(\u8d85\u65f6) \u2192 SO_ERROR \u6821\u9a8c<br \/>\n    \u2502<br \/>\nsend(\u5faa\u73af) \u2192 select \u7b49\u53ef\u5199(\u6bcf\u8f6e\u91cd\u65b0\u7b97\u5269\u4f59\u8d85\u65f6) \u2192 \u7d2f\u8ba1\u5b57\u8282<br \/>\n    \u2502<br \/>\nrecv(\u5faa\u73af) \u2192 select \u7b49\u53ef\u8bfb(\u8d85\u65f6) \u2192 n&gt;0 \u5904\u7406 \/ n&#061;&#061;0 \u5173\u95ed \/ n&lt;0 \u8d85\u65f6\u6216\u9519\u8bef<br \/>\n    \u2502<br \/>\nclose \u2192 \u5ef6\u65f6 \u2192 \u91cd\u8fde<\/p>\n<p>\u6574\u4e2a\u4efb\u52a1\u5185\u90e8\u6ca1\u6709\u4efb\u4f55\u65e0\u9650\u963b\u585e\u8c03\u7528&#xff0c;\u6bcf\u4e2a\u7f51\u7edc\u64cd\u4f5c\u90fd\u6709\u660e\u786e\u4e0a\u9650&#xff0c;\u6ee1\u8db3\u5b9e\u65f6\u7cfb\u7edf\u5bf9\u4efb\u52a1\u54cd\u5e94\u6027\u7684\u8981\u6c42\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\/* MD \/ \u5bcc\u6587\u672c\u4e2d\u7684 .toc\uff08\u542b\u535a\u5ba2\u56ed\u642c\u5bb6\u7b49\u5d4c\u5957\u7ed3\u6784\uff09\uff1b.toc-box \u5728\u4fa7\u680f\uff0c\u4e0d\u53d7\u5f71\u54cd *\/#content_views .toc,\/* \u7f16\u8f91\u5668\u5e38\u5728\u76ee\u5f55\u524d\u540e\u63d2\u5165\u7a7a p\uff08:empty \u4ecd\u5360 20px\uff09\uff0c\u4e00\u5e76\u53bb\u6389\u907f\u514d\u9876\u7a7a\u9699 *\/#content_views.markdown_views &gt; p:empty:has(+ .toc),#content_views.markdown_views &gt; .toc + p:empty,\/* \u5bcc\u6587\u672c\u65e7\u7248\u76ee\u5f55\u6807\u8bb0 *\/#content<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[217,270],"topic":[],"class_list":["post-123681","post","type-post","status-publish","format-standard","hentry","category-server","tag-stm32","tag-270"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v20.3 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>FreeRTOS + STM32 + LwIP \u8d85\u65f6\u7f51\u7edc I\/O \u5b8c\u6574\u793a\u4f8b - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.wsisp.com\/helps\/123681.html\" \/>\n<meta property=\"og:locale\" content=\"zh_CN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"FreeRTOS + STM32 + LwIP \u8d85\u65f6\u7f51\u7edc I\/O \u5b8c\u6574\u793a\u4f8b - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\" \/>\n<meta property=\"og:description\" content=\"\/* MD \/ \u5bcc\u6587\u672c\u4e2d\u7684 .toc\uff08\u542b\u535a\u5ba2\u56ed\u642c\u5bb6\u7b49\u5d4c\u5957\u7ed3\u6784\uff09\uff1b.toc-box \u5728\u4fa7\u680f\uff0c\u4e0d\u53d7\u5f71\u54cd *\/#content_views .toc,\/* \u7f16\u8f91\u5668\u5e38\u5728\u76ee\u5f55\u524d\u540e\u63d2\u5165\u7a7a p\uff08:empty \u4ecd\u5360 20px\uff09\uff0c\u4e00\u5e76\u53bb\u6389\u907f\u514d\u9876\u7a7a\u9699 *\/#content_views.markdown_views &gt; p:empty:has(+ .toc),#content_views.markdown_views &gt; .toc + p:empty,\/* \u5bcc\u6587\u672c\u65e7\u7248\u76ee\u5f55\u6807\u8bb0 *\/#content\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.wsisp.com\/helps\/123681.html\" \/>\n<meta property=\"og:site_name\" content=\"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\" \/>\n<meta property=\"article:published_time\" content=\"2026-11-07T17:40:46+00:00\" \/>\n<meta name=\"author\" content=\"admin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 \u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/123681.html\",\"url\":\"https:\/\/www.wsisp.com\/helps\/123681.html\",\"name\":\"FreeRTOS + STM32 + LwIP \u8d85\u65f6\u7f51\u7edc I\/O \u5b8c\u6574\u793a\u4f8b - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\",\"isPartOf\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/#website\"},\"datePublished\":\"2026-11-07T17:40:46+00:00\",\"dateModified\":\"2026-11-07T17:40:46+00:00\",\"author\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/123681.html#breadcrumb\"},\"inLanguage\":\"zh-Hans\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.wsisp.com\/helps\/123681.html\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/123681.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9875\",\"item\":\"https:\/\/www.wsisp.com\/helps\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"FreeRTOS + STM32 + LwIP \u8d85\u65f6\u7f51\u7edc I\/O \u5b8c\u6574\u793a\u4f8b\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#website\",\"url\":\"https:\/\/www.wsisp.com\/helps\/\",\"name\":\"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\",\"description\":\"\u9999\u6e2f\u670d\u52a1\u5668_\u9999\u6e2f\u4e91\u670d\u52a1\u5668\u8d44\u8baf_\u670d\u52a1\u5668\u5e2e\u52a9\u6587\u6863_\u670d\u52a1\u5668\u6559\u7a0b\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.wsisp.com\/helps\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"zh-Hans\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41\",\"name\":\"admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery\",\"contentUrl\":\"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery\",\"caption\":\"admin\"},\"sameAs\":[\"http:\/\/wp.wsisp.com\"],\"url\":\"https:\/\/www.wsisp.com\/helps\/author\/admin\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"FreeRTOS + STM32 + LwIP \u8d85\u65f6\u7f51\u7edc I\/O \u5b8c\u6574\u793a\u4f8b - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.wsisp.com\/helps\/123681.html","og_locale":"zh_CN","og_type":"article","og_title":"FreeRTOS + STM32 + LwIP \u8d85\u65f6\u7f51\u7edc I\/O \u5b8c\u6574\u793a\u4f8b - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","og_description":"\/* MD \/ \u5bcc\u6587\u672c\u4e2d\u7684 .toc\uff08\u542b\u535a\u5ba2\u56ed\u642c\u5bb6\u7b49\u5d4c\u5957\u7ed3\u6784\uff09\uff1b.toc-box \u5728\u4fa7\u680f\uff0c\u4e0d\u53d7\u5f71\u54cd *\/#content_views .toc,\/* \u7f16\u8f91\u5668\u5e38\u5728\u76ee\u5f55\u524d\u540e\u63d2\u5165\u7a7a p\uff08:empty \u4ecd\u5360 20px\uff09\uff0c\u4e00\u5e76\u53bb\u6389\u907f\u514d\u9876\u7a7a\u9699 *\/#content_views.markdown_views &gt; p:empty:has(+ .toc),#content_views.markdown_views &gt; .toc + p:empty,\/* \u5bcc\u6587\u672c\u65e7\u7248\u76ee\u5f55\u6807\u8bb0 *\/#content","og_url":"https:\/\/www.wsisp.com\/helps\/123681.html","og_site_name":"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","article_published_time":"2026-11-07T17:40:46+00:00","author":"admin","twitter_card":"summary_large_image","twitter_misc":{"\u4f5c\u8005":"admin","\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4":"6 \u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.wsisp.com\/helps\/123681.html","url":"https:\/\/www.wsisp.com\/helps\/123681.html","name":"FreeRTOS + STM32 + LwIP \u8d85\u65f6\u7f51\u7edc I\/O \u5b8c\u6574\u793a\u4f8b - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","isPartOf":{"@id":"https:\/\/www.wsisp.com\/helps\/#website"},"datePublished":"2026-11-07T17:40:46+00:00","dateModified":"2026-11-07T17:40:46+00:00","author":{"@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41"},"breadcrumb":{"@id":"https:\/\/www.wsisp.com\/helps\/123681.html#breadcrumb"},"inLanguage":"zh-Hans","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.wsisp.com\/helps\/123681.html"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.wsisp.com\/helps\/123681.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9875","item":"https:\/\/www.wsisp.com\/helps"},{"@type":"ListItem","position":2,"name":"FreeRTOS + STM32 + LwIP \u8d85\u65f6\u7f51\u7edc I\/O \u5b8c\u6574\u793a\u4f8b"}]},{"@type":"WebSite","@id":"https:\/\/www.wsisp.com\/helps\/#website","url":"https:\/\/www.wsisp.com\/helps\/","name":"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","description":"\u9999\u6e2f\u670d\u52a1\u5668_\u9999\u6e2f\u4e91\u670d\u52a1\u5668\u8d44\u8baf_\u670d\u52a1\u5668\u5e2e\u52a9\u6587\u6863_\u670d\u52a1\u5668\u6559\u7a0b","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.wsisp.com\/helps\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"zh-Hans"},{"@type":"Person","@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41","name":"admin","image":{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/image\/","url":"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery","contentUrl":"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery","caption":"admin"},"sameAs":["http:\/\/wp.wsisp.com"],"url":"https:\/\/www.wsisp.com\/helps\/author\/admin"}]}},"_links":{"self":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts\/123681","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/comments?post=123681"}],"version-history":[{"count":0,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts\/123681\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/media?parent=123681"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/categories?post=123681"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/tags?post=123681"},{"taxonomy":"topic","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/topic?post=123681"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}