These are the tools and methods for detecting Interrupts in Linux and cache-delays on the Pi Zero 2.



The VPU is a dual-core processor in the Raspberry Pi's GPU, used mainly for graphics and management functions by the proprietary Raspberry Pi firmware. The second core is unused by the default firmware, and small (under 1KB) programs can be executed on it without affecting other functionality.

ARM System Timer

Running at 1MHz, the ARM System Timer is a free-running 64-bit counter. Reading only the lower 32-bits, it overflows less than once per hour.

Detection Methods

Three methods are available for detecting interrupts and other execution delays in the pipeline display code:

System-Timer-compared delays

The time taken to execute busy-wait delay routines is compared with the ARM System timer (clocked at 1MHz). If there was a delay, the timer count will be higher than expected at the end.

Vectrex-Cycle-Counted Operations

Delays and VIA Writes are performed over periods of Vectrex clock cycles. In the time for each Vectrex clock cycle to complete at its 1.5MHz clock frequency, the Raspberry Pi CPU, at 1GHz clock frequency, executes approximately 666 instructions.

Between each write operation there is at least one Vectrex cycle delay, therefore up to 666 instructions can be executed by the CPU between write operations (specifically, prior to setting LATCH EN High) before causing any actual delay in execution time. So as long as the code length between writes is kept under this relatively high threshold, execution time for any code involving multiple writes to the VIA can be calculated according to Vectrex clock cycles, without accounting for the specific length of the code executed by the CPU between each write. In effect, sequential writes are directly clocked by the 1.5MHz Vectrex clock frequency.

At the start of each write operation, the start time of the previous write operation is compared to the current time (according to the value of the ARM System Timer counter). If this is equivalent to more than the expected number of Vectrex clock cycles, that means the CPU's execution of the code has been delayed by an interrupt or other influence (multi-core cache delays).

VPU Timer

The VPU Timer routine primarily exists to turn off the vector beam at the correct time when a visible line is drawn, regardless of delays in the execution of display code by the CPU. It does this at a fixed delay after detecting the expiry of the VIA's T1 timer which controls vector beam movement (ramping), via the IRQ signal from the Vectrex. When the VPU turns off the beam, it sets a flag in a register at the end of the "multicore sync block" to indicate as such, until the IRQ signal is disasserted by the CPU disabling it, after which the flag is cleared.

(In case the CPU checks that the beam-off flag isn't set but then gets delayed and ends up writing to the VIA at the same time as the VPU, the VPU performs the beam-off write twice. The CPU should detect the flag before performing a second write and perform a re-zero operation instead, after delaying for long enough that the VPU can complete its second beam-off write)

Between the end of the T1 timer and the VPU turning off the beam, writes are performed by the CPU to set up the for the next display operation. After the CPU detects the expiry of the T1 timer, the Beam-Off flag register is checked, and if it is set this indicates that a delay in CPU execution has occoured while the CPU was waiting for the T1 expiry, which caused it to miss the exact moment of expiry for a time greater than the T1-end-delay.

During subsequent write operations, the flag is also checked as a secondary method of detecting delays besides Vectrex-Cycle-Counting. An interrupt can only be detected if the execution time after T1-end, to that point, is expected to be shorter than the T1-end-delay.


When any of the above methods detect a delay in CPU code execution that exceeds allowable thresholds, this means that the beam position may have drifted excessively and a zeroing operation must be performed before continuing. This is done by rewriting, then jumping back, the last two sections of the vector pipeline so that the beam is zeroed and them moved to the location of the next line to be drawn, before continuing.

There may be a need to reset extra configuration registers in the VIA in case they were written to accidentally as a result of the CPU attempting to write to the VIA at the same time as the VPU performed its first Beam-Off write.