The Clover Mini Contactless Performance Story — Part 2
by Jacob Abrams
This is part 2 of Clover’s story about the performance of contactless transactions challenges we faced during the development of Clover Mini and Clover Mobile. If you haven’t read part 1 of this story please check it out.
Fine-tuning contactless performance on Clover devices
As discussed before at this point we faced the challenge of analyzing the performance of large chunks of code we didn’t author and in some cases didn’t even have the source code for. My coworkers added custom instrumentation calls to various points in our code that fired GPIOs which were being detected by an attached oscilloscope. We also utilized clocks on the secure processor to record performance timings.
We quickly discovered that the Universal Asynchronous Receiver/Transmitter (UART) message logs consumed significant time and we disabled all of them. It turns out the CPU spends a lot of time sitting around doing nothing waiting for data to transmit at 115200 baud. We weren’t logging much but this saved us 20 to 40 milliseconds.
By looking at the oscilloscope output my coworkers realized that at regular intervals of 1 millisecond there were hiccups in contactless communication activity, they determined that the Real-Time Operating System (RTOS) scheduler was stealing some time from the contactless transaction processing task. This interruption caused additional delays when it happened in the middle of contactless packet transmission. We had several RTOS tasks and though all but one of them were blocked, the RTOS still stopped the world every 1 millisecond to check which task to run, even if there was only one choice. Our solution was to disable the processor systick that drives the OS scheduler as soon as a contactless card or device was detected and until the contactless processing was complete. Unfortunately this only saved 10 to 20 milliseconds.
At this point we were down to around 150 milliseconds but we still felt far from our goal of less than 100 milliseconds and we already expended a lot of effort to reach this point. We did some looking through the code we had authored ourselves and found nothing obvious. One technique that has always proved fruitful for me is to read documentation. Often hiding in the plain sight of documentation are solutions to common problems, which are especially useful when one is trying to avoid reinventing the wheel. There in the 400 plus page documentation for our secure processor was a section titled “Instruction Cache”. The documentation was just a listing of the associated registers and the function of their bits, but I knew that CPUs use caching extensively for data and instructions to improve performance because even though RAM access is fast it isn’t free. Using the appropriate registers I was able to see that the instruction cache was not enabled on our CPU by default. Enabling the instruction cache with just a few register bit manipulations reduced the cashless transaction time by roughly 40 percent, well within MasterCard’s required limit.
This story presents just one of the challenges we faced building Clover Mini and Mobile, but overcoming this challenge was a critical step and one that demonstrates the power of persistence in engineering.
My name is Jacob Abrams, I’m an engineer at Clover since 2013 and I’ve been working on Android since 2008. I currently work on the Device OS and Platform Team at Clover.
The Device OS and Platform Team stabilizes and customizes the Android OS on Clover devices. We also build and maintain the secure processor platform that powers payments and we provide device APIs to other Clover teams and third party developers enabling them to build applications that run on Clover devices. Our team works closely with many other teams at Clover such as the Payments team and POS team.