Your browser is no longer supported. Please upgrade your browser to improve your experience.

When you’ve built a product that will be sold and used for five, ten or thirty years, accumulating technical debt with legacy code seems inevitable.

But depending on how you manage your codebase and technical debt, they don’t need to be a barrier to your product remaining feature-rich, relevant, and secure.

Still, what do you do if you’ve already got a product on the market holding back your growth ambitions?

It depends on your business case and what’s essential in terms of profit and risk, but you have options. So, let’s find out what those options are.

In this blog post:

Refresher: what are technical debt and legacy code?

Technical debt and legacy code are not the same thing but are closely related. Both technical debt and legacy code can impact overall product quality.

Technical debt is an approximate cost of how much you need to invest in making something (software, architecture, both) maintainable again. In this context, maintainable means you can make changes to the software with ease.

Like real debt, it accumulates over time and becomes more expensive to deal with the longer you leave it unpaid.

Legacy code is software in a product that has a risky amount of technical debt. It might have other issues that affect what is known as perceived integrity and conceptual integrity.

Perceived integrity are the elements of software you see and experience, such as whether it’s reliable or usable.

Whereas conceptual integrity are the elements of software that you don’t see but helps ensure that what you experience as a user or customer is reliable and pleasant. Whether software is maintainable, habitable and scalable affects conceptual integrity.

  • Maintainable software has clearly written code. It has a robust test framework, and it’s easy for developers to understand and work on.
  • Habitable software has a clear structure. The structure makes it easy for developers to change the codebase.
  • Scalable software is structurally sound. Its architecture enables new features and product evolution.

When you have software with high conceptual integrity, it’s easier to add new features, retire old ones, and fix bugs and security issues.

 

 

Bluefruit's Quality Tree

Five signs you have technical debt in embedded software

The following list is not exhaustive, but here are warnings that you’re dealing with technical debt caused by legacy embedded software.

(Note that many of these can be traced back to poor conceptual integrity in your codebase.)

1. Your product can’t take advantage of the latest anything

Not being able to make use of new things shows itself in a variety of ways. It could mean that:

  • Your product is unable to integrate with newer systems at a software or hardware layer.
  • Your embedded software can’t take advantage of more recent software programming techniques or algorithms.
  • Your product can’t use the latest version of connectivity protocols like USB, Bluetooth, Wi-Fi, RFID, mobile and so on.

And not being able to use the latest versions of the above creates security issues for you and your customers. For you, there’s terrible PR when people hack your products, whether white or black hat. For your customers, bad PR can rub off on them, depending on the nature of the product and how wide the bad press is. Meanwhile, your customers are left waiting and wondering if their systems will be compromised.

Plus, efficiency challenges become costly for customers if their kit isn’t making the most of the latest best practices. With customers unable to upgrade their equipment as they need to for their strategic digital transformation and sustainability goals.

Finally, your market presence hurts from not being seen as market-leading because you can’t release new products.

2. Your internal software team has a “complicated” relationship with your code

Signs of a complicated relationship can include:

  • Onboarding new team members is a complex and challenging process because working with your codebase is not simple. (And hiring any junior team members is becoming less and less appealing.)
  • You only have one person who knows everything about your codebase. This fact often keeps you up at 2 am, wondering what will happen if they’re no longer there.
  • People are leaving your software team because they find working with your code is like traversing a waking nightmare every single workday.

Without the right people, it becomes impossible to keep software updated with even the bare minimum of fixes, further adding to your technical debt.

3. It takes an alarming amount of effort to work on your codebase

If you do have a team managing to work on your software, what you’ll find is:

  • It’s costly to work on the software because of how long it takes to start coding for it.
  • The time needed to work on software can be partly explained by surprises in the code base, stifling productivity and general pace.
  • To accommodate those time issues, your team will have to inflate any estimates for how long work will take. (Plus those estimates will be less accurate, because of surprises.)

And with such productivity issues, again, it becomes unclear whether those critical patches that need to happen will happen.

Your bug lists might be so long that the cost of fixing them is substantial. Even with a substantial budget, poor maintainability and habitability can make fixes unworkable.

4. New features? What new features?

Despite there having been “big plans” in the beginning, your product has been unable to have any new features since the first few years of l­­aunch. It’s frustrating for you and your customers, but there’s just no way to scale the software any further.

Your team’s reached the ceiling of feature additions, and marketing and sales have given up making any promises to customers.

Of course, if you have any of the other three previous signs of technical debt, this scenario was inevitable.

5. Sideswiped by hardware

Not a software sign exactly, but if your software had been a minor headache while you had the right hardware for it—your product could have been fine. Maybe no new features, complex patching, but okay.

And then your product’s old hardware platform is being phased out, and there’s no way your antiquated software is going to work on it. Perhaps there are no more board support packages. You’ll have to switch microcontrollers or processors which is no easy task if you’re affected by the first few signs.

It doesn’t even have to be phasing out hardware. The worldwide chip shortage has sent many companies looking to port their code to alternative microprocessors as supplies dwindle.

Suppose you’ve been experiencing trouble with the previous four signs in this list. In that case, you’ve already got a drastically reduced chance of successfully handling a hardware challenge.

How do you end up with technical debt?

The causes behind the above five signs of technical debt in legacy embedded software are varied.

Choices made during the original development

What kinds of choices? Choices like deciding whether to invest in software programming practices that put quality first and support solid conceptual integrity.

These choices are often seen as expensive because they might appear to slow down time-to-market in the short term. However, they can ensure you maximise profit over a product’s lifetime sales in the long term.

No time, skills, or capacity

You can do some activities to mitigate the problems with legacy software (and I’ll talk about some of them further down).

But if the team doesn’t feel like they have the time in their schedule or the capacity or skills in-house, backlog items might get pushed further and further back. Holding back on making these changes helps technical debt to creep in.

It’s too expensive to make change

Architectural decisions are expensive to change. So, making new design decisions are costly, and you need a good reason to invest and make those changes.

Yet you have a problem when the decision to not make change becomes so entrenched that you end up with technical debt building up to unmanageable levels.

So, what can you do to cut through this technical debt?

Three options for cutting technical debt in your legacy code

The following options depend on your organisation’s circumstances. Still, understand that there is always something you and your team can do to tackle technical debt in legacy code.

High effort: go all in and upgrade

Give your team the time and space necessary to make this work. You can also hire an outsourced embedded software team to help you meet any skills or capacity gaps you have.

Making the needed changes means you benefit from:

  • Raising the software team’s productivity;
  • Stronger security;
  • Software that’s ready for new features;
  • More recent software programming techniques and algorithms;
  • A product that integrates with newer systems at a hardware and software layer;
  • Software people want to work with;
  • Easier team onboarding.

And should you also decide to invest in updating the user experience (UX)? You’ll also end up with software that can genuinely delight end users, reviving product marketability once more.

You’ll only feel these benefits if you raise the software’s conceptual integrity while changing and upgrading.

Improving integrity means you reduce the risk of ending up where you started.

And going all in means you end up with software that’s an asset rather than a liability.

The downside is that you will have a period where version two won’t be adding value to the business. But working in a Lean-Agile way could help keep this period as short as possible.

Mid-level effort: prioritise software component upgrades that will stop the most pain

There is a real need to identify which component changes will make the most significant improvements to your legacy code. The changes that will reduce some technical debt make it more tolerable in the short and (hopefully) long-term.

Sometimes the code is so poorly architected that there are no clear components. So, it’s worth taking time out to split it into them, decoupling where possible and appropriate along the way.

Once the software is in tinier components, it will make it easier to handle upgrades that you’ve identified will benefit you the most first. Doing this is especially helpful with retrofitting, like keeping the operating system but upgrading a specific protocol and so on.

Being pickier means your developers can get back to adding value to the business sooner.

But this is only going to work if the team works consistently to tackle technical debt before problems can balloon further.

Low effort: make minor improvements where you can

Opting for this approach means taking small steps to make working with the software less terrible. You could get the team to write unit tests to help reduce the time it takes to handle bugs.

And when you add new features, your software engineers could improve the software architecture where they add features. At least then, it will make dealing with those newer features easier.

Graph showing how technical debt affects how hard it is to add new features to software.Deciding to make only slight improvements is just a delaying tactic—you’re going to need to tackle the technical debt at some point. Plus, it will still be difficult, slow and expensive to do.

Find a way through

It is hard making the right choice when it comes to handling technical debt in embedded software. The choice you make depends on many factors that vary from organisation to organisation, product to product, team to team.

Should you need help assessing your course of action, Bluefruit Software can help you find what will work for you—so get in touch.

Did you know that we have a monthly newsletter?

If you’d like insights into software development, Lean-Agile practices, advances in technology and more to your inbox once a month—sign up today!

Find out more