541 views
in System Integration by

Hi   

We use following software components.  

- Embedded Wizard Studio Pro v8.30 

- Embedded Wizard Platform Package for Generic RGBA8888 

- Embedded Wizard Build Environment for Generic RGBA8888 

- Generic RGBA8888 NEON AddOn  

Our target system specification.  

- NXP i.mx6 quad and Yocto embedded linux.

 


 

There is a vertical list.

The OnloadItem() function exchanges strings with the user application.

Below is a part of OnloadItem().


var Application::NvcJobItem ewJob = new Application::NvcJobItem;

native (itemNo, ewJob)
{
    GArray* jobs = HTS_GetPtrJob();

    if (itemNo < jobs->len)
    {
        JOB_T* job          = &g_array_index(jobs, JOB_T, itemNo);

        ewJob->index         = job->jobIndex;
        ewJob->name          = EwNewStringAnsi(job->jobName);
        ewJob->totalSteps    = job->totalSteps;
        ewJob->totalScrews   = job->totalScrews;            
    }
}
    
itemView.NoPP       = ewJob.index;
itemView.JobNamePP  = ewJob.name;
itemView.StepsPP    = ewJob.totalSteps;
itemView.ScrewsPP   = ewJob.totalScrews;

After the first OnLoadItem () function is executed,

When scroll the vertical list or

Refresh the vertical list (VerticalList.Invalidate.InvalidateItems( 0, VerticalList.NoOfItems-1 );

The following error occurs.

[FATAL ERROR in ../PlatformPackage/RTE/ewstring.c:1389] Trying to release a string with usage counter 0.

PANIC: System halted

What is the cause?

In addition, it is very similar to the following questions.

https://ask.embedded-wizard.de/1600/program-crashes-when-working-with-vertical-list?show=1602#c1602

Thanks.

2 Answers

0 votes
by

Hello,

the problem is, that you assign a string to a property of an object within native code - please see the section 'Be careful when exchanging strings'.

In order to avoid the problem, you can change the implementation:

var int32 jobIndex;
var int32 jobSteps;
var int32 jobScrews;
var string jobName;

native (itemNo, jobIndex, jobSteps, jobScrews, jobName )
{
    GArray* jobs = HTS_GetPtrJob();

    if (itemNo < jobs->len)
    {
        JOB_T* job  = &g_array_index(jobs, JOB_T, itemNo);

        jobIndex    = job->jobIndex;
        jobName     = EwNewStringAnsi(job->jobName);
        jobSteps    = job->totalSteps;
        jobScrews   = job->totalScrews;            
    }
}
    
itemView.NoPP       = jobIndex;
itemView.JobNamePP  = jobName;
itemView.StepsPP    = jobSteps;
itemView.ScrewsPP   = jobScrews;

Now, the Runtime Environment can manage the assignment of the string.

Does it work within your application?

Best regards,

Manfred

0 votes
by

Hi,

you are trying an advance technique to access object members directly from C code. In particular, you assign the new created string directly to the variable name of ewJob object. Doing this in C stores just the string in the variable. When you implement such operation in Chora and then you take a look at the generated code you would see, that the simple assignment is represented by an invocation of a Runtime Environment function EwRetainString(). For example:

EwRetainString( &ewJob->name, someString )

The function EwRetainString() manages the garbage collection of strings. The usage of this function, however, is advanvce and expects a good understanding of the Embedded Wizard code generation and runtime environment. In our documentation we limit to address techniques, which are safer and more simple. These exclude the case of directly accessing the members of an object. Instead we recommend to use local variables to exchange data between Chora and native implementation.

Following could be the safer implementation of your method. Here we use 4 additional tmp variables to receive the data from the C native code. After the native statement we can evaluate the variables as usual in Chora:

/* Local variables to receive the values from 'C' native code */
var int32  tmpIndex       = 0;
var string tmpName        = "";
var int32  tmpTotalSteps  = 0;
var int32  tmpTotalScrews = 0;


/* Native code section to initialize the tmpXXX variables */
native ( itemNo, tmpIndex, tmpName, tmpTotalSteps, tmpTotalScrews )
{
    GArray* jobs = HTS_GetPtrJob();

    if (itemNo < jobs->len)
    {
      JOB_T* job = &g_array_index(jobs, JOB_T, itemNo);

      tmpIndex       = job->jobIndex;
      tmpName        = EwNewStringAnsi( job->jobName );
      tmpTotalSteps  = job->totalSteps;
      tmpTotalScrews = job->totalScrews;
    }
}
    
var Application::NvcJobItem ewJob = new Application::NvcJobItem;

/* Again in Chora code it is safe to work with the local variables */
ewJob.index         = tmpIndex;
ewJob.name          = tmpName;
ewJob.totalSteps    = tmpTotalSteps;
ewJob.totalScrews   = tmpTotalScrews;            

itemView.NoPP       = ewJob.index;
itemView.JobNamePP  = ewJob.name;
itemView.StepsPP    = ewJob.totalSteps;
itemView.ScrewsPP   = ewJob.totalScrews;

Since the tmp local variables are not persistent they donÄt interfer with garbage collection. It is not necessary to invoke EwRetainString() when assigning a string to a local variable.

Furthermore, in your implementation you use the object ewObj. Do you use it only to exchange data with native code? If yes, you can omit it and limit to use the tmp local variables only as demonstrated below. It makes the implementation even much more simple and faster:

/* Local variables to receive the values from 'C' native code */
var int32  tmpIndex       = 0;
var string tmpName        = "";
var int32  tmpTotalSteps  = 0;
var int32  tmpTotalScrews = 0;


/* Native code section to initialize the tmpXXX variables */
native ( itemNo, tmpIndex, tmpName, tmpTotalSteps, tmpTotalScrews )
{
    GArray* jobs = HTS_GetPtrJob();

    if (itemNo < jobs->len)
    {
      JOB_T* job = &g_array_index(jobs, JOB_T, itemNo);

      tmpIndex       = job->jobIndex;
      tmpName        = EwNewStringAnsi( job->jobName );
      tmpTotalSteps  = job->totalSteps;
      tmpTotalScrews = job->totalScrews;
    }
}
    
/* Again in Chora code it is safe to work with the local variables */
itemView.NoPP       = tmpIndex;
itemView.JobNamePP  = tmpName;
itemView.StepsPP    = tmpTotalSteps;
itemView.ScrewsPP   = tmpTotalScrews;

Hope it helps you.

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

...