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 =
|
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) |
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 |
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 |
..... | ...... |