My most life-changing decision

A little time ago, I tweeted this: “>50y ago, I was fixated on symmetry; decided to seek out beauty of asymmetry. Turned out to be most life-changing decision I ever made.” A couple of people suggested I expand this, and blog about it, which surprised me, but here goes:

I have no idea when I made this decision, but it must have been when I was quite young. I could’ve been 3 for all I know, but it seems unlikely. And, given the known shortcomings of human memory, the memory I have may not be what happened. I.e. what actually went on in my mind.

Anyway, I became aware that I was too fixed on symmetry. I loved squares, but only liked rectangles. I shied away from asymmetry, as an almost emotional thing. I recognised this too-fixed mindset as something undesirable, and decided to school myself to appreciate non-symmetrical things too.

This was a literal and metaphorical thing. I opened my mind to quadrilaterals without even one right-angle, but also to chaos and uncertainty. I broadened and opened my mental outlook sufficiently that, in time, I was able to become a software designer. I would’ve been too rigid otherwise; the Gods know what career I might’ve ended up in.

I have remembered this decision maybe half a dozen times in my life, but only this last time did I give it any serious thought. I have no idea what prompted it. It may have been something somebody said, or something I heard on the radio or TV. I have even toyed with the idea that it never happened at all, that it is just a reflection of my mental growing-up, as I began to entertain notions that didn’t originate with an adult. It seems possible, but I don’t think so….

The memory seems real to me. The effects of my actions enabled me to listen to (and enjoy) Indian singing, which uses notes that Westerners typically hear as dischordant. That’s just an example, but it illustrates the importance of the change in me as I sought out the beauty of asymmetry, and similarly scary concepts.

I would not be – not even in the smallest way – the man I am today if I had not had this realisation, and done something about it. Having spent a few days wondering, the most interesting thing (to me) is whether this really happened, and when. I think it did. By ‘feel’, I estimate my age to have been 5 or 6, but I don’t really have a clue.

P.S. One thing I am sure of: when I first had these thoughts, I did not think of them using the sophisticated and mature terms that hindsight gave me to write the above.

My most life-changing decision

Firmware – the tunnel at the end of the light

I think we have reached a point where the demise of firmware is clearly visible. It’s quite a way away, but now is the time to start planning, while there is still plenty of time.

Let’s be clear. If you still dream of 64k of contiguous RAM for your (application + RTOS + stack(s) + heap), then you write firmware. If your target hardware comfortably exceeds this, you write embedded software. [I know these terms aren’t universally agreed or understood, but this is how I’m using them.]

These days, fast 32-bit micro-controllers are available cheaply; RAM is the main limitation on what we can do with them. As the amount of RAM in micro-controllers increases, it will reach a point where they can support embedded software.

Embedded software is more mainstream than firmware. Applications run under grown-up OSs like Linux or Android. And they’re coded in modern languages that firmware target platforms can’t yet support. Like much modern software, embedded software is largely independent of its target hardware. It’s a different world.

When affordable micro-controllers can support embedded software, the need for firmware will start to decrease. Eventually, firmware will become a backwater, a small one. Before this happens, we firmware designers need to have expanded our skills into embedded software.

This means that we must embrace software design to a greater extent than we have in the past. Embedded software is less tolerant of, er, laxity than our smaller and simpler firmware designs. And embedded software is where the future lies. It’s what the tunnel in the title of this post leads to.

Today, firmware is a thriving discipline, and this will continue for some time. It will take a while before on-chip micro-controller RAM reaches the threshold needed to support embedded software (256k? 1M?). But when it does, the transition will be rapid, I think. Firmware will become a maintenance occupation. In my experience, many firmware-containing products stay in the field for ten years or more, sometimes a lot more. For as long as these products are supported, there will be a need for firmware designers.

So the end of firmware is visible, on the horizon, and we have years to prepare. Any improvement we decide to make in our design skills will benefit our firmware in the short term, as well as preparing us for the future. So this post is not a woe-ridden ‘the end is nigh!‘ sort of thing. It’s more like: forewarned is forearmed.

Firmware – the tunnel at the end of the light

The Guidance of Goldilocks

We are often advised to include just enough of this or that in our designs. It’s good advice. It doesn’t teach, it just reminds us to optimise, well, everything. Our development environments can often benefit from a substantial dose of just enough. Our designs too. Documentation. Our tools and methods, and how we use them, often cry out for some just enough. And don’t get me started on processes!

Take architecture as an example. Every design needs just enough architecture. Because projects vary in just about every way, just enough architecture for one is too much for a second, but too little for a third. Just enough architecture is the right amount of architecture for the project in question. It’s not a fixed thing that can be codified, followed and forgotten. Optimisation is a dynamic and continuing process. You need just enough of it, of course. 😉

Everything Goldilocks chose was ‘just right’, or just enough, in our parlance. This also embraces “Make things as simple as possible, but not simpler” (usually attributed to Einstein). I.e. Employ just enough simplicity.

Desperation can lead us to take a crude average and call it an acceptable compromise. Goldilocks is no such thing. It advises us to employ just enough up-front design, which is to say, the right amount of design. Given that this advice is offered to designers, it reduces to “Do your job right”. This is good advice, but a designer will do this anyway, so it’s a null command. This is why we stick with the phrase “just enough”. It means the same, but it evokes the spirit of the Einstein quote. It reminds us that too much design is sub-optimal, and too little design is sub-optimal too. Specifically, it tells us there is an optimum amount of design, which we should discover and apply. This optimum amount is not a theoretical chase after the perfect design (whatever that is). It is a practically achievable aim.

Repeat just enough to yourself at least once daily. But don’t restrict it to the amount of up-front design you should apply. Your design needs just enough documentation. The documentation should contain just enough detail, with diagrams that contain just enough information to maximise clarity. Your code needs just enough unit-tests to meet your needs. And so on. The Guidance of Goldilocks applies usefully at all levels, throughout your development environment. So, although it reduces logically to nothing, it still offers something useful. Good, eh? 😉

Porridge, anyone?

The Guidance of Goldilocks

Why does my firmware need … honesty?

There are some things that have been believed for so long, and so universally, we don’t think to question them. Mostly, this makes sense: we believe them because they’re right. But it isn’t true in every case.

The waterfall method of design is an infamous example. It took a carefully-applied dose of doublethink to do what actually worked, while still believing that waterfall was correct. We weren’t deliberately lying to ourselves or each other; we didn’t (consciously) realise what we were doing. And this is the sort of (dis)honesty I’m referring to. Intentional deception is very rare in firmware design, in my experience.

I think I may have spotted something of this kind. Let’s see if you agree. 🙂 Many commentators publish articles and books containing good and wise advice. [No irony intended: their advice is good and wise, as far as I can tell.] But they often seem to assume that we (designers) are all good (enough) at what we do, and that we want to get better at it. There are many working developers who do not meet these criteria. This matters because the advice often depends for its goodness and wisdom on its recipients (us) being both able and willing to take its recommendations on board.

Ego-less code reviews, for example, are often recommended, and with good reason. But some of us can only manage this some of the time, and some of us can’t do it at all. We’re human! We exhibit human failings. So ego-assassination code reviews are more common than we would prefer, with all the negative consequences we might expect. [Better not to review at all than this?]

I’m not attacking humans. What would be the point? 😉 But I do think the design practices we create and recommend should be suitable for real designers, not just for Vulcans or androids. I think there’s a point in that, and I think it may be one of those things we’ve accidentally ignored for too long. What do you think? Do I have a point? Are there other things we ignore, that we should look at more carefully and more critically? How about leaving a comment? 😉

“Who cares, wins.”

This blog post is the latest in a series that is longer than I expected it to be.:) Their main (intended) purpose is to stimulate discussion, so please leave a comment. Thanks for dropping by! [Find me on Twitter as @Patternchaser.]

Why does my firmware need … honesty?

Why does my firmware need … state?

State — that’s static variables in firmware-speak — is considered harmful by hipster designers. But they are as different from us as two software specialisations can be. They live on the Ethereal Plane. [Why do you think it’s called “Ethernet”? 🙂] They belong to different schools of magick from us, they cast different spells, with different intent, in their world of nets and webs. State introduces problems for them.

The arguments hipsters have put together to vilify state have merit, but many of their objections describe problems with state in the context of their Ethereal Plane. They do not affect us or our firmware. What remains after we discard these context-specific objections is that state represents a hidden parameter passed to every method when it’s called. No programming technique is without its downside, and that is a downside of state.

State is unavoidable in firmware. Our applications contain tasks that are continually executed. In between task invocations, the state of each task is stored. When that task is executed again, its state tells it where it has got to, and (therefore) what to do next. Unless we make radical changes to the way we design — and this is not impossible… — we need state.

Another objection to state is that it makes code more difficult to test. It does, but so does any addition to existing code. Instead of just testing a method once, we have to run each test in every possible state. This is not a reason for us to give up on state, but it is a reason to minimise it. An application with too much state becomes difficult to understand and, eventually, impossible to extend or maintain. Clearly, some caution is appropriate in our use of state. But caution is appropriate to all of our coding, whatever we’re doing. It doesn’t just apply to state.

Hipsters found problems, and traced them to state. At this point I think they adopted the belief that state is bad. Then they searched for justifications for their beliefs, and they found some. That some or all of their arguments are valid doesn’t change what they have done, and are doing. They seek to optimise their working practices for their world, and the work they do, which is eminently sensible. And for them, the bad points of state outweigh the good ones. For us, that is not necessarily the case, and we should resist being carried along with the tide, just because that’s what hipsters are doing.

State is not harmful, but it should be used with care.

“Who cares, wins.”

This blog post is the latest in a series that is longer than I expected it to be. 🙂 Their main (intended) purpose is to stimulate discussion, so please leave a comment. Thanks for dropping by! [Find me on Twitter as @Patternchaser.]

Why does my firmware need … state?

Why does my firmware need … architecture?

Every design has its architecture, but if your design is small enough, you may not need to consider it separately. I will qualify this heresy after I’ve defined how I use a couple of very important words.

Firmware — The operational program that runs on an embedded processor with significant resource constraints. Although fast 32-bit micro-controllers are now commonplace, 8 kBytes of RAM is quite normal, and 64 kBytes is undreamed-of luxury. Supported (and supportable) languages are assembler, C and C++, although the latter is rarely used. Resource limitations mean that firmware cannot support WinCE, embedded Linux or Android.

Architecture — Like “design”, “architecture” is difficult to define. It is a superficial overview of your design, but it extends down to the smallest details. Grady Booch said “All architecture is design, but not all design is architecture”. Architecture is the collected features — the significant ones — that define your design. But it is also the collected details that enable these features to be reified. Consider your design as a flower, and each significant feature as a petal. Your architecture must describe each petal well enough for it to be designed and built, but it must also describe how the features (petals) blend together to make a flower. At the detail level, even petal-attachment protocols may be needed. 😉

So why does my firmware need architecture? Like RTOSs (link), your firmware has architecture anyway, so “need” doesn’t really come into it. It has design too (link), which incorporates your architecture. In software, it is normal and desirable – if not mandatory — to consider the application’s architecture separately. This should sometimes be the case for firmware too. But, for the smallest firmware, the design is compact enough that splitting it into architecture and ‘the rest’ is one simplification beyond necessity. The whole is simple enough that it is acceptable just to consider its design (where that design silently embraces and includes the architecture).

You can tell if you should consider your application’s architecture separately by answering this simple question: Will my design be clearer and easier to understand if I split it into architecture and the rest? Just enough design applies to architecture too.

This blog post is the latest in a series that is longer than I expected it to be. 🙂 Their main (intended) purpose is to stimulate discussion, so please leave a comment. Thanks for dropping by! [Find me on Twitter as @Patternchaser.]

Why does my firmware need … architecture?

Why does my firmware need … humans?

Unlike the other posts in this series, human influence on our firmware is not central to firmware development. However, it is something we all should look at, straight in the eyes, at least once. I’m going to assume that this is that once.

Snap question: Why does my firmware need humans?

Barely-considered response: We need humans as users and customers, because without them there could be no product and no firmware, and because they are the original source of the requirements our firmware must meet.

Just as science mostly ignores humans, or reduces them to impartial observers (nullifying any possible active influence they may exert), we tend to consider human firmware developers as logical and rational beings. Humans can, of course, act rationally and logically, but only sometimes. At other times we are anything but. This is our nature; let’s not deny it, or cry about it, but let’s admit it, and allow for it.

Our users and customers are outside our businesses, but humans within our businesses occupy quite a few roles in our firmware development ecosystem. They include the firmware design team, maybe a software and/or hardware team, your immediate (technical) manager (team leader?), a Product Manager, a Sales Manager, a Project Manager, maybe a QA testing team, and so on. All of these roles should and do exert a direct influence on your firmware development. Some humans may play more than one role, depending on how your company is organised. Their collective influence can be summed up in one word: uncertainty.

Some uncertainties emerge from the roles, for example a mid-project requirements change. We don’t know if they will happen, although past experience indicates they often do. If they do happen, we don’t know when in the project timeline, and we don’t know their exact nature, so we don’t know how significantly they will affect the current state of our firmware design. Uncertainty.

Other uncertainties emerge from the humans playing these roles, and they are all errors of one sort or another. The most obvious example is bugs in your code. As before, we don’t know if or when they will happen, when and where they will be discovered, and we don’t know how badly they will affect the operation of our firmware. Uncertainty again.

None of this should be a surprise to you, but I don’t think we account for these uncertainties as we should, in our work, and in our development processes. We can and do exhibit logical rational behaviour, but not all the time. We should account for this, to the extent it’s practical and useful.

We have already made progress on this topic. We used to freeze requirements during the lifetime of a project. Now we understand that mid-project requirement changes are a commercial reality, and we allow for them (however reluctantly). But there is more to human influence (on our firmware) than requirements changes.

The roles I listed control the availability of equipment, the developers available to the current project, access to tools and training, support (or the lack of it) for professional design practices, and so on. Can your firmware development process usefully allow for any/all of these?

Edited to add> Here’s an uncertainty that I always overlook. [Shame on me. 😦 ] We ask our firmware designers to solve problems that have not been solved before (otherwise we’d use the existing solutions). To do this, they sometimes have to think of things that haven’t been tried before, and sometimes this leads them to ‘break the rules’, or maybe make new ones. We ask our designers to use imagination and creativity, the outcome of which is unpredictable. From the perspective of our firmware, this is another uncertainty. And it’s meant to be there.

The uncertainties that stem from humans, rather than the roles they play, are basically errors of some sort. But it is a mistake to think that coding bugs are all there is to it. Any part/aspect of a design that is incomplete or incorrect is an error. But there’s much more to it than even this.

Of all the humans who exert influence on our firmware development, we should ask: are they competent to enact their roles? [We are not excluded from this!] Do we get the resources we need to complete our projects? Do we use them as well as we should?  Can your firmware development process usefully allow for any/all of these?

With all these humans involved, we would be remiss to ignore communication. An incorrect or incomplete communication can wreak havoc during firmware development. In the worst case (or a pretty bad one), the information you need to form the requirements your firmware must meet might reach you by the following route: users -> customer -> sales representative -> Sales Manager -> Product Manager -> your line manager -> you. The words “Chinese” and “whispers” should be dominating our thoughts right now. 🙂 Add to this that many of these humans have their own agendas, prompting them to ‘interpret’ the information as it passes by, for the benefit of all (let’s be kind).   Can your firmware development process usefully allow for any/all of these?

In the case of human error, is it enough simply to adopt practices to minimise them, or should we also allow for them, and maybe introduce ways of tolerating them (resilience)?

You won’t be considering all this stuff again (probably), so think: are there any other examples I haven’t written down here? How do they affect your firmware development?

This blog post is the latest in a series that is longer than I expected it to be. 🙂 Their main (intended) purpose is to stimulate discussion, so please leave a comment. Thanks for dropping by! [Find me on Twitter as @Patternchaser.]

Why does my firmware need … humans?