Dfort, while I was trying to compile from crop_rec_4k, I noticed that lua module wasn't going fine due to a missing reference to "Value2Raw", this isn't also into a1ex's patch
I saw your latest commit and it's missing some diff; let's add the patch below.
diff --git a/modules/lua/lua_lens.c b/modules/lua/lua_lens.c
--- a/modules/lua/lua_lens.c
+++ b/modules/lua/lua_lens.c
@@ -17,12 +17,24 @@
static int luaCB_lens_index(lua_State * L)
{
LUA_PARAM_STRING_OPTIONAL(key, 2, "");
- /// Get the name of the lens (reported by the lens).
- // @tfield string name readonly
+ /// Get/Set the name of the lens (reported by the lens)
+ // @tfield string name
if(!strcmp(key, "name")) lua_pushstring(L, lens_info.name);
- /// Get the focal length of the lens (in mm). Only updated in LiveView.
- // @tfield int focal_length readonly
+ /// Get the lens id
+ // @tfield int id readonly
+ else if(!strcmp(key, "id")) lua_pushinteger(L, lens_info.lens_id);
+ /// Get the serial number of the lens
+ // @tfield int serial
+ else if(!strcmp(key, "serial")) lua_pushinteger(L, lens_info.lens_serial);
+ /// Get/Set the focal length of the lens (in mm)
+ // @tfield int focal_length
else if(!strcmp(key, "focal_length")) lua_pushinteger(L, lens_info.focal_len);
+ /// Get/Set the minimum focal length of the lens (in mm)
+ // @tfield int focal_min
+ else if(!strcmp(key, "focal_min")) lua_pushinteger(L, lens_info.lens_focal_min);
+ /// Get/Set the maximum focal length of the lens (in mm)
+ // @tfield int focal_max
+ else if(!strcmp(key, "focal_max")) lua_pushinteger(L, lens_info.lens_focal_max);
/// Get the current focus distance (in mm). Only updated in LiveView.
// @tfield int focus_distance readonly
else if(!strcmp(key, "focus_distance")) lua_pushinteger(L, lens_info.focus_dist * 10);
@@ -84,7 +96,55 @@
static int luaCB_lens_newindex(lua_State * L)
{
LUA_PARAM_STRING_OPTIONAL(key, 2, "");
- if(!strcmp(key, "name") || !strcmp(key, "focal_length") || !strcmp(key, "focus_distance") || !strcmp(key, "hyperfocal") || !strcmp(key, "dof_near") || !strcmp(key, "dof_far") || !strcmp(key, "af") || !strcmp(key, "is_chipped"))
+ if(!strcmp(key, "name"))
+ {
+ LUA_PARAM_STRING(value, 3);
+ strncpy(lens_info.name, value, sizeof(lens_info.name)-1);
+ }
+ else if(!strcmp(key, "exists"))
+ {
+ LUA_PARAM_BOOL(value, 3);
+ lens_info.lens_exists = value;
+ }
+ else if(!strcmp(key, "focal_length"))
+ {
+ LUA_PARAM_INT(value, 3);
+ lens_info.focal_len = value;
+ }
+ else if(!strcmp(key, "focal_min"))
+ {
+ LUA_PARAM_INT(value, 3);
+ lens_info.lens_focal_min = value;
+ }
+ else if(!strcmp(key, "focal_max"))
+ {
+ LUA_PARAM_INT(value, 3);
+ lens_info.lens_focal_max = value;
+ }
+ else if(!strcmp(key, "manual_aperture"))
+ {
+ LUA_PARAM_NUMBER(value, 3);
+ lens_info.aperture = (int)(value * 10);
+ lens_info.raw_aperture = VALUE2RAW(aperture, lens_info.aperture);
+ }
+ else if(!strcmp(key, "aperture_min"))
+ {
+ LUA_PARAM_NUMBER(value, 3);
+ int tmp = (int)(value * 10);
+ lens_info.raw_aperture_min = VALUE2RAW(aperture, tmp);
+ }
+ else if(!strcmp(key, "aperture_max"))
+ {
+ LUA_PARAM_NUMBER(value, 3);
+ int tmp = (int)(value * 10);
+ lens_info.raw_aperture_max = VALUE2RAW(aperture, tmp);
+ }
+ else if(!strcmp(key, "serial"))
+ {
+ LUA_PARAM_INT(value, 3);
+ lens_info.lens_serial = value;
+ }
+ else if(!strcmp(key, "focus_distance") || !strcmp(key, "hyperfocal") || !strcmp(key, "dof_near") || !strcmp(key, "dof_far") || !strcmp(key, "af") || !strcmp(key, "is_chipped"))
{
return luaL_error(L, "'%s' is readonly!", key);
}
diff --git a/modules/lua/lua_property.c b/modules/lua/lua_property.c
--- a/modules/lua/lua_property.c
+++ b/modules/lua/lua_property.c
@@ -21,8 +21,6 @@
// !!!DANGER WILL ROBINSON!!!
//#define LUA_PROP_REQUEST_CHANGE
-struct msg_queue * lua_prop_queue = NULL;
-
struct lua_prop
{
struct lua_prop * next;
@@ -32,100 +30,69 @@
int prop_handler_ref;
};
-struct lua_prop_msg
-{
- unsigned property;
- void * value;
- unsigned len;
-};
-
-int lua_prop_task_running = 0;
static struct lua_prop * prop_handlers = NULL;
-//TODO: create a new task per script so that scripts don't block each other's prop handlers, necessary?
-static void lua_prop_task(int unused)
+static void lua_prophandler(unsigned property, void * priv, void * buf, unsigned len)
{
- lua_prop_queue = msg_queue_create("lua_prop_queue", 1);
- TASK_LOOP
+ struct lua_prop * lua_prop = 0;
+ int found = 0;
+ for (lua_prop = prop_handlers; lua_prop; lua_prop = lua_prop->next)
{
- struct lua_prop_msg * msg = NULL;
- int err = msg_queue_receive(lua_prop_queue, &msg, 0);
-
- if(err || !msg) continue;
-
- struct lua_prop * lua_prop = NULL;
- int found = 0;
- for(lua_prop = prop_handlers; lua_prop; lua_prop = lua_prop->next)
+ if (lua_prop->prop_id == property)
{
- if(lua_prop->prop_id == msg->property)
+ found = 1;
+ break;
+ }
+ }
+
+ if (found)
+ {
+ lua_State * L = lua_prop->L;
+ struct semaphore * sem = NULL;
+ if (lua_take_semaphore(L, 100, &sem) == 0)
+ {
+ ASSERT(sem);
+ if (lua_rawgeti(L, LUA_REGISTRYINDEX, lua_prop->prop_handler_ref) == LUA_TFUNCTION)
{
- found = 1;
- break;
+ lua_rawgeti(L, LUA_REGISTRYINDEX, lua_prop->self_ref);
+ if (len > 4)
+ {
+ /* fixme: pass proper data types (requires knowledge about each property) */
+ //long, probably a string
+ //((char*)(msg->value))[msg->len] = 0x0;
+ lua_pushstring(L, (char*)buf);
+ }
+ else
+ {
+ lua_pushinteger(L, *(uint32_t*)buf & (0xFFFFFFFF >> ((4-len) * 8)) );
+ }
+
+ int t0 = get_us_clock();
+
+ if (docall(L, 2, 0))
+ {
+ fprintf(stderr, "[Lua] prop handler failed:\n %s\n", lua_tostring(L, -1));
+ lua_save_last_error(L);
+ }
+
+ int t1 = get_us_clock();
+
+ if (t1 - t0 > 10000)
+ {
+ printf("[%s] slow property handler %X (%d us)\n", lua_get_script_filename(L), lua_prop->prop_id, t1 - t0);
+ }
}
+ give_semaphore(sem);
}
-
- if(found && msg->value)
+ else
{
- lua_State * L = lua_prop->L;
- struct semaphore * sem = NULL;
- if (lua_take_semaphore(L, 1000, &sem) == 0)
- {
- ASSERT(sem);
- if(lua_rawgeti(L, LUA_REGISTRYINDEX, lua_prop->prop_handler_ref) == LUA_TFUNCTION)
- {
- lua_rawgeti(L, LUA_REGISTRYINDEX, lua_prop->self_ref);
- if(msg->len > 4)
- {
- //long, probably a string
- ((char*)(msg->value))[msg->len] = 0x0;
- lua_pushstring(L, (char*)(msg->value));
- }
- else if(msg->len == 4) lua_pushinteger(L, *((uint32_t*)(msg->value)));
- else if(msg->len >= 2) lua_pushinteger(L, *((uint16_t*)(msg->value)));
- else lua_pushinteger(L, *((uint8_t*)(msg->value)));
- if(docall(L, 2, 0))
- {
- fprintf(stderr, "[Lua] prop handler failed:\n %s\n", lua_tostring(L, -1));
- lua_save_last_error(L);
- }
- }
- give_semaphore(sem);
- }
- else
- {
- printf("[Lua] semaphore timeout: prop handler %d (%dms)\n", lua_prop->prop_id, 1000);
- }
+ printf("[%s] semaphore timeout: prop handler %X (%dms)\n", lua_get_script_filename(L), lua_prop->prop_id, 100);
}
- free(msg->value);
- free(msg);
- }
-}
-
-static void lua_prophandler(unsigned property, void * priv, void * addr, unsigned len)
-{
- if (!lua_prop_queue) return;
- struct lua_prop_msg * msg = malloc(sizeof(struct lua_prop_msg));
- msg->property = property;
- msg->len = MIN(len,255);
- msg->value = malloc(msg->len + 1);
- if(msg->value)
- {
- memcpy(msg->value, addr, MIN(len,255));
- msg_queue_post(lua_prop_queue, (uint32_t)msg);
- }
- else
- {
- fprintf(stderr, "[Lua] lua_prophandler: malloc error");
}
}
static void lua_register_prop_handler(unsigned prop_id)
{
- if(!lua_prop_task_running)
- {
- lua_prop_task_running = 1;
- task_create("lua_prop_task", 0x1c, 0x10000, lua_prop_task, 0);
- }
//check for existing prop handler
struct lua_prop * current;
for(current = prop_handlers; current; current = current->next)
diff --git a/src/lens.c b/src/lens.c
--- a/src/lens.c
+++ b/src/lens.c
@@ -1941,7 +1941,11 @@
factor = 1/2.54;
}
- if(lens_info.lens_focal_min == lens_info.lens_focal_max)
+ if(!lens_info.lens_focal_min || !lens_info.lens_focal_max)
+ {
+ MENU_SET_VALUE("%d %s", (int)(lens_info.focal_len * factor), unit);
+ }
+ else if(lens_info.lens_focal_min == lens_info.lens_focal_max)
{
MENU_SET_VALUE("%d %s", (int)(lens_info.lens_focal_min * factor), unit);
}
@@ -1955,6 +1959,7 @@
{
.name = "Lens Info Prefs",
.select = menu_open_submenu,
+ .submenu_width = 700,
.children = (struct menu_entry[]) {
#ifndef CONFIG_FULLFRAME
{
diff --git a/src/lens.h b/src/lens.h
--- a/src/lens.h
+++ b/src/lens.h
@@ -307,7 +307,12 @@
//~ static const int codes_aperture[] = {0,13,14,16,19,21,24,27,29,32,35,37,40,44,45,48,51,52,53,56,59,60, 61, 64, 68, 69, 72, 75, 76, 77, 80, 83, 84, 85, 88, 91, 92, 93, 96};
#define RAW2VALUE(param,rawvalue) ((int)values_##param[raw2index_##param(rawvalue)])
-#define VALUE2RAW(param,value) ((int)val2raw_##param(value))
+#define VALUE2RAW(param,value) val2raw_##param(value)
+
+/* prototypes for VALUE2RAW */
+int VALUE2RAW(iso, int);
+int VALUE2RAW(shutter, int);
+int VALUE2RAW(aperture, int);
// UNIT_1_8_EV
#define APEX_TV(raw) ((int)(raw) - 56)
diff --git a/src/mem.c b/src/mem.c
--- a/src/mem.c
+++ b/src/mem.c
@@ -582,7 +582,8 @@
memcheck_add(ptr, file, line);
- /* keep track of allocated memory and update history */
+ /* keep track of allocated memory and update history */
+ unsigned int state = cli();
allocators[allocator_index].num_blocks++;
allocators[allocator_index].mem_used += len + 2 * MEM_SEC_ZONE;
alloc_total += len;
@@ -590,7 +591,8 @@
alloc_total_peak_with_memcheck = MAX(alloc_total_peak_with_memcheck, alloc_total_with_memcheck);
history[history_index] = MIN(alloc_total_with_memcheck / 1024, USHRT_MAX);
history_index = MOD(history_index + 1, HISTORY_ENTRIES);
-
+ sei(state);
+
return (void*)(ptr + MEM_SEC_ZONE);
}
@@ -784,12 +786,64 @@
/* if we arrive here, you should probably solder some memory chips on the mainboard */
return -1;
}
+
+static void * check_and_adjust_ptr(void * ptr, size_t size, unsigned int flags, const char* file, unsigned int line, int allocator_index)
+{
+ if (!ptr)
+ {
+ /* didn't work? */
+ snprintf(last_error_msg_short, sizeof(last_error_msg_short), "%s(%s,%x)", allocators[allocator_index].name, format_memory_size_and_flags(size, flags));
+ snprintf(last_error_msg, sizeof(last_error_msg), "%s(%s) failed at %s:%d, %s.", allocators[allocator_index].name, format_memory_size_and_flags(size, flags), file, line, get_current_task_name());
+ dbg_printf("alloc fail, took %s%d.%03d s\n", FMT_FIXEDPOINT3(t1-t0));
+ }
+ else
+ {
+ /* force the cacheable pointer to be the way user requested it */
+ /* note: internally, this library must use the vanilla pointer (non-mangled) */
+ ptr = (flags & MEM_DMA) ? UNCACHEABLE(ptr) : CACHEABLE(ptr);
+
+ dbg_printf("alloc ok, took %s%d.%03d s\n", FMT_FIXEDPOINT3(t1-t0));
+ }
+
+ return ptr;
+}
+
+/* used for property handler / vsync hooks / GUI handlers / other tricky places */
+/* not to be called directly, but exported to modules for test purposes (seltest.mo) */
+void * __fast_malloc(size_t size, unsigned int flags, const char* file, unsigned int line)
+{
+ /* for small sizes only */
+ ASSERT(size < 65536);
+
+ /* Canon code uses AllocateMemory for these, so... let's try */
+ int allocator_index = 1;
+
+ /* is this thread-safe? */
+ void * ptr = memcheck_malloc(size, file, line, allocator_index, flags);
+
+ return check_and_adjust_ptr(ptr, size, flags, file, line, allocator_index);
+}
/* these two will replace all malloc calls */
/* returns 0 if it couldn't allocate */
void* __mem_malloc(size_t size, unsigned int flags, const char* file, unsigned int line)
-{
+{
+ /* running from PROP_HANDLER's will cause trouble
+ * slow allocators (in particular, srm_malloc) will keep the semaphore busy
+ * this would delay Canon's property handlers, possibly overflowing the queue
+ * similar issues may appear with GUI handlers, LiveView "vsync" hooks etc
+ * todo: generic way to figure out whether we are running from such hooks or from regular tasks
+ */
+ const char * current_task_name = get_current_task_name();
+ if (streq(current_task_name, "PropMgr") ||
+ streq(current_task_name, "GuiMainTask") ||
+ streq(current_task_name, "Evf"))
+ {
+ dbg_printf("fast_malloc(%s) from %s:%d task %s\n", format_memory_size_and_flags(size, flags), file, line, get_current_task_name());
+ return __fast_malloc(size, flags, file, line);
+ }
+
ASSERT(mem_sem);
take_semaphore(mem_sem, 0);
At this point we should have a changeset which extends lens name as a1ex's patch and a possible lua implementation, but I don't expect to run lens.lua script fine because It misses a lot of old commits from manual_lens_info, which I don't know exactly how to manage as my work is based on top of old version of lens.lua
Anyway it compiles for 5D3 but I can't test it. Can you try it?