Hi All,
Running in to a bit of trouble with the timer.device. I'm been able to build one of the examples on the AmigaOS dev wiki which runs with out issue. I'm trying to use the time is such a way that I can jump around my code while maintaining the timer state. Here's my code:
//Test of My Timer functions #include <exec/types.h> #include <exec/memory.h> #include <devices/timer.h> #include <proto/dos.h> #include <proto/exec.h> struct BlankerData { struct MsgPort *TimerMP; struct TimeRequest *TimerIO; }; int PrepareTimer(struct BlankerData *bd) { uint32 error; int32 result_code = 0; IDOS->Printf( "--> PrepareTimer() Start\n" ); //Allocate the TimerMP, assigned in blanker.h to create ASOT if ( bd->TimerMP == NULL ) { IDOS->Printf( "--> PrepareTimer() AllocSysObjectTags bd->TimerMP\n" ); bd->TimerMP = IExec->AllocSysObjectTags(ASOT_PORT, TAG_END); } ///Setup the Timer device for high res control of the rendering if ( (bd->TimerIO == NULL) && (bd->TimerMP != NULL) ) { IDOS->Printf( "--> PrepareTimer() AllocSysObjectTags bd->TimerIO\n" ); bd->TimerIO = IExec->AllocSysObjectTags(ASOT_IOREQUEST, ASOIOR_Size, sizeof(struct TimeRequest), ASOIOR_ReplyPort, bd->TimerMP, TAG_END); } if (bd->TimerIO != NULL ) { // Open the timer device error = IExec->OpenDevice( TIMERNAME, UNIT_VBLANK, (struct IORequest *) bd->TimerIO, 0L); if ( error != 0 ) { IDOS->Printf("--> PrepareTimer() Error: Could not OpenDevice %d\n", error); result_code = 1; } } return result_code; } int WaitForEvent(struct BlankerData *bd) { //Here we check to see if we get a signal from the timer or the blanker int32 return_code, loopcount = 0; int run = 0; IDOS->Printf("-->WaitForEvent() Enter\n"); IExec->WaitPort(bd->TimerMP); /* Get the reply message */ struct Message *TimerMSG; TimerMSG = IExec->GetMsg(bd->TimerMP); if (TimerMSG == (struct Message *)bd->TimerIO) { IDOS->Printf("Request finished\n"); } else { IDOS->Printf("Not our request, this is odd"); } // while (run == 0 ) // { // if ( (IExec->CheckIO( bd->TimerIO) ) != NULL ) // { // IDOS->Printf("-->WaitForEvent() CheckIO is NULL \n"); // run = 1; // return_code = 0; // } // if ( loopcount >= 30 ) // { // run = 1; // return_code = 2; // } // IDOS->Printf("-->WaitForEvent() Current Time %d\n", bd->TimerIO->Time.Seconds ); // IDOS->Delay( 50 ); // loopcount++; // } return 0; } void CleanForExit(struct BlankerData *bd) { if ( bd->TimerIO != NULL ) { IDOS->Printf("-->CleanForExit() Freeing TimerIO\n"); IExec->CloseDevice((struct IORequest *) bd->TimerIO); IExec->FreeSysObject(ASOT_IOREQUEST, bd->TimerIO); } if ( bd->TimerMP != NULL) { IDOS->Printf("-->CleanForExit() Freeing TimerMP\n"); IExec->FreeSysObject(ASOT_PORT, bd->TimerMP); } } int main() { struct BlankerData *bd; PrepareTimer(bd); //Set the timer for when to show the next photo bd->TimerIO->Request.io_Command = TR_ADDREQUEST; bd->TimerIO->Time.Seconds = 10; bd->TimerIO->Time.Microseconds = 0; IDOS->Printf("--> main() Initialized TimerIO \n"); IExec->SendIO((struct IORequest *)bd->TimerIO); WaitForEvent(bd); CleanForExit(bd); bd = NULL; return 0; }
The code builds but crashes here: TimerMSG = IExec->GetMsg(bd->TimerMP);
Uncommenting the while loop in WaitforEvent (and commenting out the WaitPort stuff, will allow it to build and run but it crashes after exit. The crash is what I'm really after...
Any suggestion on what I'm doing wrong here?
Thanks!
Bill "tekmage" Borsari
I'm working from a tiny netbook, so I might have missed the "big picture".;)
But when/where is the BlankerData structure allocated?
Main declares a POINTER to a BlankerData structure.. not the structure itself..
Unless I missed that part. ??
bd = AllocVecTags(sizeof(struct BlankerData... ))
Or something like that, with a matching free()later mght be a good start.
LyleHaze
Hi Lyle!
The BlankerData structure is declared at the beginning of the code. I played with AllocVecTags with no joy. Now I get a DSI at "bd->TimerIO->Request.io_Command = TR_ADDREQUEST;"
Thanks,
Bill
That should be at least:
bd = IExec->AllocVecTags(sizeof(struct BlankerData), TAG_END);
Also since your PrepareTimer() function seems to expect that the memory is cleared you really should request that it is in fact so:
Also your IExec->WaitPort()/IExec->GetMsg() code in WaitForEvent() can be replaced by a simple call to IExec->WaitIO():
IExec->WaitIO((struct IORequest *)bd->TimerIO)
I'm so confused..
Bill, I didn't see the allocation in the original code.. I still don't.
In your revised code I see an AllocVecTags without any tags after it.. As Salass pointed out, Needs a TAG_END after all other tags, including a CLEARTOVALUE, 0, tag pair..
I do NOT have the autodocs in front of me. I'm away visiting family..
A good idea, especially when adding new code, is to look up each function call in the autodocs to get all the details needed.
Finally, Salass pointed out that you need to allocate sizeof(struct BlankerData), but then his example showed sizeof(*bd).. sizeof a pointer will not do.. size of the BlankerData structure is needed.
Stuck in a tiny room with three adults arguing about parade floats, a four year old crying about..?? (no clue) and grampa pulling another laptop out from under this one because "it HAS to be on"... Happy Thanksgiving!
I could be completely mistaken. But I'll try anyway!
LyleHaze
sizeof(bd) would be the size of the pointer.
sizeof(*bd) is the size of what the pointer points to, i.e. struct BlankerData.
P.S. I would never dare to hack on my laptop with relatives sitting around me trying to do conversation... (actually I wouldn't have my laptop with me in such a situation) ;-)
You are correct.. Thank You!
Using * to de-reference a pointer might be confusing to new programmers (or old programmers trying to post from a netbook!)
Thanks for pointing that out.
:)
Lyle
LyleHaze
Your "bd" pointer is pointing to nowhere so PrepareTimer() is clobbering memory.
@tekmage
Have you also tried a standard WaitIO() on the Timer request?