Questions about PSRAM allocation & size

bortch

New member
Hello,

I have soldered 16MB to my teensy 4.1 card and it works fine.

I am thinking about how to use it properly.

I would like to load audio files from the SD card into PSRAM and then play them back using multiple playmem (I hope this is a good way to do it, if not let me know).

I have created a Memory class which will be responsible for managing the writing, reading and deleting of audio files into the PSRAM.

A first question:
Is it better to statically declare an array of the desired size and pass it to the class instance or dynamically create it when instantiating my class?
Code:
#define MEM_SIZE_IN_32BIT_BLOCKS 4194304

class Memory {
    public:
        Memory(uint32_t *memory): _memory(memory) {}
        
        void begin(uint32_t* memory){
            _memory = memory;
            memset(_memory,0xFFFF,MEM_SIZE_IN_32BIT_BLOCKS);
        }
            
     private:
        uint32_t *_memory;
    };

EXTMEM uint32_t mem[MEM_SIZE_IN_32BIT_BLOCKS];

Memory memory(mem);

}

Code:
    class Memory {
    public:
        Memory() = default;
        
        ~Memory() {
            extmem_free(_memory);
        }
        
        void begin(){
            _memory = (uint32_t *) extmem_malloc(MEM_SIZE_IN_32BIT_BLOCKS);
            memset(_memory,0xFFFF,MEM_SIZE_IN_32BIT_BLOCKS);
        }
   
     private:
        uint32_t *_memory;
    };

Second questions:
To save a few cycles, I want to store the files in RAM as 32 bits block (is this a bad idea?).
On the one hand, I figure that if I pass extmem_malloc the value 4194304 (which is the number of 32-bit blocks) and the function expects to receive the size of the memory in byte, it won't use all 16MB available, but only a quarter. Should the size be given in bytes or in 32-bit blocks?
On the other hand, I read that memset works with one byte only (I was thinking of using it to initialize the memory). Is it a specific implementation of memset for 32bits processor?

Code:
// 16 Megabytes = 16*1024*1024 = 16777216 Bytes = 134217728 bits
// An unsigned int (uin32_t) = 32 bits
// 134217728 bits / 32 bits = 4194304 block of 32bit

#define MEM_SIZE_IN_BYTE 16777216

class Memory {
    public:
        Memory() = default;
        
        ~Memory() {
            extmem_free(_memory);
        }
        
        void begin(){
            _memory = (uint32_t *) extmem_malloc(MEM_SIZE_IN_BYTE);
            memset(_memory,0xFFFF,MEM_SIZE_IN_BYTE);
        }
   
     private:
        uint32_t *_memory;
    };
 
Last edited:
Is it better to statically declare an array of the desired size and pass it to the class instance or dynamically create it when instantiating my class?

Not sure if one is preferred. Either should work.

Should the size be given in bytes or in 32-bit blocks? Is it a specific implementation of memset for 32bits processor?

memset() is a standard library function, defined as shown below. The address (s) is type void*, value (c) is type int, and size (n) is size_t and is the number of bytes. Each byte is set to the value (c). If you pass a value of type uint32_t* as the address, there is an implicit cast to void*. For Teensy 4.x, the implementation of memset() is in file cores\Teensy4\memset.S

Code:
void *memset(void *s, int c, size_t n);
 
Hi Joe,

Thank you for your answers, thanks to which I was able to use memset properly.

Also, I opted for the static version, because first of all, as far as I could see, the dynamic version obviously adds some time to the startup and secondly, the size of this memory is not supposed to vary during the use of the program, so it can be known at compile time.
 
Back
Top