Skip to content
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

Further work to Esp32 arch. #2151

Merged
merged 38 commits into from Nov 30, 2020
Merged

Further work to Esp32 arch. #2151

merged 38 commits into from Nov 30, 2020

Conversation

mikee47
Copy link
Contributor

@mikee47 mikee47 commented Nov 11, 2020

Build changes:

  • Switch to CMake build (Ninja) and SDK v4.1 (latest stable release)
  • SDK builds empty project with empty app_main() so it completes without error
  • SDK paths are configured within makefile, do not run export.sh (simplifies usage, especially with eclipse)
  • SDK builds in Win32
  • Use sub-make to copy files after building SDK - portable
  • Add ESP_VARIANT support (esp32, esp32s2)
  • Use esptool Component (updated to latest v3.0 release) for both Esp8266 and Esp32

Structural changes:

  • Move esp_idf and esp_hal into esp32 Component
  • Enforce coding style

Fixes:

  • malloc_count needs to wrap strdup
  • Compile warnings (except tcpip_adapter deprecation warnings - STRICT required)
  • Tweak memanalyzer.py going from memory map in soc/soc.h
  • Implement task queue
  • Implement flashmem_get_address using mmap registers
  • Flash data segments. ESP32 has separate segments for instruction and data. Instruction segment must use aligned accesses, but this is not required for the data segment. Additional values added to the arch esp_attr.h file to support this.

TODO:

  • Investigate why libc tests fail - items without init_priority attribute get placed first, in other builds they're first.
  • Implement timers - don't use task (get stack overflow errors running HostTests) increase task timer stack size
  • Revise HAL/driver code and interface headers - there's way too much duplication.
  • Add partition table support. By default, auto-generate a project's .csv file from existing configuration data but also allow file to be specified in component.mk file.
  • Implement uart driver without FreeRTOS. Test against Basic_Serial sample (enable receive on second port).
  • Get HostTests to run through on Esp32 arch. without error
  • Check/fix timer values are accurate
  • Revise networking to use netif interfaces, tcpip_adapter is deprecated.

For separate PR:

  • Add Hal layer to minimise code duplication and provide consistent interface between framework and arch hardware
  • Port segment mapping - probably add fragment to IDF project.
  • ESP32 has more segment types than ESP8266. Update all esp_attr.h files to define the full set.
  • Can ESP32 CPU clock be changed?
  • Fix malloc_count, doesn't work

@mikee47 mikee47 force-pushed the dev/esp32 branch 3 times, most recently from 87e5085 to 7ab1929 Compare November 11, 2020 09:34
@slaff slaff added this to the 4.2.0 milestone Nov 11, 2020
@mikee47 mikee47 force-pushed the dev/esp32 branch 3 times, most recently from a454b1a to c869424 Compare November 12, 2020 17:50
@mikee47 mikee47 force-pushed the dev/esp32 branch 5 times, most recently from 9bc577e to 61ba0f5 Compare November 13, 2020 23:43
@mikee47 mikee47 force-pushed the dev/esp32 branch 4 times, most recently from 71f7b6c to c040c2c Compare November 28, 2020 11:03
@mikee47
Copy link
Contributor Author

mikee47 commented Nov 29, 2020

@slaff Although I've had some esp32 modules for a couple of years, I've not touched them until now and was impressed with how easily Sming builds and runs on them. Awesome work!

Something which grates a little about the IDF is the amount of stuff that needs to be installed. If we assume that this specific IDF installation is only for use with Sming, there are some further improvements to be had:

  • Install the IDF in a versioned directory. On my dev. machine I use c:\tools\esp-idf\v4.1 and c:\tools\esp-idf\v4.2 (the latter just to look ahead). Both install different tool versions, however using the latest tool versions should be OK.
  • Don't do a recursive clone of the ESP-IDF during installation. Many of these submodules are not used or required.

The fastest setup could be achieved by adding slimmed-down, pre-configured IDF and tool images to the SmingTools repository.

@mikee47
Copy link
Contributor Author

mikee47 commented Nov 29, 2020

Re #2100 here's a docker script to try out:

FROM ubuntu:16.04
RUN apt-get update && \
    apt-get upgrade -y && \
    apt-get install -y git wget flex bison gperf cmake ninja-build ccache libffi-dev libssl-dev dfu-util python3 python3-pip python3-setuptools && \
    update-alternatives --install /usr/bin/python python /usr/bin/python3 10 && \
    python -m pip install --upgrade virtualenv==16.7.9
WORKDIR /opt
RUN git clone -b dev/esp32 https://github.com/mikee47/Sming.git
ENV SMING_HOME=/opt/Sming/Sming
RUN git clone -b release/v4.1 --recursive https://github.com/espressif/esp-idf.git
RUN cd esp-idf && ./install.sh && export IDF_PATH=$(pwd) && echo $IDF_PATH
ENV IDF_PATH=/opt/esp-idf
RUN cd $SMING_HOME/../samples/Basic_Blink/ && make -j5 python-requirements all SMING_ARCH=Esp32

@mikee47
Copy link
Contributor Author

mikee47 commented Nov 29, 2020

I've added the sming-arch Component to provide common declarations for the arch. driver Components, e.g. smg_uart. This is really the HAL interface so should really go somewhere else with a more appropriate name. How about this:

  • Create a new Sming/Hal directory (for the sming-arch stuff). i.e. non-Component
  • Rename low-level Arch components: driver -> hal-driver, esp_spiffs -> hal-spiffs, esp_wifi -> hal-wifi, etc.

This will avoid any conflict with the Esp32 (or Esp8266) SDK and make the build more robust and code easier to follow.

Note I'm specifically using a lower-case convention for these names to identify them as low-level code, and differentiate from regular framework Components.

Thoughts?

@slaff
Copy link
Contributor

slaff commented Nov 29, 2020

@mikee47 If you are ready with the planned improvements for this PR then let merge it as it is.
After that create a new PR with the proposed HAL restructuring. We can use the lower-case naming also in the future to specify low-level code.

@mikee47
Copy link
Contributor Author

mikee47 commented Nov 29, 2020

@slaff The only thing holding me up now is timers, specifically the PolledTimerClock implementation. I cannot seem to get the calibration right. Attempting to set the prescaler crashes the device, so it's clearly used elsewhere...

@mikee47 mikee47 changed the title [WIP] Further work to Esp32 arch. Further work to Esp32 arch. Nov 29, 2020
@mikee47
Copy link
Contributor Author

mikee47 commented Nov 29, 2020

@slaff OK, ready for review

@slaff
Copy link
Contributor

slaff commented Nov 30, 2020

@mikee47 The changes look awesome! Thanks a lot for your help!

I have tried the Basic_Serial sample and it is constantly segfaulting for me. Can you try to reproduce it on your Linux box?

IDF version:

idf.py --version
ESP-IDF v4.1-520-gc3324a8

Steps to reproduce:

make dist-clean
cd $SMING_HOME/../samples/Basic_Serial
make config-clean
make clean
make SMING_ARCH=Esp32
make flash

Application output:

4441640 mount res: 0
4441711 (INFO) message printed on UART0
4441754 (WARNING) message printed on UART0
4441784 (ERROR) message printed on UART0
4441826 (INFO) message printed with debugf on UART0
4641982 (DEBUG) print me again on UART0
Guru Meditation Error: Core  1 panic'ed (IllegalInstruction). Exception was unhandled.
Memory dump at 0x401432c8: ffffffff ffffffff ffffffff
Core 1 register dump:
PC      : 0x401432cc  PS      : 0x00060530  A0      : 0x801234f1  A1      : 0x3ffc28f0  
A2      : 0x00000009  A3      : 0x00000001  A4      : 0x0ffd114c  A5      : 0x00000000  
A6      : 0x00000020  A7      : 0x0000001f  A8      : 0x80143a82  A9      : 0x3ffc28c0  
A10     : 0x00000009  A11     : 0x3ffc2820  A12     : 0x00000000  A13     : 0xffffffff  
A14     : 0x00000000  A15     : 0x00000000  SAR     : 0x00000017  EXCCAUSE: 0x00000000  
EXCVADDR: 0x00000000  LBEG    : 0x4000c46c  LEND    : 0x4000c477  LCOUNT  : 0x00000000 

It looks to me as if IDFs code is clashing with our uart code.

The decoded backtrace points to the following error stack:

Decode stack trace: Paste stack trace here
0x401432c9:0x3ffc28f0 0x401234ee:0x3ffc2920 0x40123727:0x3ffc2940 0x4011e532:0x3ffc2960 0x400e2df6:0x3ffc29a0 0x400e2485:0x3ffc2a20 0x40087e11:0x3ffc2b00

0x401432c9: gpio_od_enable at ~/dev/esp32.dev.box/esp-idf/components/driver/gpio.c:211
0x401234ee: smg_uart_set_pins at ~/dev/Sming/Sming/Arch/Esp32/Components/driver/uart.cpp:851
 (inlined by) smg_uart_set_pins at ~/dev/Sming/Sming/Arch/Esp32/Components/driver/uart.cpp:825
0x40123727: smg_uart_init_ex at ~/dev/Sming/Sming/Arch/Esp32/Components/driver/uart.cpp:716
 (inlined by) smg_uart_init_ex at ~/dev/Sming/Sming/Arch/Esp32/Components/driver/uart.cpp:660
0x4011e532: HardwareSerial::begin(unsigned int, SerialConfig, SerialMode, unsigned char, unsigned char) at ~/dev/Sming/Sming/Core/HardwareSerial.cpp:49
0x400e2df6: init() at ~/dev/Sming/Sming/Core/HardwareSerial.h:133
 (inlined by) init() at ~/dev/esp8266.dev.box/dev/Sming/samples/Basic_Serial/app/application.cpp:288
0x400e2485: (anonymous namespace)::main(void*) at ~/dev/Sming/Sming/Arch/Esp32/Components/esp32/src/startup.cpp:67
0x40087e11: vPortTaskWrapper at ~/dev/esp32.dev.box/esp-idf/components/freertos/port.c:143

Config:

[slavey@/media/sla...dev/Sming/samples/Basic_Serial] make list-config 

Basic_Serial: Invoking 'list-config' for Esp32 (debug) architecture

** Sming build configuration **

CUSTOM_TARGETS
- check-ssl
- checksdk
- files/README.md
- out/Esp32/debug/build/partitions.csv
- out/Esp32/debug/firmware/spiff_rom.bin
LIBS
- app_update
- bootloader_support
- c
- coexist
- core
- cxx
- driver
- efuse
- esp-tls
- esp32
- esp_adc_cal
- esp_common
- esp_event
- esp_gdbstub
- esp_netif
- esp_ringbuf
- esp_wifi
- espcoredump
- espnow
- freertos
- gcc
- hal
- heap
- log
- lwip
- m
- mbedcrypto
- mbedtls
- mesh
- net80211
- newlib
- nvs_flash
- openssl
- phy
- pp
- protobuf-c
- protocomm
- pthread
- rtc
- smartconfig
- soc
- spi_flash
- stdc++
- tcp_transport
- tcpip_adapter
- vfs
- wifi_provisioning
- wpa_supplicant
- xtensa
ARDUINO_LIBRARIES
SUBMODULES
- /home/slavey/dev/esp8266.dev.box/dev/Sming/Sming/Components/FlashString
- /home/slavey/dev/esp8266.dev.box/dev/Sming/Sming/Components/esptool/esptool
- /home/slavey/dev/esp8266.dev.box/dev/Sming/Sming/Components/http-parser
- /home/slavey/dev/esp8266.dev.box/dev/Sming/Sming/Components/libyuarel
- /home/slavey/dev/esp8266.dev.box/dev/Sming/Sming/Components/mqtt-codec
- /home/slavey/dev/esp8266.dev.box/dev/Sming/Sming/Components/spiffs/spiffs
- /home/slavey/dev/esp8266.dev.box/dev/Sming/Sming/Components/ws_parser
CONFIG_VARS
- COM_SPEED_SERIAL = $(COM_SPEED)
- DEBUG_PRINT_FILENAME_AND_LINE = 0
- DEBUG_VERBOSE_LEVEL = 2
- DISABLE_SPIFFS = 0
- DISABLE_WIFI = 0
- ENABLE_CMD_EXECUTOR = 1
- ENABLE_GDB = 
- ENABLE_SMART_CONFIG = 
- ENABLE_SSL = 0
- ENABLE_TASK_COUNT = 
- ENABLE_WPS = 
- HTTP_SERVER_EXPOSE_NAME = 1
- HTTP_SERVER_EXPOSE_VERSION = 0
- LOCALE = 
- MQTT_NO_COMPAT = 
- SPIFF_SIZE = 65536
- SPI_MODE = dio
- SPI_SIZE = 4M
- SPI_SPEED = 40
- STRING_OBJECT_SIZE = 12
- TASK_QUEUE_LENGTH = 10
- USER_CFLAGS = 
- WIFI_PWD = 
- WIFI_SSID = 
CACHE_VARS
- APP_NAME = app
- COM_OPTS = --raw --encoding ascii
- COM_PORT = /dev/ttyUSB0
- COM_PORT_ESPTOOL = $(COM_PORT)
- COM_SPEED = 115200
- COM_SPEED_ESPTOOL = $(COM_SPEED)
- FULL_COMPONENT_BUILD = 
- GDB_CMDLINE = trap '' INT; $(GDB) -x $(ARCH_TOOLS)/gdbinit $(TARGET_OUT)
- KILL_TERM = pkill -9 -f "$(COM_PORT) $(COM_SPEED_SERIAL)" || exit 0
- PIP_ARGS = 
- SDK_FULL_BUILD = 0
- SERVER_OTA_PORT = 9999
- SPIFF_BIN = spiff_rom
- SPIFF_FILES = files
- TERMINAL = $(PYTHON) -m serial.tools.miniterm $(COM_OPTS) $(COM_PORT) $(COM_SPEED_SERIAL)
- TRACE = 
RELINK_VARS
- ENABLE_SSL = 0
- SPIFF_FILEDESC_COUNT = 7
- SSL_DEBUG = 0
DEBUG_VARS
- APP_CFLAGS =  -DCOM_SPEED_SERIAL=$(COM_SPEED_SERIAL) -DDISABLE_SPIFFS=$(DISABLE_SPIFFS) -DSPIFF_SIZE=$(SPIFF_SIZE) -DSPIFF_SIZE=$(SPIFF_SIZE) -DSPIFF_START_ADDR=$(SPIFF_START_ADDR)
- APP_LIBDIR = out/Esp32/debug/lib
- ARCH_BASE = /home/slavey/dev/esp8266.dev.box/dev/Sming/Sming/Arch/Esp32
- AWK = POSIXLY_CORRECT= awk
- BUILD_BASE = $(OUT_BASE)/build
- CLANG_FORMAT = clang-format
- CMAKE = cmake
- ESP32_COMPILER_PATH = /home/slavey/.espressif/tools/xtensa-esp32-elf/esp-2020r3-8.4.0/xtensa-esp32-elf
- ESP32_OPENOCD_PATH = /home/slavey/.espressif/tools/openocd-esp32/v0.10.0-esp32-20200709
- ESP32_PYTHON_PATH = /home/slavey/.espressif/python_env/idf4.0_py3.5_env/bin
- ESP32_ULP_PATH = /home/slavey/.espressif/tools/esp32ulp-elf/2.28.51.20170517
- ESPTOOL = python /home/slavey/dev/esp8266.dev.box/dev/Sming/Sming/Components/esptool/esptool/esptool.py
- ESP_VARIANT = esp32
- FW_BASE = $(OUT_BASE)/firmware
- GCC_VERSION = 8.4.0
- GIT = git
- GLOBAL_CFLAGS = -DSMING_ARCH=$(SMING_ARCH) -DESP_VARIANT=$(ESP_VARIANT) -DPROJECT_DIR=\"$(PROJECT_DIR)\" -DSMING_HOME=\"$(SMING_HOME)\" $(USER_CFLAGS) -DENABLE_CMD_EXECUTOR=$(ENABLE_CMD_EXECUTOR) -DHTTP_SERVER_EXPOSE_NAME=$(HTTP_SERVER_EXPOSE_NAME) -DHTTP_SERVER_EXPOSE_VERSION=$(HTTP_SERVER_EXPOSE_VERSION) -DDEBUG_PRINT_FILENAME_AND_LINE=$(DEBUG_PRINT_FILENAME_AND_LINE) -DCUST_FILE_BASE=$$* -DDEBUG_VERBOSE_LEVEL=$(DEBUG_VERBOSE_LEVEL) -DSTRING_OBJECT_SIZE=$(STRING_OBJECT_SIZE) 
- IDF_PATH = /media/slavey/416431e8-fd46-4982-896d-5025a72dd361/slavey/dev/esp32.dev.box/esp-idf
- IDF_TOOLS_PATH = /home/slavey/.espressif
- IDF_VER = v4.1-520-gc3324a8
- OS = 
- OUT_BASE = out/Esp32/debug
- PROJECT_DIR = /media/slavey/416431e8-fd46-4982-896d-5025a72dd361/slavey/dev/esp8266.dev.box/dev/Sming/samples/Basic_Serial
- PYTHON = python
- SMING_ARCH = Esp32
- SMING_CXX_STD = c++17
- SMING_HOME = /home/slavey/dev/esp8266.dev.box/dev/Sming/Sming
- SMING_RELEASE = 
- STRICT = 0
- TOOLS_BASE = $(SMING_HOME)/$(OUT_BASE)/tools
- UNAME = Linux
- USER_LIBDIR = $(SMING_HOME)/$(OUT_BASE)/lib

@slaff
Copy link
Contributor

slaff commented Nov 30, 2020

Ok, the following small change helped me stop the Basic_Serial application from segfaulting.

--- a/samples/Basic_Serial/app/application.cpp
+++ b/samples/Basic_Serial/app/application.cpp
@@ -285,10 +285,11 @@ void init()
        debugf("(DEBUG) print me again on UART0");
 
        // Initialise and prepare the second (debug) serial port
+#ifndef ARCH_ESP32
        Serial1.begin(SERIAL_BAUD_RATE);
-#ifdef ARCH_ESP32
+#else
        // Default pins are occupied by flash lines
-       Serial1.pins(17, 16);
+       Serial1.begin(SERIAL_BAUD_RATE, SERIAL_8N1, SERIAL_FULL, 17, 16);
        Serial1.onDataReceived([](Stream& stream, char arrivedChar, unsigned short availableCharsCount) {
                debug_e("arrivedchar: %c, avail = %d", arrivedChar, availableCharsCount);
        });

Also it seems that there is bigger variety in ESP32 pinout compared to ESP8266 and the one that I use is ESP32 WROOM with TX1 and RX1 29 and 28 respectively. So we should move the pin numbers as const variables in the sample.

@mikee47
Copy link
Contributor Author

mikee47 commented Nov 30, 2020

I re-tested with builds on both Windows and Linux and all fine. Your esp32 uses the same pins as mine, but clearly doesn't like being configured with the defaults. Fix forthcoming.

@slaff slaff merged commit 6bbcba9 into SmingHub:develop Nov 30, 2020
@mikee47 mikee47 deleted the dev/esp32 branch November 30, 2020 14:19
@slaff
Copy link
Contributor

slaff commented Nov 30, 2020

@mikee47 Something broke the generation of the documentation. Excerpt from travis logs(https://travis-ci.org/github/SmingHub/Sming/jobs/746741886)

make[2]: Leaving directory '/home/travis/build/SmingHub/Sming/docs'
Extension error:
Could not import extension sphinxcontrib.seqdiag (exception: cannot import name 'u')
None
Makefile:77: recipe for target 'html' failed
make[1]: *** [html] Error 2

Can it be that Esp32 arch is now removing/adding python stuff that breaks the generation of the documentation?

@mikee47
Copy link
Contributor Author

mikee47 commented Dec 1, 2020

@slaff I've reviewed logs and the fault happened with the Basic_AWS commit. In either case I don't believe we did anything! Comparing working/failed logs shows that the Python 3.7 distro package version changed and that's where the fault is triggered. Some preliminary tests have failed to fix the problem, and I think we'll have to upgrade some doc packages which will probably meanmoving off sphinx 1.8.5. That is pretty old now...

@slaff
Copy link
Contributor

slaff commented Dec 1, 2020

packages which will probably mean moving off sphinx 1.8.5. That is pretty old now...

Is there something in particular holding us back at version 1.8.5? If not let's upgrade to the latest Sphinx version. As far as I can see on my Ubuntu distribution the pip version is 3.3.x:

$ pip install -U sphinx

Collecting sphinx
  Downloading Sphinx-3.3.1-py3-none-any.whl (2.9 MB)

@slaff
Copy link
Contributor

slaff commented Dec 1, 2020

My digging into the Travis logs showed the following:

From: https://api.travis-ci.org/v3/job/742560539/log.txt

ERROR: After October 2020 you may experience errors when installing or updating packages. This is because pip will change the way that it resolves dependency conflicts.

We recommend you use --use-feature=2020-resolver to test your packages with the new resolver before it becomes the default.

sphinxcontrib-seqdiag 2.0.0 requires Sphinx>=2.0, but you'll have sphinx 1.8.5 which is incompatible.

The used packages where the build is succeeding are the ones below (excerpt from the same log file)

Successfully installed attrdict-2.0.1 blockdiag-2.0.1 breathe-4.11.1 cairosvg-2.5.0 cssselect2-0.3.0 defusedxml-0.6.0 funcparserlib-0.3.6 imagesize-1.2.0 m2r-0.2.1 mistune-0.8.4 packaging-20.4 pillow-7.2.0 pyparsing-2.4.7 seqdiag-2.0.0 snowballstemmer-2.0.0 sphinx-1.8.5 sphinx-copybutton-0.3.1 sphinxcontrib-seqdiag-2.0.0 sphinxcontrib-serializinghtml-1.1.4 sphinxcontrib-wavedrom-2.1.1 sphinxcontrib-websupport-1.2.4 svgwrite-1.3.1 tinycss2-1.0.2 wavedrom-2.0.3.post2 webcolors-1.11.1 webencodings-0.5.1 xcffib-0.10.1

And in the latest builds below are the ones that are failing:

Successfully installed Pillow-7.2.0 attrdict-2.0.1 blockdiag-2.0.1 breathe-4.11.1 cairosvg-2.5.0 cssselect2-0.3.0 defusedxml-0.6.0 funcparserlib-0.3.6 imagesize-1.2.0 m2r-0.2.1 mistune-0.8.4 packaging-20.7 pyparsing-2.4.7 seqdiag-2.0.0 setuptools-50.3.2 snowballstemmer-2.0.0 sphinx-1.8.5 sphinx-copybutton-0.3.1 sphinxcontrib-seqdiag-0.8.5 sphinxcontrib-serializinghtml-1.1.4 sphinxcontrib-wavedrom-2.1.1 sphinxcontrib-websupport-1.2.4 svgwrite-1.3.1 tinycss2-1.0.2 wavedrom-2.0.3.post2 webcolors-1.11.1 webencodings-0.5.1 xcffib-0.11.1

The major difference is sphinxcontrib-seqdiag which is downgraded in the latest builds from 2.0.0 to 0.8.5

image

I have to read a bit more about pip resolves and maybe can find a way to use the old resolver that was working for us. So stay tuned ...

@slaff
Copy link
Contributor

slaff commented Dec 1, 2020

See #2160.

@slaff
Copy link
Contributor

slaff commented Dec 4, 2020

I've not touched them until now and was impressed with how easily Sming builds and runs on them. Awesome work!

Awesome work thanks to you ;-) And with your help and the help from other contributors things will only get better. We may add soon support for the RISC-V based ESP32 microcontroller.

@slaff slaff removed the 0 - Backlog label Dec 4, 2020
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.

None yet

3 participants