The Pico/W In C: A Better Connect
Written by Harry Fairhead   
Monday, 23 January 2023
Article Index
The Pico/W In C: A Better Connect
The cyw43_arch Functions
A Better Connect

The Pico W has WiFi and getting started is easier than you might think from the documentation. But how do you get connected? This isn't a matter of only connect - there is more to do! This is an extract from our latest book all about the Pico/W in C.

Programming the Raspberry Pi Pico In C

By Harry Fairhead


Buy from Amazon.


  • Preface
  • Chapter 1 The Raspberry Pi Pico – Before We Begin
  • Chapter 2 Getting Started
  • Chapter 3 Getting Started With The GPIO
  • Chapter 4 Simple Output
  • Chapter 5 Some Electronics
  • Chapter 6 Simple Input
  • Chapter 7 Advanced Input – Events and Interrupts
  • Chapter 8 Pulse Width Modulation
        Extract: Basic PWM
  • Chapter 9 Controlling Motors And Servos
  • Chapter 10 Getting Started With The SPI Bus
  • Chapter 11 A-To-D and The SPI Bus
  • Chapter 12 Using The I2C Bus
  • Chapter 13 Using The PIO
        Extract: A 1-Wire PIO Program  
  • Chapter 14 The DHT22 Sensor Implementing A Custom Protocol
  • Chapter 15 The 1‑Wire Bus And The DS1820
  • Chapter 16 The Serial Port
  • Chapter 17 Using the Pico W
       Extract: Simple Web Client
       Extract:A Better Connect
  • Chapter 18 The Pico/W In C: Direct To Hardware ***NEW!



The Pico and the Pico W are very similar and, with the exception of anything that uses the built-in LED, all of the programs presented so far work on both models. The important difference between them is that the Pico W has additional hardware that enables it to use WiFi. From the programming point of view, however, the task is to learn how to use the new WiFi driver and the LwIP library that provides higher-level networking. This is made more difficult than need be by the inadequate documentation provided for both. This will probably improve over time.

In chapter but not in this extract

  • The Pico W


The WiFi Stack

The Pico W has additional libraries to make it possible to work with the WiFi hardware without having to work at the level of the SPI interface. You can think of these libraries as forming a set of levels. The lowest level is the cyw43_driver which provides an interface to the hardware via the SPI interface. In most cases you can ignore the functions in this module apart from the ones concerned with scanning for access points and power management.

The pico_cyw43_arch library provides higher-level functions mostly concerned with setting up the WiFi and making connections. This is documented and is a good place to start.

The pico_lwip is a set of wrapper functions around the LwIP open source IP stack. This has been ported to the Pico and works with IP via the WiFi drivers. There is almost no documentation of pico_lwip but the original LwIP project is fully, if not particularly clearly, documented.

The WiFi hardware needs periodic attention and when used with an operating system this is usually taken care of by multithreading, but the Pico doesn’t have an operating system unless you install one. The pico_cyw43_arch library provides three different ways of achieving the regular attention that the hardware needs. The first relies on polling, the second uses interrupts and the third makes use of the threads provided by the FreeRTOS operating system.

The mode used depends on which library you link to in CMakeLists.txt. There are three choices, the first being pico_cyw43_arch_lwip_poll. Using this library the client program has to call cyw43_arch_poll() every so often to allow it to run the WiFi software so that it can call callbacks and generally move data. This is a very simple arrangement as it is entirely synchronous and there is no danger of a race condition and hence no need for locking of any kind. It has the disadvantage that it is not multi-core nor interrupt-safe. That is, if you are running code on the second core or if you are making use of interrupts, the networking code can be interrupted in ways that corrupt data.

The second choice is, pico_cyw43_arch_lwip_threadsafe_background. In this case there is nothing the client program has to do and the driver and LwIP code is called by an interrupt. This is multi-core and interrupt-safe, but only if you use locking when you call LwIP code. All callbacks are called in interrupt mode. Any code not run by LwIP has to be bracketed by the instructions cyw43_arch_lwip_begin and cyw43_arch_lwip_end. These apply locks which stop interrupts and other cores running the code at the same time. You don’t have to bracket calls to LwIP made within callbacks because these are being run by LwIP, but if you do they have no effect.

While you can use the threadsafe_background mode with freeRTOS, the preferred mode is to use it with pico_cyw43_arch_lwip_sys_freertos, the third library. The freeRTOS operating system adds the ability to run multiple tasks at different levels of priority – it provides a basic “threads” capability. This allows the LwIP software to run independently and in an organized way with your custom code. The installation and use of freeRTOS is a big undertaking and in most cases it is best avoided for simple WiFi applications.

The freeRTOS approach to WiFi is best taken if you want to use freeRTOS to structure your entire application. In the rest of this chapter the examples will use the threadsafe_background mode, but it is easy to convert them to polling mode by adding calls to cyw43_arch_poll(). It is important to notice that you can only use LwIP sockets if you are also using freeRTOS. Without freeRTOS you are limited to the “raw” LwIP APIs.

There is also a mode, set by using the pico_cyw43_arch_none library, which disables WiFi but allows access to the onboard LED. This is what was used in Chapter 2 to flash the onboard LED.

Last Updated ( Monday, 23 January 2023 )