DIP & Vitamins

I came across an interesting parallel between biology and software.

Dependency inversion principle (DIP) is key to creating portable software. The essence of this principle is defining interfaces top-down based on the needs of the software. This has the consequence of putting the requirement first instead of the underlying implementation. So, we become user-oriented instead of technology-oriented and hopefully succeed. Continue reading DIP & Vitamins

Checklist for embedded communication

Embedded systems – being embedded – talk to their environment quite intensively. And nowadays, as system complexity has increased, the environment doesn’t only consist of simple sensors and actuators which one could talk to via ADCs, DACs, PWMs or GPIOs; but of more complex peripherals to which the embedded systems talks via some protocols such as CAN, I2C/SMBus, SPI, EIA-232/422/485 and so on.[1]I can recommend John Catsoulis’ book Designing Embedded Systems for a walkthrough of these interfaces.

These protocols provide the design for the physical layer and some data link control layer. So, one has to implement his own design for the remaining layers if they are needed by the specific requirements. In my experience, development teams tend to underestimate the requirements on the protocols[2]“It’s just two microcontrollers talking.”, so high costs and delays occur when protocol designs – which are architectural – are being amended in later phases of projects. Continue reading Checklist for embedded communication

Footnotes

Footnotes
1 I can recommend John Catsoulis’ book Designing Embedded Systems for a walkthrough of these interfaces.
2 “It’s just two microcontrollers talking.”

Key architectural skill: conquering code without understanding every detail

Climb the mountain just a little bit to test that it’s a mountain. From the top of the mountain, you cannot see the mountain.
— Frank Herbert, Dune

Once, I was working with a colleague who was responsible for the storage subsystem. As typical in most cases, instead of developing the storage hardware, drivers and the file system, we reused such components as OTS (off-the-shelf) and implemented the additional requirements on our own. When something in the storage subsystem didn’t work as expected (e.g. bugs, insufficient performance), we had to sit down with my colleague and look at the components (reused ones as well as ours). And I often heard the argument that in order to be able to make a proper analysis he had to study the components in detail. However this would cause us to miss the release deadline, and kill our development budget. Continue reading Key architectural skill: conquering code without understanding every detail

Fault, failure and co.

What’s in a name? that which we call a rose
By any other name would smell as sweet
–Shakespeare

Names aren’t that important, but consistency is. I had a discussion with my colleague Onur Taviloglu about the terminology used in my post Debugging: a detailed look at failures.  He pointed to me the terminology used by Algirdas Avižienis, which somewhat contradicted with the terminology of my post. So, I got in touch with my university professor Oguz Tosun, and dug through some resources:

Continue reading Fault, failure and co.

Anti-pattern: architect as “superdeveloper”

Architects almost always come from successful development backgrounds. And they should remain as developers, i.e. keep coding on the non-critical path of the project in order to not to become a stranger to the development perspective.

However, this more often than not leads to a situation that the architect is regarded as a “superdeveloper”. In other words, you will rarely find any good developers besides the architects. Continue reading Anti-pattern: architect as “superdeveloper”

Debugging: a detailed look at failures

SW-intensive systems are quite complicated. When they are not working as expected, this complexity increases even further dramatically. This is where debugging comes in, and a solid methodology is essential in approaching systems of such complexity.

In a series of posts, I’ll try to summarize the debugging methodology I have picked up from trainings, books and of course colleagues. In this first post, I’d like to start with some theory as I couldn’t find a good summary on the web directly fitting to my purposes. Those who get bored with theory ;-) are welcome to jump to the end of this post for the definitions of symptom, root cause and excitation, and continue to the upcoming more practical posts. So, here goes…

Continue reading Debugging: a detailed look at failures

Nice ways of changing external code

All SW-intensive systems have a lot generic functionality[1]i.e. functionality not specific to the product, e.g. network protocols, XML parsing, graphics, and therefore contain a lot of generic components developed by external vendors. Sometimes the requirements force us to modify some of the behavior implemented in those components.

One of proper solutions is implementing the desired behavior via the decorator pattern. This keeps our modification dependent only on the interface of the component and not the implementation. Sometimes, however, the access provided by the interface is not sufficient to provide the desired functionality. For example, if you need to change a driver’s interaction with HW, most likely you won’t find the necessary “hook point” in the driver’s upper interface, since it cleverly hides HW-level specifics from the higher layers. Another by-the-book solution is pushing the change to the mainline, as open source community always recommends with good reason. But let’s focus on the remaining problematic cases. Continue reading Nice ways of changing external code

Footnotes

Footnotes
1 i.e. functionality not specific to the product, e.g. network protocols, XML parsing, graphics