[Ovmsdev] Playing with SPI RAM
Michael Balzer
dexter at expeedo.de
Sat Jan 13 02:30:12 HKT 2018
Mark,
a base class can also provide an malloc() override.
Additionally, all standard containers can be instantiated with a custom Allocator. Default is std::allocator.
http://en.cppreference.com/w/cpp/concept/Allocator
So with an SPIAllocator we can put the container management overhead into SPI RAM as well very easily. But that may affect performance badly on central lists &
maps under load, we should be careful with that option.
Regards,
Michael
Am 12.01.2018 um 03:09 schrieb Mark Webb-Johnson:
>
> Before:
>
> OVMS > module memory
> ============================
> Free 8-bit 4291676/4507468, 32-bit 1608/16760, blocks dumped = 0
> task=no task total= 38116 0 0 0 change= +38116 +0 +0 +0
> task=esp_timer total= 49628 0 644 0 change= +49628 +0 +644 +0
> task=main total= 9868 0 0 26924 change= +9868 +0 +0 +26924
> task=ipc0 total= 11096 0 0 0 change= +11096 +0 +0 +0
> task=Housekeeping total= 44032 0 0 12 change= +44032 +0 +0 +12
> task=ipc1 total= 12 0 0 0 change= +12 +0 +0 +0
> task=Tmr Svc total= 16 0 0 0 change= +16 +0 +0 +0
> task=tiT total= 0 0 0 128 change= +0 +0 +0 +128
> task=AsyncConsole total= 20 0 14404 12000 change= +20 +0 +14404 +12000
> ============================
>
>
> The change:
>
> class OvmsCommand
> {
> public:
> void* operator new(size_t sz) { return heap_caps_malloc(sz, MALLOC_CAP_SPIRAM); }
> void operator delete (void* ptr) { return free(ptr); }
>
>
> After:
>
> OVMS > module memory
> ============================
> Free 8-bit 4291676/4507468, 32-bit 1608/16760, blocks dumped = 0
> task=no task total= 38116 0 0 0 change= +38116 +0 +0 +0
> task=esp_timer total= 28708 0 644 20916 change= +28708 +0 +644 +20916
> task=main total= 9868 0 0 26924 change= +9868 +0 +0 +26924
> task=ipc0 total= 11096 0 0 0 change= +11096 +0 +0 +0
> task=Housekeeping total= 37984 0 0 6060 change= +37984 +0 +0 +6060
> task=ipc1 total= 12 0 0 0 change= +12 +0 +0 +0
> task=Tmr Svc total= 16 0 0 0 change= +16 +0 +0 +0
> task=tiT total= 0 0 0 128 change= +0 +0 +0 +128
> task=AsyncConsole total= 12020 0 14404 0 change= +12020 +0 +14404 +0
> ============================
>
>
> So, simply moving OvmsCommand objects to SPI RAM saves us about 26KB of internal RAM.
>
> Our goal would be to move as much of our infrequently accessed stuff as possible to SPI RAM. This would free up as much internal ram as possible for things
> like stacks, DMA, etc.
>
> Here are the restrictions on SPI RAM that Espressif point out:
>
> The use of external RAM has a few restrictions:
>
> * When disabling flash cache (for example, because the flash is being written to), the external RAM also becomes inaccessible; any reads from or
> writes to it will lead to an illegal cache access exception. This is also the reason that ESP-IDF will never allocate a tasks stack in external RAM.
> * External RAM cannot be used as a place to store DMA transaction descriptors or as a buffer for a DMA transfer to read from or write into. Any
> buffers that will be used in combination with DMA must be allocated using |heap_caps_malloc(size, MALLOC_CAP_DMA)| (and can be freed using a
> standard |free()| call.)
> * External RAM uses the same cache region as the external flash. This means that often accessed variables in external RAM can be read and modified
> almost as quickly as in internal ram. However, when accessing large chunks of data (>32K), the cache can be insufficient and speeds will fall back
> to the access speed of the external RAM. Moreover, accessing large chunks of data can ‘push out’ cached flash, possibly making execution of code
> afterwards slower.
> * External RAM cannot be used as task stack memory; because of this, xTaskCreate and similar functions will always allocate internal memory for
> stack and task TCBs and xTaskCreateStatic-type functions will check if the buffers passed are internal. However, for tasks not calling on code in
> ROM in any way, directly or indirectly, the menuconfig option SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY
> <http://esp-idf.readthedocs.io/en/latest/api-reference/kconfig.html#config-spiram-allow-stack-external-memory> will eliminate the check in
> xTaskCreateStatic, allowing task stack in external RAM. Using this is not advised, however.
>
> Because there are a fair few situations that have a specific need for internal memory, but it is also possible to use malloc() to exhaust internal memory,
> there is a pool reserved specifically for requests that cannot be resolved from external memory; allocating task stack, DMA buffers and memory that stays
> accessible when cache is disabled is drawn from this pool. The size of this pool is configurable in menuconfig.
>
> I’m not having much luck trying to globally override the new() and delete() memory allocators, so I’m now thinking of making a base class with new and delete
> operators, plus some other utility functions to make spi ram allocation easier. Then whenever we want to make one of our objects allocatable from spiram we
> simply derive from that base class. That class could pickup on the menuconfig hardware version (3.0 WROOM-32 vs 3.1 WROVER) and turn on/off SPIRAM appropriately.
>
> Here is how Espressif do it:
>
> IRAM_ATTR void *heap_caps_malloc_default( size_t size )
> {
> if (malloc_alwaysinternal_limit==MALLOC_DISABLE_EXTERNAL_ALLOCS) {
> return heap_caps_malloc( size, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL);
> } else {
> void *r;
> if (size <= malloc_alwaysinternal_limit) {
> r=heap_caps_malloc( size, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL );
> } else {
> r=heap_caps_malloc( size, MALLOC_CAP_DEFAULT | MALLOC_CAP_SPIRAM );
> }
> if (r==NULL) {
> //try again while being less picky
> r=heap_caps_malloc( size, MALLOC_CAP_DEFAULT );
> }
> return r;
> }
> }
>
>
> We want to do the opposite - try to allocate from SPIRAM if it is available. There is a heap_caps_malloc_prefer that could do it for us.
>
> Thoughts?
>
> Regards, Mark.
>
>
>
> _______________________________________________
> OvmsDev mailing list
> OvmsDev at lists.teslaclub.hk
> http://lists.teslaclub.hk/mailman/listinfo/ovmsdev
--
Michael Balzer * Helkenberger Weg 9 * D-58256 Ennepetal
Fon 02333 / 833 5735 * Handy 0176 / 206 989 26
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openvehicles.com/pipermail/ovmsdev/attachments/20180112/4d6558ed/attachment.htm>
More information about the OvmsDev
mailing list