This tutorial demonstrates how Mongoose Library can be used to implement a device dashboard on a Raspberry Pi Pico W using the Pico-SDK with FreeRTOS and lwIP.
This tutorial is an example following on the device dashboard tutorial. You should read and follow that tutorial first.
This example uses the Pico-SDK and includes configuration files for lwIP and FreeRTOS:
raspberry-pi-pico-w/- the main example code that we clone from a sibling repo
raspberry-pi-pico-w/main.c- main application file, contains Mongoose logic and WiFi network initialization code
raspberry-pi-pico-w/mongoose.c- Mongoose Library source code
raspberry-pi-pico-w/mongoose.h- Mongoose Library header file
raspberry-pi-pico-w/net.c- the common code for this example
raspberry-pi-pico-w/packed_fs.c- a packed filesystem containing the web files to be served
raspberry-pi-pico-w/lwipopts.h- some lwIP config macros tweaked to suit this implementation
raspberry-pi-pico-w/FreeRTOSConfig.h- some FreeRTOS config macros tweaked to suit this implementation
Makefile- mainly invokes Docker to call the toolchain compiler
Build the project
It is assumed that you're using Linux or Mac as a workstation, you have Docker installed, and your user is able to run it. If in doubt, check it:
$ docker ps
Start a terminal in the project directory; clone the Mongoose Library repo,
and run the
$ git clone https://github.com/cesanta/mongoose $ cd mongoose/examples/raspberry/raspberry-pi-pico-w/ $ make
This will clone the git repository with the project files; before building the project we need to edit the WiFi credentials, so open the
raspberry-pi-pico-w/Makefile file and edit your WiFi network name and WiFi password settings:
The next step is to build the project.
$ make build
- Once the build succeeds, boot your Pico W in USB Mass Storage Mode by holding down the
BOOTSELbutton while you plug it into the USB port. Once it is connected, then release the
BOOTSELbutton. It should automatically mount as a new USB disk in your machine. Now either manually copy or drag and drop the generated
firmware.uf2file into this new USB disk device.
- The Pico W will flash this code and reboot, unmounting this disk and running the flashed code.
- Now open a second terminal, this will be our serial console to see the logs. Run a serial port software (we use minicom; make sure you configure it at 115200bps). Device name is usually
$ minicom -D /dev/ttyACM0
Try it out
Start a browser on
IP_ADDRESS is the board's IP address assigned by your DHCP server. You should see a login screen.
From here on, please go to the device dashboard tutorial and repeat some of the steps depicted there
main() function initializes the board and starts the FreeRTOS scheduler, creating a new task for us. This task has two blocks:
- Initialize WiFi and wait until the netwok is ready (DHCP has assigned us an IP address)
- Run Mongoose
Initialize the network
We call the function in charge of initializing the wireless chip, then call the WiFi connect function, which is a blocking function and returns when we have a valid IP address or the process has failed
Next goes Mongoose. It should be run after network initialization is complete. The logic is standard; we initialize the event manager, start a listener on port 80, and fall into an infinite event loop:
For this example we've chosen to embed all the web files in a packed filesystem, more information on the embedded filesystem tutorial
Note that Mongoose has been configured to run under FreeRTOS and lwIP, we do so in the Makefile by defining
We have covered those aspects that are specific to the Pico W implementation, for the details on the application and the UI, please see the device dashboard tutorial.
- Task Memory allocation defaults to dynamic. This means that memory for the stack of each new task, will be allocated from FreeRTOS heap. To work with applications requiring a high stack size, FreeRTOS heap size must be large:
- Some tasks, like the WiFi chip driver, need a stack a bit over the bare minimum that is usually FreeRTOS default. As it will use the configured minimum, we define that on the FreeRTOS configuration file (in words):
- Mongoose needs a large stack, we specify that at the task creation function call (in words):
- Since we'll be using several connections simultaneously, we need to tell lwIP so. Even though we are using the socket interface, internally in lwIP it uses a decoupling API called netconn, so we'll set the number of allowed connections high enough: Make sure you don't modify `LWIP_NETCONN`, the default is for it to be enabled, so leave it as it is and don't redefine it in your lwipopts.h file
- lwIP default priorities are simple numbers which might or might not coincide with the RTOS defined range; we take care to assign them in accordance with the rest of our project. Don't go much higher as the WiFi chip driver task is currently at tskIDLE_PRIORITY + 4. Furthermore, lwIP stack size default definitions are in bytes, while FreeRTOS uses words, so there is a macro to clearly express our choice on the stack sizes beyond doubt: