Putting my hw to sleep

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
Alberto
Posts: 51
Joined: Mon Feb 12, 2007 8:16 pm
Location: Sofia

Putting my hw to sleep

Post by Alberto »

Hi,

I am writing a small piece of hw, a very simple bookreader (I know there are many out there, but this is...).
However, when I hit the power switch up for a little, tu put the PSP to sleep, it never goes: the screen becomes black, the power light goes off for a second, then keeps blinking, but the PSP doesn't turn off.
Do I need to code something special to deal with the sleep mode?
Maybe I just stupidly thought that the PSP would just freeze everything, and then restore it...

Thanks for any clue,
A.
User avatar
Torch
Posts: 825
Joined: Wed May 28, 2008 2:50 am

Post by Torch »

Usually caused by not sleeping enough in a loop.

You need to re-open any file handles after resuming from suspend.
Alberto
Posts: 51
Joined: Mon Feb 12, 2007 8:16 pm
Location: Sofia

Post by Alberto »

Torch wrote:Usually caused by not sleeping enough in a loop.
ok, thou' how do I "sleep" in the main loop? What is the function I need to call?
Torch wrote:You need to re-open any file handles after resuming from suspend.
thanks for the tip, anyway till now I managed to read the whole book in memory; but just in case, how do I notice in my applicatino that I have been resumed from sleep (and that I am being put to sleep)?

Thanks for your help,
A.
User avatar
Torch
Posts: 825
Joined: Wed May 28, 2008 2:50 am

Post by Torch »

sceKernelDelayThread(...) in the loop.

Use the power callbacks from psppower.h
Alberto
Posts: 51
Joined: Mon Feb 12, 2007 8:16 pm
Location: Sofia

Post by Alberto »

Torch wrote:sceKernelDelayThread(...) in the loop.
thanks, I was trying to use sceKernelSleepThread, and that obviously wasn't the thing to do ;-)
Torch wrote:Use the power callbacks from psppower.h
Good, although ATM I don't need to know anything about, I'll definitely have a look at them.

Again, thanks for your help.

Cheers, A.
john_he
Posts: 5
Joined: Wed Jan 06, 2010 1:44 am

Post by john_he »

Hello.
I have exactly the same problem as Alberto do. Can anybody figure out the reason and solution?
User avatar
Torch
Posts: 825
Joined: Wed May 28, 2008 2:50 am

Post by Torch »

Post the complete code.
john_he
Posts: 5
Joined: Wed Jan 06, 2010 1:44 am

Post by john_he »

Actually it's the PSP port of the PC-98 emulator NP2.

Here is the callback and the main function: (commented in Japanese)

Code: Select all

static void exit_proc(void)
{
    //廔椆張棟

    taskmng_exit();

    /* main thread偺儖乕僾敳偗懸偪丄傑偨偼
       menu偺exit偲PSP偺HOME僉乕or揹尮抐偱偺廔椆張棟偺攔懠 */
    sceKernelWaitSema(exit_sem, 1, 0); //lock

    pccore_cfgupdate();
    if (np2oscfg.resume) {
        flagsave(str_sav);
    }
    else {
        flagdelete(str_sav);
    }

    pccore_term();
    S98_trash();
    soundmng_deinitialize();

    if (sys_updates & (SYS_UPDATECFG | SYS_UPDATEOSCFG)) {
        initsave();
    }
}

int exit_callback(void)
{
    exit_proc();

    sceKernelExitGame();
    return 0;
}

void power_callback(int unknown, int pwrflags)
{
    int cbid;
    char *p;

    if(pwrflags & PSP_POWER_CB_POWER_SWITCH){
        exit_proc();
    }

    cbid = sceKernelCreateCallback("Power Callback", power_callback, NULL);
    scePowerRegisterCallback(0, cbid);
}

int CallbackThread(void *arg)
{
    int cbid;

    cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
    sceKernelRegisterExitCallback(cbid); //SetExitCallback(cbid);
    cbid = sceKernelCreateCallback("Power Callback", power_callback, NULL);
    scePowerRegisterCallback(0, cbid);

    sceKernelSleepThreadCB(); //KernelPollCallbacks();

    return 0;
}

int SetupCallbacks(void)
{
    int thid;

    thid = sceKernelCreateThread("update_thread", CallbackThread,
                                0x11, 0xFA0, 0, 0);
    if (thid >= 0) {
        sceKernelStartThread(thid, 0, 0);
    }

    return thid;
}

Code: Select all

int main(int argc, char *argv[])
{
    int id;

    set_datadir(argv[0]);

    pgGeInit();
    //    scrnmng_gu_init0();
    sceDisplaySetMode(0, SCREEN_WIDTH, SCREEN_HEIGHT);
    pgScreenFrame(2, 0);

    exit_sem = sceKernelCreateSema("exitcsec", 0, 1, 1, NULL);
    SetupCallbacks();

    GeCB gecb;
    gecb.signal_func = NULL;
    gecb.signal_arg = NULL;
    gecb.finish_func = Gu_Finish_Callback;
    gecb.finish_arg = NULL;
    gecbid = sceGeSetCallback(&gecb);

    /* 僇儗儞僩僼傽僀儖憖嶌 */
    file_setcd(datadir);
    /* np2.cfg僼傽僀儖偺撉傒崬傒? */
    initload();

    scrnmng_change_scrn(np2oscfg.pspscrn);

    TRACEINIT();

    sceCtrlSetSamplingCycle(0);
    sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG);

    // .......
Everything is okay except, when I push the power switch to suspend the PSP, the screen comes black and the power LED keeps blinking. PSP can't be resumed after that and must be manually powered off. So what's the matter?

It's too big to post the whole program, and I don't know which part gets wrong.

Complete source package here:
http://emuhani.up.seesaa.net/image/np2_ ... _v0.37.zip

Thanks for replying.
User avatar
Torch
Posts: 825
Joined: Wed May 28, 2008 2:50 am

Post by Torch »

That's massive. It could be hanging anywhere. Can't be bothered to look through everything.
Alberto
Posts: 51
Joined: Mon Feb 12, 2007 8:16 pm
Location: Sofia

Post by Alberto »

I don't have the time to look at your code, and as Torch says... it's massive...

Just be sure that in your main loop (whether you have one...) you call sceKernelDelayThread() with at least 5 as parameter. And of course, be sure that you _always_ go through the entire main loop, that is, be sure you are not in any other close loop.

To be sure, I inserted the delaythread in the thread for checking the exit control by the HOME key - that basic, always the same SetupCallbacks you can see in the examples - (since my loop is very fast, I did the trick only once every 1000 passes, so the whole thing keeps fast enough and is able to detect the sleep-switch)

HTH, Just my 2c


Cheers, A.
Criptych
Posts: 64
Joined: Sat Sep 12, 2009 5:18 am

Post by Criptych »

I've had a related (I think) problem; putting the PSP to sleep works, but it will sometimes crash when I try to turn it back on. Interestingly, it happens with regular games, too, not just homebrew. Could this be something to do with CFW, or maybe it's just my PSP? (It has gotten dropped a few times.)
"You hungry? I haven't eaten since later this afternoon."
willow :--)
Posts: 107
Joined: Sat Jan 13, 2007 11:50 am

Post by willow :--) »

john_he wrote: (commented in Japanese)
That's doesn't look like Japanese, I believe it's Chinese

Sorry for the OffTopic....
john_he
Posts: 5
Joined: Wed Jan 06, 2010 1:44 am

Post by john_he »

@Alberto:

So the main reason is when the hardware suspend and trigger the callback, which runs in the callback thread, the main thread breaks it's execution and then can't go into suspending. Is that right?

The program does have a main loop, that's the cpu emulation core.

I just want to know in what situation the problem occurs.

Thank Alberto and Torch for help.
That's doesn't look like Japanese, I believe it's Chinese
It's in Japanese but I copy it in a Chinese encoding(GBK), so it looks like Chinese.
psPea
Posts: 60
Joined: Sat Sep 01, 2007 12:51 pm

Post by psPea »

maybe your problem is calling exit_proc in your power callback, you should call a function that prepares the app for suspension not exit.

Also I see you waiting for a semaphore in exit_proc, is it being signaled?
john_he
Posts: 5
Joined: Wed Jan 06, 2010 1:44 am

Post by john_he »

Thanks to Alberto's suggestions, I solved the problem by adding the following line to the main loop.

Code: Select all

sceKernelDelayThread(20);
Now the remaining task is reopen file descriptors.
Is it suitable to do it right in the power callback like this?

Code: Select all

int power_callback(int unknown, int pwrflags)
{
    if (pwrflags & PSP_POWER_CB_SUSPENDING)
    {
    	// when falling to suspend, records offsets for all opened file descriptor.
    	file_record_offsets();
    }
    if (pwrflags & PSP_POWER_CB_RESUMING)
    {
    	// when resuming from suspend, reopen all files.
    	file_reopen_all();
    }
    return 0;
}
The file_record_offsets() function retrieves file offsets of all opened descriptors by calling sceIoLseek(fd, 0, SEEK_CUR) and save them to the memory; the file_reopen_all() function reopen all files calling sceIoOpen then set their offset recorded previously by calling sceIoLseek(...).
I code these functions but it doesn't seem working. Am I making a mistake?
maybe your problem is calling exit_proc in your power callback, you should call a function that prepares the app for suspension not exit.

Also I see you waiting for a semaphore in exit_proc, is it being signaled?
The semaphone is to wait until the main loop exits properly, and it's signaled inside the main loop.

Thanks again.
Alberto
Posts: 51
Joined: Mon Feb 12, 2007 8:16 pm
Location: Sofia

Post by Alberto »

john_he wrote:Thanks to Alberto's suggestions, I solved the problem by adding the following line to the main loop.

Code: Select all

sceKernelDelayThread(20);
you can probably go down to 10, but if that 20 doesn't slow the things down too much, of course you can leave it like that.

For what concerning the saving of the FDs, I think it should work, thou' you may want to check other statuses; as I think there is something like RESUME_COMPLETE and BEGIN_SUSPEND, or the like.
Also, you may want to semaphore the reopening of the files as well...
...and I cannot read "and then closes the open files" in your statements, has that just been forgotten inside your fingers or is it actually missing?
(although I don't know whether the PSP "kind of dirty-automatically" closes them)

Cheers, A.
john_he
Posts: 5
Joined: Wed Jan 06, 2010 1:44 am

Post by john_he »

you can probably go down to 10, but if that 20 doesn't slow the things down too much, of course you can leave it like that.
20 slows down just a bit, in my situation. Actually I tried 0 and it still worked, though I don't know the mechanism.

I tried reopening files in the callback, without semaphores, and failed. I just didn't notice that it requires semaphores. I tried using a "resume counter" and check it on file operations(read, write, seek) to tell whether the FDs needs to be reopened. This seems working on most cases, but still fails sometimes. I'm trying semaphore later.
...and I cannot read "and then closes the open files" in your statements, has that just been forgotten inside your fingers or is it actually missing?
(although I don't know whether the PSP "kind of dirty-automatically" closes them)
I fotgot it, but it works as well. Maybe files are automatically closed when the PSP goes into sleep?
Post Reply