From 5c490665080b7ea70972cf2919ee59fb671410f4 Mon Sep 17 00:00:00 2001 From: "Kwabena W. Agyeman" Date: Sun, 14 Feb 2021 15:12:33 -0800 Subject: [PATCH 1/6] Cache align jpeg and frame buffer --- src/omv/imlib/framebuffer.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/omv/imlib/framebuffer.h b/src/omv/imlib/framebuffer.h index f1474e187..eca1aba79 100644 --- a/src/omv/imlib/framebuffer.h +++ b/src/omv/imlib/framebuffer.h @@ -21,8 +21,8 @@ typedef struct framebuffer { int32_t u,v; int32_t bpp; int32_t streaming_enabled; - // NOTE: This buffer must be aligned on a 16 byte boundary - OMV_ATTR_ALIGNED(uint8_t pixels[], 16); + // NOTE: This buffer must be aligned on a 32 byte boundary + OMV_ATTR_ALIGNED(uint8_t pixels[], 32); } framebuffer_t; extern framebuffer_t *framebuffer; @@ -33,7 +33,9 @@ typedef struct jpegbuffer { int32_t enabled; int32_t quality; mutex_t lock; - uint8_t pixels[]; + int64_t __padding; + // NOTE: This buffer must be aligned on a 32 byte boundary + OMV_ATTR_ALIGNED(uint8_t pixels[], 32); } jpegbuffer_t; extern jpegbuffer_t *jpeg_framebuffer; From 900477383e63ef539e73ff17014f5f4fdff52046 Mon Sep 17 00:00:00 2001 From: "Kwabena W. Agyeman" Date: Sun, 14 Feb 2021 15:41:10 -0800 Subject: [PATCH 2/6] Add cache alignment support to fb_alloc --- src/omv/alloc/fb_alloc.c | 43 +++++++++++++++++++++++++++++++++++++++- src/omv/alloc/fb_alloc.h | 14 +++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/omv/alloc/fb_alloc.c b/src/omv/alloc/fb_alloc.c index bef12bad3..3d088e3bf 100644 --- a/src/omv/alloc/fb_alloc.c +++ b/src/omv/alloc/fb_alloc.c @@ -132,7 +132,15 @@ void *fb_alloc(uint32_t size, int hints) return NULL; } - size=((size+sizeof(uint32_t)-1)/sizeof(uint32_t))*sizeof(uint32_t);// Round Up + size = ((size + sizeof(uint32_t) - 1) / sizeof(uint32_t)) * sizeof(uint32_t); // Round Up + + #if __DCACHE_PRESENT + if (hints & FB_ALLOC_CACHE_ALIGN) { + size = ((size + __SCB_DCACHE_LINE_SIZE - 1) / __SCB_DCACHE_LINE_SIZE) * __SCB_DCACHE_LINE_SIZE; + size += __SCB_DCACHE_LINE_SIZE; + } + #endif + char *result = pointer - size; char *new_pointer = result - sizeof(uint32_t); @@ -144,6 +152,7 @@ void *fb_alloc(uint32_t size, int hints) // size is always 4/8/12/etc. so the value below must be 8 or more. *((uint32_t *) new_pointer) = size + sizeof(uint32_t); // Save size. pointer = new_pointer; + #if defined(FB_ALLOC_STATS) alloc_bytes += size; if (alloc_bytes > alloc_bytes_peak) { @@ -151,6 +160,7 @@ void *fb_alloc(uint32_t size, int hints) } printf("fb_alloc %lu bytes\n", size); #endif + #if defined(OMV_FB_OVERLAY_MEMORY) if ((!(hints & FB_ALLOC_PREFER_SIZE)) && (((uint32_t) (pointer_overlay - OMV_FB_OVERLAY_MEMORY_ORIGIN)) >= size)) { @@ -160,6 +170,16 @@ void *fb_alloc(uint32_t size, int hints) *new_pointer |= FB_OVERLAY_MEMORY_FLAG; // Add flag. } #endif + + #if __DCACHE_PRESENT + if (hints & FB_ALLOC_CACHE_ALIGN) { + int offset = ((uint32_t) result) % __SCB_DCACHE_LINE_SIZE; + if (offset) { + result += __SCB_DCACHE_LINE_SIZE - offset; + } + } + #endif + return result; } @@ -186,13 +206,23 @@ void *fb_alloc_all(uint32_t *size, int hints) temp = IM_MIN(temp, *size); } #endif + *size = (temp / sizeof(uint32_t)) * sizeof(uint32_t); // Round Down + + #if __DCACHE_PRESENT + if (hints & FB_ALLOC_CACHE_ALIGN) { + *size = ((*size + __SCB_DCACHE_LINE_SIZE - 1) / __SCB_DCACHE_LINE_SIZE) * __SCB_DCACHE_LINE_SIZE; + *size += __SCB_DCACHE_LINE_SIZE; + } + #endif + char *result = pointer - *size; char *new_pointer = result - sizeof(uint32_t); // size is always 4/8/12/etc. so the value below must be 8 or more. *((uint32_t *) new_pointer) = *size + sizeof(uint32_t); // Save size. pointer = new_pointer; + #if defined(FB_ALLOC_STATS) alloc_bytes += *size; if (alloc_bytes > alloc_bytes_peak) { @@ -200,6 +230,7 @@ void *fb_alloc_all(uint32_t *size, int hints) } printf("fb_alloc_all %lu bytes\n", *size); #endif + #if defined(OMV_FB_OVERLAY_MEMORY) if (!(hints & FB_ALLOC_PREFER_SIZE)) { // Return overlay memory instead. @@ -208,6 +239,16 @@ void *fb_alloc_all(uint32_t *size, int hints) *new_pointer |= FB_OVERLAY_MEMORY_FLAG; // Add flag. } #endif + + #if __DCACHE_PRESENT + if (hints & FB_ALLOC_CACHE_ALIGN) { + int offset = ((uint32_t) result) % __SCB_DCACHE_LINE_SIZE; + if (offset) { + result += __SCB_DCACHE_LINE_SIZE - offset; + } + } + #endif + return result; } diff --git a/src/omv/alloc/fb_alloc.h b/src/omv/alloc/fb_alloc.h index 7d799eef5..4935d04a0 100644 --- a/src/omv/alloc/fb_alloc.h +++ b/src/omv/alloc/fb_alloc.h @@ -35,6 +35,19 @@ * mark. * * Note that fb_free() and fb_free_all() do not respect any marks and permanent regions. + * + * Regardings the flags below: + * - FB_ALLOC_NO_HINT - fb_alloc doesn't do anything special. + * - FB_ALLOC_PREFER_SPEED - fb_alloc will make sure the allocated region is in the fatest possible + * memory. E.g. allocs will be in SRAM versus SDRAM if SDRAM is available. + * Setting this flag affects where fb_alloc_all() gets RAM from. If this + * flag is set then fb_alloc_all() will not use the SDRAM. + * - FB_ALLOC_PREFER_SIZE - fb_alloc will make sure the allocated region is the largest possible + * memory. E.g. allocs will be in SDRAM versus SRAM if SDRAM is available. + * Setting this flag affects where fb_alloc_all() gets RAM from. If this + * flag is set then fb_alloc_all() will use the SDRAM (default). + * - FB_ALLOC_CACHE_ALIGN - Aligns the starting address returned to a cache line and makes sure + * the amount of memory allocated is padded to the end of a cache line. */ #ifndef __FB_ALLOC_H__ #define __FB_ALLOC_H__ @@ -42,6 +55,7 @@ #define FB_ALLOC_NO_HINT 0 #define FB_ALLOC_PREFER_SPEED 1 #define FB_ALLOC_PREFER_SIZE 2 +#define FB_ALLOC_CACHE_ALIGN 4 char *fb_alloc_stack_pointer(); void fb_alloc_fail(); void fb_alloc_init0(); From 103042d27abd066c796dbba9545039eacc801c0b Mon Sep 17 00:00:00 2001 From: "Kwabena W. Agyeman" Date: Sun, 14 Feb 2021 15:45:23 -0800 Subject: [PATCH 3/6] Use new cache alignment for flir lepton --- src/omv/ports/stm32/modules/py_fir_lepton.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/src/omv/ports/stm32/modules/py_fir_lepton.c b/src/omv/ports/stm32/modules/py_fir_lepton.c index 3e24e9212..0b68f57de 100644 --- a/src/omv/ports/stm32/modules/py_fir_lepton.c +++ b/src/omv/ports/stm32/modules/py_fir_lepton.c @@ -455,22 +455,8 @@ int fir_lepton_init(cambus_t *bus, int *w, int *h, int *refresh, int *resolution FB_ALLOC_NO_HINT); } - size_t size = VOSPI_BUFFER_SIZE * sizeof(uint16_t); - - // The DMA buffer must not start/end partially on a cache line. - #if defined(MCU_SERIES_F7) || defined(MCU_SERIES_H7) - size = ((size + __SCB_DCACHE_LINE_SIZE - 1) / __SCB_DCACHE_LINE_SIZE) * __SCB_DCACHE_LINE_SIZE; - size += __SCB_DCACHE_LINE_SIZE; - #endif - - fir_lepton_spi_rx_cb_dma_buffer = (uint16_t *) fb_alloc(size, FB_ALLOC_PREFER_SPEED); - - #if defined(MCU_SERIES_F7) || defined(MCU_SERIES_H7) - int offset = ((uint32_t) fir_lepton_spi_rx_cb_dma_buffer) % __SCB_DCACHE_LINE_SIZE; - if (offset) { - fir_lepton_spi_rx_cb_dma_buffer += __SCB_DCACHE_LINE_SIZE - offset; - } - #endif + fir_lepton_spi_rx_cb_dma_buffer = (uint16_t *) fb_alloc(VOSPI_BUFFER_SIZE * sizeof(uint16_t), + FB_ALLOC_PREFER_SPEED | FB_ALLOC_CACHE_ALIGN); dma_init(&fir_lepton_spi_rx_dma, OMV_FIR_LEPTON_CONTROLLER->rx_dma_descr, From 09121b378e769e6969bdd9a14cc5499f3cf8a45e Mon Sep 17 00:00:00 2001 From: "Kwabena W. Agyeman" Date: Sun, 14 Feb 2021 19:14:30 -0800 Subject: [PATCH 4/6] Update src/omv/imlib/framebuffer.h Remove padding. Co-authored-by: Ibrahim Abd Elkader --- src/omv/imlib/framebuffer.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/omv/imlib/framebuffer.h b/src/omv/imlib/framebuffer.h index eca1aba79..1ded2c434 100644 --- a/src/omv/imlib/framebuffer.h +++ b/src/omv/imlib/framebuffer.h @@ -33,7 +33,6 @@ typedef struct jpegbuffer { int32_t enabled; int32_t quality; mutex_t lock; - int64_t __padding; // NOTE: This buffer must be aligned on a 32 byte boundary OMV_ATTR_ALIGNED(uint8_t pixels[], 32); } jpegbuffer_t; From 45b7e12cf96f7162f0cc6cf70c405be88b605619 Mon Sep 17 00:00:00 2001 From: "Kwabena W. Agyeman" Date: Mon, 15 Feb 2021 09:25:14 -0800 Subject: [PATCH 5/6] Fix fb_alloc_all cache alignment --- src/omv/alloc/fb_alloc.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/omv/alloc/fb_alloc.c b/src/omv/alloc/fb_alloc.c index 3d088e3bf..7059738cd 100644 --- a/src/omv/alloc/fb_alloc.c +++ b/src/omv/alloc/fb_alloc.c @@ -209,13 +209,6 @@ void *fb_alloc_all(uint32_t *size, int hints) *size = (temp / sizeof(uint32_t)) * sizeof(uint32_t); // Round Down - #if __DCACHE_PRESENT - if (hints & FB_ALLOC_CACHE_ALIGN) { - *size = ((*size + __SCB_DCACHE_LINE_SIZE - 1) / __SCB_DCACHE_LINE_SIZE) * __SCB_DCACHE_LINE_SIZE; - *size += __SCB_DCACHE_LINE_SIZE; - } - #endif - char *result = pointer - *size; char *new_pointer = result - sizeof(uint32_t); @@ -244,8 +237,11 @@ void *fb_alloc_all(uint32_t *size, int hints) if (hints & FB_ALLOC_CACHE_ALIGN) { int offset = ((uint32_t) result) % __SCB_DCACHE_LINE_SIZE; if (offset) { - result += __SCB_DCACHE_LINE_SIZE - offset; + int inc = __SCB_DCACHE_LINE_SIZE - offset; + result += inc; + *size -= inc; } + *size = (*size / __SCB_DCACHE_LINE_SIZE) * __SCB_DCACHE_LINE_SIZE; } #endif From 666c9dd386362ad9992142e3c660d88d11ee98cb Mon Sep 17 00:00:00 2001 From: "Kwabena W. Agyeman" Date: Mon, 15 Feb 2021 09:35:10 -0800 Subject: [PATCH 6/6] Use 4 less bytes per alginment --- src/omv/alloc/fb_alloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/omv/alloc/fb_alloc.c b/src/omv/alloc/fb_alloc.c index 7059738cd..79da3daec 100644 --- a/src/omv/alloc/fb_alloc.c +++ b/src/omv/alloc/fb_alloc.c @@ -137,7 +137,7 @@ void *fb_alloc(uint32_t size, int hints) #if __DCACHE_PRESENT if (hints & FB_ALLOC_CACHE_ALIGN) { size = ((size + __SCB_DCACHE_LINE_SIZE - 1) / __SCB_DCACHE_LINE_SIZE) * __SCB_DCACHE_LINE_SIZE; - size += __SCB_DCACHE_LINE_SIZE; + size += __SCB_DCACHE_LINE_SIZE - sizeof(uint32_t); } #endif