Utility.hpp
Go to the documentation of this file.
1 /****
2  * Utility.hpp - Definitions, common macros and utility functions
3  *
4  * Copyright 2019 mikee47 <mike@sillyhouse.net>
5  *
6  * This file is part of the FlashString Library
7  *
8  * This library is free software: you can redistribute it and/or modify it under the terms of the
9  * GNU General Public License as published by the Free Software Foundation, version 3 or later.
10  *
11  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
12  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13  * See the GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along with this library.
16  * If not, see <https://www.gnu.org/licenses/>.
17  *
18  * @author: Nov 2019 - Mikee47 <mike@sillyhouse.net>
19  *
20  ****/
21 
22 #pragma once
23 
24 #include "config.hpp"
25 
58 #define DECL(t) argument_type<void(t)>::type
59 template <typename T> struct argument_type;
60 template <typename T, typename U> struct argument_type<T(U)> {
61  typedef U type;
62 };
63 
87 // clang-format off
88 #define STR(x) XSTR(x)
89 #define XSTR(x) #x
90 #ifdef __WIN32
91 #define IMPORT_FSTR_DATA_SECTION(name) \
92  ".section .rodata\n" \
93  ".def " STR(name) "; .scl 2; .type 32; .endef\n"
94 #elif defined(__APPLE__)
95 #define IMPORT_FSTR_DATA_SECTION(name) \
96  ".const_data\n" \
97  ".globl " STR(name) "\n"
98 #elif defined(__arm__)
99 #define IMPORT_FSTR_DATA_SECTION(name) \
100  ".section " ICACHE_RODATA_SECTION "." STR(name) "\n" \
101  ".type " STR(name) ", %object\n"
102 #else
103 #define IMPORT_FSTR_DATA_SECTION(name) \
104  ".section " ICACHE_RODATA_SECTION "." STR(name) "\n" \
105  ".type " STR(name) ", @object\n"
106 #endif
107 
108 #define IMPORT_FSTR_DATA(name, file) \
109  __asm__(IMPORT_FSTR_DATA_SECTION(name) \
110  ".align 4\n" \
111  STR(name) ":\n" \
112  ".long " STR(name) "_end - " STR(name) " - 4\n" \
113  ".incbin \"" file "\"\n" \
114  STR(name) "_end:\n");
115 // clang-format on
116 
126 #define DECLARE_FSTR_IMPORT(ObjectType, name) extern const ObjectType name __asm__(STR(name));
127 
128 namespace FSTR
129 {
137 template <typename T> FSTR_INLINE typename std::enable_if<sizeof(T) == 1, T>::type readValue(const T* ptr)
138 {
139  return static_cast<T>(pgm_read_byte(ptr));
140 }
141 
142 template <typename T> FSTR_INLINE typename std::enable_if<sizeof(T) == 2, T>::type readValue(const T* ptr)
143 {
144  return static_cast<T>(pgm_read_word(ptr));
145 }
146 
147 template <typename T> FSTR_ALIGN32 FSTR_INLINE typename std::enable_if<sizeof(T) == 4, T>::type readValue(const T* ptr)
148 {
149  union {
150  uint32_t u32;
151  T value;
152  } tmp;
153  tmp.u32 = pgm_read_dword(ptr);
154  return tmp.value;
155 }
156 
157 template <typename T>
158 FSTR_INLINE typename std::enable_if<(sizeof(T) > 4) && IS_ALIGNED(sizeof(T)), T>::type readValue(const T* ptr)
159 {
160  T value;
161  memcpy_aligned(&value, ptr, sizeof(T));
162  return value;
163 }
164 
167 } // namespace FSTR
168 
#define pgm_read_byte(addr)
Definition: Arch/Esp32/Components/libc/src/include/sys/pgmspace.h:43
#define pgm_read_dword(addr)
Definition: Arch/Esp32/Components/libc/src/include/sys/pgmspace.h:49
#define pgm_read_word(addr)
Definition: Arch/Esp32/Components/libc/src/include/sys/pgmspace.h:44
uint32_t u32
Definition: c_types.h:19
#define FSTR_INLINE
Definition: config.hpp:28
#define FSTR_ALIGN32
Definition: config.hpp:32
#define IS_ALIGNED(_x)
determines if the given value is aligned to a word (4-byte) boundary
Definition: FakePgmSpace.h:34
void * memcpy_aligned(void *dst, const void *src, unsigned len)
copy memory aligned to word boundaries
Definition: Array.hpp:118
std::enable_if< sizeof(T)==1, T >::type readValue(const T *ptr)
Read a typed value from flash memory ensuring correct alignment of access.
Definition: Utility.hpp:137
U type
Definition: Utility.hpp:61
Definition: Utility.hpp:59