947 views
in System Integration by

Hello EW Team,

I am working on plotting graph with data received every 50ms from another device (iMXRT1060) using Device Object. I have checked the RAM usage (PFA image).
OBSERVATION 1: Graph is successfully plotted for first 6 tests. While executing 7th time, EwProcess() is not getting executed. Regarding Memory Allocation:

#define EW_FRAME_BUFFER_ADDR  DisplayInfo.FrameBuffer
#define EW_FRAME_BUFFER_SIZE  EW_FRAME_BUFFER_WIDTH * EW_FRAME_BUFFER_HEIGHT * EW_FRAME_BUFFER_DEPTH    //480*272*2 = 261,120
#define EW_DOUBLE_BUFFER_SIZE  EW_FRAME_BUFFER_SIZE        //480*272*2 = 261,120
#define EW_MEMORY_POOL_ADDR      DisplayInfo.MemoryPool
#define EW_MEMORY_POOL_SIZE      EW_FRAME_BUFFER_SIZE +  EW_FRAME_BUFFER_SIZE //480*272*2*2 

aDisplayInfo->FrameBuffer    = (void*)os_mem_alloc(EW_FRAME_BUFFER_SIZE);    // EW_FRAME_BUFFER_ADDR;
aDisplayInfo->DoubleBuffer   = (void*)os_mem_alloc(EW_DOUBLE_BUFFER_SIZE);    // EW_DOUBLE_BUFFER_ADDR;
aDisplayInfo->MemoryPool    = (void*)os_mem_alloc(EW_MEMORY_POOL_SIZE);    // EW_MEMORY_POOL_SIZE;

OBSERVATION 2: Graph is successfully plotted for first 13 tests. While executing 14th time, EwProcess() is not getting executed. Regarding Memory Allocation, only change is in Memory Pool Size:

#define EW_MEMORY_POOL_SIZE      EW_FRAME_BUFFER_SIZE +  EW_FRAME_BUFFER_SIZE +  EW_FRAME_BUFFER_SIZE //480*272*2*3

QUERY 1: How shall I check the Memory usage? As soon as I add

#ifdef EW_PRINT_MEMORY_USAGE
    EwPrintProfilerStatistic( 1 );
#endif

in my code, EwProcess() doesn't execute at all. However, I get the following in my Serial Logs, for first observation.

220909 12:56:35.38 GuiThread      OS_mem_alloc   : Alloc Size = 261120, 0x3fc00, at address 0x807da6e0
220909 12:56:35.38 GuiThread      OS_mem_alloc   : Alloc Size = 261120, 0x3fc00, at address 0x8081a300
220909 12:56:35.38 GuiThread      OS_mem_alloc   : Alloc Size = 522240, 0x7f800, at address 0x80859f20

QUERY 2: After plotting the graph, seems that data is still there in Device Object. If this is correct, then how should I free the memory allocated at the end of test so that fresh data is plotted; currently I am Clearing the screen using     ChartsCoordList_ClearList( &_this->CoordList ); at the end of test. Does it clears the memory allocated to DeviceObject?

Thanks in advance,

Vandana Matai

1 Answer

0 votes
by

Hi Vandana,

thank you for the provided explanations and observations - nevertheless, it is not still clear to me how your system initialization and your main loop are implemented.

First of all, I'm confused because the MemoryPool is not a member of the DisplayInfo structure. The DisplayInfo structure keeps the framebuffers, which can be allocated statically or (in your case) dynamically. The memory pool is the memory area that is given to the Embedded Wizard GUI application in order to manage the memory for the GUI application (Chora objects, graphical objects, strings, ...). This is provided typically as a static piece of memory, but it can be also allocated by an OS. In any case, the allocation of framebuffers and memory pools has to be done within the initialization of the system - in EwInit(). If you do that within EwProcess() - which represents the main loop of the GUI application - you will do further allocations with every call of EwProcess().

Can you check that and present your current implementation?

Furthermore, please make sure that the console outputs are working properly, then you can activate the monitoring of the RAM usage.

Concerning your second question: It is not clear to me, which memory you mean. If you are talking about Chora objects, then you do not have to care about freeing. All objects that are no more used are freed automatically by the GarbageCollection - for this purpose, the function EwReclaimMemory() of the Runtime Environment is called.

Let me know some more details about your tests.

Best regards,

Manfred.

 

 

 

by

Hello Manfred,

Thank you for quick response.

Firstly, I have added a new member in XDisplayInfo, namely MemoryPool. We work on dynamic allocation and its difficult to give fix address to any variable, here Memory Pool. 

typedef struct
{
  void*             FrameBuffer;
  void*             DoubleBuffer;
  int               BufferWidth;
  int               BufferHeight;
  int               DisplayWidth;
  int               DisplayHeight;
  int               UpdateMode;
  void*             Context;
  void*             MemoryPool;
} XDisplayInfo;

Then, I have allocated memory in Init() only, like this:

int EwBspDisplayInit( int aGuiWidth, int aGuiHeight, XDisplayInfo* aDisplayInfo )
{
    EW_UNUSED_ARG( aGuiWidth );
      EW_UNUSED_ARG( aGuiHeight );

      // check and clean display info structure
      if ( !aDisplayInfo )
        return 0;
      memset( aDisplayInfo, 0, sizeof( XDisplayInfo ));

      aDisplayInfo->FrameBuffer    = (void*)os_mem_alloc(EW_FRAME_BUFFER_SIZE);    // EW_FRAME_BUFFER_ADDR;
      aDisplayInfo->DoubleBuffer   = (void*)os_mem_alloc(EW_DOUBLE_BUFFER_SIZE);    // EW_DOUBLE_BUFFER_ADDR;
      aDisplayInfo->BufferWidth    = EW_FRAME_BUFFER_WIDTH;
      aDisplayInfo->BufferHeight   = EW_FRAME_BUFFER_HEIGHT;
      aDisplayInfo->DisplayWidth   = EW_DISPLAY_WIDTH;
      aDisplayInfo->DisplayHeight  = EW_DISPLAY_HEIGHT;
      aDisplayInfo->MemoryPool    = (void*)os_mem_alloc(EW_MEMORY_POOL_SIZE);    // EW_MEMORY_POOL_SIZE;

      #if EW_USE_DOUBLE_BUFFER == 1
        aDisplayInfo->UpdateMode   = EW_BSP_DISPLAY_UPDATE_NORMAL;
      #else
        aDisplayInfo->UpdateMode   = EW_BSP_DISPLAY_UPDATE_PARTIAL;
      #endif

.

.

.
}

QUERY: It seems to me that EwReclaimMemory(), which is in EwProcess() is not clearing the memory. Because as soon as I increase the size of MemoryPool my count of Test cycles gets increased. That means more memory for more tests? Which might mean that memory is just getting allocated and not deallocated to Device Object.

 

Thanks in advance,

Vandana Matai 

by
Hi Vandana,

the memory pool is 500kB - the Device Object is only a few bytes - so why should you run into an out-of-memory situation? I don't think there is any problem with the EwReclaimMemory()...

Can you provide the entire Console Output from the start of your application? Do you get any error messages on the console?

What do you mean with "While executing 7th time, EwProcess() is not getting executed."? Can you explain your test more detailed? Can you share some code snippets?

Sorry for asking you so much questions - I still did not get the real problem...

Thanks and best regards,

Manfred.
by

Hello Manfred,

Please don't be sorry, it's great that you are trying to help and giving response.

I agree that Memory Pool is very large as compared to Device Object. This makes me curious to know the reason of not plotting. There are no Error messages or warnings on console.

PFA video for reference: https://ask.embedded-wizard.de/?qa=blob&qa_blobid=14660713487985806455

The smallest test cycle is of 4+ sec, during which, X and Y coord (float values) are sent for plotting every 50 ms. So at the end of test we have minimum 80 values for X and 80 values for Y. At the end of test, I am clearing the screen using "ChartsCoordList_ClearList( &_this->CoordList )". Then again restart the test. Video has 6th cycle, which runs fine. 7th time, the test is executing, but plotting is stopped in between. And after that is no processing on screen. While debugging, it's observed that execution doesn't go in section EwProcess() section.

updateProg_Counter(float,float) is called every 50ms to update the coordinates, which is successfully printed on console also. PFA image for reference.

Thank you for all support, Vandana Matai.

by

Hello Manfred,

here is another information which might be relevant: As soon as I enable EwPrintProfilerStatistic(1) or EwDumpHeap(1), screen never updates at all. Also there is no output on console, related to GUI Task executed.

 

NOTE: We are using free edition of Embedded Wizard.

Thank you!

by
Hello Vandana,

thank you for providing further information and the video - now I understand your application.

So we should have a look on your DeviceDriver implementation (this part is only running on the target and not used within the Prototyper). Can you share that?

Btw: Please try to get the serial connection working, so that we can print information out of the running application.

This brings another question: How large is the stack or your system? According to the code snippets you shared in your first post, I assume you have an operating system in use - correct? How large is the stack configured for the GUI task?

Best regards,

Manfred.
by

Hello Manfred,

I am trying to get output on console. Meanwhile, here are the two files that I have created using ew_bsp_XXX and other device related code provided by Embedded Wizard; ew_main.c File and ew_main.h File. DeviceDriver implementation is in these, along with all init(), process() and deinit().

Regarding your another question, yes, we are using MQX Operating system. Stack size configured for GUI task is 0x9000L (36864). This is the largest size allocated to any task in our project.

Thanks & Regards,

Vandana Matai

 

by
Hello Vandana,

stack size seems to be enough.

Can you reproduce the same issue on the iMXRT1060EVK? I have seen that you have done a lot of changes within the provided Build Environment. Is there a reason why you completely restructured the provided software? It will be almost impossible to work with future updates.

Best regards,

Manfred.
by

Hello Manfred,

I am afraid that I can't reproduce the issue on EVK, as we don't have it because of very high lead time.

The major changes are includes dynamic allocation of MemoryPool (already mentioned) and related to Glymph/Surface Cache (commented out), rest functions are all exactly same. Luckily, I have enabled the console and attaching the log now. Heading in Bold states the details of the column. I have added as a sheet as it becomes easy to compare and understand. PFA: Console Output

Thanks in advance and sorry for asking so much.

Vandana Matai

by

Hi Vandana,

still confusing...

Can you please disable EwDumpHeap() and use only EwPrintProfilerStatistic( 0 ) not ( 1 ).

Then it would be great to see the entire startup message and the profiler statistics after the start and before the error happens. Just a short text file.

Thanks,

Manfred.

by

Hello Manfred,

I have tried many times, I get Error code 3,4,10.

Note: This time I am running for 8.60 secs, and halt is observed in 6th cycle. Text "Start Streaming" and "Stop Streaming" is identification of Start and End of Test respectively. PFA:

1. Error code 10 with EwPrintProfilerStatistic( 0 ), ew_query2 File

2. Error code 3,4 with EwPrintProfilerStatistic( 0 ), ew_query3

3. Error code 4 with EwPrintProfilerStatistic( 0 ), ew_query4

Also attaching video of 6th cycle for reference https://ask.embedded-wizard.de/?qa=blob&qa_blobid=2684869574844821691

Thanks & Regards,

Vandana Matai

by
Hi Vandana,

thank you for the provided test results - very helpful, but still strange...

Based on the outputs it seems that there is still enough memory (200 kByte) but it is not possible to allocate memory for a small Chora object or for a string. This is strange.

Some further things to check:

1.) You removed the configuration of ewconfig.h and there are a couple of values missing in the startup message. Can you add that and check again?

2.) Can you ensure that there is no other task / thread calling any function of the Embedded Wizard generated code or Graphics Engine or Runtime Environment?

3.) Did you modify any of the files within the folder /PlatformPackage? If yes, what has changed?

4.) Can you show me the Embedded Wizard project (if you do not want to post it, let me know, you can send it by email).

Best regards,

Manfred.
by

Hello Manfred,

Here are the findings:

1. Added all #define from ewconfig.h in our code. Found that now halt is in 10th cycle. But still plotting is very slow. (updated ew_main.h @line 340 to 360 is attached in folder for reference). Also printed all the additional info.

2. Yes, I am sure. Although, there are two things to be mentioned, firstly, I am calling EwBspClockTickIncrement() from our 1ms_tick() function (ew_main.c @line 50). And secondly, updateProg_Counter() is called in our code every 50ms, while executing the test, to update X and Y coord (ew_main.c @line 400).

3. No, nothing is modified in /PlatformPackage. But in GeneratedCode/Application.c file, I have used one extern boolean variable for clearing the graph plot at the end of every result (Application.c @line 216).

4. PFA  Folder which has:

4.1 Project Created in EW

4.2 Used Code in our Project (generatedCode, PlatformPackage, ew_main.h and ew_main.c)

4.3 Two text docx of Log; ew_query7 which has Error Code 10 and ew_query8 which as Error Code3,4 observed after adding configuration as mentioned by you in point 1.

 

Thanks & Regards,

Vandana Matai

by

Hi Vandana,

it is very difficult to give you helpful support... Overall, I'm not very happy with the status of the project - for several reasons:

1.) The approach that you have chosen to draw the graph is several years old - the example you have used is neither part of the installed examples nor part of the Build Environment. The Charts::Graph class is only for compatibility - but no more recommended for new developments. Let me recommend to use vector graphics - see Stroked Path and Path Data. Of course, the current implementation should work also and I'm sure this is not the root cause. But anyhow, for a new development vector graphics is the better choice.

2.) Manual modifications in the generated code should be considered as "no go". There should be never a reason to "patch" the generated code.

3.) All files from the Build Environment (e.g. /TargetSpecific, main.c, ewmain.c, ewconfig.c) are ripped apart and partially copied into other files.

4.) It is not possible to run the project in the Prototyper and it is not possible to run the project on the EVK.

I assume that the error is somehow related to your start / stop activities (which happens outside of the GUI project) - but I have no chance to debug that. In the video there appears some other screens, which are not part of the Embedded Wizard project. Very confusing.

Honestly speaking, I would start from scratch and try to keep a proper software architecture. Once the porting to your target is done, test applications (e.g. GraphicsAccelerator demo provided in /Examples of the Build Environment) should run stable for hours and days.

Btw: We are offering Port and Verification as a service - maybe this is interesting for you.

Sorry - but I cannot solve the integration issue without having the board on the table...

Best regards,

Manfred.

by
Hi Manfred,

Thank you for all the support provided. As per your suggestion,I'll start from scratch and use vector graphics this time.
Regarding all files from the Build Environment, we have own bsp/pxp files in project so I can't use /Source or /TargetSpecific completely as it is.
Thank you for offering Port and Verification as a service - we may consider this after a few more trials.

Best regards,
Vandana Matai
by

Hello Manfred,

PFA stroked path Project and respective console log;  Project and Console1 with 200 edges, Console 2 with 250 edges. This time also graph gets disappeared.

I have involved: 

#define EW_PRINT_MEMORY_USAGE
// #define EW_DUMP_HEAP

#define EW_MAX_STRING_CACHE_SIZE      0x4000
#define EW_MAX_SURFACE_CACHE_SIZE   0x800000
#define EW_MAX_GLYPH_SURFACE_WIDTH       256
#define EW_MAX_GLYPH_SURFACE_HEIGHT      256
#define EW_MAX_NO_OF_GLYPHS                0
#define EW_MAX_ISSUE_TASKS               100

#define EW_LAZY_LOAD_BITMAPS                              1
#define EW_LAZY_LOAD_BITMAPS_IF_ANIMATED_ONLY             1
#define EW_DISCARD_BITMAPS                                1
#define EW_DISCARD_BITMAPS_IF_ANIMATED_ONLY               1
#define EW_DISCARD_BITMAPS_IF_NOT_USED_IN_CURRENT_UPDATE  0
#define EW_DISCARD_BITMAPS_IF_NOT_USED_IN_RECENT_UPDATES  0
#define EW_CACHE_OFFSCREEN_SURFACES                       0

from ew_config.h

NOTE: This time I am not editing any Package or Generated Code files except EwBspClockTickIncrement() is called from our 1ms_tick() function.

Sorry for bothering again,

Vandana Matai

by
Hi Vandana,

as mentioned in one of the comments above, I do not believe that the using vector graphs will solve the issue. It was recommended to have good implementation from the beginning of your project.

Can you try to run one of the provided examples with endless animations (e.g. GraphicsAccelerator demo) on your hardware and run that for some hours? Just to ensure that - without any events or data from outside - the GUI application is running stable.

I assume that the issue is somehow related to the integration.

Let me know the outcome.

Best regards,

Manfred.
by

Hello EW Team,

Appreciate the support so far. We had many trials of EW for our devices and probably go ahead with the licensing process soon.

In regard to the above query, I have disabled existing screen and enabled only EW GUI on our device with Graphic Accelerator Project files. This time also log report is same. Screen stops after some seconds; minimum time being 16 secs and maximum being 20 s. Please find the attached link: Query_12.12.22 which as some videos 1,3 ,4 and respective numbered log files. File numbered with 1 has LOG with EwPrintProfilerStatistic( 1 ) with Error 13 , numbered 3 has both EwPrintProfilerStatistic( 1 ) and EwDumpHeap( 1 ); numbered 4 has neither Statistic nor DumpHeap. 

Regards

Vandana Matai

by

Hello Vandana,

great to hear that you have now used the Graphics Accelerator demo to check the system stability. Thanks for providing the logs. Especially the Log3 is very helpful.

As you can see, the memory statistic is more or less stable - so the application should run for ever.

However, the heap dump indicates, that the memory is consumed and consumed until there is no memory left and the system stops. There was never a memory block freed. The counter FreeCounter is always 0.

One of the following situations could cause this issue:

  • There happens some memory allocation in some other thread by using EwAlloc().
  • The main loop does not contain the necessary function call EwReclaimMemory() to start the garbage collection.
  • The function EwFree() within the file ewextrte.c was modified and does not call the corresponding heap manager function.
 
Can you please check the above points and let me know the results? Can you post your current EwAlloc() and EwFree() implementation?
Thanks and best regards,
Manfred.

 

by
Hello Manfred,

Great catch!

EwFree() within the ewextrte.c was not calling EwFreeHeapBlock(). The EW project files are working with our firmware application and executing for hours now.

Thank you so much for the endless support.

Best Regards,

Vandana Matai

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

...