MadDog
Member
I've almost got my 920 and 940 talking to each other. The 920 writes commands in a buffer, the 940 reads them. The code for the 940 to wait when there is nothing to do works fine, this also prevents it from getting ahead of the 920.
Also the code stopping the 920 writing over work (catching up with its tail) works a treat too. But the code that stops the 920 from getting more than two frames ahead of th 940 is failing. This bit of code is the only bit that needs and is using a semephone.
I have an uncached var that the 920 inc's and the 940 dec's. There is also a var thats used to lock this counter so only one of the chips can write to it. This code is tricky to get right as if the 920 thinks its too far ahead then it will block and the 940 will be starved of work and will also block. Thus leaving the app bust.
This is the code on the 940, does the lock, dec's the var, then unlocks.
asm volatile(
"stmfd sp!, {r0-r3} \n"
"mov r1,#1 \n"
"mov r2,%0 \n"
"mov r3,%1 \n"
"lock_loop: \n"
" swp r3, r1,[r2] \n"//swap 1 into the lock
" cmp r3, #1 \n"//if a 1 was already there
" beq lock_loop \n"//go back and try again
"ldr r0,[r3] \n"//Get current frame count.
"sub r0,r0,#1 \n"//Dec by one,
"str r0,[r3] \n"//Store it
"mov r1,#0 \n"//set the lock to 0
"str r1,[r2] \n"//Store zero
"ldmfd sp!, {r0-r3} \n"
:
:"r"(®.cmd.cmd_buf->lock),"r"(®.cmd.cmd_buf->frames_in_command_buffer)
);
And this is the code on the 920 that does the lock, incs the var, unlocks then spins of the var is > 2.
asm volatile(
"stmfd sp!, {r5-r8} \n"
"mov r5,#1 \n"
"mov r7,%0 \n"
"mov r8,%1 \n"
"lock_loop: \n"
" swp r6, r5,[r7] \n"//swap 1 into the lock
" cmp r6, #1 \n"//if a 1 was already there
" beq lock_loop \n"//go back and try again
"ldr r6,[r8] \n"//Get current frame count.
"add r6,r6,#1 \n"//Inc by one,
"str r6,[r8] \n"//Store it
"mov r5,#0 \n"//set the lock to 0
"str r5,[r7] \n"//Store zero
"frame_ahead_lock: \n"
" ldr r6,[r8] \n"//Get current frame count.
" cmp r6,#2 \n"//If greater than 2, wait.
" bgt frame_ahead_lock \n"//Go back, we are too far ahead.
"ldmfd sp!, {r5-r8} \n"
:
:"r"(&command_buffer->lock),"r"(&command_buffer->frames_in_command_buffer)
);
Both chips get stuck on the lock loop waiting for it to go zero. I've got to have done something daft here.
Also the code stopping the 920 writing over work (catching up with its tail) works a treat too. But the code that stops the 920 from getting more than two frames ahead of th 940 is failing. This bit of code is the only bit that needs and is using a semephone.
I have an uncached var that the 920 inc's and the 940 dec's. There is also a var thats used to lock this counter so only one of the chips can write to it. This code is tricky to get right as if the 920 thinks its too far ahead then it will block and the 940 will be starved of work and will also block. Thus leaving the app bust.
This is the code on the 940, does the lock, dec's the var, then unlocks.
asm volatile(
"stmfd sp!, {r0-r3} \n"
"mov r1,#1 \n"
"mov r2,%0 \n"
"mov r3,%1 \n"
"lock_loop: \n"
" swp r3, r1,[r2] \n"//swap 1 into the lock
" cmp r3, #1 \n"//if a 1 was already there
" beq lock_loop \n"//go back and try again
"ldr r0,[r3] \n"//Get current frame count.
"sub r0,r0,#1 \n"//Dec by one,
"str r0,[r3] \n"//Store it
"mov r1,#0 \n"//set the lock to 0
"str r1,[r2] \n"//Store zero
"ldmfd sp!, {r0-r3} \n"
:
:"r"(®.cmd.cmd_buf->lock),"r"(®.cmd.cmd_buf->frames_in_command_buffer)
);
And this is the code on the 920 that does the lock, incs the var, unlocks then spins of the var is > 2.
asm volatile(
"stmfd sp!, {r5-r8} \n"
"mov r5,#1 \n"
"mov r7,%0 \n"
"mov r8,%1 \n"
"lock_loop: \n"
" swp r6, r5,[r7] \n"//swap 1 into the lock
" cmp r6, #1 \n"//if a 1 was already there
" beq lock_loop \n"//go back and try again
"ldr r6,[r8] \n"//Get current frame count.
"add r6,r6,#1 \n"//Inc by one,
"str r6,[r8] \n"//Store it
"mov r5,#0 \n"//set the lock to 0
"str r5,[r7] \n"//Store zero
"frame_ahead_lock: \n"
" ldr r6,[r8] \n"//Get current frame count.
" cmp r6,#2 \n"//If greater than 2, wait.
" bgt frame_ahead_lock \n"//Go back, we are too far ahead.
"ldmfd sp!, {r5-r8} \n"
:
:"r"(&command_buffer->lock),"r"(&command_buffer->frames_in_command_buffer)
);
Both chips get stuck on the lock loop waiting for it to go zero. I've got to have done something daft here.
Last edited by a moderator: