diff --git a/core/main.c b/core/main.c index d1475105..eb53b5c0 100644 --- a/core/main.c +++ b/core/main.c @@ -54,8 +54,14 @@ int core_get_free_memory() { // If using the exmem / suba memory allocation system then don't need // to try allocating memory to find out how much is available // Call function to scan free list for the largest free block available. - extern int exmem_largest_block(); - return exmem_largest_block(); + cam_meminfo camera_meminfo; + GetExMemInfo(&camera_meminfo); + return camera_meminfo.free_block_max_size; +#elif defined(CAM_FIRMWARE_MEMINFO) + // Call firmware function to fill memory info structure and return size of largest free block + cam_meminfo camera_meminfo; + GetMemInfo(&camera_meminfo); + return camera_meminfo.free_block_max_size; #else int size, l_size, d; char* ptr; diff --git a/core/suba.c b/core/suba.c index 9d7a45b6..f98a99a6 100644 --- a/core/suba.c +++ b/core/suba.c @@ -85,22 +85,33 @@ struct cell { //#define RECLAIM_DEPTH_MAX 2 #define SUBA_MAGIC "\xFF\x15\x15\x15SUBA" -int suba_largest_block(struct allocator *suba) +void suba_getmeminfo(struct allocator *suba, int *allocated_size, int *allocated_peak, int *allocated_count, int *free_size, int *largest_block, int *free_block_count) { - size_t sz = 0; + size_t largest = 0; + size_t free = 0; + size_t count = 0; if (suba) { struct cell *c = SADR(suba, suba->tail); - if (c->size > sz) sz = c->size; + if (c->size > largest) largest = c->size; + free += c->size; + count++; while (c->next != suba->tail) { c = SADR(suba, c->next); - if (c->size > sz) sz = c->size; + if (c->size > largest) largest = c->size; + free += c->size; + count++; } } - return sz; + *largest_block = largest; + *free_size = free; + *free_block_count = count; + *allocated_size = suba->size_total; // TODO check this is a reasonable value for this field + *allocated_peak = suba->alloc_total; // TODO check this is a reasonable value for this field + *allocated_count = 0; // TODO implement this } void * diff --git a/include/camera.h b/include/camera.h index 3cb5a793..bd2830ae 100644 --- a/include/camera.h +++ b/include/camera.h @@ -145,6 +145,11 @@ #undef PARAM_CAMERA_NAME // parameter number for GetParameterData to get camera name + +#undef CAM_FIRMWARE_MEMINFO // Use 'GetMemInfo' function in firmware to get free memory details + // GetMemInfo should be found correctly by the gensig/finsig signature + // finder for all dryos based cameras. + //---------------------------------------------------------- // Override Default values for Camera if necessary //---------------------------------------------------------- diff --git a/include/platform.h b/include/platform.h index 9f5457ed..2ce386d1 100644 --- a/include/platform.h +++ b/include/platform.h @@ -559,8 +559,26 @@ int switch_mode_usb(int mode); // 0 = playback, 1 = record; return indicates suc void ExitTask(); +// Data returned from GetMemInfo & GetExMemInfo functions stored in this data structure +typedef struct { + int start_address; + int end_address; + int total_size; + int allocated_size; + int allocated_peak; + int allocated_count; + int free_size; + int free_block_max_size; + int free_block_count; +} cam_meminfo; + +#if defined(CAM_FIRMWARE_MEMINFO) +extern void GetMemInfo(cam_meminfo*); +#endif + #ifdef OPT_EXMEM_MALLOC void exmem_malloc_init(void); +void GetExMemInfo(cam_meminfo*); #endif #endif diff --git a/platform/d10/platform_camera.h b/platform/d10/platform_camera.h index 6dbc4dbd..3b2a6657 100644 --- a/platform/d10/platform_camera.h +++ b/platform/d10/platform_camera.h @@ -130,9 +130,6 @@ #define CAM_CHDK_PTP 1 // include CHDK PTP support -//---------------------------------------------------------- - +#define CAM_FIRMWARE_MEMINFO 1 // Use 'GetMemInfo' to get free memory size. -//========================================================== -// SD-Series (IXUS-Series) -//========================================================== +//---------------------------------------------------------- diff --git a/platform/g12/platform_camera.h b/platform/g12/platform_camera.h index b8379693..0a7493be 100644 --- a/platform/g12/platform_camera.h +++ b/platform/g12/platform_camera.h @@ -109,5 +109,7 @@ #define CAM_STARTUP_CRASH_FILE_OPEN_FIX 1 // enable fix for camera crash at startup when opening the conf / font files // see http://chdk.setepontos.com/index.php?topic=6179.0 +#define CAM_FIRMWARE_MEMINFO 1 // Use 'GetMemInfo' to get free memory size. + //---------------------------------------------------------- diff --git a/platform/generic/wrappers.c b/platform/generic/wrappers.c index 9c9e7b15..001e2afe 100644 --- a/platform/generic/wrappers.c +++ b/platform/generic/wrappers.c @@ -699,11 +699,11 @@ void exmem_malloc_init() { // and reduce available space by CHDK size (MEMISOSIZE) // round MEMISOSIZE up to next 4 byte boundary if needed (just in case) exmem_start = mem + ((MEMISOSIZE+3)&0xFFFFFFFC); - exmem_size = EXMEM_HEAP_SIZE - EXMEM_HEAP_SKIP - ((MEMISOSIZE+3)&0xFFFFFFFC); + exmem_size = EXMEM_BUFFER_SIZE - ((MEMISOSIZE+3)&0xFFFFFFFC); #else // Set start & size based on requested values exmem_start = mem; - exmem_size = EXMEM_HEAP_SIZE - EXMEM_HEAP_SKIP; + exmem_size = EXMEM_BUFFER_SIZE; #endif exmem_end = exmem_start + exmem_size; #if defined(OPT_EXMEM_TESTING) @@ -736,10 +736,18 @@ void free(void *p) { _free(p); } -int exmem_largest_block() +// Use suba functions to fill meminfo structure to match firmware GetMemInfo function + +void GetExMemInfo(cam_meminfo *camera_meminfo) { - extern int suba_largest_block(void*); - return suba_largest_block(exmem_heap); + extern void suba_getmeminfo(void*, int*, int*, int*, int*, int*, int*); + + camera_meminfo->start_address = (int)exmem_start; + camera_meminfo->end_address = (int)exmem_start + exmem_size; + camera_meminfo->total_size = exmem_size; + suba_getmeminfo(exmem_heap, + &camera_meminfo->allocated_size, &camera_meminfo->allocated_peak, &camera_meminfo->allocated_count, + &camera_meminfo->free_size, &camera_meminfo->free_block_max_size, &camera_meminfo->free_block_count); } // regular malloc #else @@ -784,6 +792,44 @@ void *memchr(const void *s, int c, int n) { return (void *)0; #endif } + +#if defined(CAM_FIRMWARE_MEMINFO) + +// Use firmware GetMemInfo function to retrieve info about Canon heap memory allocation + +void GetMemInfo(cam_meminfo *camera_meminfo) +{ + // Prior to dryos R39 GetMemInfo returns 9 values, after R39 it returns 10 (all but 1 are used in each case) + int fw_info[10]; + extern void _GetMemInfo(int*); + _GetMemInfo(fw_info); + +#if defined(CAM_DRYOS_2_3_R39) + // For newer dryos version copy all 9 used values to CHDK structure + camera_meminfo->start_address = fw_info[0]; + camera_meminfo->end_address = fw_info[1]; + camera_meminfo->total_size = fw_info[2]; + camera_meminfo->allocated_size = fw_info[3]; + camera_meminfo->allocated_peak = fw_info[4]; + camera_meminfo->allocated_count = fw_info[5]; + camera_meminfo->free_size = fw_info[6]; + camera_meminfo->free_block_max_size = fw_info[7]; + camera_meminfo->free_block_count = fw_info[8]; +#else + // For older dryos version copy 8 used values to CHDK structure and calculate missing value + camera_meminfo->start_address = fw_info[0]; + camera_meminfo->end_address = fw_info[0] + fw_info[1]; + camera_meminfo->total_size = fw_info[1]; + camera_meminfo->allocated_size = fw_info[2]; + camera_meminfo->allocated_peak = fw_info[3]; + camera_meminfo->allocated_count = fw_info[4]; + camera_meminfo->free_size = fw_info[5]; + camera_meminfo->free_block_max_size = fw_info[6]; + camera_meminfo->free_block_count = fw_info[7]; +#endif +} + +#endif //---------------------------------------------------------------------------- diff --git a/platform/sx30/platform_camera.h b/platform/sx30/platform_camera.h index bdfabc1d..086a6cd7 100644 --- a/platform/sx30/platform_camera.h +++ b/platform/sx30/platform_camera.h @@ -103,4 +103,7 @@ // see http://chdk.setepontos.com/index.php?topic=6179.0 #define CAM_KEY_CLICK_DELAY 150 // SX30 appears to need extra delay for clicks + +#define CAM_FIRMWARE_MEMINFO 1 // Use 'GetMemInfo' to get free memory size. + //----------------------------------------------------------