ESP32-S3编译lvgl-micropython固件

ESP32-S3编译lvgl-micropython固件

网上一堆不靠谱的,虽然有固件直接下载,但是自己动手能自定义更多的选项

此篇文章仅描述如何编译固件,至于固件里面的选项以及如何刷入等,请看我之后发布的另外几篇文章

编译环境

Ubuntu22.04

gcc version 11.3.0 (Ubuntu 11.3.0-1ubuntu1~22.04.1)

esp-idf v4.4

因为需要访问github,并且资源很多,建议在翻墙的环境或者非境内服务器操作,或者可以使用github镜像源,防止出现奇奇怪怪的网路错误问题

参考资料

micropython对于esp32的编译说明

lv_micropython关于支持esp32s3的讨论

lv_micropython

环境准备

定义一个构建目录变量

根据自己修改,重开终端之后需要重新定义

export dir=/www/wwwroot/esp32s3

esp-idf(esp32s3需要v4.4版本或者以上的idf)

mkdir -p $dir
cd $dir
git clone -b v4.4 --recursive https://github.com/espressif/esp-idf.git
cd $dir/esp-idf
git checkout v4.4
git submodule update --init --recursive
./install.sh

完成安装之后激活idf环境

# 激活idf环境,重新打开终端之后需要重新激活
source $dir/export.sh

micropython

如果仅需编译lvgl-micropython固件,这一步可以省略,因为lv-micropython中已经包含了micropython环境

cd $dir
git clone https://github.com/micropython/micropython.git
cd $dir/micropython
make -C mpy-cross
cd $dir/micropython/ports/esp32
make submodules

这时如果没有出错,就可以正常编译固件了(如果不改参数,默认编译的就是n8r8的固件和官方的一样)

make BOARD=GENERIC_S3_SPIRAM_OCT

完成之后,在同一级的目录下会出现build-GENERIC_S3_SPIRAM_OCT目录,里面的firmware.bin就是生成好的固件,可以使用工具刷入

lv_micropython

基本步骤和官网的说明一样

cd $dir
git clone https://github.com/lvgl/lv_micropython.git
cd $dir/lv_micropython
git submodule update --init --recursive lib/lv_bindings
make -C mpy-cross
cd $dir/lv_micropython/ports/esp32
make submodules

此时如果没报错,lv_micropython环境已经准备就绪,使用以下命令来构建固件

make BOARD=GENERIC_S3_SPIRAM

这个命令不出意外的话就报错了,报错解决请看下文

完成之后,在同一级的目录下会出现build-GENERIC_S3_SPIRAM目录,里面的firmware.bin就是生成好的固件,可以使用工具刷入

关于ESP32-S3编译lv_micropython报错

大概错误如下:

/www/wwwroot/clone/esp32-s3/lv_micropython/lib/lv_bindings/driver/esp32/modrtch.c:394:5: 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
cc1: some warnings being treated as errors
make[3]: *** [esp-idf/main/CMakeFiles/__idf_main.dir/build.make:7472:esp-idf/main/CMakeFiles/__idf_main.dir/www/wwwroot/clone/esp32-s3/lv_micropython/lib/lv_bindings/driver/esp32/modrtch.c.obj] 错误 1
cc1: some warnings being treated as errors
make[3]: *** [esp-idf/main/CMakeFiles/idf_main.dir/build.make:7500:esp-idf/main/CMakeFiles/idf_main.dir///lv_espidf.c.obj] 错误 1
GEN /www/wwwroot/clone/esp32-s3/lv_micropython/ports/esp32/build-GENERIC_S3_SPIRAM_OCT/frozen_content.c
make[3]: 离开目录“/www/wwwroot/clone/esp32-s3/lv_micropython/ports/esp32/build-GENERIC_S3_SPIRAM_OCT”
make[2]: *** [CMakeFiles/Makefile2:4971:esp-idf/main/CMakeFiles/__idf_main.dir/all] 错误 2
make[2]: 离开目录“/www/wwwroot/clone/esp32-s3/lv_micropython/ports/esp32/build-GENERIC_S3_SPIRAM_OCT”
make[1]: *** [Makefile:136:all] 错误 2
make[1]: 离开目录“/www/wwwroot/clone/esp32-s3/lv_micropython/ports/esp32/build-GENERIC_S3_SPIRAM_OCT”
make failed with exit code 2
make: *** [Makefile:34:all] 错误 2

github上也有类似的反馈:https://github.com/lvgl/lv_binding_micropython/issues/227

解决方法查看这个pullrequest:https://github.com/lvgl/lv_binding_micropython/pull/243/files#diff-a83d385a7a3e9e5931ba0ea4e886753ed2496df54b96f2cbc736832f67ec042d

手动修改下这几个文件:

driver/esp32/espidf.c
   ili9xxx_send_data_dma(disp_drv, color_p, size * color_size, dc, *spi_ptr);
}
//249行
#if CONFIG_IDF_TARGET_ESP32S3
// Cheat linker :)
// Related issue:
//     https://github.com/espressif/esp-idf/issues/10203
//     https://github.com/espressif/esp-idf/issues/10204
//     https://github.com/espressif/esp-idf/issues/10205

uint32_t gpio_input_get_high(void) {
    return 0;
}

void gpio_output_set_high(uint32_t set_mask, uint32_t clear_mask, uint32_t enable_mask, uint32_t disable_mask) {
}

esp_err_t rtc_gpio_force_hold_all(void) {
    return ESP_OK;
}
#endif

image-20230601130901059

driver/esp32/espidf.h
//83行
static inline void SPH0645_WORKAROUND(int i2s_num)
{
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
    REG_SET_BIT( I2S_TIMING_REG(i2s_num), BIT(9));
    REG_SET_BIT( I2S_CONF_REG(i2s_num), I2S_RX_MSB_SHIFT);
#elif CONFIG_IDF_TARGET_ESP32S3
    REG_SET_BIT( I2S_RX_TIMING_REG(i2s_num), BIT(9));
    REG_SET_BIT( I2S_RX_CONF_REG(i2s_num), I2S_RX_MSB_SHIFT);
#endif
}

/////////////////////////////////////////////////////////////////////////////////////////////
//182行
#if defined(ESP_IDF_VERSION_MAJOR) && ESP_IDF_VERSION_MAJOR >= 4
// SPI HOST enum was changed to macros on v4
enum {
#if CONFIG_IDF_TARGET_ESP32
    ENUM_SPI_HOST = SPI_HOST,
    ENUM_HSPI_HOST = HSPI_HOST,
    ENUM_VSPI_HOST = VSPI_HOST,
#elif CONFIG_IDF_TARGET_ESP32S3
    ENUM_SPI_HOST = SPI1_HOST,
    ENUM_HSPI_HOST = SPI2_HOST,
    ENUM_VSPI_HOST = SPI3_HOST,
#endif
};
#endif

image-20230601131027355

driver/esp32/ili9XXX.py

            esp.gpio_set_direction(self.mosi, esp.GPIO_MODE.OUTPUT)
            esp.gpio_set_direction(self.clk, esp.GPIO_MODE.OUTPUT)
//234行
            # USE SPI_DMA_CH_AUTO
            ret = esp.spi_bus_initialize(self.spihost, buscfg, 3)
            if ret != 0: raise RuntimeError("Failed initializing SPI bus")

        self.trans_buffer = esp.heap_caps_malloc(TRANS_BUFFER_LEN, esp.MALLOC_CAP.DMA)

image-20230601131134020

driver/esp32/modrtch.c
#endif

#define GPIO_TO_ADC_ELEMENT(x) [x] = CONCAT3(ADC1_GPIO, x, _CHANNEL)
//60行
#if CONFIG_IDF_TARGET_ESP32
// ESP32 ADC1 has 8 channels
static const int gpio_to_adc[] = {
        GPIO_TO_ADC_ELEMENT(36),
        GPIO_TO_ADC_ELEMENT(37),

    
    static const int gpio_to_adc[] = {
        GPIO_TO_ADC_ELEMENT(34),
        GPIO_TO_ADC_ELEMENT(35),
};
//72行
#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2
// ESP32-C3 & ESP32-H2 ADC1 has 5 channels
static const int gpio_to_adc[] = {
        GPIO_TO_ADC_ELEMENT(0),
        GPIO_TO_ADC_ELEMENT(1),
        GPIO_TO_ADC_ELEMENT(2),
        GPIO_TO_ADC_ELEMENT(3),
        GPIO_TO_ADC_ELEMENT(4),
};
#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
// ESP32-S2 & ESP32-S3 ADC1 has 10 channels
static const int gpio_to_adc[] = {
        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),
};
#endif

//////////////////////////////////////////////////////////////////////////////
// Module definition
    
    
    
    
    adc1_channel_t adc_channel = gpio_to_adc[measure];

//421行
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
    adc_gpio_init(ADC_UNIT_1, adc_channel);
#endif
    adc1_config_width(ADC_WIDTH_BIT_12);
    adc1_config_channel_atten(adc_channel,ADC_ATTEN_DB_11);

image-20230601131507878

driver/include/common.h
STATIC mp_int_t mp_ptr_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags)
{
//21行
    mp_ptr_t *self = (mp_ptr_t*)MP_OBJ_TO_PTR(self_in);

    if (flags & MP_BUFFER_WRITE) {
        // read-only ptr

image-20230601131553690

mkrules.cmake
    # ESPIDF bindings

    if(ESP_PLATFORM)
# 112行
        if (IDF_TARGET STREQUAL "esp32s3")
            # 1. not support Ethernet MAC Interface.
            # 2. esp32s3.rom.ld not provide lldesc_xxx functions for now.
            LIST(APPEND FILTER_HEADERS
                        esp_eth.h
                        esp_eth_phy.h
                        esp_eth_netif_glue.h
                        lldesc.h
                )

            if (IDF_VERSION_MAJOR EQUAL 4)
                # xt_clock_freq was deprecated.
                LIST(APPEND FILTER_HEADERS
                    FreeRTOSConfig_arch.h
                )
            endif(IDF_VERSION_MAJOR EQUAL 4)
        endif(IDF_TARGET STREQUAL "esp32s3")

        file(GLOB_RECURSE LV_ESPIDF_HEADERS ${IDF_PATH}/components/*.h ${LV_BINDINGS_DIR}/driver/esp32/*.h)
        lv_bindings(
            OUTPUT
            
            
            
#################
                soc/sens_struct.h
                soc/rtc.h
                driver/periph_ctrl.h
# 149行
                ${FILTER_HEADERS}
        )
    endif(ESP_PLATFORM)

image-20230601131733972

改完重新编译就不会报这些错了

评论区
头像
文章目录