Announcement

Collapse
No announcement yet.

(another) TimerEvent question

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • meldavia
    replied


    The address for the timer event is pushed into a queue, and the runtime is interrupted if anything is on the queue, and modifies the program counter accordingly.

    Her is some notes from the soon to be released PmmC v3.1 that should help.

    The timer system used in 4DGL is simple to use, but rather primitive,
    and it is up to the programmer to protect against certain pitfalls.

    When a timer is used in conjunction with a timer event, the event can
    only run in the current code space, therefore the following cautions
    must be taken into consideration.

    When a child process is run using the file_run or file_exec function,
    or if a file was loaded with file_Loadfunction and is executed, the
    loaded process gets its own code and memory space, therefore, any
    timer that reaches zero that has a timer event attached in the parent
    code space, will fail and cause a crash as an attempt is made to force
    the program counter to some wild place in the child process - not what
    we want!

    There are 2 ways to overcome this problem.

    1] If a child process will not be requiring the use of any timers
    or timer events, the parent program can simply use the eventsPostpone()
    function before calling or entering the child process. Once the parent
    program regains control, the eventsResume() function will allow any
    events in the queue to then be processed. The side effect of this
    method is that several events may bank up, and will execute immediately
    once the eventsResume() takes place. This however disallows a child
    process to use any timer events in the sub program so method 2 is
    preferable in this case.

    2] The parent program can 'disconnect' the event(s) by setting it/them
    to zero prior to child process execution, or setting the associated
    timer to zero so the event wont fire. In either case, it is necessary
    to do the following:-
    while(sys_EventQueue());
    to ensure the event queue is empty prior to calling the child process.
    Note also that if just the timer is set to zero, the child process
    cannot use this timer. If the timer was now set to a value and the old
    event still existed, when the timer reaches zero the 'bad' parent address
    event will fire causing a crash.

    The reverse situation also applies of course, the same level of respect
    is required if a child program needs to use any timer events.
    Method [1] (above) will not work as the events have been postponed,
    stopping the child process from using any timer events. If the child
    process did an eventsResume() in this case,everything would crash miserably.
    So the same applies,a child that uses any timer events must respect
    any timers that may be used by the parent, and a child must zero the
    sys_SetTimerEvent before returning to the parent.

    Leave a comment:


  • gadget
    replied


    I've managed to (hopefully this time) fix the problem but things are a little strange...

    when I go to exit the child (var key = 0), it should do the following:
    1/ disable the touchscreen
    2/ restore the output ports
    3/ make sure last timer event is processed
    4/ close the I2C comms and return

    what it does do is:
    1/ disable the touchscreen
    2/ restore the output ports
    3/ process last timer event
    ... there is a timer event, because the touchscreen is reenabled. How do I know this - I have to press the exit button AGAIN to actually exit! What happened to the return call the first time round?

    Update := TRUE;
    sys_SetTimerEvent(TM_DISPLAY_UPDATE, updateDisplay);
    sys_SetTimer(TM_DISPLAY_UPDATE, 1);

    touch_DetectRegion(0, 0, SCREEN_RIGHT, SCREEN_BOTTOM); // allow full screen

    // now just stay in a loop
    repeat
    sys_EventsPostpone(); // 4) testComm(key-5);
    endif
    sys_EventsResume(); //

    Leave a comment:


  • gadget
    started a topic (another) TimerEvent question

    (another) TimerEvent question

    In the docs it states the timer events are invoked asynchronously. Do I take it to mean that the event is handled like an interrupt - ie current variables and program counter are pushed onto the stack, timer event function is dealt with, then vars and PC popped back off stack and program resumes (eg like a 8051 microcontroller) or is the event run in parallel to the main program (ie sort of multi-tasking)?
    I'm still having program crashes when a child program (called with file_Run() and containing timer events) returns.
    Display shows first line in red: ,,,,,,,,
    next line in green:,,,,,,,,,,,,,,,,
    when crash occurs so that's no help.
Working...
X