It is a very simplistic view, but, broadly speaking, there are two ways to design an embedded software application [or pretty much anything really]: either top-down or bottom-up. There are pros and cons of each approach and it is hard to say, in the general sense, that one is better than the other.
So much for design, but how development is approached is another matter …
Software design is not a topic that I talk about much. This is not because I have no experience in that area – I have been designing software all my adult life. It is simply that, in recent years, I have worked for a company offering a number of tools and IP for embedded software development, but not design. And they pay the bills. However I think it is safe to say that most people tend to favor top-down design. First define the overall functionality of the application, then break it down iteratively into simpler and simpler functional units.
There is some logic in doing implementation top-down – following the logic of the design. This involves creating the high level components first – commonly the user interface [UI] – with these functions calling “stub” functions which do not do anything [or nothing useful anyway]. In my experience, this approach has a distinct psychological benefit, as getting the UI to work first makes the device appear to be doing something, which feels like progress.
In reality, top down implementation is rarely possible in the true sense, as lower level software – operating system, drivers etc. – need to be in place before anything else can run. But there is a more important reason why top-down implementation may be troublesome: all embedded systems have limited resources. Those limitations vary from system to system, but, ultimately, there is a fixed amount of memory and a specific amount of CPU power available, along with a power budget. The difficulty with a top-down implementation approach is that, if resource limits are hit, it may not be apparent until quite a late stage in development, when there is little time to do anything about it.
A bottom-up approach to development enables the software to be constructed as a series of increasingly complex components. Each component can have its resource utilisation measured and optimized straight away. This results in less possibility for surprises late in the project. Every engineer needs to be equipped with the appropriate tools and skills:
- Memory footprint is normally easy to read from the linker map. This is a zero cost option, that simply requires the engineer to be aware of the requirement.
- Measuring the performance [speed] of software is more challenging. An instrument like an oscilloscope was traditional, but is a rather frightening option for many modern developers. Using CPU tick timers or instruction-acurate simulation tools are other options.
- Power consumption is an increasingly important facet of embedded software development. Power measurement tools should be available to enable developers to optimize the power profile [CPU voltage/frequency, peripheral shut-down and standby/hibernate usage, for example] to be fine tuned.
I am sure that there are other perspectives and arguments against my proscription. Comments, email and communication via social networking are all welcome