Eos 400d ( Rebel XTI ) - page 168 - DSLR Hack development - CHDK Forum

Eos 400d ( Rebel XTI )

  • 1871 Replies
  • 891275 Views
VRAM
« Reply #1670 on: 28 / March / 2013, 06:23:31 »
Advertisements
Looks like I successfully locked vram. OLC can't change anything on screen after lock, but direct write to vram still works . 

DEF(TakeVramSemaphore, 0xFF92E41C)  //
DEF(GiveSemaphore__, 0xFF92E468)      // goes in funclist.txt

#define VramInstance_address *(int*)0x5190

TakeVramSemaphore(VramInstance_address);  // takes vram semaphore so other tasks have to wait for it to free before thay can write to vram
SleepTask(2000);
bmp_printf(50, 134, "test", COLOR_BLACK, COLOR_GRAY); //writes directly to vram
SleepTask(7000);
GiveSemaphore__(VramInstance_address);  //releases the semaphore


Not exactly what I needed but it can be used for custom windows on OLC screen or maybe to hide menu screen when firmware goes into 400plus menu. 

VRAM
« Reply #1671 on: 28 / March / 2013, 06:23:47 »
  Well, firmware waits for semaphore to free before it starts menu, so I guess it's no way to hide the menu screen.

VRAM
« Reply #1672 on: 28 / March / 2013, 06:24:08 »
Looks like I successfully locked vram. OLC can't change anything on screen after lock, but direct write to vram still works . 

DEF(TakeVramSemaphore, 0xFF92E41C)  //
DEF(GiveSemaphore__, 0xFF92E468)      // goes in funclist.txt

#define VramInstance_address *(int*)0x5190

TakeVramSemaphore(VramInstance_address);  // takes vram semaphore so other tasks have to wait for it to free before thay can write to vram
SleepTask(2000);
bmp_printf(50, 134, "test", COLOR_BLACK, COLOR_GRAY); //writes directly to vram
SleepTask(7000);
GiveSemaphore__(VramInstance_address);  //releases the semaphore


Not exactly what I needed but it can be used for custom windows on OLC screen or maybe to hide menu screen when firmware goes into 400plus menu. 

Very interesting, thanks for sharing.

I guess this could be used to make our own menus, writing directly to VRAM, no? And I should probably update our overlay code, and use that semaphore.

But, do you think this could be used to avoid flickering? Actually, we do not want to lock the OLC, we just want to know when somebody else writes to the display; perhaps we could "watch" that semaphore, or get informed each time it is released, so we can update our overlay afterwards. Just some thoughts...

VRAM
« Reply #1673 on: 28 / March / 2013, 06:24:27 »
Looks like I successfully locked vram. OLC can't change anything on screen after lock, but direct write to vram still works . 

DEF(TakeVramSemaphore, 0xFF92E41C)  //
DEF(GiveSemaphore__, 0xFF92E468)      // goes in funclist.txt

#define VramInstance_address *(int*)0x5190

TakeVramSemaphore(VramInstance_address);  // takes vram semaphore so other tasks have to wait for it to free before thay can write to vram
SleepTask(2000);
bmp_printf(50, 134, "test", COLOR_BLACK, COLOR_GRAY); //writes directly to vram
SleepTask(7000);
GiveSemaphore__(VramInstance_address);  //releases the semaphore


Not exactly what I needed but it can be used for custom windows on OLC screen or maybe to hide menu screen when firmware goes into 400plus menu. 

Very interesting, thanks for sharing.

I guess this could be used to make our own menus, writing directly to VRAM, no? And I should probably update our overlay code, and use that semaphore.

But, do you think this could be used to avoid flickering? Actually, we do not want to lock the OLC, we just want to know when somebody else writes to the display; perhaps we could "watch" that semaphore, or get informed each time it is released, so we can update our overlay afterwards. Just some thoughts...

If "everybody else" who writes to the main display uses this same semaphore (looks like they should, that is what semaphores are for, no?), and we could somehow intercept all calls to TakeVramSemaphore, then we would know when to refresh our overlay. Could the "cache hack" be used here?

VRAM
« Reply #1674 on: 28 / March / 2013, 06:24:43 »
  Yes, you're right, it will not help to stop flickering. I'm not familiar with semaphores but it looks like it is just a flag and some info, so you will have to check it all the time to know if something is using it. Would be nice to find a way to execute a function on semaphore access without checking it all the time.

VRAM
« Reply #1675 on: 28 / March / 2013, 06:25:05 »
Hi guys,
This reply is going to be a long one, sorry for that.
It seems the forum didn't sent any mail notifications to me and I'm way behind this conversation.
So here we go...


Looks like I successfully locked vram. OLC can't change anything on screen after lock, but direct write to vram still works . 

DEF(TakeVramSemaphore, 0xFF92E41C)  //
DEF(GiveSemaphore__, 0xFF92E468)      // goes in funclist.txt

#define VramInstance_address *(int*)0x5190

TakeVramSemaphore(VramInstance_address);  // takes vram semaphore so other tasks have to wait for it to free before thay can write to vram
SleepTask(2000);
bmp_printf(50, 134, "test", COLOR_BLACK, COLOR_GRAY); //writes directly to vram
SleepTask(7000);
GiveSemaphore__(VramInstance_address);  //releases the semaphore


Not exactly what I needed but it can be used for custom windows on OLC screen or maybe to hide menu screen when firmware goes into 400plus menu. 

This is very good finding, I think this can be useful in many cases, though may be not what exactly we dreamed of ;).
Thanks for sharing it.


  Well, firmware waits for semaphore to free before it starts menu, so I guess it's no way to hide the menu screen.
I've expected that, by locking this semaphore, we are blocking some tasks (the one that want to Take it).
I think this can turn out to be dangerous (ErrXX or something) if we block for too long.
But on a second thought these ErrXX stuff only shows when the MPU cant do something or return error to main CPU.
I guess the main firmware is not locking up with ErrXX on it's own, it does only when MPU is in trouble. This is just a guess.


Very interesting, thanks for sharing.

I guess this could be used to make our own menus, writing directly to VRAM, no? And I should probably update our overlay code, and use that semaphore.

But, do you think this could be used to avoid flickering? Actually, we do not want to lock the OLC, we just want to know when somebody else writes to the display; perhaps we could "watch" that semaphore, or get informed each time it is released, so we can update our overlay afterwards. Just some thoughts...

Edu, It can be used for some stuff, but not for full display control. If we TAKE the semaphore we will block one or more canon TASKs.
I think blocking canon tasks for long time is not a good idea. On the other hand, only experiments can prove me right or wrong.
I guess we wont find an easy way to be informed of screen updates, at least not with this semaphore.
Watching the semaphore wont be efficient, since it's not atomic operation, so we may miss some changes. At least I do not know if we can watch it.
Busy-looping to watch the semaphore is out of question too.


If "everybody else" who writes to the main display uses this same semaphore (looks like they should, that is what semaphores are for, no?), and we could somehow intercept all calls to TakeVramSemaphore, then we would know when to refresh our overlay. Could the "cache hack" be used here?
I think you are right, everyone who wants to write to display should rely on this semaphore, though it could be only one task (GUI) and everyone else talk to this task. Quite possible, but not so reasonable... If this is the case, then why would it need a Semaphore ?
The approach with "cache hacks" sounds possible, I will try to find some time soon to implement them in 400Plus.
I see one major disadvantage to this, wrapping the real TakeVramSemaphore means to execute extra code (time) on every call to it.
And if I'm not mistaken the Semaphore routines are atomic. This is very important, since it guarantees that no race-condition can happen.


  Yes, you're right, it will not help to stop flickering. I'm not familiar with semaphores but it looks like it is just a flag and some info, so you will have to check it all the time to know if something is using it. Would be nice to find a way to execute a function on semaphore access without checking it all the time.
Sergei, semaphores are just flags (similar to mutex'es in posix). The idea of these flags are to block you if someone is using the flag.
The idea of semaphore is to prevent race conditions.

Here is an example:

Basically you have 2 tasks and one variable which is used (read/write) in both tasks.

Code: [Select]
var x=0;
taks1() {
if (x) {
do_something();
} else {
do_other();
}
}

task2() {
while(1) {
x = !x; // invert x
}
}

now the problem comes when task1() is in this line:
Code: [Select]
if (x) {
lets say x == 1 in this case.
durring the check the x is 1, and task1() is going to do_something();
but before executing the call (Branch) to do_something(), the scheduler changes to task2() and task2() sets x to 0.
then in this case task1() is still going to call do_something() which is wrong already.

to prevent this you need atomic instructions
but i guess you already know the rest of the story...





Final notes:
I think this conversation should be pasted to the forum thread, so others can learn about it. And ML guys can join the conversation if they know more.



VRAM
« Reply #1676 on: 28 / March / 2013, 06:25:25 »
My idea was to use the cache hack to substitute the original TakeVramSemaphore to something similar to:

Code: [Select]
MyTakeVramSemaphore(int *address) {
    TakeVramSemaphore(address);
    enqueue_action(overlay_refresh);
}

It should be almost as fast as the original, and we use the original functionality. Then, our overlay_refresh function should use the same semaphore before writing to the display. This would tell us when to refresh the overlay, and I think it would avoid all the flickering.

VRAM
« Reply #1677 on: 28 / March / 2013, 06:26:38 »
I see what you mean, but I guess it would be better to use GiveVramSemaphore in this manner...
I will find time soon to try some cache hacks stuff...
  GiveVramSemaphore and TakeVramSemaphore have been called in many different places and it called from ROM address. I think it will be hard to change anything without knowing exact path which firmware takes to write OLC screen. Probably we can find an easier way to get hook for our function.

Final notes:
I think this conversation should be pasted to the forum thread, so others can learn about it. And ML guys can join the conversation if they know more.
I don't mind if you want to paste it in main thread. I didn't know if anybody else would have interest in firmware hacking on 400D. Looks like only three of us who is still working on it.
    0xAF, thanks for explanation of how semaphores are operating.


VRAM
« Reply #1678 on: 28 / March / 2013, 06:27:08 »
I see what you mean, but I guess it would be better to use GiveVramSemaphore in this manner...
I will find time soon to try some cache hacks stuff...
  GiveVramSemaphore and TakeVramSemaphore have been called in many different places and it called from ROM address. I think it will be hard to change anything without knowing exact path which firmware takes to write OLC screen. Probably we can find an easier way to get hook for our funyction.

The people at ML found a method to 'poison' the CPU's cache, so all calls to a certain function are redirected to another function; and you do not need to find or modify all the calls.

VRAM
« Reply #1679 on: 28 / March / 2013, 06:27:24 »
I see what you mean, but I guess it would be better to use GiveVramSemaphore in this manner...
I will find time soon to try some cache hacks stuff...
  GiveVramSemaphore and TakeVramSemaphore have been called in many different places and it called from ROM address. I think it will be hard to change anything without knowing exact path which firmware takes to write OLC screen. Probably we can find an easier way to get hook for our funyction.

The people at ML found a method to 'poison' the CPU's cache, so all calls to a certain function are redirected to another function; and you do not need to find or modify all the calls.
  That's interesting! I will see if I can figure out their method of changing program flow.
Thanks.

 

Related Topics


SimplePortal © 2008-2014, SimplePortal