toitlang / toit

Program your microcontrollers in a fast and robust high-level language.
https://toitlang.org/
GNU Lesser General Public License v2.1
1.22k stars 81 forks source link

Add ESP32-C3 (32-bit RISC-V) platform support #89

Open dsobotta opened 2 years ago

dsobotta commented 2 years ago

Should be possible with some tweaks and extensions to the Toit build pipeline.

Initial testing is showing underlying compatibility with ESP-IDF; just a matter of identifying and abstracting all of the necessary entry points in the Toit build pipeline. Initial support will only be targeting arm64/Linux hosts for now, to minimize complexity.

dsobotta commented 2 years ago

Could probably use some assistance at this point. What would it take to utilize cmake or idf.py instead of make? Is there some context as to why the make path was used for ESP32 in the Toit build pipeline?

libtoit is compiling with the changes found here: https://github.com/dsobotta/toit

After compiling libtoit_image.a , we get the following errors:

[dusten@dls-shuttle toit]$ make esp32 ESP32_CHIP=esp32c3
mkdir -p build/esp32c3/
make -C toolchains/esp32c3 -s /home/dusten/git/toit/build/esp32c3/include/sdkconfig.h
Toolchain path: /home/dusten/.espressif/tools/riscv32-esp-elf/esp-2021r1-8.4.0/riscv32-esp-elf/bin/riscv32-esp-elf-gcc
Toolchain version: esp-2021r1
Compiler version: 8.4.0
Python requirements from /home/dusten/git/toit/third_party/esp-idf/requirements.txt are satisfied.
/home/dusten/git/toit/third_party/esp-idf/components/esp_timer/component.mk:21: *** esp_timer is only supported by the Make build system for esp32 chip. For other chips, use the Cmake build system.  Stop.
(cd build/host && cmake ../.. -G Ninja -DCMAKE_BUILD_TYPE=Release)
CMake Deprecation Warning at third_party/esp-idf/components/mbedtls/mbedtls/CMakeLists.txt:1 (cmake_minimum_required):
  The OLD behavior for policy CMP0076 will be removed from a future version
  of CMake.

  The cmake-policies(7) manual explains that the OLD behaviors of all
  policies are deprecated and that a policy should be set to OLD only under
  specific short-term circumstances.  Projects should be ported to the NEW
  behavior and not rely on setting a policy to OLD.

-- Configuring done
-- Generating done
-- Build files have been written to: /home/dusten/git/toit/build/host
(cd build/host && ninja build_toitvm)
ninja: no work to do.
build/host/bin/toitc -w build/snapshot examples/hello.toit -Dwifi.ssid= -Dwifi.password=
(cd build/host && ninja build_toitvm)
ninja: no work to do.
build/host/bin/toitvm tools/snapshot_to_image.toit build/snapshot build/esp32c3/esp32c3.image.s
(cd build/esp32c3 && IMAGE=build/esp32c3/esp32c3.image.s cmake ../../ -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=../../toolchains/esp32c3/esp32c3.cmake --no-warn-unused-cli)
Not searching for unused variables given on the command line.
CMake Deprecation Warning at third_party/esp-idf/components/mbedtls/mbedtls/CMakeLists.txt:1 (cmake_minimum_required):
  The OLD behavior for policy CMP0076 will be removed from a future version
  of CMake.

  The cmake-policies(7) manual explains that the OLD behaviors of all
  policies are deprecated and that a policy should be set to OLD only under
  specific short-term circumstances.  Projects should be ported to the NEW
  behavior and not rely on setting a policy to OLD.

-- Could NOT find Threads (missing: Threads_FOUND) 
-- Configuring done
-- Generating done
-- Build files have been written to: /home/dusten/git/toit/build/esp32c3
(cd build/esp32c3 && ninja toit_image)
[2/2] Linking CXX static library lib/libtoit_image.a
#idf.py set-target esp32c3
make -C toolchains/esp32c3/
make[1]: Entering directory '/home/dusten/git/toit/toolchains/esp32c3'
Toolchain path: /home/dusten/.espressif/tools/riscv32-esp-elf/esp-2021r1-8.4.0/riscv32-esp-elf/bin/riscv32-esp-elf-gcc
Toolchain version: esp-2021r1
Compiler version: 8.4.0
Python requirements from /home/dusten/git/toit/third_party/esp-idf/requirements.txt are satisfied.
make[2]: Entering directory '/home/dusten/git/toit/build/esp32c3/esp_timer'
/home/dusten/git/toit/third_party/esp-idf/components/esp_timer/component.mk:21: *** esp_timer is only supported by the Make build system for esp32 chip. For other chips, use the Cmake build system.  Stop.
make[2]: Leaving directory '/home/dusten/git/toit/build/esp32c3/esp_timer'
make[2]: Entering directory '/home/dusten/git/toit/third_party/esp-idf/components/bootloader/subproject'
make[3]: Entering directory '/home/dusten/git/toit/build/esp32c3/bootloader/esp_hw_support'
CC /home/dusten/git/toit/build/esp32c3/bootloader/esp_hw_support/compare_set.o
/home/dusten/git/toit/third_party/esp-idf/components/esp_hw_support/include/soc/compare_set.h: Assembler messages:
/home/dusten/git/toit/third_party/esp-idf/components/esp_hw_support/include/soc/compare_set.h:33: Error: unrecognized opcode `wsr a1,SCOMPARE1'
/home/dusten/git/toit/third_party/esp-idf/components/esp_hw_support/include/soc/compare_set.h:34: Error: unrecognized opcode `s32c1i a5,a0,0'
make[3]: *** [/home/dusten/git/toit/third_party/esp-idf/make/component_wrapper.mk:292: compare_set.o] Error 1
make[3]: Leaving directory '/home/dusten/git/toit/build/esp32c3/bootloader/esp_hw_support'
make[2]: *** [/home/dusten/git/toit/third_party/esp-idf/make/project.mk:644: component-esp_hw_support-build] Error 2
make[2]: Leaving directory '/home/dusten/git/toit/third_party/esp-idf/components/bootloader/subproject'
make[1]: *** [/home/dusten/git/toit/third_party/esp-idf/components/bootloader/Makefile.projbuild:43: /home/dusten/git/toit/build/esp32c3/bootloader/bootloader.bin] Error 2
make[1]: Leaving directory '/home/dusten/git/toit/toolchains/esp32c3'
make: *** [Makefile:79: build/esp32c3/toit.bin] Error 2
dsobotta commented 2 years ago

And here are the ESP-IDF changes necessary to get this far:

[dusten@dls-shuttle make]$ git diff
diff --git a/components/driver/esp32c3/include/driver/adc.h b/components/driver/esp32c3/include/driver/adc.h
index 2678a9e61..bfce779c6 100644
--- a/components/driver/esp32c3/include/driver/adc.h
+++ b/components/driver/esp32c3/include/driver/adc.h
@@ -13,6 +13,7 @@

 #pragma once

+#include "hal/adc_types.h"
 #include "driver/adc_common.h"

 #ifdef __cplusplus
diff --git a/components/freertos/port/xtensa/include/freertos/portmacro.h b/components/freertos/port/xtensa/include/freertos/portmacro.h
index 222a5ae80..9050146e3 100644
--- a/components/freertos/port/xtensa/include/freertos/portmacro.h
+++ b/components/freertos/port/xtensa/include/freertos/portmacro.h
@@ -42,6 +42,8 @@ extern "C" {
 #include <xtensa/config/core.h>
 #include <xtensa/config/system.h>      /* required for XSHAL_CLIB */
 #include <xtensa/xtruntime.h>
+
+#include "xt_instr_macros.h"
 #include "esp_private/crosscore_int.h"
 #include "esp_timer.h"              /* required for FreeRTOS run time stats */
 #include "esp_system.h"
@@ -71,7 +73,6 @@ extern "C" {

 #include "esp_system.h"
 #include "hal/cpu_hal.h"
-#include "xt_instr_macros.h"

 /* Type definitions. */
 #define portCHAR               int8_t
diff --git a/make/project.mk b/make/project.mk
index b64012db6..3569dc2ed 100644
--- a/make/project.mk
+++ b/make/project.mk
@@ -93,11 +93,11 @@ $(error IDF_PATH variable is not set to a valid directory.)
 endif

 ifdef IDF_TARGET
-ifneq ($(IDF_TARGET),esp32)
-$(error GNU Make based build system only supports esp32 target, but IDF_TARGET is set to $(IDF_TARGET))
-endif
+  ifneq ($(IDF_TARGET),esp32)
+    #$(error GNU Make based build system only supports esp32 and esp32-c3 targets, but IDF_TARGET is set to $(IDF_TARGET))
+  endif
 else
-export IDF_TARGET := esp32
+  export IDF_TARGET := esp32
 endif

@@ -407,12 +407,21 @@ COMMON_WARNING_FLAGS += -Wwrite-strings
 endif #CONFIG_COMPILER_WARN_WRITE_STRINGS

 # Flags which control code generation and dependency generation, both for C and C++
+
+ifeq ("$(ESP32_CHIP)", "esp32c3")
+COMMON_FLAGS = \
+       -Wno-frame-address \
+       -ffunction-sections -fdata-sections \
+       -fstrict-volatile-bitfields \
+       -nostdlib
+else
 COMMON_FLAGS = \
        -Wno-frame-address \
        -ffunction-sections -fdata-sections \
        -fstrict-volatile-bitfields \
        -mlongcalls \
        -nostdlib
+endif

 ifndef IS_BOOTLOADER_BUILD
 # stack protection (only one option can be selected in menuconfig)
dsobotta commented 2 years ago

Currently blocked by the need for ESP-IDF 4.4. Will continue to work on build system in the meantime, but flashed builds will always crash until we upgrade ESP-IDF.

dsobotta commented 2 years ago

Finished setting up my new pc over the weekend, so I'll be digging into upgrading ESP-IDF to 4.4 this week.

kasperl commented 2 years ago

Hi @dsobotta! We're finally on ESP-IDF v4.4. Maybe your work on ESP32-C3 support is finally unblocked?

dsobotta commented 2 years ago

Thanks for the heads up. I'll take a look tomorrow.

dsobotta commented 2 years ago

Hey @kasperl ,

This definitely gets us closer to where we need to be for esp32-c3 support.

Since I last touched this in Jan, there's been a few changes in toit source that directly include mbedtls again. Later this week, I'll have to dig through the related code and strip that out for esp32c3 builds again before I can evaluate where we are at.

But in the meantime, know that the current approach will still not be supported officially by ESP-IDF, since the toit build system depends on GNU Make. While I was technically able to generate a binary and run it on an esp32-c3 months back, it's hard to tell if the crashes were related to toit, or us hijacking the ESP-IDF build system to do something unsupported.

This will likely be a constricting factor for other esp32 variants as well.

kasperl commented 2 years ago

Hi @dsobotta,

Thank you for looking into this. We're planning to transition to CMake and maybe we're close enough to supporting C3 that we should try to get hold of a few boards. I'll let you know when we start making progress on the build system!

dsobotta commented 2 years ago

Sounds good! I think it will go quite smooth once on CMake. I've had good experiences with rust on the esp32c3 thus far.

kasperl commented 2 years ago

Hi @dsobotta! We just landed most (all?) of what is need to get Toit to work on the ESP32-C3. Check it out :)

dsobotta commented 1 year ago

Excellent. I'll take a look this weekend @kasperl !

kasperl commented 1 year ago

We're building and releasing generic firmware for the C3 by now. Have you tried it out yet, @dsobotta? I think you can do something like this on Jaguar v1.9.1:

jag flash --chip esp32c3
dsobotta commented 1 year ago

That's fantastic news @kasperl ! Unfortunately my ESP32-C3 is being used for other things right now, so I can't perform any testing on my end in the near future. Please feel free to close this issue out if things are in a good place!