Updating QGLWidget - event or signal/slot? - qt

I need to flash some images with very precise timing (order of milliseconds) for which I developed a subclass of QGLwidget. The images are loaded as textures at initialization. I am using a QTimer instance to change the image being displayed. The timer's timeOut signal is connected to a timeOutSlot which does some file I/O and then calls updateGL().
While I understand that event handlers are for external events and signal/slot is for communication internal to the GUI, I could also implement this as a timeOutEvent handler.
Is there any performance difference between the two? Any performance penalty above 2-3 milliseconds is important to me (hardware is average, say Intel core 2 duo T5700 with nVidia 8600M GT graphics card).

Signals and slots are about 10 x slower than the plain old function calls. But they are definitely not so slow that they would take milliseconds to process. The time to process one signal is about 0.001 ms (see slide 27).
You say that you are requiring a very precise timing, so are you aware how the display refresh rate affects the drawing? Image is (usually) drawn using 60 Hz refresh rate. The time between images is 16.7 ms so that is the maximum accuracy you can get.

I would say signal/slot because events are added to an event queue where Qt often does call optimisations and importance ordering, whilst s/s are executed immediately - albeit slower than direct calls.

Related

STM32F3 High Resolution Timer

I'm looking to develop an ultrasonic time-of-flight (ToF) sensor and have been looking at high speed timing circuits. Many versions use the TDC7200, but ST offers the STM32F334 which has a high-resolution timer with apparent 217ps resolution.
What I'm wondering whether this timer can actually be used to measure time with 217ps between each count value (assuming it's run at maximum clock rate)?
Does anyone have experience using this microcontroller's high-resolution timer like this?
According to the reference manual it should be possible:
High-Resolution Timer (HRTIM) : For control and monitoring purposes, the timer has also timing measure capabilities and links to built-in ADC and DAC converters. Last, it features light-load management mode and
is able to handle various fault schemes for safe shut-down purposes. --page 626
The timing unit has the capability to capture the counter value, triggered by internal and
external events. The purpose is to:
• measure events arrival timings or occurrence intervals --page 641

Multiple timers or single task with multiple counter?

Assume you have some functions that must be called at different point in times but continuosly (constant task like each 250ms, each 2s, each 5 mins).
Is it better to use 4-5 timers each one dedicated to a task or is it better to code everything in the smaller task and then use a counter variable to run the other function?
e.g.
//callback each 250ms
void 250ms_TASK(){
if (counter % 8 != 0){ //250ms*8 = 2s
return;
}
// do 2 sec stuff
if (counter != 4800){ //250ms*4800 = 20min
return;
}
//do 20min stuff
counter = 0;
}
Assume also that you want to avoid/be bulletproof to situations like this:
before doing 2 secs stuff you MUST be sure that the 8th 250ms task is computed.
before doing 20 min stuff you MUST be sure that the 4800th 250ms and the 600th 2s task is computed.
The question is related to best practice and performance.
Moreover is it better to perform those calculations in the callback or use the callback to modify flags and perform the calculations in the main loop ?
I assume you are using STM32 since you tagged STM32.
Unless your application is very much time critical that you need to use preemptive and asynchronous timer interrupts (for example 5 mins task is very important so it should be called even while a separated 250ms callback task is running), using multiple timer interrupts is just waste of timers and you need to use as fewer interrupts as possible IMHO. Counting variable is not costly so it is okay to do that.
The real consideration is the length of tasks. The ISRs should be as short as possible so if the timer callback tasks are quite long you should use flags and use polling operation in the main loop. Polling flags is more preferable especially when you are using multiple callbacks in a single timer ISR. Imagine the moment that 250ms, 2s, and 20min callbacks should be called in the ISR and the ISR will take 3 times longer than usual.
By the way, if you decide to use a single timer, why not using SysTick? The SysTick timer is provided in every Cortex M MCUs and its operation is the same across the MCU families. You can easily configure this as 1ms interrupt timer very easily. As far as you use polling in the main loop 1ms interrupt must be fine. There are many tutorials on Systick (for example, part1 and part2)
The standard way to do this for tasks that aren't very time critical, is to implement a single timer, which triggers once every millisecond.
That timer then goes through a list of registered "software timers" and checks if it is time for them to be executed. If so, the timer then calls a function pointer which contains the timer-specific code. That is, a callback function called upon by the timer driver.
If these functions are kept minimal, for example just setting a flag, you can execute them from the main timer ISR.
You can make various arguments regarding power consumption and real timer requirement. It really depends on your application. But these question can deliver insightful answers for beginners, and even more experienced developers. The keyword here is scheduling.
The typical setup I prefer, bare metal real-time:
Main runs all low priority and idle tasks. Main bases these timings on the systick timer that ticks every 1 ms: if( (now - then) > delay ){ then = now; foo(); }
These tasks can be interrupted by everything, except in a critical zone (when using ISR threadspace data).
Low priority tasks are blinking LED's and handling communications.
There are peripheral interrupts and timers that set IRQ pending bits to signal real-time work is ready to be done. Eg: read uart or adc register before overrun.
The interrupt priorities and timers are setup in a way that the work is done in the correct order at the correct time. Eg: when processing ADC samples, and the hardware alarm IRQ arrives, this is handled immediately.
This way I have the DMA signal samples are ready to be processed, whilst a synchronized timer at a lower frequency set the IRQ-pending for the process loop. The process loop must run after the samples, thus has lower priority in the NVIC.
Advantage: Real time performance is not impeded when the communication channel is overflowed with data.
Disadvantage: The cpu never sleeps long.
The ISR's of the real time tasks may not exceed their time window. This is where Windowed Watchdog Timers are useful. Also, idle tasks will only run when there is time to spare. They might be late.
A similar option here is to use a real time operating system. Like ChibiOS.
However, when you're a battery application you don't want the MCU to wake up every second. You want the MCU to wake up only when work has to be done. You can do this in two ways.
Multiple hardware timers signal the wake-up event.
This requires multiple timers to keep running and might still use too much energy.
Tickless operation. You use one timer, the chip wakes up and does work when the time is reached. Then it reloads the timer compare with the time of the next deadline. If your intervals are long enough apart you can use the RTC for this to get ultra low power consumption.
Advantage: chip is allowed to go to sleep for longer period depending on workload.
Disadvantage: the design is a bit more complicated to implement and debug.
Similar option here is to use a tickless operating system.
Assuming you're not using a real time OS, I'd use a timer to do the time critical stuff (if it's handled with few clock cycles) and long timer counters through an interrupt and use non time critical stuff and longer periods in the main loop (with or without a watchdog timer/sleep).
The interrupts will interrupt the main loop stuff so you can be sure the time critical stuff happens when it needs to, the less time critical stuff happens whenever it can.
You could use a state machine in the main loop to do the logic stuff to make sure everything is done in the right order, things are checked, loaded, sensors read etc.
There is no right answer here, best practices would be to implement the design to meet the requirements, since requirements for a project vary from project to project there is no single right answer. One common solution will fail to work right for a wide array of products, as would another common solution. You could force one solution but that can add a lot of hacked up band-aids simply adding risk to the project, possibly lead to failure and or recalls or field upgrades that were unecessary that make the product and the company look bad. Do your system engineering and most of the time the correct solution will simply present itself, dont do your system engineering and the failures will simply present themselves.

Oscilloscope type design with FPGA PL and PS framebuffer interface?

I am generating a certain signal (digital pulse) in one of my verilog module running on programmable logic in Xilinx Zynq chip. Signal is pretty fast, with clock of about 200MHz.
I also have a simple linux and framebuffer Qt interface running for later controlling my application.
How can I sample my signal in order to make oscilloscope like interface inside my Qt app? I want to be able to provide visual of the pulse I am generating.
What do I need to use to be able to sample enough data at such clock frequency? And how do I pass it with kernel module or mmap to Qt?
You would do best to do what most oscilloscopes do: sample the data to RAM, and only then transfer it to the processor for display/analaysis, at a more "relaxed" pace.
On the FPGA side you will need a state machine that detects some sort of start or trigger condition, probably after a bit in a mode register is set from the software side to arm it.
The state machine will then fill samples into a buffer made of one or more block rams. If you want to placing the trigger somewhere in the middle of the samples captured, you should it as a circular buffer, and have it record continuously, stopping configurable number of samples after the trigger, so that some desired number from before the trigger condition remain un-overwritten by newer ones following it.
Since FPGA block rams are typically dual port, you can simply hook the other port up to your CPU bus for readout. You will probably want a register to read the state of the sampling state machine, and if you go with the circular buffer approach, the address where it stopped, so that you can unwrap the data to a linear record of time.
Trying to do streaming realtime sampling might be possible, but would be a lot harder and it is not clear that you could do anything meaningful with the data so produced in real time. Still, if you want to try you would probably need to put a FIFO buffer in between the sampling and the processor bus, as you will probably only be able to consume data in chunks, while having to service other operations in between, so something is needed to absorb the constant-rate inflow of samples. Another approach could be to try to build a DMA engine which would write samples directly to external system ram, but that will likely be even harder.
You could also see if there are any high speed interfaces available in the CPU which you could leverage - they might be things originally intended for video, for example.
It also appears that you are measuring only a digital signal, ie, probalby one bit. If you want to handle a higher input sample rate than the FPGA fabric can support, that could mean you could potentially use something like a deserializer block at the edge of the FPGA to turn the 1-bit input stream into a slower stream of wider samples to store.
In terms of output, once you have a vector of samples in a buffer it's pretty simple to turn that into a scope/logic analyzer type plot, with as much zooming, cursor annotation, automatic measurement or whatever you like.
Also don't forget that if the intent is only to use this during development, FPGAs and their tools often have the ability to build a logic analyzer right into the design, with the data claimed over the programming interface for plotting on a PC.

Does QElapsedTimer actually create a timer?

QTimer seems to actually create a "timer" that consumes CPU ticks and posts events etc. Is the same true for QElapsedTimer?
Or is this just something like win32's GetTickCount where by when you call a method on QElapsedTimer it grabs the current tick count and subtracts from the count where it was started?
I want to know if its a good idea to have these things hanging around, or will they eat battery like QTimer?
QTimer will "eat" battery only in some cases. Specifically, if it is a Qt::PreciseTimer on Windows 7 and earlier - on those systems, it will ramp up the tick frequency to 1000Hz. Very short timers will force the same behavior. Since those systems are not tickless, the presence of an active coarse timer does nothing to power consumption, since the system ticks at a fixed rate whether it needs to or not.
On a tickless operating system, QTimer does not have such ill effects. This includes OS X/xnu, Windows 8 or tickless Linux.
QElapsedTimer is not a QObject and does not provide any asynchronous events. It simply provides an interface to the platform's time APIs (not timer APIs).

Qt: When QTimer actually started?

When application calls QTimer::start() is it started immediately or will be started after current event processed ? In other words, should I use single-shot timer with time correction in case of long-time processing in its timeout() slot ?
To answer with certainty would require inspecting platform-specific code within Qt. That's a good sign that this is not something you should be depending on. Moreover, QTimer doesn't promise much in terms of accuracy:
Timers will never time out earlier than the specified timeout value
and they are not guaranteed to time out at the exact value specified.
In many situations, they may time out late by a period of time that
depends on the accuracy of the system timers.
The accuracy of timers depends on the underlying operating system and
hardware. Most platforms support a resolution of 1 millisecond, though
the accuracy of the timer will not equal this resolution in many
real-world situations.
If Qt is unable to deliver the requested number of timer clicks, it
will silently discard some.
If you need to know precisely how much time has passed between timeout signals, use your QTimer in conjunction with a QElapsedTimer.

Resources