Monday, September 17, 2018

Building MicroPython for esp8266 - to freeze modules

For my esp8266 project with the ssd1306 screen I was starting to run out of memory for all the 'threads' I needed. I have a TCP client talking to the server, temperature readings coming from the 1-wire device, and button inputs. Not to mention that I want to run a webserver for configuration.

The answer, and it has so far worked very well, is to build my own firmware, and 'freeze' the modules that are least likely to change into the firmware. I have a font class for the ssd1306 screen, the asyncio library, the aswitch library, and a few others which are unlikely to change, so I picked them.

This is the procedure I followed.

Create a VirtualBox VM, running some recent version of Ubuntu (18.04) (select minimal options), and log into it. I installed opensshd-server, and on the settings for the VM I enabled a bridged network so it gets an IP address on my home router.
sudo apt-get install net-tools openssh-server
Then you can ssh

I more-or-less follow this : http://akshaim.in/IoT/MicroPython_ESP8266/MP_ESP_101.html


sudo apt-get install make unrar-free autoconf automake libtool gcc g++ gperf flex bison texinfo gawk ncurses-dev libexpat-dev python-dev python python-serial sed git unzip bash help2man wget bzip2 libtool-bin

git clone --recursive https://github.com/pfalcon/esp-open-sdk.git
cd esp-open-sdk
make

(takes about 40 minutes)
(NOTE - this path is shown at the end of the install - run the command)
export PATH=/home/akshaim/Documents/ESP8266/esp-open-sdk/xtensa-lx106-elf/bin:$PATH




git clone --recursive https://github.com/micropython/micropython.git
cd micropython
git submodule update --init
make -C mpy-cross
 cd ports/esp8266
(different from original instructions)
make
(different from original instructions)

Now you can put modules (and subdirectories) into the modules directory, and they end up in the firmware. When you put a new module, you need to 'make' again.

output is firmware-combined.bin located in esp8266/build

This is the current content of my modules dir:
 1624 Sep 15 16:39 websocket_helper.py
 2748 Sep 15 16:39 webrepl_setup.py
 2118 Sep 15 16:39 webrepl.py
   31 Sep 15 16:39 upip_utarfile.py -> ../../../tools/upip_utarfile.py
   22 Sep 15 16:39 upip.py -> ../../../tools/upip.py
 1094 Sep 15 16:39 port_diag.py
   35 Sep 15 16:39 onewire.py -> ../../../drivers/onewire/onewire.py
  850 Sep 15 16:39 ntptime.py
  836 Sep 15 16:39 neopixel.py
 1425 Sep 15 16:39 inisetup.py
 1110 Sep 15 16:39 flashbdev.py
   35 Sep 15 16:39 ds18x20.py -> ../../../drivers/onewire/ds18x20.py
   27 Sep 15 16:39 dht.py -> ../../../drivers/dht/dht.py
  219 Sep 15 16:39 _boot.py
  470 Sep 15 16:39 apa102.py
 1716 Sep 15 17:42 config.py
 6397 Sep 15 17:42 freesans34_num.py
 4096 Sep 15 17:42 uasyncio
   35 Sep 15 17:57 ssd1306.py -> ../../../drivers/display/ssd1306.py

Installing modules

Python uses a package manager to install modules, and it is also available for micropython. I'm not very familiar with all this, and I find it a bit fiddly. However, here are some instructions to install asyncio, logging, and picoweb.

Build micropython for unix.
cd into ports/unix, and here is a version of micropython which can run on the host. This is used to install modules locally before freezing them.

#first some prerequisite packages to install :
sudo apt-get install pkg-config python-pip libffi-dev

#next make the unix version of micropython
make axtls
make

#now you can download and install modules
#cd back into ports/esp8266
../unix/micropython -m upip install -p app picoweb (also installs uasyncio)
../unix/micropython -m upip install -p app micropython-logging

now I move all the files/dirs from app to modules - I suppose you could just install to modules first, but I liked the buffer of not messing up my modules directory, but instead checking the app directory before deciding what to move.

After that just make to build your new firmware, and you're good to go.