Skip to content

Commit 45712de

Browse files
committed
Add psram_or_malloc and psram_or_free
These will either statically allocate in psram, or malloc if the static allocation is not in available psram. Sections are sorted, so the group can be used to set priority. Not sure how useful these are, so could be removed if not wanted.
1 parent c01cf0e commit 45712de

3 files changed

Lines changed: 43 additions & 1 deletion

File tree

src/rp2_common/hardware_psram/include/hardware/psram.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,22 @@ int psram_reinitialise(void);
220220
*/
221221
size_t psram_eid_to_size(uint8_t kgd, uint8_t eid);
222222

223+
/*! \brief Provide a static PSRAM allocation, or malloc if PSRAM is not available
224+
* \ingroup hardware_psram
225+
*
226+
* This will allocate a static buffer in PSRAM and if available use that, otherwise it will use the heap.
227+
*
228+
* This will fail to compile if PICO_PSRAM_SIZE_BYTES is not set
229+
*/
230+
#define psram_or_malloc(group, type, var, size) static type __psram_uninitialised(group) var##_psram[size]; type* var; if (psram_check_address(var##_psram + size)) { var = (type*)var##_psram; } else { var = (type*)malloc(size * sizeof(type)); }
231+
232+
/*! \brief Free a buffer if it is not in PSRAM
233+
* \ingroup hardware_psram
234+
*
235+
* This will free the buffer from \ref psram_or_malloc if it was created by malloc
236+
*/
237+
#define psram_or_free(var) if (!psram_check_address(var##_psram)) { free(var); }
238+
223239
#ifdef __cplusplus
224240
}
225241
#endif

test/kitchen_sink/CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,16 @@ if (NOT PICO_RP2040)
178178
set_target_properties(kitchen_sink_psram_tiny PROPERTIES PICO_TEST_SUCCESS_STRING "psram tiny size binary")
179179
set_target_properties(kitchen_sink_psram_tiny PROPERTIES PICO_TEST_FAILURE_STRING "PASSED")
180180

181+
add_executable(kitchen_sink_psram_small ${CMAKE_CURRENT_LIST_DIR}/kitchen_sink.c)
182+
target_link_libraries(kitchen_sink_psram_small kitchen_sink_libs kitchen_sink_options)
183+
target_compile_definitions(kitchen_sink_psram_small PRIVATE FIXED_PSRAM_SIZE=1 SMALL_PSRAM=1)
184+
# Override the PSRAM size to allow variables in PSRAM
185+
target_compile_definitions(kitchen_sink_psram_small PRIVATE PICO_AUTO_DETECT_PSRAM=1)
186+
pico_override_psram_size(kitchen_sink_psram_small "(1 * 1024 * 1024)")
187+
pico_add_extra_outputs(kitchen_sink_psram_small)
188+
target_compile_definitions(kitchen_sink_psram_small PRIVATE KITCHEN_SINK_ID="psram small size binary")
189+
set_target_properties(kitchen_sink_psram_small PROPERTIES PICO_TEST_FAILURE_STRING "ERROR:")
190+
181191
add_executable(kitchen_sink_psram_detect ${CMAKE_CURRENT_LIST_DIR}/kitchen_sink.c)
182192
target_link_libraries(kitchen_sink_psram_detect kitchen_sink_libs kitchen_sink_options)
183193
target_compile_definitions(kitchen_sink_psram_detect PRIVATE PICO_AUTO_DETECT_PSRAM=1)

test/kitchen_sink/kitchen_sink.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,15 @@ uint32_t dma_from = 0xaaaa5555;
5151
#ifdef FIXED_PSRAM_SIZE
5252
int __psram("foo") foo_psram = 23;
5353
char __psram_uninitialised("bar") bar_psram[0x8000];
54-
#ifdef TINY_PSRAM
54+
#if defined(TINY_PSRAM) || defined(SMALL_PSRAM)
5555
void make_tiny_psram(void) {
56+
#if defined(TINY_PSRAM)
5657
// Override flash_devinfo cs size to be tiny, so bar_psram doesn't fit in it
5758
flash_devinfo_set_cs_size(1, FLASH_DEVINFO_SIZE_8K);
59+
#elif defined(SMALL_PSRAM)
60+
// Override flash_devinfo cs size to be small, so bar_psram fits but int_buffer doesn't
61+
flash_devinfo_set_cs_size(1, FLASH_DEVINFO_SIZE_128K);
62+
#endif
5863
// Still auto-detect CS pin, as we don't know that
5964
uint8_t cs_gpios[] = PICO_AVAILABLE_CS1_GPIOS;
6065
psram_detect_cs_and_size(cs_gpios, sizeof(cs_gpios));
@@ -152,6 +157,17 @@ int main(void) {
152157
#endif
153158
#endif
154159

160+
#if PICO_PSRAM_SIZE_BYTES
161+
psram_or_malloc("z0000", char, char_buffer, 0x8000);
162+
memset(char_buffer, 0x55, 0x8000);
163+
printf("char_buffer in %s at %p\n", char_buffer < (char*)SRAM_BASE ? "PSRAM" : "Normal SRAM", char_buffer);
164+
psram_or_free(char_buffer);
165+
psram_or_malloc("z0001", int, int_buffer, 0x8000);
166+
memset(int_buffer, 0x55, 0x8000 * sizeof(int));
167+
printf("int_buffer in %s at %p\n", int_buffer < (int*)SRAM_BASE ? "PSRAM" : "Normal SRAM", int_buffer);
168+
psram_or_free(int_buffer);
169+
#endif
170+
155171
#ifdef FIXED_PSRAM_SIZE
156172
if (psram_is_available()) {
157173
printf("PSRAM is available\n");

0 commit comments

Comments
 (0)