40 views
in System Integration by

In my device class I have defined a String property "IP_Addr" with the following "OnSet_IP_Addr" function:

if ( pure IP_Addr == value )
  return;

pure IP_Addr = value;

notifyobservers ^IP_Addr;

The Generator for "OnSet_IP_Addr"  is set to true.

In my C code I run the following piece of code to update the String property

char ipstr[IP4ADDR_STRLEN_MAX];
ip4addr_ntoa_r(&netif->ip_addr, ipstr, IP4ADDR_STRLEN_MAX); // code convert IP to character string
XString test = EwNewStringAnsi(ipstr);
SetIP(test);

Where SetIP is given by:

void SetIP(XString value)
{
	RF_DriverDeviceClass__OnSetIP_Addr(DeviceObject, value );
}

With "RF_DriverDeviceClass__OnSetIP_Addr" the function that has been automatically generated by embedded wizard which is given by:

/* 'C' function for method : 'RF_Driver::DeviceClass.OnSetIP_Addr()' */
void RF_DriverDeviceClass_OnSetIP_Addr( RF_DriverDeviceClass _this, XString value )
{
  if ( !EwCompString( _this->IP_Addr, value ))
    return;

  _this->IP_Addr = EwShareString( value );
  EwNotifyRefObservers( EwNewRef( _this, RF_DriverDeviceClass_OnGetIP_Addr, RF_DriverDeviceClass_OnSetIP_Addr ), 
    0 );
}

 

When I run my C code the IP_Addr string in embedded wizard is updated as it is supposed to. However when I execute the code multiple times the GUI freezes and becomes unreponsive. For example when I run:

for (int i=0; i<10; i++)
{
    char ipstr[5];
    sprintf(ipstr,"%i",i);
    XString test = EwNewStringAnsi(ipstr);
    SetIP(test);
}

With a breakpoint on "SetIP" I see the screen being updated to 0, 1, and then it crashes.

Can you point out where my code fails and why ?

 

 

1 Answer

0 votes
by
 
Best answer

Hello Jim,

At first glance your implementation looks fully correct. I would focus on following two aspects:

1. Are you using multi-threading? If yes, please note that Embedded Wizard code is not thread safe. See also: Avoid multithreading.

2. The variable DeviceObject in C code is it valid? The variable refers to a Chora object. It is valid temporarily. If the object is not used within the application, the object will be released after the end of the screen update. See also: Don't retain nor modify objects or strings.

If none of the above hints help you further, are you able narrow down the location where the crash occurs?

Best regards

Paul Banach

by

Dear Paul,

Thanks for the quick response. 

I know that EMWi is not thread safe and yet I am using multiple threads in my application. The String property will NEVER be updated within the EMWi thread (at least not by my code), only from the other thread that takes care of TCP/IP connection. I have a mutex on the function that updates the string property so the function

SetIP(XString str);

will never be called simultaneously by two threads. How do you propose to fix the matter at hand ?

I basically have three threads. A USB thread, a TCP/IP thread and the EMWi GUI thread. The GUI can be controlled either locally or remotely (via USB or TCP/IP). The GUI has three operation modes which can be set by means of an ENUM Property in EMWi so that the device can only be controlled by one mode at a time. 

Looking forward to your answer.

Best,

Jim

 

 

 

by

Hello Jim,

in fact synchronising the access to EmWi functions by using a mutex will not solve the problem. It is necessary to ensure that EmWi functions are invoked in context of the EmWi thread only. If a foreign thread does intent to report a state alternation to EmWi application, it has to relay this event via the EmWi thread. Please see the section Multi-threading and interrupt service routines in the chapter Device Property.

Does it help you?

Best regards

Paul Banach

by
That fixed the issue ! Thanks.

Is it also possible to Invoke a function from the EmWi thread based on an Event (So not using the poller function "DeviceDriver_ProcessData" in the device driver) ?

Best,

Jim
by

Hello Jim,

that's great! Concerning your question:

Is it also possible to Invoke a function from the EmWi thread based on an Event (So not using the poller function "DeviceDriver_ProcessData" in the device driver) ?

Yes, you can invoke Embedded Wizard code also outside of the ProcessData() function - as long as the code is running in context of the GUI thread. Following example describes one possible scenario:

1. There is GUI component containing a Timer object.

2. Each time the Timer expires, the associated slot method is signaled.

3. The slot method invokes some C function e.g. Foo()

4. The function Foo() evaluates some C variables, queries some device states, etc.

5. Depending on the results of the evaluation in step 4, the Foo() function decides to invoke GUI code. It can, for example, trigger a system event in the GUI application.

The above communication example worked without ProcessData(). The function ProcessData() provides a kind of central point where device data and device events can be handled. It exists for convenience purpose only to simplify the integration of GUI and device specific code.

Best regards

Paul Banach

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

...