Some more progress on this problem (at least for the G12 & SX30).
After almost a week with no crashes the G12 started doing it again, today it was crashing on every 2nd or 3rd startup (with no changes to CHDK).
I've now copied the 'Open' (actually eventproc_export_Open) code from the firmware into the G12 CHDK code along with the problem code from the '_sub_FF8735FC__FsIoNotify.c__0' function (see first post).
This '_sub_FF8735FC__FsIoNotify.c__0' code has another path that can cause the crash that I missed earlier. In addition to crashing if no empty slots are found in the array, it will also crash if it finds the file handle (returned from 'open') already in the array.
So I modified the code so that instead of crashing (calling DebugAssert) if it finds the file handle, it just returns without adding the handle to the array. This makes the file open behave as though the 'open' function was called instead of 'Open'.
I also added code to increment counters on each successful and failed call, and displayed these on screen in gui_draw_debug_vals_osd.
On a normal startup it displays 0 for the failed count and 4 for the successful count. Occasionally it will now display 1 for the failed count and 3 for the successful count meaning that it is indeed hitting the 'found file handle in array' error condition. Since my code no longer crashes in this case, the camera continues to start and CHDK seems to work correctly.
What I now suspect is happening is that one task (probably a Canon task) is closing a file handle and before that call to 'Close' can remove the closed file from the FsIoNotify array our CHDK task calls 'Open'. Because the previous file was closed we get back the same file handle from 'open'; but this value is still in the array so the firmware code crashes.
The code changes are below.
boot.c (this is going to be camera specific so the equivalent code will need to be found, copied and modified from the firmware for each camera / firmware version):
int fsionotify_compfail = 0; // count of number of times the file handle was already in the array
int fsionotify_success = 0; // count of number of times the code succeeded
int __attribute__((naked,noinline)) _Open(const char *name, int flags, int mode) {
asm volatile (
"STMFD SP!, {R4-R8,LR} \n"
"MOV R6, R0 \n"
"LDRB R0, [R0] \n"
"MOV R7, R2 \n"
"MOV R4, R1 \n"
"BL sub_FF875690 \n"
"MOV R8, R0 \n"
"MOV R0, #1 \n"
"BIC R5, R0, R4,LSR#12 \n"
"BIC R4, R4, #0x9000 \n"
"MOV R0, R8 \n"
"MOV R1, #1 \n"
"BL sub_FF876A20 \n"
"MOV R2, R7 \n"
"MOV R1, R4 \n"
"MOV R0, R6 \n"
"BL _open \n"
"CMP R5, #0 \n"
"MOV R7, R0 \n"
"MOVNE R0, R7 \n"
"MOVNE R2, R4 \n"
"MOVNE R1, R6 \n"
"BLNE sub_FF8735FC_my \n"
"MOV R0, R8 \n"
"BL sub_FF876A98 \n"
"MOV R0, R7 \n"
"LDMFD SP!, {R4-R8,PC} \n"
);
return 0; // stop compiler warning
}
void __attribute__((naked,noinline)) sub_FF8735FC_my() {
asm volatile (
"STMFD SP!, {R4-R8,LR} \n"
"MOV R5, R0 \n"
"LDR R0, =0x2BA0 \n"
"MOV R7, R1 \n"
"LDR R0, [R0,#4] \n"
"MOV R6, R2 \n"
"CMP R0, #0 \n"
"LDMEQFD SP!, {R4-R8,PC} \n"
"CMP R5, #0 \n"
"LDMLTFD SP!, {R4-R8,PC} \n"
"MOV R4, #0 \n"
"LDR R2, =0x39684 \n"
"MOV R0, #0 \n"
"loc_FF873630: \n"
"ADD R1, R0, R0,LSL#1 \n"
"LDR R1, [R2,R1,LSL#5] \n"
"CMN R1, #1 \n"
"ADDEQ R0, R0, R0,LSL#1 \n"
"ADDEQ R4, R2, R0,LSL#5 \n"
"BEQ loc_FF873658 \n"
"CMP R1, R5 \n"
"BEQ loc_2 \n" // + // branch if found entry matching new file handle
"ADDNE R0, R0, #1 \n"
"CMPNE R0, #0xA \n"
"BLT loc_FF873630 \n"
"loc_FF873658: \n"
"CMP R4, #0 \n"
"LDREQ R1, =0x1C9 \n"
"LDREQ R0, =0xFF873544 \n" //aFsionotify_c
"BLEQ _DebugAssert \n"
"LDR R1, =fsionotify_success \n" // + // increment counter
"LDR R0, [R1] \n" // + // of successful calls
"ADD R0, R0, #1 \n" // +
"STR R0, [R1] \n" // +
"MOV R0, #0 \n" // original code - save handle in array
"STR R0, [R4,#0x58] \n"
"STR R5, [R4] \n"
"MOV R0, R4 \n"
"MOV R1, R7 \n"
"STR R6, [R4,#0x24] \n"
"BL sub_FF8733C4 \n"
"ADD R1, R4, #0x28 \n"
"MOV R0, R7 \n"
"LDMFD SP!, {R4-R8,LR} \n"
"B sub_FF837244 \n"
"loc_2: \n" // + // Handle case when new file handle returned from _open is already in array
"LDR R1, =fsionotify_compfail \n" // + // increment counter then return rather than throw exception
"LDR R0, [R1] \n" // + // equivalent to calling _open rather than _Open
"ADD R0, R0, #1 \n" // +
"STR R0, [R1] \n" // +
"LDMFD SP!, {R4-R8,PC} \n" // +
);
}
You also need to comment out the entry for Open in stubs_entry_2.s
Phil.