A simple ESP8266 C SDK project template

2016-11-04 01:33:16

A little while ago I started a new ESP8266 based project. Last time I touched one of them was probably around a year ago, so my memory was a bit blurry on how to approach it. Somehow I always start with NodeMCU and then get too impatient to wrap my head around Lua and instead fall back to the native C SDK. To avoid starting from zero again next time, I created a simple project template based around the "standard" example Makefile (see file itself for author credits)

I'm going to skip all basic introduction of ESP8266 and all alternative development options. Everybody is using them and writing about it, I doubt I could add much value here. Check the ESP8266 community forum and Espressif's official forum instead.

Get the toolchain

Can't develop without a toolchain. Thanks to the esp-open-sdk project on Github, this is straightforward for Ubuntu/Debian, and based on the dependencies list, it should be equally smooth for other distributions.

By default, the toolchain is built inside its own directory, so wherever you clone the repository into, the toolchain will be located. I'll be cloning into /opt, so the toolchain will be in /opt/esp-open-sdk/, but any other place is fine as well.

SDK project template

Get the ESP C SDK template from GitHub and clone it anywhere you want to. It doesn't have to be the same place you put the toolchain.

git clone https://github.com/sgreg/esp8266-c-sdk-template

Still need to point the template to the toolchain, so edit the setenv.sh file and change the ESP_SDK_ROOT variable to the directory to the location of the toolchain (i.e. where you cloned the esp-open-sdk repository into).

cd esp8266-c-sdk-template
vim setenv.sh

With the paths adjusted, source the setenv.sh file

. ./setenv.sh

Now all is set up to create a first ESP8266 project. The mkproject.sh script will set up the base directory structure and Makefile in a directory of your choice. Again, this can be anywhere in the file system and doesn't have to be in the same place as either the toolchain or the template files themselves.

./mkproject.sh ~/work/esp8266/something/firmware

On success, the script will print a crappy guidance to set up an Eclipse project, not sure if this will ever be any better or even automated in the future, don't get your hopes up. But you can always just use the command line, as additionally stated in the script's output. To verify all works as intended, we'll be doing exactly that.

File structure

The template creates four files/directories:

  • user/main.c main source file with program entry point. Start writing your code here
  • user/user_config.h user defined configuration header, empty by default. SDK header files rely on the existence of this file, so don't delete it even if you don't use it
  • driver/ empty directory to place code for drivers. Mainly to separate external components' driver code from the main code, can be deleted if not used.
  • Makefile putting it all neatly together. Again, this was copied from an example project and I don't take credit for it.

Compile the created project

The main.c file doesn't do much but setting up a UART for serial communication and printing a hello. For the purpose of this article, that should be enough to verify functionality. Again, the internet is full of other examples.

Make sure you're using the same terminal you sourced setenv.sh before, otherwise source it again. Afterwards, go to the source directory the template script created and simply run make to compile and create the firmware binaries. In best case, you shouldn't get any errors but the output shown here.

$ cd ~/work/esp8266/something/firmware
$ make
CC user/main.c
AR build/app_app.a
LD build/app.out
FW firmware/
esptool.py v1.2
FW firmware/
esptool.py v1.2

A word about ESP8266 boards

Before we continue to flash the freshly created firmware binaries, I'd like to say a few words about ESP boards and hardware set up for flashing.

There are quite a few boards available, see the community wiki family overview for some of them. Personally, I've been mostly using the ESP-01 because it's cheap, small and has the basic pins available, and Olimex's MOD-WIFI-ESP8266-DEV board which has most pins broken out and is breadboard friendly.

There's also a USB adapter board for the ESP-01 providing both power and serial interface. But flashing the boards still require some hackish wiring. There are probably some boards out there that have a "flash" button taking care of this..?

ESP-01 adapter board

Flashing the firmware

The ESP8266 uses some of its GPIOs to determine the boot mode. The two most interesting boot modes are Flash to load the firmware from the flash memory, and UART to transfer the firmware via serial interface. Usually the hardware is arranged to have the Flash boot mode as default, and pulling GPIO0 to Ground during reset will set the boot mode to UART. We're gonna need the latter one to flash the firmware.

As mentioned, buttons would be nice for this, but at least the boards I've been using don't have this luxury. Instead I'll use some jumper wire and for example a breadboard. Since we need to pull both GPIO0 and RST to Ground and don't need to handle the supply voltage in any way, the risk of killing the microcontroller is quite low.

Prepare for flashing:

  1. have the ESP board powered and a serial connection
  2. connect the GPIO0 pin to Ground
  3. connect the RST pin to Ground for a brief moment, the remove the connection

Now the hardware is ready. Make sure you don't have any serial connection to the ESP board open, e.g. minicom or any other terminal emulator running. Also make sure you have source setenv.sh at some point.

Note, the Makefile assumes your serial port is /dev/ttyUSB0. Depending on your serial connection / adapter, it might use a different device.

$ make flash
esptool.py --port /dev/ttyUSB0 write_flash 0x00000 firmware/0x00000.bin 0x40000 firmware/0x40000.bin
esptool.py v1.2
Auto-detected Flash size: 8m
Running Cesanta flasher stub...
Flash params set to 0x0020
Writing 28672 @ 0x0... 28672 (100 %)
Wrote 28672 bytes at 0x0 in 2.5 seconds (91.9 kbit/s)...
Writing 188416 @ 0x40000... 188416 (100 %)
Wrote 188416 bytes at 0x40000 in 16.3 seconds (92.2 kbit/s)...

Remove the grounded connection of GPIO0, open a serial connection to /dev/ttyUSB0 with 9600 baud 8N1 configuration and reset the board.

You should now see a greeting from the ESP:

ESP8266 says hello

It's possible you see some additional output after that, in which case the ESP8266 is starting up as access point. Either way - hooray. Everything seems to work just fine if you got this far.

Continue from here

Again, there are enough examples out there to study and play with. Something you probably want to take a look at is the ESP8266 Non-OS SDK API Reference.