summaryrefslogtreecommitdiff
path: root/src/memory/include/himem.hpp
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2023-03-10 11:28:33 +1100
committerjacqueline <me@jacqueline.id.au>2023-04-19 10:27:59 +1000
commita9531c86a433c8b7ae1f77ff0266c27c39eca7f4 (patch)
tree11835552aa2ecb400537781d8eb3851118c47e61 /src/memory/include/himem.hpp
parent2a46eecdc6334c31cee2b40427d2536b48cbb6be (diff)
downloadtangara-fw-a9531c86a433c8b7ae1f77ff0266c27c39eca7f4.tar.gz
mostly single task pipeline
Diffstat (limited to 'src/memory/include/himem.hpp')
-rw-r--r--src/memory/include/himem.hpp78
1 files changed, 78 insertions, 0 deletions
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;
+};