{"id":7923,"date":"2022-08-29T09:05:52","date_gmt":"2022-08-29T16:05:52","guid":{"rendered":"https:\/\/visualgdb.com\/w\/?p=7923"},"modified":"2022-08-29T09:05:52","modified_gmt":"2022-08-29T16:05:52","slug":"creating-a-simple-tcp-server-with-raspberry-pi-pico-w","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/tutorials\/raspberry\/pico_w\/","title":{"rendered":"Creating a simple TCP Server with Raspberry Pi Pico W"},"content":{"rendered":"<p>This tutorial shows how to create a basic Raspberry Pi Pico W project that will connect to the specified Wi-Fi network and accept TCP connections.We will explain how to configure the Pico W board to connect to a specific network and use the lwIP API to handle the incoming connections. Before you begin, install VisualGDB 5.6R8 or later.<\/p>\n<ol>\n<li>Make sure you have a Wi-Fi network that Pico W can connect to. In this tutorial we will use the Windows Mobile Hotspot to create a new test network, however any other Wi-Fi network will work as well:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/08\/05a-share.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7928\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/08\/05a-share.png\" alt=\"\" width=\"863\" height=\"661\" \/><\/a><\/li>\n<li>Start Visual Studio and locate the Raspberry Pi Pico Project Wizard:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/08\/01-newprj.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7924\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/08\/01-newprj.png\" alt=\"\" width=\"1024\" height=\"680\" \/><\/a><\/li>\n<li>Select the name and location for your project, then press &#8220;Create&#8221;: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/08\/02-picow.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7925\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/08\/02-picow.png\" alt=\"\" width=\"1024\" height=\"680\" \/><\/a><\/li>\n<li>Proceed with creating a new project based on the sample:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/08\/03-new.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7926\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/08\/03-new.png\" alt=\"\" width=\"856\" height=\"693\" \/><\/a><\/li>\n<li>Make sure you are using a recent ARM toolchain and the Pico SDK 1.4.0 or later, since the earlier versions do not support Pico W. You can install the latest Pico SDK by clicking the &#8220;Install Raspberry Pi Pico SDK&#8221; link in the SDK selector:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/08\/04-sdk.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7927\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/08\/04-sdk.png\" alt=\"\" width=\"856\" height=\"694\" \/><\/a><\/li>\n<li>Once you have selected the SDK 1.4.0+, set the board type to <strong>PICO_W<\/strong> and enter the Wi-Fi SSID and password below:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/08\/05-net.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7929\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/08\/05-net.png\" alt=\"\" width=\"856\" height=\"693\" \/><\/a>If you are using a custom board with a different name and VisualGDB does not show the SSID\/Password prompt, try editing the\u00a0<strong>BoardWithWiFi<\/strong> element in the <strong>&lt;VisualGDB Directory&gt;\\Rules\\PicoSDK.xml<\/strong> file. The element contains a regular expression that can cover multiple board names.<\/li>\n<li>On the next page of the wizard pick the <strong>tcp_server<\/strong> example:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/08\/06-server.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7930\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/08\/06-server.png\" alt=\"\" width=\"856\" height=\"693\" \/><\/a><\/li>\n<li>Finally, connect the SWD pins of your Pico W to a debug probe (see <a href=\"https:\/\/visualgdb.com\/documentation\/embedded\/raspberry\/pico\/swd\/\">this page<\/a> for detailed instructions) and select the matching configuration on the Debug Method page: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/08\/07-debug.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7931\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/08\/07-debug.png\" alt=\"\" width=\"856\" height=\"693\" \/><\/a>You can use the Test button to instantly verify that OpenOCD can connect to the target via SWD.<\/li>\n<li>Press &#8220;Finish&#8221; to create the project. Before you can build it, we advise opening VisualGDB Project Properties via the context menu in Solution Explorer and referencing the <strong>Fast Semihosting and Embedded Profiler<\/strong> framework:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/08\/08-profiler.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7932\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/08\/08-profiler.png\" alt=\"\" width=\"1188\" height=\"754\" \/><\/a>This will redirect the output from <strong>printf()<\/strong> to the <strong>VisualGDB Output<\/strong> window, so you won&#8217;t need to setup the UART connection. If you do not need the <strong>printf()<\/strong> output, you can skip this step.<\/li>\n<li>Open the main source file (<strong>picow_tcp_server.c<\/strong>) and use the <strong>View-&gt;VisualGDB Code Explorer<\/strong> to get a quick overview of its contents. You can right-click on any top-level node in Code Explorer and select &#8220;<strong>Collapse-&gt;Nodes at this Level<\/strong>&#8221; to quickly view all functions inside the file:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/08\/struct.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7936\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/08\/struct.png\" alt=\"\" width=\"1230\" height=\"841\" \/><\/a><\/li>\n<li>The <strong>tcp_server<\/strong> example works as shown below:\n<ol style=\"list-style-type: lower-alpha;\">\n<li>First it connects to the Wi-Fi network by calling\u00a0<strong>cyw43_arch_enable_sta_mode()<\/strong> and <strong>cyw43_arch_wifi_connect_timeout_ms().<\/strong><\/li>\n<li>Then it calls the <strong>tcp_server_open()<\/strong> function that:\n<ul>\n<li>Creates a new TCP connection object by calling <strong>tcp_new_ip_type().<\/strong><\/li>\n<li>Binds it to port 4242 by calling <strong>tcp_bind() <\/strong>and then starts listening for incoming connections by calling <strong>tcp_listen_with_backlog().<\/strong><\/li>\n<li>Configures lwIP to call the <strong>tcp_server_accept()<\/strong> callback whenever anyone connects to the TCP port.<\/li>\n<\/ul>\n<\/li>\n<li>When a client connects to the TCP port 4242, the <strong>tcp_server_accept()<\/strong> callback sets 4 additional callbacks on the newly created connection:\n<ol style=\"list-style-type: lower-alpha;\">\n<li><strong>tcp_server_sent()<\/strong> that will be called by lwIP once it completed sending a chunk of data to the client.<\/li>\n<li><strong>tcp_server_recv()<\/strong> once it received data from the client.<\/li>\n<li><strong>tcp_server_poll()<\/strong> once there has not been any activity on the socket for 10 seconds (<strong>POLL_TIME_S<\/strong> * 2)<\/li>\n<li><strong>tcp_server_err()<\/strong> once the socket encounters an internal error.<\/li>\n<\/ol>\n<\/li>\n<li>Once the callbacks are set, <strong>tcp_server_accept()<\/strong> sends a random payload to the client, expecting it to echo it back.<\/li>\n<li>The <strong>tcp_server_recv()<\/strong> callback buffers the incoming data in the <strong>TCP_SERVER_T::buffer_recv<\/strong> buffer, and once the amount of received data matches the amount of sent data, it compares it against the sent block.<\/li>\n<\/ol>\n<\/li>\n<li>Normally, the TCP server example would require a small test program that could receive and echo back a large random chunk of data, however we will modify it so that it could be tested with the <strong>telnet<\/strong> tool. First of all, locate the definition of BUF_SIZE and reduce it to 8. Then, locate the <strong>tcp_server_send_data()<\/strong> function and replace the initialization logic for buffer_sent with this:\n<pre class=\"\">memcpy(state-&gt;buffer_sent, \"test123\\r\", BUF_SIZE);<\/pre>\n<\/li>\n<li>Now set a breakpoint at the <strong>tcp_write()<\/strong> call and press F5 to build the project and begin debugging it:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/08\/09-bkpt.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7933\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/08\/09-bkpt.png\" alt=\"\" width=\"1230\" height=\"841\" \/><\/a><\/li>\n<li>Wait for the board to connect to the Wi-Fi network (it will report the IP address it got via the <strong>printf()<\/strong> output) and run &#8220;telnet &lt;Board IP&gt; 4242&#8221; on your Windows machine. Telnet will connect to the board and the breakpoint in <strong>tcp_server_send_data()<\/strong> will trigger: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/08\/10-connected.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7934\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/08\/10-connected.png\" alt=\"\" width=\"1230\" height=\"841\" \/><\/a><\/li>\n<li>Note that due to security considerations, Windows does not have the telnet client installed by default. You can install it via <strong>Control Panel -&gt; Add\/Remove Programs-&gt;Turn Windows features on and off -&gt; Telnet Client<\/strong>:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/08\/telnet.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7937\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/08\/telnet.png\" alt=\"\" width=\"415\" height=\"368\" \/><\/a><\/li>\n<li>Press F5 to continue debugging. Go to the telnet client, type &#8220;<strong>test123<\/strong>&#8221; and press &lt;ENTER&gt;. The board will show a series of <strong>&#8220;tcp_server_recv X\/Y err 0&#8221;<\/strong> messages in the semihosting console (one for each received packet) and will finally call <strong>tcp_server_send_data()<\/strong> to do another round of tests:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/08\/11-pass2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7935\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2022\/08\/11-pass2.png\" alt=\"\" width=\"1230\" height=\"841\" \/><\/a><\/li>\n<\/ol>\n<p>Note that the TCP server example shown in this tutorial does not use FreeRTOS, so it has to do handle <strong>ALL<\/strong> the connections inside the one and only thread, forcing the use of the callbacks instead of the classic socket API. For all practical purposes, we recommend using FreeRTOS-based projects instead.<\/p>\n<p>You can find the source code of the project shown in this tutorial in our <a href=\"https:\/\/github.com\/sysprogs\/tutorials\/tree\/master\/visualgdb\/ARM\/PicoSDK\/PicoW\/PicoWDemo\">GitHub repository<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows how to create a basic Raspberry Pi Pico W project that will connect to the specified Wi-Fi<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[89],"tags":[43,102],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/7923"}],"collection":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/comments?post=7923"}],"version-history":[{"count":3,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/7923\/revisions"}],"predecessor-version":[{"id":7948,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/7923\/revisions\/7948"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=7923"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=7923"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=7923"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}