Variable reset to 0 in Application Class

115 views
asked Aug 27, 2019 in System Integration by davide.dalfra

Dear all,

We're using EW 9.10 on a test project we asked support few weeks ago for the integration with a custom touch driver. On that point, everything has been solved.
We're encountering a small issue while integrating the system with the DeviceClass / DeviceDriver structure.

We have create a DeviceClass with the relative autoObject. We use this class to update the values & trigger actions from the GUI to the Device.
The software architecture is based on cmsis_os2 & FreeRTOS 10.x where the producer (the device) send a Message on a Queue, and the DeviceDriver(consumer) on EW-Side is just checking in non-blocking mode if there's any message on the queue.
The producer send a message on the queue only if the value is changed, nothing otherwise.


Here is the  implementation:
 

On the EwProcess side, we've remapped the process data with our workerQueue_GUISide() function

int EwProcess( void )
{
  int          timers  = 0;
  int          signals = 0;
  int          events  = 0;
  int          devices = 0;
  XEnum        cmd     = CoreKeyCodeNoKey;
  static int   touched = 0;
  XPoint       touchPos;

  
  /* process data of your device driver(s) and update the GUI
     application by setting properties or by triggering events */
  //devices = DeviceDriver_ProcessData();
  devices = workerQueue_GUISide();

 

And here is the above mentioned function

uint8_t workerQueue_GUISide(void)
{
    osStatus_t retQueue ;
    mw_update_message msg;

    retQueue = osMessageQueueGet( queueGUI, &msg, NULL, 0U);
    if ( retQueue == osOK )
    {
      ApplicationHome_1Class  homepage = EwGetAutoObject( &ApplicationaoHome_1Class,  ApplicationHome_1Class );
      
      if ( homepage != NULL )
      {
        switch ( msg.subject )
        {
          case MW_UPDATE_TDRY :
          {
            ApplicationHome_1Class_updateTMP( homepage, msg.value );
          }
          break;
          
          case MW_UPDATE_TWET :
          {
          }
          break;
          
          case MW_UPDATE_TDT:
          {
          }
          break;
          case MW_UPDATE_RH:
          {
            ApplicationHome_1Class_updateRH( homepage , msg.value );
          }
          break;
          default:
          {
          }
          break;
        }
      }
      return 1;
    }
    return 0;
}

 

All the task on Freertos is started at the same time(including EW), and on the Gui Side we have a sort of splash screen for 10 second, when the 10s timer expires we launch the main page with this chora code:

 if (disableLoading == 0){
  var Core::Root rootObject = GetRoot();    

  th_goTScal.Enabled= false;
  th_gotoVendor.Enabled = false;

  // Create a new instance of some alert panel component.
  var Application::Home_1 home_1 = new Application::Home_1;

  home_1.Bounds.origin.x = 0;
  home_1.Bounds.origin.y = 0;
  startupTimer.Enabled =false ;



  // Add the alert component directly to the application component.
  // Thereupon the alert panel will appear on the screen.
  rootObject.Add( home_1, 0 );

  home_1.realtime_dry.String = string( (float)Application::aoHome_1Class.var_TMP/10.0, 0, 1 );
  home_1.realtime_rh.String = string( (float)Application::aoHome_1Class.var_RH/10.0, 0, 1 );

}



The problem we're facing out is that the values on the main application (after the splash screen) are displayed as 0 (the default value) even if at least 2/3 message has been processed by the producer-consumer. 
We also noted that, by breaking-into the Application.c code, after the first two iterations on the "if" , the _this->var_RH is alwasy zero but the code inside the if has been executed before (so i expect to have the variable _this->var_RH initialized correctly).
 

/* 'C' function for method : 'Application::Home_1Class.updateRH()' */
XInt32 ApplicationHome_1Class_updateRH( ApplicationHome_1Class _this, XInt32 rh )
{
  if ( rh != _this->var_RH )
  {
    _this->var_RH = rh;
    EwNotifyRefObservers( EwNewRef( _this, ApplicationHome_1Class_OnGetvar_RH, ApplicationHome_1Class_OnSetvar_RH 
      ), 0 );
  }

  return 0;
}

After few check it seems that the autoObject address is changed after the splash screen have loaded the main page application.

We was able to prevent this  behavior by start processing the message Queue, only when the main page is displayed. We reached this by triggering the start of the consumer with a chora method in native mode.

Are we doing somethign wrong? Any suggestion?

 

Thanks in advance
Davide

 

1 Answer

0 votes
answered Aug 27, 2019 by Paul Banach

Hello David,

I suppose, the problem is related to the ApplicationaoHome_1Class autoobject being automatically discarded. Please see the documentation Lifetime of an autoobject. Can you add a variable to your Application Root object, declare the variable with type corresponding to the of the autoobject and initialize the variable with the autoobject. This will prevent the autoobject from being discarded.

Does it help?

Best reghards

Paul Banach

commented Aug 27, 2019 by davide.dalfra
Hello Paul,

 

Thansk for your comment, you was right. Everything is now solved.

Thanks again
Davide

Ask Embedded Wizard

Welcome to the question and answer site for Embedded Wizard users and UI developers.

Ask your question and receive answers from the Embedded Wizard support team or from other members of the community!

Embedded Wizard Website | Privacy Policy | Imprint

...