Watching the Olympics this past summer was quite exciting. I enjoyed seeing athletes at the peak of their performance and multiple records broken in many sports. What we don’t see is the years of practice and work behind this excellence. These athletes work at the technique, strength, endurance and mental attitude of winning. To me, this is no different than the work that goes on behind the scenes of a new chip introduction or for that matter, any new product introduction.
Finally, nine months after the next-generation SoC project was kicked off, the first prototype board has finally arrived! There are just six months left to get Android and Linux up and running. Since Android should take full advantage of the latest hardware additions, let’s make sure we get it ported as quickly as possible. Unfortunately, it is not that easy. Before you can care about porting your OS and developing the drivers for your special hardware, you have to deal with the boring, but necessary initialization of the hardware. This is typically done by a so-called boot monitor. A boot monitor is a software program in ROM that gets launched after pressing the power-on button on your hardware. Even though the boot monitor is not a large piece of software (compared to the OS etc.), it provides complex functions and interacts with many hardware peripherals. As an example, the classic minimal functions of a boot loader are given below:
Debugging software by adding printf statements in the code is not considered the cleanest and most advanced debugging approach, but when you are searching for the root cause of a problem you often look to the debugging method you are most familiar with and can apply easily. The hurdle of setting up a complex debug or trace tool is counterproductive when dealing with schedule commitments and printf is the fallback method which almost always works as long as you are able to modify and rebuild the software source code. I was recently talking to a software engineer who was working on driver development for a new WiFi chip. When I asked how he is debugging the driver, he answered, “I am doing printk debugging” (printk: debug messages inside the Linux kernel). The reason behind his decision was to avoid the complicated steps involved in setting up a kernel debugger such as kdb. Luckily, the entire Linux kernel is full of printk messages; just like each and every module of the Android source code is instrumented with “log” messages. The beauty of this kind of debugging is that it can be used to expose the semantics of the software and identify what the software is actually doing. Instead of tracing functions like foo and bar you get useful information such as, “Probing device returned false!” message. It becomes immediately clear what is going on, even if the code has been written by somebody else. However, there are limitations, drawbacks and side-effects to consider:
Developing embedded software often requires a physical target to run software for the purpose of validation and debug. As is often the case, the exact hardware may not exist yet. The software developer is faced with a few choices: explore using models, use a previous generation board or consider another solution where the exact hardware is available. Most software developers generally try to find a solution that is “good enough”, yet pragmatic, which serves their time and cost requirements. For example, in order to work on the Linux scheduler for big.LITTLE processing, software developers used “old” hardware such as those presented at the recent Linaro Connect event. Software developers gave an example of this exact scenario and how they leveraged “old” hardware to complete their Linux scheduler development for big.LITTLE processing. Here, the performance asymmetry of an ARM Cortex-A15/A7 MPCore big.LITTLE processing system is emulated using an off-the-shelf Cortex-A9 MPCore board In the case of big.LITTLE processing, two CPUs with different performance characteristics are combined together, while the Cortex-A9MPCore has common CPUs with identical performance. To mimic big.LITTLE processing on the Cortex-A9MPCore, asymmetry is emulated by running a so called “cycle stealer” software process on one of the Cortex-A9 CPUs, resulting in reduced processing bandwidth on the second CPU. This solution creates a set up that mirrors the expected big.LITTLE processing capabilities and the software under test takes longer to run on one CPU, than it takes for the same software to run on the second CPU. Is it cycle accurate? For sure not, but this is certainly a pragmatic, “good enough” solution to start optimizing the Linux kernel scheduler.
How to win over the embedded software developer, their customer and their boss.
In the last month, I had the opportunity to get some hands-on experience with hardware virtualization and hypervisors. My knowledge so far on this has been mainly limited to what I could read about it and what other people are saying about it. However, the PowerPoint slides I’ve seen leave a lot of white fog between the bullet items. This didn’t make me feel very comfortable talking about this topic myself; but, there was no escape. Hypervisors play an increasingly important role for system designers in context of supporting multiple guest operating systems on the same device, or taking advantage of ARM®’s new big.LITTLETM processing. The fog is not all gone, but let me provide you some insight on what I found out. As a disclaimer, I’m not going to (and I cannot) write an expert almanac about all the aspects of virtualization covering Xen, VMWare, etc. Instead, I’m going to focus on my personal experience that I believe will be relevant to you as well. This post is the starting point for a series on this topic in this blog.
Transaction-level models are the main building blocks of virtual prototypes, which are used for early software development. In my last blog post, I briefly introduced the different kinds of software tasks and the implications for models. Today, I want to talk about the modeling requirements for early SoC bring up. As I mentioned, understanding the software requirements correctly provides two clear benefits: 1) it makes modeling easier through a more focused application and 2) it increases the value for the software developer through more tailored modeling capabilities such as debug features.
Virtual prototypes are essential to effectively debugging a system and still meeting market windows.
I am involved in discussions about adoption of system-level technologies a lot. System-level design in EDA and embedded software are always intertwined as the software is the main factor changing when going beyond RTL. Given that system-level design technologies expand beyond the traditional realm of hardware, their adoption is non-trivial for project teams. The overall situation reminds me more and more of Malcolm Gladwell’s “Outliers”: for success several factors have to fall in place together, not all of them in our control.