2020-12-10 06:05 AM
2021-01-05 11:36 PM
2021-01-05 11:36 PM
@Flemming Gram CHRISTENSEN When I install ChromART, the program enters the functions STM32F4DMA :: setupDataFill (const BlitOp & blitOp) and STM32F4DMA :: setupDataCopy (const BlitOp & blitOp). But I get "No source available for ..." errors about some functions. I have encountered problems with pictures. But my main problem is how do I know if ChromART is running successfully?
2021-01-06 12:03 AM
If you're hitting setupDataCopy/Fill and what you're seeing in memory or, more easily, on the display is correct - Then chromart working. You can do more concrete experiments, but if you're hitting those functions then chromart is handling filling boxes and moving image data from flash to framebuffer.
Some parts of your stack trace come from the library and you do not have the source for that. By design.
/Martin
2021-01-06 01:23 AM
@Martin KJELDSEN @Flemming Gram CHRISTENSEN
Glad to hear it working. Thank you for patiently answering every question I asked from the beginning. In fact, the best way to understand that it works will be to show the processor load. But I've been trying since yesterday. I could not show the processor load as a percentage on the screen.
2021-01-06 01:28 AM
You can get some inspiration from our demos. If you're using an RTOS like FreeRTOS then you need to add some hooks to your freertos config and add some hooks to signal when the idle task is entered. Then you can get the mcu load from the HAL class in TouchGFX. Check it out.
2021-01-06 10:33 PM
@Martin KJELDSEN
I am not using RTOS. How can I measure without RTOS?
2021-01-13 12:49 AM
Hi.
Normally with an RTOS the cpu load is establiched by calculating the amount of time spend in the Idle thread. The idea is that the RTOS switches to this thread whenever the other threads, e.g. GUI thread, is waiting for something. In TouchGFX the GUI thread is often waiting the the DMA to finish or the VSYNC/TE signal.
You can try to do the same. We don't have sample code for this.
The application will call the function OSWrappers::waitForVSync() when waiting for the next screen update. In this function you can do some counting or output a GPIO. If you have an oscilloscope or USB logic analyzer this is probably the easiest.
Another approach is to set a GPIO high when the DMA is rendering and take it down when it is done. You can do that in the setup functions in your DMA class and the DMA interrupt.
If you monitor this signal together with the RENDER_TIME you can see how long time in total it took to render a frame, and how much of this time was DMA.
Example:
Assume the Vsync is every 16ms.
And render time is 10ms. So 6ms is idle.
In the render time, if the DMA is active in a total of 8 ms (could be many small activations), these can also be subtracted.
CPU is therefore active in 2 ms, and idle in 14.
These 14ms is only useful if you can use all the small pauses for something without slowing down the UI.
This is the main reason for having an RTOS.
2021-01-13 05:11 AM
Thank you for your answer, Mr. @Flemming Gram CHRISTENSEN . I'll try this. In the meantime, I will ask you another question. As seen in the picture, I am trying to transfer the pixel data to FMC with DMA. But when I enter the data length more than 40, the DMA function becomes Busy. I can't figure out the reason for this.
2021-01-25 04:04 AM
@Flemming Gram CHRISTENSEN @Martin KJELDSEN
Finally, I can transfer 800 bytes of RAM to FMC with DMA. But I want to transfer data with DMA interrupt. I'm running into a problem here. Normally, I transfer DMA with the 'for' loop inside TouchGFXHAL :: flushFrameBuffer. Since I cannot use the 'for' loop in the interrupt, I also used software interrupt. But it hasn't been as successful as the other and has severe pixel shifts and flickering. Related cuts are available in the pictures. I would be glad if you help me in this regard.
2021-01-25 04:25 AM
Maybe it is busy because it is transferring data? I don't see that you are waiting for the DMA for i=0, before starting for i=1.
Try something like this
for (i=0;i<height; i++)
{
pixels* = ...
HAL_DMA_Start_It(...);
semTake(fmcDMAsemaphore); //lock UI thread until DMA has finished
}
and then in the DMA interrupt, signal the fmcDMASemaphore.
This way the UI thread is sleeping while the DMA is running. Other threads can run meanwhile.
Other synchronization primitives can also be used. But if you are busywaiting on the DMA here, then you could also just write the data with the cpu.
Good luck.