TouchGFX with hardware encoder wheel - touchgfx

Trying to implement touchGFX on ARM with the UI controlled from a push-button encoder wheel, often seen in cars.
The problem I encounter is that the low-level, encoder wheel part is handled from the main backend application in C.
TouchGFX, is in C++. The designer app allows to implement hardware button directly, that is directly handled by the stack, but an encoder wheel needs to have some logic implemented, preferably on the backend.
Usually, the way to interact from the backend to touchGFX is through the model class where data are polled (about 60Hz according to the documentation).
However, for a physical encoder, it would be preferable to have a trigger-based communication between the backend and GFX, however, it isn't clear on the doc or examples how to get GFX context and how to integrate triggers from the backend, either by direct call or by callbacks rather than polling.
I tried to implement a C->C++ callback but couldn't find the GFX context.
After digging through documentation and plenty of post, I have yet to find a solution.

You could do the following:
Add a function to the frontend application which returns a pointer to the model
Add a C++ source file with a function which is called from C and which calls a function in the model:
#include <gui/common/FrontendApplication.hpp>
#ifdef __cplusplus
extern "C" {
#endif
void func1()
{
Model * model = static_cast<FrontendApplication*>(Application::getInstance())->getModelPtr();
if (model)
{
model->funcOnModel();
}
}
#ifdef __cplusplus
}
#endif
call func1() from your C backend
From funcOnModel the touchgfx widgets can be accessed via the ModelListener or the derived Presenters.

Related

How to manage the cuda streams and TensorRT context in multiple threads GPU application?

For a tensorrt trt file, we will load it to an engine, and create Tensorrt context for the engine. Then use cuda stream to inference by calling context->enqueueV2().
Do we need to call cudaCreateStream() after the Tensorrt context is created? Or just need to after selecting GPU device calling SetDevice()? How the TensorRT associate the cuda stream and Tensorrt context?
Can we use multiple streams with one Tensorrt context?
In a multiple thread C++ application, each thread uses one model to inference, one model might be loaded in more than 1 thread; So, in one thread, do we just need 1 engine, 1 context and 1 stream or multiple streams?
Do we need to call cudaCreateStream() after the Tensorrt context is created?
By cudaCreateStream() do you mean cudaStreamCreate()?
You can create them after you've created your engine and runtime.
As a bonus trivia, you don't necessarily have to use CUDA streams at all. I have tried copying my data from host to device, calling enqueueV2() and then copying the from device to host without using a CUDA stream. It worked fine.
How the TensorRT associate the cuda stream and Tensorrt context?
The association is that you can pass the same CUDA stream as an argument to all of the function calls. The following c++ code will illustrate this:
void infer(std::vector<void*>& deviceMemory, void* hostInputMemory, size_t hostInputMemorySizeBytes, cudaStream_t& cudaStream)
{
auto success = cudaMemcpyAsync(deviceMemory, hostInputMemory, hostInputMemorySizeBytes, cudaMemcpyHostToDevice, cudaStream)
if (not success) {... handle errors...}
if (not executionContext.enqueueV2(static_cast<void**>(deviceMemory.data()), cudaStream, nullptr)
{ ... handle errors...}
void* outputHostMemory; // allocate size for all bindings
size_t outputMemorySizeBytes;
auto success2 = cudaMemcpyAsync(&outputHostMemory, &deviceMemory.at(0), outputMemorySizeBytes, cudaMemcpyDeviceToHost, cudaStream);
if (not success2) {... error handling ...}
cudaStream.waitForCompletion();
}
You can check this repository if you want a full working example in c++. My code above is just an illustration.
Can we use multiple streams with one Tensorrt context?
If I understood your question correctly, according to this document the answer is no.
In a multiple thread C++ application, each thread uses one model to inference, one model might be loaded in more than 1 thread; So, in one thread, do we just need 1 engine, 1 context and 1 stream or multiple streams?
one model might be loaded in more than 1 thread
this doesn't sound right.
An engine (nvinfer1::ICudaEngine) is created from a TensorRT engine file. The engine creates an execution context that is used for inference.
This part of TensorRT developer guide states which operations are thread safe. The rest can be considered non-thread safe.

What is the proper way to get continuously processed data from a thread?

The following functions and fields are part of the same class in a Visual Studio DLL. Data is continuously being read and processed using the run function on a thread. However, getPoints is being accessed in a Qt app on a QTimer. I don't wan't to miss a single processed vector, because it seems it could be skipping leading to jumpy data. What's the safest way to get the points to the updated version?
If possible I'd like an answer that uses the C++ standard library as I've been exploring mutex-es, but it still seems to lead to jumpy data.
vector<float> points;
// std::mutex ioMutex;
// function running on a thread
void run(){
while(running){
//ioMutex.lock()
vector<byte> data = ReadData()
points = processData(data);
//ioMutex.unlock()
}
}
vector<float> getPoints(){
return points;
}
I believe there is a mistake in your code. The while loop will consume all the process activity and will not allow proper functionality of other functions. In Qt, in such continuous loops, usually it is a good habit to use the following because it actually gives other process time to access the event buffer properly. If this dll is written in Qt, please add the following within the while loop
QCoreApplication::processEvents();
The safest (and probably easiest) way to deliver your points-data to the main thread is by calling qApp->postEvent() with an object of a custom QEvent-subclass that contains your vector<float> as a member-variable.
That will cause the event(QEvent *) method of (whatever Qt object you specified as the first argument to postEvent()) to be called from inside the main/GUI thread, and so you can override that method to read the vector<float> out of the QEvent-subclassed object and update the GUI with that data.

VC++ native mutex heap corruption

I have a native c++ library that gets used by a managed C++ application. The native library is compiled with no CLR support and the managed C++ application with it (/CLR compiler option).
When I use a std::mutex in the native library I get a heap corruption when the owning native class is deleted. The use of mutex.h is blocked by managed C++ so I'm guessing that could be part of the reason.
The minimal native class that demonstrates the issue is:
Header:
#pragma once
#include <stdio.h>
#ifndef __cplusplus_cli
#include <mutex>
#endif
namespace MyNamespace {
class SomeNativeLibrary
{
public:
SomeNativeLibrary();
~SomeNativeLibrary();
void DoSomething();
#ifndef __cplusplus_cli
std::mutex aMutex;
#endif
};
}
Implementation:
#include "SomeNativeLibrary.h"
namespace MyNamespace {
SomeNativeLibrary::SomeNativeLibrary()
{}
SomeNativeLibrary::~SomeNativeLibrary()
{}
void SomeNativeLibrary::DoSomething(){
printf("I did something.\n");
}
}
Managed C++ Console Application:
int main(array<System::String ^> ^args)
{
Console::WriteLine(L"Unit Test Console:");
MyNamespace::SomeNativeLibrary *someNativelib = new MyNamespace::SomeNativeLibrary();
someNativelib->DoSomething();
delete someNativelib;
getchar();
return 0;
}
The heap corruption debug error occurs when the attempt is made to delete the someNativeLib pointer.
Is there anything I can do to use a std::mutex safely in the native library or is there an alternative I could use? In my live code the mutex is used for is to ensure that only a single thread accesses a std::vector.
The solution was to use a CRITICAL_SECTION as the lock instead. It's actually more efficient than a mutex in my case anyway since the lock is only for threads in the same process.
Not sure were you reading your own post but there is a clue in your code:
#ifndef __cplusplus_cli
std::mutex aMutex;
#endif
Member 'aMutex' compiles only if compile condition '__cplusplus_cli' is undefined.
So the moment you included that header in Managed C++ it vanished from definition.
So your Native project and Managed project have mismatch in class definition for beginners == mostly ends in Access Violation if attempted to write to location beyond class memory (non existing member in CLI version if instantiated there).
Or just HEAP CORRUPTION in managed code to put it simply.
So what you have done is no go, ever!
But I was actually amazed that you managed to include native lib, and successfully compile both projects. I must ask how did you hack project properties to manage that. Or you just may have found yet another bug ;)
About question: for posterity
Yes CRITICAL_SECTION helps, Yes it's more faster from mutex since it is implemented in single process and some versions of it even in hardware (!). Also had plenty of changes since it's introduction and some nasty DEAD-LOCKS issues.
example: https://microsoft.public.win32.programmer.kernel.narkive.com/xS8sFPCG/criticalsection-deadlock-with-owningthread-of-zero
end up just killing entire OS. So lock only very small piece of code that actually only accesses the data, and exit locks immediately.
As replacement, you could just use plain "C" kernel mutex or events if not planning cross-platform support (Linux/iOS/Android/Win/MCU/...).
There is a ton of other replacements coming from Windows kernel.
// mutex
https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-createmutexw
HANDLE hMutex = CreateMutex(NULL, TRUE, _T("MutexName"));
NOTE: mutex name rules 'Global' vs 'Local'.
// or event
https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-createeventw
HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, _T("EventName"));
to either set, or clear/reset event state, just call SetEvent(hEvent), or ResetEvent(hEvent).
To wait for signal (set) again simply
int nret = WaitForSingleObject(hEvent, -1);
INFINITE define (-1) wait for infinity, a value which can be replaced with actual milliseconds timeout, and then return value could be evaluated against S_OK. If not S_OK it's most likely TIMEOUT.
There is a sea of synchronization functions/techniques depending on which you actually need to do !?:
https://learn.microsoft.com/en-us/windows/win32/sync/synchronization-functions
But use it with sanity check.
Since you might be just trying to fix wrong thing in the end, each solution depends on the actual problem. And the moment you think it's too complex know it's wrong solution, simplest solutions were always best, but always verify and validate.

How to pause threaded worker with QThread?

First of all, forgive me if there’s an obvious solution, I’m completely new to the use of thread (and only know a bit about the theory).
I’m currently developing an application in which I want to use threads. Basically, it retrieves data an displays it on a graph in real time with Qt.
I’ve followed the guidelines of this post on how to use correctly QThread, but then I’m concerned with a few details.
Basically, I want to implement a pause, that will stop the real-time query and update, which can then be resumed later on.
At the moment, my class looks like this :
class DataProcessor : public QObject{
Q_OBJECT
public:
DataProcessor();
~DataProcessor();
//Internal details
public slots:
//mapped to the started() signal of a QThread
void process();
signals:
void finished();
void error(QString error);
}
I wonder how I could implement a pause feature. After reading Bruce Dawson’s post In praise of Idleness, I’ve noted a few methods that I should avoid (most importantly, avoiding busy wait)
Then, it doesn’t quite fit my needs, as Bruce talks about waiting for another thread to exit its critical section. Here, I just want to pause the work done by the thread’s worker on user input, and restart it the same way.
My question is: how can I implement an efficient pause for my threaded code ?
I’ve thought of using a sort of flag in my worker, that could be set from the main (something like bool m_paused;), but once set, I don’t know how I can actually pause efficiently my worker.
Note: This question was not written by me, but it describes my problem exactly. Source: link

How to run parallel codes using QT?

I am developing a simulator. I have chosen QT for the GUI. My project involves a lot of manipulation of data and I use QT just to plot my results.
My code structure is such that my main function contains a global object of my data, an object of the QT GUI and other objects for manipulating this data. I need to modify this data at every 30 ms. I have also attached a simplified version of my main file.
My problem is that I cannot call functions of my other objects (other than the GUI) before exiting the QT object. I have implemented timers in QT in isolation which plots the new data and works fine. All I want to do is call my ai and phySim object at a particular time interval independant of the QT object. I want these three objects to be completely independent.
world* _world;
int main(int argc, char *args[])
{
_world = new world();
gui *GUI; ///QT object
ai *AI;//object to manipulate data
phySim *sim;//object to manipulate data
/////////////////////////////////// this gets executed only when i close the QT gui
AI = new ai(_world);
AI->doSomething();
sim = new phySim(_world);
sim->updateWorld();
//////////////////////////////////////////////////////////////////////////////
QApplication app(argc,args);
GUI = new gui(_world);
GUI->show();
return app.exec();
}
Take a look at the Signals and Slots in Qt. Connect a "closed" signal that you emit when you close your GUI to a "startThread" slot. Have your AI and Simulation running in separate threads and if they need to interact, make use of signals/slots again.
You say you want the three objects to be "completely independent" -- then you should give each of them their own thread.
Maybe you should try not not run the app.exec(), but instead create a custom (almost) infinite loop, call processEvents() within that loop and your updateWorld() plus a wait of 30ms (or a little less, due to the function execution will take some ms). Drawing is then part of Qt (you should pass the instance of your simulator and add a render method (maybe best in pure OpenGL, as this can be passed through the Qt layer via a QGLWidget). Call that method within paint() or respectivly paintGL() for QGLWidget I hope this helps (a little), you should read QGLWidget doc
Note: You will have to write some wrappers in form of signals, calling your simulationObj methods, otherwise no UI interaction will be possible within Qt.
I was going to suggest overriding some event methods on QApplication but event loops can be tricky since you have some "child loops" http://labs.trolltech.com/blogs/2010/02/23/unpredictable-exec. In one of the 2009 Tech talks on there is a part that explains this too.
One approach is to separate your GUI a bit more by using a Client Server architecture. Your sim can be the server and Qt GUI the client. There are some nice samples in Qt using sockets.
Another approach is to use QTimer to update (or poll) your Sim. You might not even need threads.
void SomeGUI::SomeGUI(..)...
{
//Init sim
m_World = new world();
m_AI = new ai(m_World);
m_Sim = new phySim(m_World);
...
//Connect timer
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(updateWorld()));
timer->start(100); //or whatever interval works
...
}
void SomeGUI::updateWorld()
{
//Update sim state
m_AI->doSomething();
m_Sim->updateWorld();
updateGUI();
}

Resources