This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Z stack: events sequentially executed in task

For example, in MyApp_event_loop task. I have two events: one default sys_msg and one is my app. it looks like this

 

if ( events & SYS_EVENT_MSG )

{

  //sys code

......

    case KEY_CHANGE:

        osal_set_event(MyApp_event_loop,MyApp_event);

 

}

 

if ( events & MyApp_event )

{

MyApp_process();

 

}

I have received a INT from HAL which trigger key change handler which set the event in MyApp_event, if code gets sequentially executed in task. so it will process MyApp_event immediately or it will go back to big loop in osal_start_system() to process events of other task and then come back?(I think it is former way, just make sure)

 

Also is it possible that compiler re-order the if statement so that the later if ( events & MyApp_event ) will be executed before if ( events & SYS_EVENT_MSG )?

 

thanks

 

Rui

 

 

 

  • hi,

    it will go back to big loop in osal_start_system() to process events of other task and then come back

    yes, if you use   return (events ^ SYS_EVENT_MSG).

    Also is it possible that compiler re-order the if statement so that the later if ( events & MyApp_event ) will be executed before if ( events & SYS_EVENT_MSG )?

    yes. But if you would like to prioritize events from an interrupt context, in case your MyApp_process() could be executed into ISR, from my point of view, I would prefer that way. You may also try to set your event from ISR and remove the KEY_CHANGE event...

    Yoann Hilairet

  • Thanks Yoann,

     

          I don't want to put too many codes in ISR, which increases the chance of race condition. Do you know any method to force the compiler do not re-order the if statement?

     

    thanks

     

     

    Rui

  • Can you try that kind of code ? But I think not prioritizing sys events is not very good, because of incoming packets, etc...

     

    UINT16 GenericApp_ProcessEvent( byte task_id, UINT16 events )
    {

      // only step into when there is no "MyApp_event" event
      if ( (events & SYS_EVENT_MSG) && !(events & MyApp_event))
      {
        ...

        // return unprocessed events
        return (events ^ SYS_EVENT_MSG);
      }
     
      if ( events & MyApp_event )
      {
        MyApp_process();
        // return unprocessed events
        return (events ^ MyApp_event);
      }
    }


     

  • Sorry, I actually want to "prioritizing" SYS_MSG, so every time this task get executed, SYS_MSG will be executed first. But if the compiler force the SYS_MSG statement to be executed last. it may affect the process of program.

     

    thanks


  • ok,

    so if I understand well, what you intend to do is to execute SYS_MSG events and then, whithout leaving the task handler, execute MyApp_event ? I may be misunderstanding, if you could enlighten me...

    thanks

     

     

     

     

  • Actually I want to make sure SYS_MSG event is executed first if both SYS_MSG and MyApp_event has been set. If compiler won't re order the code, that will be no problem. But just in case compiler will re order the if statement, I may need to find some other way.

     

    thanks

     

    Rui

  • The compiler should not re order the if statements, but if you want to be sure to not execute any MyApp_event before all the SYS_EVENT_MSG are processed, you can try something like this :

    UINT16 MyApp_ProcessEvent( byte task_id, UINT16 events )
    {

      if ( events & SYS_EVENT_MSG )
      {
        MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( GenericApp_TaskID );
        while ( MSGpkt )
        {
          switch ( MSGpkt->hdr.event )
          {
            ... 
            case KEY_CHANGE:
              osal_set_event(MyApp_event_loop,MyApp_event);
              break;
             
            default:
              break;
          }

          // Release the memory
          osal_msg_deallocate( (uint8 *)MSGpkt );

          // Next
          MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( GenericApp_TaskID );
        }

        // return unprocessed events
        return (events ^ SYS_EVENT_MSG);
      }
     
      if ( events & MyApp_event )
      {
        // case there is still a SYS_EVENT_MSG
        if(events & SYS_EVENT_MSG) {
          // return & don't clear the MyApp_event to process it later.
          return;
        }
        MyApp_process();
        // return unprocessed events
        return (events ^ MyApp_event);
      }
    }


    But I am surprised you are worrying about that because the while loop should process every SYS_EVENT_MSG, and then when there is no more, the task handler will process the other events.

    I hope this will do the trick,

    Yoann Hilairet