diff options
Diffstat (limited to 'src/memory')
| -rw-r--r-- | src/memory/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/memory/include/himem.hpp | 78 |
2 files changed, 79 insertions, 1 deletions
diff --git a/src/memory/CMakeLists.txt b/src/memory/CMakeLists.txt index 67e64267..69afc454 100644 --- a/src/memory/CMakeLists.txt +++ b/src/memory/CMakeLists.txt @@ -1,2 +1,2 @@ -idf_component_register(SRCS "arena.cpp" INCLUDE_DIRS "include" REQUIRES "span") +idf_component_register(SRCS "arena.cpp" INCLUDE_DIRS "include" REQUIRES "span" "esp_psram") target_compile_options(${COMPONENT_LIB} PRIVATE ${EXTRA_WARNINGS}) diff --git a/src/memory/include/himem.hpp b/src/memory/include/himem.hpp new file mode 100644 index 00000000..c65091d7 --- /dev/null +++ b/src/memory/include/himem.hpp @@ -0,0 +1,78 @@ +#pragma once + +#include <cstddef> +#include <cstdint> + +#include "esp32/himem.h" +#include "span.hpp" + +/* + * Wrapper around an ESP-IDF himem allocation, which uses RAII to clean up after + * itself. + */ +template <std::size_t size> +class HimemAlloc { + public: + esp_himem_handle_t handle; + const bool is_valid; + + HimemAlloc() : is_valid(esp_himem_alloc(size, &handle) == ESP_OK) {} + + ~HimemAlloc() { + if (is_valid) { + esp_himem_free(handle); + } + } + + // Not copyable or movable. + HimemAlloc(const HimemAlloc&) = delete; + HimemAlloc& operator=(const HimemAlloc&) = delete; +}; + +/* + * Wrapper around an ESP-IDF himem allocation, which maps a HimemAlloc into the + * usable address space. Instances always contain the last memory region that + * was mapped within them. + */ +template <std::size_t size> +class MappableRegion { + private: + std::byte* bytes_; + + public: + esp_himem_rangehandle_t range_handle; + const bool is_valid; + + MappableRegion() + : bytes_(nullptr), + is_valid(esp_himem_alloc_map_range(size, &range_handle) == ESP_OK) {} + + ~MappableRegion() { + if (bytes_ != nullptr) { + esp_himem_unmap(range_handle, bytes_, size); + } + if (is_valid) { + esp_himem_free_map_range(range_handle); + } + } + + auto Get() -> cpp::span<std::byte> { + if (bytes_ != nullptr) { + return {}; + } + return {bytes_, size}; + } + + auto Map(const HimemAlloc<size> &alloc) -> cpp::span<std::byte> { + if (bytes_ != nullptr) { + ESP_ERROR_CHECK(esp_himem_unmap(range_handle, bytes_, size)); + } + ESP_ERROR_CHECK(esp_himem_map(alloc.handle, range_handle, 0, 0, size, 0, + reinterpret_cast<void**>(&bytes_))); + return Get(); + } + + // Not copyable or movable. + MappableRegion(const MappableRegion&) = delete; + MappableRegion& operator=(const MappableRegion&) = delete; +}; |
