Sunday, January 13, 2019

Refactoring legacy embedded code

Recently we had to add new functionality to existing embedded software. When we analyzed the code, in many cases there were little to no documentation and code smells were all over the place. It was difficult to use existing functionality because it was very hard to understand. But replacing them with new clean code was not an option becaue the functions were used in many places. We would have to repeat costly HWIL and field tests, setting us back for months.

We decided to leave the existing functions but added comments about our suspicions, marked them as "deprecation candidate", wrote new ones that were only called from new code. We also heavily documented our additions. This approach is similar to changing public APIs: You rarely delete, you usually add and mark old code as deprecated so that existing software continues to function with the new API version.

To be able to update design/architecture, we first had to improve comprehensibility of existing code by removing clutter with these steps:
  1. Renamed variables, functions and classes to make them easier to understand.
  2. There were a lot of repeating code due to creation of new classes by copy-pasting old classes. We moved common code to utility classes/namespaces which made classes a lot lighter.
After performing the above two steps for a couple of months, we had a good grasp of what the code was trying to do. Think of it as discovering detailed requirements. Then we deleted dead code and out of date comments. Gradually we came up with simpler design ideas that would satisfy requirements.

No comments: