Hi Sam,
I retired just as you started out as a firmware designer. I want to pass on something, both to round off my career, and to offer yours a flying start. So I’ve based this on my time-travel letter. You know, the one that old-me sends to young-me, brimming with wisdom, wit and good advice? 🙂 So here is a view of my career, in the context of my learning to do what a designer does. [That is, to get from customer needs to an executable that meets those needs.] First I’ll cover what I learned while writing this (more than I could possibly have imagined!), and then the things I learned that I can date, if only roughly. Then I’ll describe the things that just crept up on me.
When I started this letter, it was to be the list of ego-driven imperatives that you might expect from a programmer. 😉 But young-me would’ve binned a list of commandments without compunction, and I’m sure you would too. So the first thing I learned is that I need to offer you something useful, or you won’t read it. This is my best effort at that. Enjoy! 😉
As I looked back with the wisdom of hindsight, I made connections I hadn’t made before. Things I had thought important or significant turned out to be neither when viewed from a historical perspective. And things I had overlooked turned out to be pivotal. If I’d known how much I would learn from serious consideration of my progress, I would’ve done it every ten years. No less than that: we need the temporal distance for hindsight to work. Ten hours of solid introspection, every ten years, would’ve vastly improved my rate of progress!
The jobs I had, in the order I had them, influenced my journey more than anything else (except a mentor) could have done. My employers’ attitudes to training, the provision of tools and equipment, their development processes, and the work that was available for me to do, defined and constrained how I could progress. If I could do it all again, I would give much greater priority to selecting the right employer for me, at that point in my career.
My first job offered three highlights: I learned C, got exposed to an OS, and had to leave in a hurry.
Having previously flirted with FORTRAN, BASIC, assembly language and Pascal, I picked up C quite easily, and learned that all languages are basically the same, and provide the same features. I had a shock when I encountered C++, but it was true for the languages I had encountered so far.
We used OS-9, a multi-user, multi-tasking OS. Uniquely in firmware, we used it on our development and target systems. Having learned the benefits of an OS on the target, I was open to RTOSs when I encountered them later.
I also learned an uncomfortable lesson in reality. Friday morning: we told the boss we would have something working in 6 to 8 weeks; Lunch: the boss promised the customer a demonstration on Monday; Late afternoon: the boss instructed me to work 20-hour days over the weekend to reify his lunacy. I refused, and had to find a new job. Not all lessons are happy ones.
My next job was a disaster, something else I only realised while writing this. As I look back, I can see nothing worthy of mention, and I was designing firmware there for five years! I should’ve been aware of my stagnation, and moved on sooner. As it was, I moved when our senior managers destroyed the company. I suppose that was a lesson of sorts.
My next job introduced design methodologies, Quality Processes, OO and C++, software patterns, and I gained access to the internet. I learned a lot in my ten years there. [Sadly, as above, I also left after senior managers destroyed the company.]
I mistook design methodologies for ‘design’, at first. We used Schlaer-Mellor, which wasn’t known as S&M for nothing. Of course, there was no training; we were expected to pick up what we needed by our own undirected efforts. I learned doublethink. We pretended to use waterfall. We dutifully wrote and reviewed useless documents. But we actually did what we needed to do to make our firmware work.
I encountered Quality Processes for the first time, and learned that a QA process can be a good thing, if (and only if) it helps us make quality products. I learned to be an ISO9000 auditor, to add credibility to my claim that you can have a firmware development process that is useful, usable and ISO9000-compliant. [In a later job, I wrote such a process, and we used it with success for years.]
This is when I got internet access at work. No websites yet, but I could access mailing lists and newsgroups. My learning had been limited to books and magazines. Now I discovered software patterns and OO, and gurus like Cope and Uncle Bob. I learned so much from these people! I asked ignorant, arrogant questions, and they responded with patience and courtesy. <blush> I started to get a proper idea of what design was/is, and even how I might go about practicing it. I conversed with some of the greatest software designers of the last 50 years. Not on equal terms, you understand. But I did learn.
It is unfortunate that my employer was unwilling to let me deviate from company processes and practices, to try out some of this amazing new knowledge. [My next employer was the same, but I played dumb, and started using TDD and software patterns anyway. When they queried me, I acted surprised that they didn’t already use them, and got away with it.]
In my final job, I applied what I had learned. I introduced them to software patterns and TDD (as I mentioned above), and wrote a firmware development process that (I think) is still useful and in use. I started to take part in product design discussions much earlier. In short, I was doing design properly. When I finished, I still had ideas that I hadn’t got around to trying, but I was doing good work, and still getting better at it. Then our employer closed and outsourced our development department. As suddenly as that. And that was it.
We have covered all my employers now, but there are other things I learned that I can’t tie to a time or a place. These are they:
There are no binding rules or laws in firmware design, only guidelines. But our guidelines are based on years of thought and experience. They may be broken freely, but only if you can justify it to your peers in a design review! There are no laws, but you are not thus a law unto yourself.
Perspective is a magical spell, stolen ages ago from the Plane of Design. The more you have, the better. Mostly. Sometimes, irreconcilable requirements can be reconciled just by finding and adopting the right perspective. Perspective also evokes viewpoint, paradigm, metaphor, analogy, vocabulary (words, symbols and concepts), and so on. It’s about the way you (choose to) look at something. Imagination is the only limit. See yourself standing on the API of your new class, looking out at the application. Look at your design from a Taoist perspective, if it helps.
A perspective that is sometimes useful is that your software design will tend to grow, or evolve, organically. This isn’t a problem, as long as it doesn’t compromise your clear and easily-understood design. When and if it does, some gentle refactoring is in order.
Simplicity is not a virtue, it’s a necessity. But avoid the mistaken KISS acronym: it isn’t stupid to produce complex designs, it’s human. The quote usually attributed to Einstein — “as simple as it can be, but no simpler” — is a much better guide. As well as the obvious message, it also warns us that a too-simple solution cannot adequately meet all of its requirements. Simplicity is hard work, but we need to pursue it, or complexity renders our designs unmanageable and incapable of change.
Clarity is second only to simplicity when it comes to desirable attributes our designs should display. Everything about a design should be clear: code, diagrams, documents, processes…. Everything. [Code] readability is just clarity by another name, and we all know how important and valuable readability is … don’t we? 😉
The ‘just enough’ concept is strongly related to simplicity. It applies to everything that has an optimum value that lies between extremes. Just enough documentation, design, testing, and so forth, are things to aim for. But there’s no such thing as just enough bugs….
Context is all, as it is for many disciplines. Designs don’t exist in a vacuum. Neither do designers or design teams. Context is almost always more extensive than we think. Your manager, that guy who compromises your work with those ridiculous demands, is part of your development context. You are too. Consider all influences on your firmware, whatever they are. If you cannot control them, at least be aware of them, and their effect(s).
Discussion is useful when co-operative, and counter-productive when adversarial. We developers have to find a way to embrace this, and many of us find it difficult. I did. I made the final push when I realised that, if I didn’t grow up (in this particular way), I could progress no further as a designer. [Being a designer meant, and still means, a great deal to me.] Find your own reason to avoid the worst consequences of ego, without losing your opinions, creativity or imagination.
Testing. In my experience, unit-testing – often referred to as “TDD” (Test-driven Design) or “TFD” (Test-First Design) – is unavoidably vital. If you don’t test your code, you can’t know it will work as you intend. Speed of execution is more important than you might think too. If your unit-tests execute in 300 ms, you will run them often. If it takes several hours, you will run them rarely, and gain no benefit from them. Once you’ve acquired the skill of TFD and unit-testing, it will save you time, even though the tests seem to demand extra work that you would not otherwise have done. You will save that time ten times over during debugging.
Abstraction is a useful, common and well-known way of looking at our designs. The lowest abstract level for us is the hardware. It’s not the least important, it just exists at the lowest abstract level. The highest abstract level is the view of your design as a single entity, existing in the context of the product, the customer, life, the universe and everything. A successful designer is aware of their design at all abstract levels, from the tiniest detail to the most general overview. If you lose track of your design, at any abstract level, the universe will bite you for it, sooner or later, in my experience.
Estimation of timescales is an impossible task that will be demanded of you. Managers will ask how long it will take to create your firmware. From their perspective, this is not only reasonable, but essential. But they rarely appreciate that a designer must create a solution to a problem that has not been solved before. [If it had, we would use the existing solution, wouldn’t we?] Creating something new introduces uncertainties, making prediction difficult, especially timescales.
N.B. managers will expect four man-days of effort, done by a team of two, to take two days.
When estimating, make your best guess as to how long it will take, double it (to account for the things you haven’t accounted for!) and then add between ten and a hundred percent for ‘contingencies’. That’s how long it will actually take, after the delay waiting for the new equipment to arrive, Ken’s unanticipated illness, and so forth.
When your manager tries to enforce a timescale, or reduce your estimates, explain that less time means fewer features, and ask them to decide which of their requirements can be sacrificed. Otherwise you will fail to bring your project in on time, and the blame will fall on you. No designer is capable of doing a week’s work in a day.
Best wishes on your journey,
Great-uncle Pattern-chaser
Sam is my fictitious relative, invented for the purposes of this article. No firmware designers were harmed during the creation of this document.
This is my final firmware blog. As time passes, firmware development recedes from me, and what I have to offer becomes less useful, less helpful, and just … less. Thank you for reading. If you care to leave a comment, that would be great.
P.S. I reserve the right to edit and add to this blog as improvements occur to me. If I could’ve made it perfect first time, I would have done! 😉 Continuous improvement, as they say…. 🙂
Edit #1. 05/12/2017. Minor text clarifications. Added a paragraph on ego.
Edit #2. 06/12/2017. Added paragraph about clarity.
Edit #3. 20/05/2021. Added paragraphs about testing and abstraction.
Edit #4. 26/04/2023. Added paragraphs about estimation.
Edit #5. 08/07/2023. Added a paragraph about organic growth.