Skip to content

ESP8266 port #990

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Nov 28, 2014
Merged

ESP8266 port #990

merged 5 commits into from
Nov 28, 2014

Conversation

dpgeorge
Copy link
Member

This adds support for ESP8266 as a target port for Micro Python. Ie, Micro Python runs directly on the ESP8266 chip. Currently no board-specific features are implemented, only REPL and core uPy modules.

At the moment there is only 19k of heap RAM available for uPy. This is because of 32k bss (need to investigate why...) and 28k rodata (can rodata go elsewhere?).

Garbage collection and exceptions seem to work.

Build using @pfalcon's open sdk: https://github.com/pfalcon/esp-open-sdk . Need to have xtensa-gcc in your path, and then do something like:

$ ESP_SDK=~/esp-open-sdk/sdk make

Binary image available at http://micropython.org/resources/upy.img

@dhylands
Copy link
Contributor

You should be able to determine the bss offenders from the linker map file.

You should be able to put .rodata into flash (that's what we don for stmhal)

@pfalcon
Copy link
Contributor

pfalcon commented Nov 27, 2014

$ ESP_SDK=~/esp-open-sdk/sdk

FYI, the toolchain built by default with esp-open-sdk contains Esspressif SDK in its sysroot. Which means it can build apps without using extra paths for SDK. Is that good? Not always, that's not how I initially implemented, this feature was contributed, and as it makes layman people easier, I didn't oppose having it as default. Well, getting to bottom line: unless you built esp-open-sdk with "make STANDALONE=n", it my pick up headers/libs from its sysroot "as a fallback", so you may miss a case when something doesn't come from ESP_SDK. Again, just FYI, to clarify how it works.

@pfalcon
Copy link
Contributor

pfalcon commented Nov 27, 2014

You should be able to determine the bss offenders from the linker map file.

And these offenders are stuff from vendor SDK (lwip, their own code, etc.)

You should be able to put .rodata into flash (that's what we don for stmhal)

Except that it's different architecture. Which for example may not be so well wearing von Neuman mask on the underlying Harvard architecture as ARM. Remember AVR for example? So far reading IROM with bootloader gives zeros. Of course, it can be bootloader. But rumors say it's not easy still. And well, I can blame Espressif for a lot of oversights, but I doubt that waste precious RAM just out of sloppiness. Anyway, should be pretty easy try to put .rodata into IROM segment. If it works, it works. If not - who said that making a port for barely documented, blob-ridden arch will be easy? ;-)

@dpgeorge
Copy link
Member Author

Well, getting to bottom line: unless you built esp-open-sdk with "make STANDALONE=n"

Yes, I built it with STANDALONE=n, so that's why I needed the ESP_SDK variable.

@pfalcon
Copy link
Contributor

pfalcon commented Nov 27, 2014

Another point: if you do "makeimg.py" step only to avoid manual pin-munging when flashing 2 separate flash segments, then latest esptool.py has my patch to flash multiple segments in one go. But I guess it's to simplify users' life with downloading and flashing anyway.

@dpgeorge
Copy link
Member Author

if you do "makeimg.py" step only to avoid manual pin-munging when flashing 2 separate flash segments

Yes. With the version of esptool.py that I have (not latest) it doesn't cleanly exit from a flash download, so it's much easier to just burn it all in one go.

latest esptool.py has my patch to flash multiple segments in one go.

Ok, will get it.

But I guess it's to simplify users' life with downloading and flashing anyway.

Yes, I think having 1 binary image to download (from internet) then upload (to device) is much easier than having 2 :)

I didn't want to add such a simple script as makeimg.py, but couldn't do it with a 1-line sed/dd/awk command :) Perhaps we can put this functionality in esptool?

@pfalcon
Copy link
Contributor

pfalcon commented Nov 27, 2014

Yes. With the version of esptool.py that I have (not latest) it doesn't cleanly exit from a flash download, so it's much easier to just burn it all in one go.

The why did you give a try to esp-open-sdk at all? ;-) It's whole idea is to collect latest and greatest pieces into 1 or 2 dirs automatically. The latest esptool.py is installed together with toolchain binaries.

Perhaps we can put this functionality in esptool?

Well, I started hacking together flashing directly out of ELF.

Speaking of all that, what programmings speed you get? I have ESP-03 module, wires aren't really long, but connected via breadboard. So, I got decent programming speed couple of times (in row). Otherwise, programming is very slow to me. Really need to put speed counter to esptool too, but I suspect ESP bootloader "autodetects" rate as 9600.

@pfalcon
Copy link
Contributor

pfalcon commented Nov 27, 2014

So, it builds, it flashes (after allowing to override port - pushed), it runs ;-).

@dpgeorge
Copy link
Member Author

The why did you give a try to esp-open-sdk at all? ;-)

I think we are confused here. I have the latest esp-open-sdk (nice work BTW!), and along with it comes esptool (which I'm using). But I didn't notice your patch, so I did my hack with makeimg.py (from me using an old version of esptool before esp-open-sdk existed).

@dpgeorge
Copy link
Member Author

Speaking of all that, what programmings speed you get?

I'm using a pyboard as a motherboard for the ESP-03 from electrodragon. The pyboard does USB-UART pass through, and also allows to set the GPIO pins of the ESP to easily select the boot mode. Pyboard also supplies regulated 3.3v (but needs a beefy capacitor to smooth startup current). I can download the 300k image in about 30secs.

esp-pyboard

@pfalcon
Copy link
Contributor

pfalcon commented Nov 28, 2014

Anyway, should be pretty easy try to put .rodata into IROM segment.

Ok, with the following patch it hangs after flashing:

--- a/esp8266/esp8266.ld
+++ b/esp8266/esp8266.ld
@@ -89,8 +89,8 @@ SECTIONS
     .rodata : ALIGN(4)
     {
         _rodata_start = ABSOLUTE(.);
-        *(.rodata)
-        *(.rodata.*)
+/*        *(.rodata)
+        *(.rodata.*)*/
         *(.gnu.linkonce.r.*)
         *(.rodata1)
         __XT_EXCEPTION_TABLE__ = ABSOLUTE(.);
@@ -151,6 +151,10 @@ SECTIONS
         _irom0_text_start = ABSOLUTE(.);
         *(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom.text)
         *py*.o*(.literal* .text*)
+
+        *(.rodata)
+        *(.rodata.*)
+
         _irom0_text_end = ABSOLUTE(.);
     } >irom0_0_seg :irom0_0_phdr

@dpgeorge
Copy link
Member Author

Ok, with the following patch it hangs after flashing:

Yeah, I tried putting rodata in IRAM (and moving stuff from IRAM to IROM), but that also crashed. But might be because too much stuff moved to IROM. Seems that some things must live in IRAM so it boots... ahh, the joys of little to no documentation!

@pfalcon
Copy link
Contributor

pfalcon commented Nov 28, 2014

I can download the 300k image in about 30secs.

Yeah, that's definitely much better than what I have. So, let's blame breadboard and/or my UART module then.

So, great start, @dpgeorge ! Wanted to give it a try before I pack out my modules for travel (and then being lazy to redeploy setup for a week or two ;-) ).

@dpgeorge
Copy link
Member Author

Ok, so we'll merge this then? I think having another port such as this gives us good direction to keeping the code base generic and able to support multiple targets. Also, it shows what components from stmhal can be factored out (such as readline, pyexec, string0, etc).

@pfalcon
Copy link
Contributor

pfalcon commented Nov 28, 2014

If the idea is to merge this soon rather than develop in a branch, then yes, +1 from me for merging.

@dpgeorge
Copy link
Member Author

Turns out you can put some rodata items in IROM or IRAM... but it's not yet clear what exactly can/can't and why. I managed to put the qstr data there, but couldn't put the parser rules there.

Some rodata items can go in iram/irom segment, but not others.  With
this patch ESP now has 24256 bytes of heap ram.  It passes 228 out of
248 tests from tests/basics directory.
@dpgeorge dpgeorge merged commit fbea810 into master Nov 28, 2014
@dpgeorge
Copy link
Member Author

Merged into master.

@dpgeorge dpgeorge deleted the esp8266-port branch November 28, 2014 17:48
tannewt added a commit to tannewt/circuitpython that referenced this pull request Dec 6, 2018
This creates a common safe mode mechanic that ports can share.
As a result, the nRF52 now has safe mode support as well.

The common safe mode adds a 700ms delay at startup where a reset
during that window will cause a reset into safe mode. This window
is designated by a yellow status pixel and flashing the single led
three times.

A couple NeoPixel fixes are included for the nRF52 as well.

Fixes micropython#1034. Fixes micropython#990. Fixes micropython#615.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants