Android hardware-software design using virtual prototypes - Part 2: Building a sensor subsystem
Sensor subsystem firmware development
The sensor firmware communicates with the Linux sensor device driver via a so-called Inter Processor Communication Module (IPCM). This peripheral is located in a shared memory region and is accessible from the main CPU and the embedded controller. The IPCM can send out notifications through interrupts when a new message for the main CPU or the controller has arrived. For this purpose, the IPCM contains some control registers that allow the sending processor to notify the receiving processor. The sensor subsystem controller firmware receives commands such as “read accelerometer” from the main CPU. Therefore, the main CPU writes the required command ID into the IPCM and notifies the controller. The controller interrupt handler wakes up, reads out the command from the IPCM, determines the sensor value from the GPIOs/I2C, and provides the data back into the IPCM. The firmware for the ARM Cortex-M3 microcontroller can be developed using a standard tool chain such as GCC, DS-5/RVDS. The resulting binary image can be loaded directly into the memories using the VP tool infrastructure. Afterwards, the software developer can use his favorite debug tool along with the embedded controller CPU as shown in Figure 6.

Click on image to enlarge.
Figure 6 - Using standard Lauterbach TRACE32 for software debugging on a VP
A VP integrates a debug server that manages the connection to 3rd party debuggers such as gdb, Lauterbach TRACE32 and ARM’s DS-5. In a multicore system, even multiple debuggers can be connected in parallel. The connection is performed in the previously introduced stop-mode. When the debugger suspends the simulation, the entire simulation is halted and not just the core. Thus, no watchdogs expire or interrupts executed during the period of suspension. This mode enables repeatable debugging due to the fact that debugging is non-intrusive and therefore deterministic.
Beyond what a debugger exposes, the VP complements the software debugger with extra visibility into the system peripherals, their registers, and signals as shown in Figure 7.

Click on image to enlarge.
Figure 7 - Virtual Prototype Analyzer
This extra visibility is helpful for any kind of low-level software development where large parts of the software program's peripheral registers react to interrupts etc. A VP also allows setting watchpoints on system aspects (e.g. signals) which are typically not visible to the software developer, making it possible to set a watchpoint on the interrupt line of the IPCM. Thus, the interrupt handler debugging can be started before the CPU even enters the interrupt vector. Wrongly masked interrupts are much easier to debug with this level of control.
A challenge with firmware development for a subsystem is typically the interaction with the main CPU and the off-chip interfaces. Since the firmware needs to react based on commands from the Linux driver running on the main CPU and needs to deliver data received via GPIO, it is hard to validate the firmware without having this interaction. A VP provides some helpful capabilities in this case. Through a TCL-based scripting interface, the user can poke data into the IPCM, GPIO, and/or I2C at defined points in time. Thus, the VP user can easily create deterministic and repeatable test and debug scenarios that simulate the external environment without bringing up the main CPU Linux and drivers. This way of debugging facilitates firmware bring-up since no additional complexity is introduced and also reduces testing complexity. All unit tests for the sensor subsystem can be executed in isolation without introducing potential fault sources through the main CPU, Linux OS or drivers etc.
Linux driver development for the sensor subsystem
As a next step, the Linux device driver will need to be developed. This Linux driver allows the upper Android software layers to query data from the sensor. The driver itself will communicate with the sensor firmware of the subsystem through the shared IPCM. Since Linux runs on an application CPU such as the ARM Cortex-A9MP core, a platform that is sufficiently equipped with the CPU and peripherals is needed. For this reference platform, we have chosen the VDK for the ARM Versatile Express system as a development vehicle for our Linux driver. Here, we can reuse the Android and Linux configurations, which are available from communities such as Linaro. This makes it easy to get Linux and Android up and running, which is needed to start our driver development for the sensor controller subsystem. For this purpose, the sensor controller subsystem will be integrated into the VDK as a “LogicTile” virtual daughterboard. Similar to the hardware, the VDK provides an easy mechanism to configure the CPU and the daughterboards, as shown in Figure 8.

Click on image to enlarge.
Figure 8 - VDK Customization
The daughterboard will be configured with the address of the IPCM in the shared memory space as well as the interrupt lines between the IPCM and the Vectored Interrupt Controller used by the Cortex-A9 CPU. After the configuration, the software developer is able to build a multicore VP that embeds the Cortex-A9 application processor as well as the Cortex-M3 based sensor control subsystem.
The driver for the sensor uses the “syssfs” pseudo file system to expose the data from the sensor to the user space (Linux applications/middleware). The code for updating a sensor value does prepare the IPCM with the required request command, sends the message, then the driver waits for the acknowledgment of the sensor control subsystem. The acknowledge flag is set in the driver’s interrupt handler so the kernel can schedule other tasks while waiting for the data. In order to ease debugging, kernel debug messages (printk) have been placed in between the lines as shown below:

Click on image to enlarge.
Example 1 - Sensor Driver Code Excerpt
When launching the VDK, the user is able to interact with the system through a VGA framebuffer console which is connected to the VDK’s color LCD controller, keyboard and mouse interfaces. As shown in Figure 9, the software developer can issue commands such as reading out the sensor values through the Linux kernel “syssfs” pseudo file system. The two console terminals visualize the debug messages that are coming from the sensor subsystem, as well as from the Linux kernel.

Click on image to enlarge.
Figure 9 - Sensor device driver testing
In a VP, the number of UARTs is unlimited, which is helpful when integrating many software entities and their layers, but also introduces the challenge of understanding the sequencing of the different debug messages. Messages from the sensor control versus messages from the interacting sensor driver require separate analysis in the order in which they occur within the system. The ability to track the sequence of events is supported by the built-in tracing infrastructure of a VP.
All debug messages are consolidated into a single data base, illustrated in Figure 10. The first two rows in the system analysis view visualize the points in time at which debug messages are issued from the driver and the sensor by drawing dots on the timeline. Each dot corresponds to a debug message that is exposed in the bottom area of the windows, displaying exactly when and in which order the messages are issued. This can be helpful when integrating and debugging multiple software entities that operate in parallel, such as in our example.

Click on image to enlarge.
Figure 10 - System Tracing
But even more visibility is provided by a VP. The IPCM interrupts between the main CPU and the controller can be traced along with the accesses to the shared IPCM registers. Next to that, the function trace of each CPU can be obtained. This allows for a successive top down debug flow for parallel software integration. A bird’s eye view allows for a quick assessment of the situation, in addition to the ability to drill deeper, uncovering more information and ultimately identifying the single instruction that accesses a register. This level of visibility is a crucial capability when dealing with low level software, especially on multicore systems.
A software debugger can be connected for Linux driver debugging in the same way (stop mode) as done in the previous section for the sensor control subsystem bare metal firmware. There is no need to setup support for a kernel debugger (kdb) or similar. The connectivity is established out of the box through the VP debug server, which is Linux thread aware for thread level debugging. We will further describe this next In Part 3 in this series on how to use Android’s Hardware Abstraction Layer to aid in integrating the sensor further up the device software stack.
Part 1: Why virtualize
Part 3: Integrating Android’s HAL
Achim Nohl is a technical marketing manager for Virtual Prototypes at Synopsys. He actively publishes technical articles, conference papers, and blog posts around the topic of developing embedded software using virtual prototypes. His specialty is bringing up firmware, drivers, and operating systems for the most recent CPUs and IPs. Achim holds a degree in Electrical Engineering from the Institute for Integrated Signal Processing Systems at the Aachen University of Technology, Germany. Before joining Synopsys, Achim has worked in various engineering and marketing roles for LISATek and CoWare.
References
1. Android SDK
2. Qemu
3. ARM Versatile Express
4. Linaro
5. HAPS Family of FPGA-Based Prototyping Solutions
6. Virtualizer
7. TI OMAP
8. Virtual Prototype Creation and Development Kits


Loading comments... Write a comment