Magic Lantern Firmware Wiki
Advertisement


Parent:http://magiclantern.wikia.com/wiki/2.0.4_AJ

Related Page: Event Dispatch tasks

Related Page2: Tasks


What is a StateObject?[]

Rather than have subroutines with millions of switch statements - it is often simpler to describe a process with a set of states and inputs.

A program can then been written with a 'State Machine'. It uses a matrix of Inputs and States to move from one state to another.

A StateObj is a structure that the DryOs uses to keep track of a SateMachine.


There are about 63 State objects in the DryOs - the complete list if given below.

Of particular interest to us are the "LVState" (Live Viewing), and "LVRecState" (Live View Recording)


Below I list the subs that Malloc (ie Create) a StateObj, example of how its used in the ASM, then an exhaustive list of all the 2.0.4 StateObjs.

Finally, I go into more detail on "LVState" and "LVRecState" (as this is where it all happens).

There is a separare page with their entire State Machines exploded on a separate wiki page.


Creating State Objects[]

There are those that call a 'spade a spade' .. and those that call it a 'terrain rellocation implement or tool'. I'm the latter (you can tell by my subroutine names)


I has look at this site (thanks for the pointer AI). CHDK site http://chdk.wikia.com/wiki/DryOS_structures

Note: That CHDK's creation of a StateObject has the Max_states and Max_transitions the other way around to the 5d's firmware.


+-----------------------------------------------------------------------------------------------------------+
|  AJ_CreateStateObj_R0.StateObjNam_R1.zero_R2.ValSubList_R3.TotInputs_STACK.TotStates_RTNR0.AdrStateObj()  |
+-----------------------------------------------------------------------------------------------------------+

int R0 = parm1 = p.StateObjectName         [ eg aAJ_0xFFC7695C_fss_StateName = "FSSState ] 
int R1 = parm2 = p.initial_state           [ This is the 'initial' state of the StateObj = Always_0 ]             
int R2 = parm3 = p.ValSubList              [ eg aAJ_0xFFC7F404_MovwInitialize_ValSubList]
                                           [ Array of Next_state, Next_sub(), for each possible 'input' ]
int R3 = parm4 = p.total_inputs            [ eg =23 for LVState. Inputs used when finding then next state in ValSubList]
STACK[0x00]    = p.total_states            [ eg =14 for LVState]        

RETURN_R0 = Address of 32 byte StateObject structure
            5 - if Malloc failed
RETURN_R1 = 0
RETURN_R2 = RETURN_R0 + 12  (ie 12 bytes into Malloced struct)

32B struct:[0x00] "StateObject"     [0x04] p.StateObjectName = parm1       [0x08] p.inital_state = Always_0 = parm2
           [0x0C] AJ_StateObj()     [0x10] p.ValSubList = parm3            [0x14] p.total_inputs = parm4    
           [0x18] p.total_states    [0x1C] p.current_state = parm2 = 0

Did I mention that I like comments too? Here's the code just incase you're itching to see if the looks like the Matrix backdrops.

STMFD   SP!, {R4-R8,LR} ; AJ: 6 Regs pushed onto stack.   After SP[0]r4, [4]r5, [8]r6, [12]r7, [16]r8, [20]LR
MOV     R4, R0 
LDR     R8, [SP,#24]    ; AJ: R8 = total_states. Get total_inputs from Stack (put there just before this routine was called)
MOV     R0, #32         ; AJ: 32 bytes to allocate
MOV     R7, R3          ; AJ: R7 = parm4 = p.total_inputs
MOV     R6, R2          ; AJ: R6 = parm3 = ValSubList    (=chdk_id)
MOV     R5, R1          ; AJ: R5 = parm2 = p.initial_state (initial state is always = 0)          
BL      AJ_malloc_R0_bytes ; Malloc 32 bytes
                        ;
CMP     R0, #0          ; AJ:  If Malloc failed -> Return
MOVEQ   R0, #5          ; AJ:  5 = failure code
LDMEQFD SP!, {R4-R8,PC} ;

ADD     R2, R0, #12     ; AJ: R0 = address of 32bytes of malloced memory
LDR     R1, =aAJ_StateObject_string
LDR     R1, [R1]        ; AJ: R1 = "StateObject"
                        ;
STMIA   R0, {R1,R4,R5}  ; Store 12 bytes
                        ;
ADR     R1, AJ_StateObj
STMIA   R2, {R1,R6-R8}  ; AJ: Store 16 bytes (thats 28 so far)
MOV     R1, #0
STR     R1, [R0,#28]    ; AJ: Store current_state (=p.initial_state)  at last 4 bytes at [0x1C].  32 in total
LDMFD   SP!, {R4-R8,PC}


Example of setup one up:


; +--------------------------------------+
; |  AJ_CreateStateObject_fss()          |
; +--------------------------------------+

AJ_CreateStateObject_fss

STMFD   SP!, {R3,LR}
LDR     R2, =aAJ_0xFFC76960_fss_ValSubList
MOV     R3, #1
STR     R3, [SP]        ; AJ: Total_states = 1       
SUB     R0, R2, #4      ; AJ: aAJ_0xFFC7695C_fss_StateName = "FSSState"
LDR     R0, [R0]
MOV     R3, #11         ; AJ: R3 = Total_inputs = 11
MOV     R1, #0
BL      AJ_CreateStateObj_R0.StateObjNam_R1.zero_R2.ValSubList_R3.TotInputs_STACK.TotStates_RTNR0.AdrStateObj
LDR     R1, =aAJ_0x3C24_fssCompleteJob_related
STR     R0, [R1]
LDMFD   SP!, {R12,PC}


See also: ValSubLists http://magiclantern.wikia.com/wiki/2.0.4_ValSubLists


2.0.4 StateObjects[]

Pointer to 32 Byte StateObject List of pairs of Value, Subroutine Keh?

ValSub Pairs =


Inputs x States

Total inputs Total States
aAJ_0x20A30_IPC_0x04_IPCSlaveState_StateObj aAJ_0xFFCC8108_IPCSlaveState_ValSubList 8 8 1
aAJ_0x20A30_IPC_0x00_to_0x04_MasterState_StateObj aAJ_0xFFCC7FC8_IPCTMasterState_ValSubList 40 8 5
aAJ_0x17714_CRP_related_0x04_StateObj aAJ_0xFFCBFD1C_CrpDecState_ValSubList

AI: oops

10 5 2
aAJ_0x15A94_AudioLevel_0x0C_StateObj aAJ_0xFFCB4970_AudioLevel_ValSubList 49 10 5
0xFF96A460 malloc in AJ_fwCreate() ... follow the rabbit. aAJ_0xFFCB1540_FWState_ValSubList File Write State 5 3
0xFF969654 malloc in AJ_frCreate () ... follow the rabbit. aAJ_0xFFCB152C_FRState_ValSubList File Read State 2 2 1
aAJ_0x1436C_MrkState_0x00_StateObj aAJ_0xFFCB0E50_MrkState_ValSubList Guess: Object State within a file 7 7 1
aAJ_0x14344_SdioTskState_0x00_StateObj aAJ_0xFFCB0C34_SdioTskState_ValSubList 6 6 1
aAJ_0x142D4_PtpSdioHddTrans_0x00_StateObj aAJ_0xFFCAFC30_PtpSdioHddTrans_ValSubList 21 18
aAJ_0x1418C_PtpSdioTrans_0x00_StateObj aAJ_0xFFCAEC0C_PtpSdioTrans_ValSubList 21 18
aAJ_0x14180_PtpTrans_0x00_StateObj aAJ_0xFFCADD10_PtpTrans_ValSubList 21 18
aAJ_0x14174_PtpEvent_0x00_StageObj aAJ_0xFFCAD994_PtpEvent_ValSubList 8 5
aAJ_0x13E78_LVAngelState_0x00_StateObj aAJ_0xFFCA7980_LVAngelState_ValSubList 6 2
aAJ_0x3E50_DpState_0x00_StateObj aAJ_0xFFCA71E0_DpState_ValSubList Dot Printer State 19 19 1
aAJ_0x97CC_DM_n_Powersave_related_0x00_StateObj aAJ_0xFFCA3DF4_DMState_ValSubList Debug Manager State 14 2
aAJ_0x8844_PropState_0x00_StateObj aAJ_0xFFC89E68_PropState_ValSubList Multicast Property Master State 18 1
aAJ_0x31D28_USB20State_0x00_to_0x10_StateObj0_USBControlPipe aAJ_0xFFC88C68_USBControlPipe_VarSubList 13 11
aAJ_0x31D28_USB20State_0x04_StateObj1_USBDataPipeBulkIn aAJ_0xFFC890E0_USBDataPipeBulkIn_VarSubList 11 9
aAJ_0x31D28_USB20State_0x08_StateObj2_USBDataPipeBulkOut aAJ_0xFFC893F8_USBDataPipeBulkOut_VarSubList 9 6
aAJ_0x31D28_USB20State_0x0C_StateObj3_USBDataPipeInterrupt aAJ_0xFFC895A8_USBDataPipeInterrupt_VarSubList 8 5
aAJ_0x31D28_USB20State_0x10_StateObj4_USBDeviceEvent aAJ_0xFFC896E8_USBDeviceEvent_VarSubList 5 1
aAJ_0x7C90_MovRecState_0x00_StateObj aAJ_0xFFC7F438_MovRecState_ValSubList Moive Record State 10 12
aAJ_0x7C80_Movw_0x00_to_0x0C_StateObj aAJ_0xFFC7F404_MovwInitialize_ValSubList Movie Write State 6 3 2
aAJ_0x7B30_FMNormalState_0x00_StateOb aAJ_0xFFC7E838_FMNormalState_ValSubList File Manager State 10 5
aAJ_0x7B1C_Ceres_0x00_StateObj aAJ_0xFFC7E6FC_Ceres_ValSubList 12 6 2
aAJ_0x7AE4_TOM_0x00_StateObj aAJ_0xFFC7E620_TOM_ValSubList 6 3
aAJ_0x7AC8_SdioDrv_0x00_StateObj aAJ_0xFFC7E5B4_SdioDrvExecJob_ValSubList 4 2 2
aAJ_0x7938_PtpSdioEvent_0x00_StateObj aAJ_0xFFC7E254_PtpSdioEvent_ValSubList Property of Standard IO Event State 8 5
0xFF83AF8C malloc in AJ_PtpDpsMgrSyncSem_n_init_StateObj() aAJ_0xFFC7D7F8_PtpDps1_ValSubList 14 13
0xFF83AF8C malloc in AJ_PtpDpsMgrSyncSem_n_init_StateObj() aAJ_0xFFC7DDA8_PtpDps2_ValSubList 4 3
0xFF83AF8C malloc in AJ_PtpDpsMgrSyncSem_n_init_StateObj() aAJ_0xFFC7DE08_PtpDpsMgr_ValSubList 48 2
aAJ_0x7780_RD_0x00_StateObj aAJ_0xFFC7D63C_RD_ValSubList 3 4
aAJ_0x76E0_MD_0x30_StateObj aAJ_0xFFC7D548_MD_ValSubList Motion Detect State 10 4
aAJ_0x46C4_LVCDEV_0x40_StateObj aAJ_0xFFC7ADCC_LVCDEV_ValSubList 11 4
aAJ_0x4690_LVCAF_0x0C_StateObj aAJ_0xFFC7A85C_LVCAF_ValSubList 14 10
aAJ_0x4660_LVCAE_0x14_StateObj aAJ_0xFFC7A568_LVCAE_VarSubList 12 7
aAJ_0x44FC_LV_0x2C_LV_StateObj aAJ_0xFFC79630_LV_VarSubList

"LVState"

Live View State (Not record)

Click here for LVState fun

Inputs x States

23 x 14 = 322

23 14
aAJ_0x44FC_LV_0x30_LVRec_StateObj aAJ_0xFFC7A040_LVRec_VarSubList

"LVRecState"

Live View Record State

Some details below this table. Also

Click here for more fun

7 x 7 = 49 7 7
aAJ_0x44E8_DpImgEdit_0x04_StateObj aAJ_0xFFC7905C_DpImgEdit_ValSubList 1 1 1
aAJ_0x3D00_SRM_0x00_to_0x08_StateObj aAJ_0xFFC779B8_SRM_ValSubList 28 2
aAJ_0x3C94_EM_related_0x00_StateObj aAJ_0xFFC777C8_EM_ValSubList Event Manager 5 5 1
aAJ_0x3C34_FCS_0x00_StateObj aAJ_0xFFC769BC_FCS_ValSubList 5 4
aAJ_0x3C24_FSS_0x00_StateObj aAJ_0xFFC76960_FSS_ValSubList 11 1
aAJ_0x369C_SDS_related_0x14_SDSFront_StateObj1 aAJ_0xFFC74450_SDSFront_ValSubList1 Front Develop State 10 10
aAJ_0x369C_SDS_related_0x18_SDSFront_StateObj2 aAJ_0xFFC74770_SDSFront_ValSubList2 10 5
aAJ_0x369C_SDS_related_0x1C_SDSFront_StateObj3 aAJ_0xFFC74900_SDSFront_ValSubList3 10 2
aAJ_0x369C_SDS_related_0x20_SDSFront_StateObj4 aAJ_0xFFC74900_SDSFront_ValSubList4 10 2
aAJ_0x3630_SDSRear_0x0C_StateObj aAJ_0xFFC740E8_SDSRear_ValSubList Rear Develop State 10 10
aAJ_0x31E8_SPS_0x24_StateObj aAJ_0xFFC73F44_SPS_ValSubList Pre Develop State 8 6
aAJ_0x31B0_SBS_0x14_StateObj aAJ_0xFFC738C0_SBS_ValSubList Dark State 16 13
aAJ_0x3164_SCS_0x04_SCS_StateObj aAJ_0xFFC72CEC_SCS_ValSubList Capture State 18 12
aAJ_0x3164_SCS_0x08_SCSEshut_StateOb aAJ_0xFFC733AC_SCSEshut_ValSubList ? Electronic Shutter 18 5
aAJ_0x3164_SCS_0x0C_SCSSR_StateObj aAJ_0xFFC7367C_SCSSR_ValSubList ? Shutter Release 18 4

Alex: I believe MD has 7 inputs instead of 10, and SDSFront2 has 8 states instead of 5. At least that's what my state diagram generator displayed on the console.

The State object use an array of Input and Current_state to determine how to move to the next state.

Eg below is an extract of the "LVRecState" state machine.

You can 'see' it in all its glory .. here

2.0.4 State Machine Diagrams[]

http://a1ex.bitbucket.org/ML/states/

... generated with Python and GraphViz. There are too many SVGs to place them on the wiki, so I've uploaded them on BitBucket. Alex

----- Example: "LVRecState" changing Current_state -----[]

+------------------------------+
|  AJ_LVREC_CallNextState()    | at 0xFF8DAF8C 
+------------------------------+ 
        
int R0 = LiveViewMgr_struct      [ptr to huge 0x29D8 LVMgr struct]
int R1 = "LVRecState" StateObj   [ie aAJ_0x44FC_LiveView_struct_0x30_LVRec_StateObj]
int R2 = input                   [0..6]

Basic logic:

Next_State = [ aAJ_0xFFC7A040_LVRec_VarSubList + 8 x (7 x input + "LVRecState"_cur_state) ]

Next_Sub() = [0x04 + [ aAJ_0xFFC7A040_LVRec_VarSubList + 8 x (7 x input + "LVRecState"_cur_state) ]

Set "LVRecState".CurState = Next_State

Then BR Next_sub()



If there are 7 CURRENT states

And N NEXT states

Input [address] Next_state Next_sub
0 ------------------ [0x00] <next_state> for Input=0 , cur_state=0 [0x04] <next_sub()> for Input=0 , cur_state=0
0 [0x08] <next_state> for Input=0 , cur_state=1 [0x0C] <next_sub()> for Input=0 , cur_state=1
0 [0x10] <next_state> for Input=0 , cur_state=2 [0x14] <next_sub()> for Input=0 , cur_state=2
0 [0x18] <next_state> for Input=0 , cur_state=3 [0x1C] <next_sub()> for Input=0 , cur_state=3
0 [0x20] <next_state> for Input=0 , cur_state=4 [0x24] <next_sub()> for Input=0 , cur_state=4
0 [0x28] <next_state> for Input=0 , cur_state=5 [0x2C] <next_sub()> for Input=0 , cur_state=5
0 [0x30] <next_state> for Input=0 , cur_state=6 [0x34] <next_sub()> for Input=0 , cur_state=6
1 ------------------ [0x38] <next_state> for Input=1 , cur_state=0 [0x3C] <next_sub()> for Input=1 , cur_state=0
1 [0x40] <next_state> for Input=1 , cur_state=1 [0x44] <next_sub()> for Input=1 , cur_state=1
1 [0x48] <next_state> for Input=1 , cur_state=2 [0x4C] <next_sub()> for Input=1 , cur_state=2
1 [0x50] <next_state> for Input=1 , cur_state=3 [0x54] <next_sub()> for Input=1 , cur_state=3
..... ......
Advertisement