https://bitbucket.org/daniel_fort/magic-lantern
Raw File
Tip revision: a1629783925ba49ccb45615fa9636f274ff768eb authored by a1ex on 28 January 2015, 16:54:24 UTC
Close branch external-monitor.
Tip revision: a162978
evf-hacks.c
/** 
 * EVF state experiments.
 * 
 **/

#include "dryos.h"
#include "bmp.h"
#include "state-object.h"


/**
 *  EVF Manager - 6D v1.1.2
 *
 *  Managers are a high-level data structure in DryOS and VxWorks. For structure definitions, look in state-object.h
 *
 *  Before, state-objects were the highest level data structure we understood in DryOS, now I understand what actually
 *  triggers the state changes, so we can track down the functions that do these changes. For this demonstration I'll
 *  examine the EVF Manager in the 6D v1.1.2 firmware.
 *
 *  The Taskclass structure is pretty important, as this is where events are queued up before processed. Events are
 *  posted to the taskclass queue by taskclass_post_message (0x39F04). Arg2 to this function is the event number to
 *  post. A taskclass has a generic task, which takes events posted to the taskclass message queue, and calls the
 *  respective EventDispatch function, in our case it's evfEventDispatch (0xFF0DD22C). This function is called by the
 *  taskclass task via a pointer stored in the Manager struct. It's because of this that we can hijack the EventDispatch
 *  handler just like state objects, to catch taskclass events as they're processed.
 *
 *  All we need to look for to find who posts the events are calls to taskclass_post_message, specifically the ones that
 *  reference the EVF Manager's struct. I hijacked the EVF Manager's event dispatch here, and got the same results as when
 *  I hijacked the state machine, so it works! For EVF state, i observed 3 events happening in each frame: 5, 3, and 4.
 *  Look at my youtube video here of live view slowed down to 2fps, the Tick message happens once every second (on another task).
 *      --> www.youtube.com/watch?v=B4n1eh8YUtE
 *
 *  The debug log after running this looked like:
 *
 *  [MAGIC] name|arg1|arg2|arg3: Evf | 0x5 | 0x0 | 0x0
 *  [MAGIC] name|arg1|arg2|arg3: Evf | 0x3 | 0x0 | 0x0
 *  [MAGIC] name|arg1|arg2|arg3: Evf | 0x4 | 0x0 | 0x0
 *      (repeated)
 *
 **/
 

#ifdef CONFIG_6D
    //~ #define EVF_MGR     (*(struct Manager **)0x74ED4)
#endif


static void evfhacks_task()
{
    TASK_LOOP
    {
        //~ not used
        msleep(200);
    }
}

/** WARNING: This implementation only supports hijacking ONE manager at a time. **/
static int (*EventDispatchHandler)(int,int,int,int);
static int eventdispatch_handler(int arg0, int arg1, int arg2, int arg3)
{
    int ans = EventDispatchHandler(arg0, arg1, arg2, arg3);
    DryosDebugMsg(0, 3, "[MAGIC] name|arg1|arg2|arg3: %s | 0x%x | 0x%x | 0x%x", MEM(arg0), arg1, arg2, arg3);
    return ans;
}

//** hijack EVF events as they're processed
static void hijack_manager(struct Manager * manager)
{
    EventDispatchHandler = (void *)manager->taskclass_ptr->eventdispatch_func_ptr;
    manager->taskclass_ptr->eventdispatch_func_ptr = (void *)eventdispatch_handler;
}

static void evfhacks_init()
{
    #ifdef EVF_MGR
        hijack_manager(EVF_MGR);
    #endif
}

INIT_FUNC("evfhacks", evfhacks_init);
//~ TASK_CREATE("evhacks_task", evfhacks_task, 0, 0x1e, 0x2000);
back to top