Almost all software designs naturally incorporate some aspects of component separation. Whether intentionally designed or accidental, components will naturally encapsulate functionality and separate behaviour in complex systems. This separation is particularly evident in embedded software design, where the code behavior separates to mirror the underlying behavior of the physical hardware.
Separating code not only helps simplify system complexity, but also lends itself to Agile development—an increasingly popular methodology for development environments. Agile helps accelerate time-to-market for products and services, often in iterations that evolve over time.
In Agile-led embedded-design projects, each component is developed in a series of sprints. Consequently, the overall system will have a set of working features, while other components are in development. System complexity will therefore map to a configuration problem.
Although component-based design opens the door to many benefits, the separation that occurs in development projects can create its own challenges. This is why embedded software design engineers are increasingly using version-management tools to maintain control over component-based projects. Before describing the role of version management in this context, it’s important to understand the benefits and implications of separating code.
Separating Code Into Components
Any developer, tester, or project planner will know that breaking a problem or task into more manageable pieces quickens the path to success. Have you ever written code and had to revisit it six months later? It can take a while to wrap one’s mind around the code’s behaviour. The larger and more complex the behavior, the more effort is required.
Separating features and behaviors can free up conscious efforts to focus on one problematic aspect of behavior. Formalizing this separation at the point of design can help project planners more accurately estimate the Agile tasks or stories, allowing developers to focus on implementing the specific behavior and testers to test that behavior.
Formal separation of code is, in essence, modularization—a key factor for larger projects. Modularization will likely occur at many different levels, even using modules to encapsulate the behavior of whole sets of other modules. So, if modules are separations of code behavior, then what are components? And when do modules become components?
A component is a module that has a defined interface, allowing it to communicate with other peer components (Fig. 1). This occurs either directly by sharing the same interface, or indirectly via a framework (the framework is usually a component unto itself). The method of communication, which also is encapsulated, varies from a simple passing of data (encapsulated data or an object) to the use of a serialised data stream or message queue.
Without components, software reuse is typically unmanaged and relies on fragments or snippets of code from other projects. This may seem like a good idea at the time, as each code snippet’s behavior is known to work. In reality, though, the copied and pasted snippet has no history in terms of linking it to its source, and will often get locally modified or tweaked. If a bug is found, the fix is unlikely to reach all projects that use the snippet.
Separating a component’s source code allows it to be independently developed, managed, and tested. Thus, the component can be reused within a similar product family or product variant.
The Role Of SCM
Managing a component in a software-configuration-management (SCM) system solves many of the aforementioned issues. The component’s history can be traced, which makes it easy to identify in all projects in which it’s shared. The complexity now shifts toward the management of components. This includes different versions along with patch and release cycles.
If components are shared across multiple projects, it’s often beneficial for the component’s lifecycle to be independent. The only exception is if all projects are released and managed within one lifecycle. With an independent lifecycle, a component can release new functionality and patch updates without affecting the projects that rely on the component. Then it’s up to the project owner to use the correct configuration of each component version.
Each project will need to effectively subscribe to its required components, as well as reference a specific release. The project remains isolated even as new component versions are released—it will only adopt newer releases by updating the subscribed components (Fig. 2). Not imposing component updates on a project is vital in the embedded software development world, because often-specific versions of software components are tied to specific hardware releases.
Such version management turns management of project variants into just a configuration, isolated from the dependent components. This simplifies the scope of testing to merely the configuration and not the components. As a result, it ensures that the deployment of bug fixes within a component will reach all intended projects.
Version-Management Best Practice
Overall project success relies heavily on a robust version-management system. When evaluating such tools, some simple questions can be asked to ensure good support for component-based development:
• Can the build environment be quickly populated with the correct set of components, configurations, and source code?
• Can all components be located, and subsequently identified in terms of their versions?
• If a bug is found in a component, can it be fixed in isolation, tested, and then guaranteed that the fix is applied to every instance?
When armed with the right version-management system, a component-based approach to embedded software development (whether or not that involves use of the Agile methodology) can help designers maintain better control over complex projects. In turn, it facilitates getting the project to market on time. If an organization’s version-management tool offers good support for these capabilities, then development, test, and release processes will undoubtedly be built upon strong foundations.
Paul Allen is a specialist in the embedded systems market for Perforce Software.