由于官方的lv_micropython编译ESP32S3/S2/C3会报错,因为这些芯片的esp-idf底层重写了接口,参照网友提供的方法修改lv_bindings/driver/esp32里的文件,解决编译错误。
问题列举:Issues · lvgl/lv_binding_micropython · GitHub
一、修改lv_bindings
1、修改espidf.h文件
文件路径:lv_micropython\lib\lv_bindings\driver\esp32
错误提示:
error: implicit declaration of function 'I2S_TIMING_REG'; did you mean 'I2S_RX_TIMING_REG'? [-Werror=implicit-function-declaration]
REG_SET_BIT( I2S_TIMING_REG(i2s_num), BIT(9));
解决方案:
SPH0645_WORKAROUND()函数之前增加代码
#if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2
#define I2S_TIMING_REG I2S_TX_TIMING_REG
#define I2S_CONF_REG I2S_TX_CONF_REG
#endif
错误提示:
/home/caiyong/share/lv_micropython/lib/lv_bindings/driver/esp32/espidf.h:180:21: error: 'SPI_HOST' undeclared here (not in a function); did you mean 'SPI3_HOST'?
ENUM_SPI_HOST = SPI_HOST,
^~~~~~~~
SPI3_HOST
/home/caiyong/share/lv_micropython/lib/lv_bindings/driver/esp32/espidf.h:181:22: error: 'HSPI_HOST' undeclared here (not in a function); did you mean 'SPI3_HOST'?
ENUM_HSPI_HOST = HSPI_HOST,
^~~~~~~~~
SPI3_HOST
/home/caiyong/share/lv_micropython/lib/lv_bindings/driver/esp32/espidf.h:182:22: error: 'VSPI_HOST' undeclared here (not in a function); did you mean 'SPI3_HOST'?
ENUM_VSPI_HOST = VSPI_HOST,
^~~~~~~~~
SPI3_HOST
解决方案:
将以下代码
// SPI HOST enum was changed to macros on v4
enum {
ENUM_SPI_HOST = SPI_HOST,
ENUM_HSPI_HOST = HSPI_HOST,
ENUM_VSPI_HOST = VSPI_HOST,
};
#endif
改为
// SPI HOST enum was changed to macros on v4
enum {
#ifdef CONFIG_IDF_TARGET_ESP32
ENUM_SPI_HOST = SPI_HOST,
ENUM_HSPI_HOST = HSPI_HOST,
ENUM_VSPI_HOST = VSPI_HOST,
#else
ENUM_SPI_HOST = SPI1_HOST,
ENUM_HSPI_HOST = SPI2_HOST,
ENUM_VSPI_HOST = SPI3_HOST,
#endif
};
#endif
2、修改modrtch.c文件
文件路径:lv_micropython\lib\lv_bindings\driver\esp32
错误提示:
error: 'ADC1_GPIO36_CHANNEL' undeclared here (not in a function); did you mean 'ADC1_GPIO6_CHANNEL'?
#define GPIO_TO_ADC_ELEMENT(x) [x] = CONCAT3(ADC1_GPIO, x, _CHANNEL)
解决方案:
将以下代码
static const int gpio_to_adc[] = {
GPIO_TO_ADC_ELEMENT(36),
GPIO_TO_ADC_ELEMENT(37),
GPIO_TO_ADC_ELEMENT(38),
GPIO_TO_ADC_ELEMENT(39),
GPIO_TO_ADC_ELEMENT(32),
GPIO_TO_ADC_ELEMENT(33),
GPIO_TO_ADC_ELEMENT(34),
GPIO_TO_ADC_ELEMENT(35),
};
改为
static const int gpio_to_adc[] = {
#if (CONFIG_IDF_TARGET_ESP32)
GPIO_TO_ADC_ELEMENT(36),
GPIO_TO_ADC_ELEMENT(37),
GPIO_TO_ADC_ELEMENT(38),
GPIO_TO_ADC_ELEMENT(39),
GPIO_TO_ADC_ELEMENT(32),
GPIO_TO_ADC_ELEMENT(33),
GPIO_TO_ADC_ELEMENT(34),
GPIO_TO_ADC_ELEMENT(35),
#elif (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3)
GPIO_TO_ADC_ELEMENT(1),
GPIO_TO_ADC_ELEMENT(2),
GPIO_TO_ADC_ELEMENT(3),
GPIO_TO_ADC_ELEMENT(4),
GPIO_TO_ADC_ELEMENT(5),
GPIO_TO_ADC_ELEMENT(6),
GPIO_TO_ADC_ELEMENT(7),
GPIO_TO_ADC_ELEMENT(8),
GPIO_TO_ADC_ELEMENT(9),
GPIO_TO_ADC_ELEMENT(10),
#elif (CONFIG_IDF_TARGET_ESP32C3)
GPIO_TO_ADC_ELEMENT(1),
GPIO_TO_ADC_ELEMENT(2),
GPIO_TO_ADC_ELEMENT(3),
GPIO_TO_ADC_ELEMENT(4),
#endif
};
错误提示:
error: implicit declaration of function 'adc_gpio_init'; did you mean 'gpio_init'? [-Werror=implicit-function-declaration]
adc_gpio_init(ADC_UNIT_1, adc_channel);
^~~~~~~~~~~~~
gpio_init
解决方案:
将以下代码
adc_gpio_init(ADC_UNIT_1, adc_channel);
改为
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
adc_gpio_init(ADC_UNIT_1, adc_channel);
#endif
3、修改mkrules.cmake文件
文件路径:lv_micropython\lib\lv_bindings
将以下代码
FILTER
i2s_ll.h
i2s_hal.h
esp_intr_alloc.h
soc/spi_periph.h
rom/ets_sys.h
soc/sens_struct.h
soc/rtc.h
driver/periph_ctrl.h
改为
FILTER
i2s_ll.h
i2s_hal.h
esp_intr_alloc.h
soc/spi_periph.h
rom/ets_sys.h
soc/sens_struct.h
soc/rtc.h
driver/periph_ctrl.h
esp_eth/include/esp_eth.h
esp_eth/include/esp_eth_netif_glue.h
esp_eth/include/esp_eth_phy.h
esp_eth/include/esp_eth_com.h
esp_eth/include/esp_eth_mac.h
esp_eth/include/eth_phy_regs_struct.h
freertos/FreeRTOSConfig_arch.h
rom/lldesc.h
driver/rtc_io.h
4、修改文件espidf.c
文件路径:lv_micropython\lib\lv_bindings\driver\esp32
错误提示:
/home/caiyong/.espressif/tools/xtensa-esp32s3-elf/esp-2021r2-8.4.0/xtensa-esp32s3-elf/bin/../lib/gcc/xtensa-esp32s3-elf/8.4.0/../../../../xtensa-esp32s3-elf/bin/ld: esp-idf/main/libmain.a(lv_espidf.c.obj):(.rodata.mp_gpio_input_get_high_mpobj+0xc): undefined reference to `gpio_input_get_high'
/home/caiyong/.espressif/tools/xtensa-esp32s3-elf/esp-2021r2-8.4.0/xtensa-esp32s3-elf/bin/../lib/gcc/xtensa-esp32s3-elf/8.4.0/../../../../xtensa-esp32s3-elf/bin/ld: esp-idf/main/libmain.a(lv_espidf.c.obj):(.rodata.mp_gpio_output_set_high_mpobj+0xc): undefined reference to `gpio_output_set_high'
原因:gpio_output_set_high()、gpio_input_get_high()这些函数在esp-idf的/components/esp_rom/include/esp32s3/rom/gpio.h中定义了,但是没有实现。
解决方案参考:
在文件开头部分添加以下代码
#if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2
inline uint32_t gpio_input_get_high(void){return 0;}
inline void gpio_output_set_high(uint32_t set_mask, uint32_t clear_mask, uint32_t enable_mask, uint32_t disable_mask){}
inline void gpio_pad_input_disable(uint32_t gpio_num){}
#endif
乐鑫开发人员解决方案:ESP32-S3 ROM not provide gpio_input_get_high and gpio_output_set_high function? (IDFGH-8773) · Issue #10205 · espressif/esp-idf · GitHub
去掉gpio.h中没有实现函数的定义。
二、编译
1、编译ESP32S3
参考文档:ubuntu环境编译micropython(lvgl for esp32s3)固件 - 哔哩哔哩 (bilibili.com)
执行命令:
cd lv_micropython
export IDF_TARGET=esp32s3
make -C ports/esp32 LV_CFLAGS="-DLV_COLOR_DEPTH=16" BOARD=GENERIC_S3
错误提示:
Error: app partition is too small for binary micropython.bin size 0x1f0110:
- Part 'factory' 0/0 @ 0x10000 size 0x1f0000 (overflow 0x110)
esp-idf/esptool_py/CMakeFiles/app_check_size.dir/build.make:70: recipe for target 'esp-idf/esptool_py/CMakeFiles/app_check_size' failed
原因:编译出的micropython.bin 的尺寸是0x1f0110而分配给app的partition为0x1f0000。
解决方案:修改partitions table文件,打开ports/esp32/build-GENERIC_S3/sdkconfig可以看到所用partitions table文件为partitions-8MiB.csv,鼠标右键,选择Open With LibreOffice Calc。
总共8MB,vfs分了6MB,factory 分了1.9375MB。将factory改为0x2F0000,vfs改为0x500000。
修改之后再次编译,编译成功:
2、编译EPS32C3
执行指令:
cd lv_micropython
export IDF_TARGET=esp32c3
make -C ports/esp32 LV_CFLAGS="-DLV_COLOR_DEPTH=16" BOARD=GENERIC_c3
错误提示:
/home/caiyong/share/esp-idf/components/soc/esp32c3/include/soc/soc.h:75:50: error: 'DR_REG_I2S_BASE' undeclared (first use in this function); did you mean 'DR_REG_I2S0_BASE'?
#define REG_I2S_BASE(i) (DR_REG_I2S_BASE + (i) * 0x1E000)
原因:没有定义DR_REG_I2S_BASE,esp-idf/components/soc/esp32c3/include/soc/soc.h中只定义了DR_REG_I2S0_BASE。
解决方案:将DR_REG_I2S_BASE 改为DR_REG_I2S0_BASE。