Table of contents:
Revving up production to meet increased demand is an obvious goal of manufacturers – especially in a way that is timely, effective and secure. Unfortunately, often the existing hardware and software are unable to handle increased workloads – especially if a company is still using legacy code. Read on to learn how organizations in the manufacturing industry can overcome this hurdle, modernize their infrastructures and ensure their operations are future ready.
Balancing increasing functionality with stability
As the complexity of a device’s functionalities grows, code development can become unstable and unreliable. That’s because increasing complexity can lead to unpredictable behavior during development, which hinders progress and impacts device reliability. Other issues that teams need to deal with include:
Low levels of abstraction can increase dependencies throughout the code.
The absence of higher-level abstractions can result in a tightly interdependent codebase, thereby complicating management and extension.
Bug fixes often cause issues in seemingly unrelated parts of a device.
Fixing bugs frequently could introduce new issues elsewhere due to a tightly coupled codebase and lack of isolation.
New functionalities may be hard – or impossible – to implement.
The intertwined nature of the codebase could make it challenging to implement new features, which would hinder development efforts.
Adding new functionality could jeopardize other parts of the codebase.
Integrating new features carries a high risk of destabilizing existing functionalities due to extensive dependencies.
No automatic verification.
Manual verification is time-consuming and prone to errors, which slows down the development process.
All of the above result in long and complex release processes for new firmware versions. For one thing, releasing a new firmware version would involve numerous manual steps, including extensive manual testing and validation, which would likely be prone to errors and delays. Furthermore, a lack of automation in the release process would require significant time and resources, further slowing down development cycles and delaying time-to-market.
How to ensure a codebase can be future-ready?
1. Analyze your existing codebase to fully assess the current operation and structure of a device and identify key problem areas.
2. Review existing documentation, in detail, and fill in gaps through stakeholder engagement to ensure comprehensive understanding
3. Design a modern approach for the newest firmware version.
4. Develop a new architectural design emphasizing modularity and maintainability to support future development.
5. Plan for domain knowledge transfer sessions – essential for developing new firmware effectively
Updating legacy hardware and software – best practices
Clearly define the application architecture using Model-View-Presenter (MVP).
- Adopt the MVP pattern to separate business logic, presentation and data handling – this will improve maintainability.
Rewrite code with automatic testing and separation of concerns in mind.
- Restructure the codebase to ensure distinct responsibilities for different components – this will enhance testability and reduce side effects.
Implement unit tests in the application firmware.
- Establish a suite of unit tests to verify component correctness – this will improve reliability and regression detection.
Split the code into distinct modules.
- Divide a monolithic codebase into smaller modules, each encapsulating specific functionality – this will reduce dependencies and enhance reusability.
Deploy the application using modern project structures with a Build system.
- Utilize Meson or Cmake for a more efficient build system – this will strengthen dependency management and streamline builds.
Make abstractions easier to implement and develop with the help of C++.
- Leverage C++ features to introduce higher-level abstractions – this will simplify the code and improve maintainability.
Conduct comprehensive knowledge transfer sessions.
- Organize multiple sessions to ensure your team fully grasps the project intricacies – this will support the effective development of new firmware.
Implement a traceability system for requirements.
- Establish a system that ensures traceability of requirements, facilitates easy mapping of releases and features to exact specifications and enhances verification and compliance processes.
Conduct weekly technical meetings to share status updates and clarify any open matters.
- Organize regular calls to encourage continuous communication within the team – this will ensure information is shared and help to resolve any open issues promptly.
The challenges of updating legacy hardware and software
Delivering clean code
An important hurdle to overcome has to do with the code itself, which must be cleaned to make it easier to change and verify. Refactoring the codebase removes redundancies and improves clarity. Doing this will make it easier to adjust the code and lead to efficient verification. The other result is increased interoperability and flexibility. Regardless of the exact nature of a project, it is important that any upgrade to code should facilitate further changes and development, including the functionality of product features.
Empowering the architecture
Developing an intuitive human-machine interface (HMI) that presents complex information in a clear and accessible manner – even on small screens – is paramount. So too is the ability to create new applications on existing hardware. This means the architecture needs to be able to share and update the board support package (BSP) between different applications, while encapsulating business logic within the MVP-based application framework. This approach facilitates the reuse of hardware and software resources and simplifies the deployment of new applications.
Facilitating changes in hardware
Development teams will often need to simplify hardware compatibility adjustments through modular design. In this way, any hardware changes will only require modifications to the BSP module. Design should ensure that changes in hardware that do not impact the overall functionality of a device and can be accommodated with minimal code adjustments, which will streamline the process of hardware updates and compatibility fixes.
Developing new applications with a new BSP
When carrying out an update, it is important to facilitate the development of new applications with new BSPs through modular design. Leveraging modularity to reuse existing modules in new devices eases the development of both new applications and new BSPs. This approach accelerates the implementation of new devices by utilizing proven components and reducing development time and complexity.
Results from successful hardware and software updates
Improved stability: A refactored codebase, modular architecture and comprehensive testing lead to a more stable and reliable reduces the frequency of bugs and unintended side effects from changes.
Easier maintenance: With modular code and better abstractions, maintenance is more straightforward.
Enhanced development speed: Streamlined processes and automated testing have accelerated the development and integration of new features – with reduced dependencies.
Better testing: Automated unit tests ensure that new changes do not break existing functionalities and catch regressions early in development cycles.
Increased reliability: Higher confidence in changes and updates due to comprehensive, automated testing and verification processes.
Scalability: Easier to add new features and support future growth.
Boosting operations with the right technology partner
Whether it’s building on Industrial 4.0 advancements, implementing emerging AI and data solutions or taking factory operations to the Edge, device manufacturers have a range of options – and challenges – in front of them. Our embedded systems experts have a proven track record of supporting innovation and accelerating development – that’s one of the reasons companies team up with Software Mind. If you’d like to discuss your embedded goals and learn how we can help you achieve them, get in touch by filling out this form.
FAQ
When increasing device functionality, what are some issues engineers need to be aware of?
The biggest issue is that code development can become unstable and unreliable. Additionally, low levels of abstraction can increase dependencies throughout the code, meaning that it may be difficult to implement new functionalities. Even if successful, adding a new functionality could put other parts of the codebase at risk. Bug fixes often cause issues in seemingly unrelated parts of a device.
How can I ensure a codebase can handle future development?
Analyze your existing codebase to fully assess the current operation and structure of a device and identify key problem areas. Next, review existing documentation and fill in gaps through stakeholder engagement to ensure comprehensive understanding, design an approach for the newest firmware version. Once an approach has been established, develop a new architectural design that focuses on modularity and maintainability to support future development. Additionally, plan for domain knowledge transfer sessions – essential for developing new firmware effectively
What should teams keep in mind when updating legacy hardware and software?
Clearly define the application architecture using Model-View-Presenter (MVP), rewrite code with automatic testing and separation of concerns in mind, implement unit tests in the application firmware, split the code into distinct modules, deploy the application using modern project structures with a Build system, make abstractions easier to implement and develop with the help of C++, conduct comprehensive knowledge transfer sessions, implement a traceability system for requirements and conduct weekly technical meetings to share status updates and clarify any open matters.
What are biggest challenges that come with updating legacy hardware and software?
Certain unique challenges could arise given exact project requirements, though there are some challenges which are somewhat universal. One is delivering clean code. Teams will need to refactor a codebase to remove redundancies and improve clarity. Another challenge involves empowering the architecture. It is crucial to develop an intuitive human-machine interface (HMI) that presents complex information in a clear and accessible manner. A third hurdle is facilitating changes in hardware, which can be overcome by simplifying hardware compatibility adjustments through modular design. A last challenge concerns developing new applications with a new BSP, in particular, leveraging modularity to reuse existing modules in new devices eases the development of both new applications and new BSPs.
About the authorRafał Jasiński
Senior Embedded Software Engineer
A senior embedded software engineer with over five years' experience, Rafał has supported global organizations across sectors. An avid follower of embedded-related trends, he's keen to integrate emerging solutions into software development life cycles. A passion for innovation is matched by a commitment to quality and attention to detail, which has made Rafał a dependable technology partner for his fellow embedded specialists and clients.