No announcement yet.

(another) TimerEvent question

  • Filter
  • Time
  • Show
Clear All
new posts

  • (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.

  • #2

    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
    sys_EventsPostpone(); // 4) testComm(key-5);
    sys_EventsResume(); //


    • #3

      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:-
      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.