diff --git a/components/esp32/CMakeLists.txt b/components/esp32/CMakeLists.txt index 735084f55..2b6a82a07 100644 --- a/components/esp32/CMakeLists.txt +++ b/components/esp32/CMakeLists.txt @@ -91,7 +91,10 @@ else() ) if(CONFIG_SPIRAM_CACHE_WORKAROUND) - add_compile_options(-mfix-esp32-psram-cache-issue) + # Note: Adding as a PUBLIC compile option here causes this option to propagate to all components that depend on esp32. + # + # To handle some corner cases, the same flag is set in project_include.cmake + target_compile_options(esp32 PUBLIC -mfix-esp32-psram-cache-issue) else() target_linker_script(esp32 "ld/esp32.rom.spiram_incompatible_fns.ld") endif() diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index 23fcf3f30..0d095da08 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -124,7 +124,8 @@ config SPIRAM_CACHE_WORKAROUND help Revision 1 of the ESP32 has a bug that can cause a write to PSRAM not to take place in some situations when the cache line needs to be fetched from external RAM and an interrupt occurs. This enables a - fix in the compiler that makes sure the specific code that is vulnerable to this will not be emitted. + fix in the compiler (-mfix-esp32-psram-cache-issue) that makes sure the specific code that is vulnerable + to this will not be emitted. This will also not use any bits of newlib that are located in ROM, opting for a version that is compiled with the workaround and located in flash instead. diff --git a/components/esp32/project_include.cmake b/components/esp32/project_include.cmake new file mode 100644 index 000000000..d54d6a9be --- /dev/null +++ b/components/esp32/project_include.cmake @@ -0,0 +1,8 @@ +if(CONFIG_SPIRAM_CACHE_WORKAROUND) + # We do this here as well as in CMakeLists.txt, because targets that + # are not part of the ESP-IDF build system (for cases where a generic + # non-IDF CMakeLists.txt file is imported into a component) don't depend + # on the esp32 component so don't get the extra flag. This handles that case. + add_compile_options(-mfix-esp32-psram-cache-issue) +endif() + diff --git a/docs/en/api-guides/build-system-cmake.rst b/docs/en/api-guides/build-system-cmake.rst index b6888870a..941af940c 100644 --- a/docs/en/api-guides/build-system-cmake.rst +++ b/docs/en/api-guides/build-system-cmake.rst @@ -720,6 +720,8 @@ the ESP-IDF build system entirely by using a CMake feature called ExternalProjec - The second set of commands adds a library target, which points to the "imported" library file built by the external system. Some properties need to be set in order to add include directories and tell CMake where this file is. - Finally, the generated library is added to `ADDITIONAL_MAKE_CLEAN_FILES`_. This means ``make clean`` will delete this library. (Note that the other object files from the build won't be deleted.) +.. note:: When using an external build process with PSRAM, remember to add ``-mfix-esp32-psram-cache-issue`` to the C compiler arguments. See :ref:`CONFIG_SPIRAM_CACHE_WORKAROUND` for details of this flag. + .. _ADDITIONAL_MAKE_CLEAN_FILES_note: ExternalProject dependencies, clean builds diff --git a/docs/en/api-guides/build-system.rst b/docs/en/api-guides/build-system.rst index e1c0c045e..0da949451 100644 --- a/docs/en/api-guides/build-system.rst +++ b/docs/en/api-guides/build-system.rst @@ -586,6 +586,7 @@ $(COMPONENT_LIBRARY) for the project make process to link into the app binary. (Actually, even this is not strictly necessary - if the COMPONENT_ADD_LDFLAGS variable is overridden then the component can instruct the linker to link other binaries instead.) +.. note:: When using an external build process with PSRAM, remember to add ``-mfix-esp32-psram-cache-issue`` to the C compiler arguments. See :ref:`CONFIG_SPIRAM_CACHE_WORKAROUND` for details of this flag. .. _esp-idf-template: https://github.com/espressif/esp-idf-template .. _GNU Make Manual: https://www.gnu.org/software/make/manual/make.html diff --git a/tools/ci/test_build_system_cmake.sh b/tools/ci/test_build_system_cmake.sh index f9bf0a264..21b4eca96 100755 --- a/tools/ci/test_build_system_cmake.sh +++ b/tools/ci/test_build_system_cmake.sh @@ -223,6 +223,17 @@ function run_tests() grep "CONFIG_PARTITION_TABLE_OFFSET=0x10000" sdkconfig || failure "The define from sdkconfig.defaults should be into sdkconfig" grep "CONFIG_PARTITION_TABLE_TWO_OTA=y" sdkconfig || failure "The define from sdkconfig should be into sdkconfig" + print_status "Building a project with CMake and PSRAM workaround, all files compile with workaround" + cp sdkconfig sdkconfig.psram + rm -rf build + echo "CONFIG_SPIRAM_SUPPORT=y" >> sdkconfig.psram + echo "CONFIG_SPIRAM_CACHE_WORKAROUND=y" >> sdkconfig.psram + # note: we do 'reconfigure' here, as we just need to run cmake + idf.py reconfigure -D SDKCONFIG="`pwd`/sdkconfig.psram" + grep -q '"command"' build/compile_commands.json || failure "compile_commands.json missing or has no no 'commands' in it" + (grep '"command"' build/compile_commands.json | grep -v mfix-esp32-psram-cache-issue) && failure "All commands in compile_commands.json should use PSRAM cache workaround" + rm sdkconfig.psram + print_status "All tests completed" if [ -n "${FAILURES}" ]; then echo "Some failures were detected:" diff --git a/tools/cmake/idf_functions.cmake b/tools/cmake/idf_functions.cmake index 6ae7698da..b24a56f3f 100644 --- a/tools/cmake/idf_functions.cmake +++ b/tools/cmake/idf_functions.cmake @@ -65,14 +65,16 @@ function(idf_set_global_compiler_options) add_compile_options(-Og) endif() - add_c_compile_options(-std=gnu99) + # Note: the visual studio generator doesn't support this syntax + add_compile_options("$<$:-std=gnu99>") - add_cxx_compile_options(-std=gnu++11 -fno-rtti) + add_compile_options("$<$:-std=gnu++11>") + add_compile_options("$<$:-fno-rtti>") if(CONFIG_CXX_EXCEPTIONS) - add_cxx_compile_options(-fexceptions) + add_compile_options("$<$:-fexceptions>") else() - add_cxx_compile_options(-fno-exceptions) + add_compile_options("$<$:-fno-exceptions>") endif() # Default compiler configuration @@ -89,9 +91,7 @@ function(idf_set_global_compiler_options) -Wextra -Wno-unused-parameter -Wno-sign-compare) - add_c_compile_options( - -Wno-old-style-declaration - ) + add_compile_options("$<$:-Wno-old-style-declaration>") if(CONFIG_DISABLE_GCC8_WARNINGS) add_compile_options( @@ -258,4 +258,4 @@ function(idf_get_git_revision) add_definitions(-DIDF_VER=\"${IDF_VER}\") git_submodule_check("${IDF_PATH}") set(IDF_VER ${IDF_VER} PARENT_SCOPE) -endfunction() \ No newline at end of file +endfunction() diff --git a/tools/cmake/utilities.cmake b/tools/cmake/utilities.cmake index bfe10c090..fcbd6f857 100644 --- a/tools/cmake/utilities.cmake +++ b/tools/cmake/utilities.cmake @@ -73,30 +73,6 @@ function(move_if_different source destination) endfunction() - -# add_compile_options variant for C++ code only -# -# This adds global options, set target properties for -# component-specific flags -function(add_cxx_compile_options) - foreach(option ${ARGV}) - # note: the Visual Studio Generator doesn't support this... - add_compile_options($<$:${option}>) - endforeach() -endfunction() - -# add_compile_options variant for C code only -# -# This adds global options, set target properties for -# component-specific flags -function(add_c_compile_options) - foreach(option ${ARGV}) - # note: the Visual Studio Generator doesn't support this... - add_compile_options($<$:${option}>) - endforeach() -endfunction() - - # target_add_binary_data adds binary data into the built target, # by converting it to a generated source file which is then compiled # to a binary object as part of the build