The book “Pure architecture. The Art of Software Development »

    image“The Ideal Programmer” and “Clean Code” - the legendary bestsellers of Robert Martin - tell how to achieve the heights of professionalism. Pure Architecture continues this theme, but doesn’t offer several “decide for yourself” options, but explains what exactly should be done, for what reason and why such a decision will be crucial for your success.

    Robert Martin provides direct and concise answers to key questions of architecture and design. “Clean architecture” must be read by developers of all levels, system analysts, architects and every programmer who wants to climb the career ladder or at least influence the people who are involved in this work. All architectures obey the same rules! Robert Martin (Uncle Bob)

    Proficiency Test

    Why is so much software turning into firmware? It seems that the main reason is the desire to get a valid embeddable code and practically no attention is paid to its structuring to increase the service life. Kent Beck describes three steps in creating software (Kent is quoted next in quotation marks and my comments are shown in italics):

    1. "Make it work first." You will remain out of work if it does not work.
    2. "Then rewrite it correctly." Reorganize the code so that you and others can understand and develop it when you need to change or understand something.
    3. "Then make it work fast." Reorganize the code to achieve the “necessary” performance.

    Most of the embedded systems that I had to see seemed to be written with the only thought in my head: “Make it work,” and sometimes with the obsession, “Make it work fast,” embodied by the introduction of microoptimizations at every opportunity. In his book The Mythical Man-Month, Fred Brooks suggests "plan for abandoning the first version." Kent and Fred advise almost the same thing: find out how it works and find the best solution.

    Embedded software is no different with respect to these issues. Many non-embedded applications are only brought to the “working” stage, and little is done to get the code correct and last a long time.

    Getting a working application is what I call a proficiency test for a programmer. A programmer who develops software, whether embedded or not, who only cares about getting a working application, harms his products and the employer. Programming is more than the ability to write working applications.

    As an example, take a look at the following functions that are in the same file of a small embedded system, written during the passage of the test for aptitude:

    ISR(TIMER1_vect) { ... }
    ISR(INT2_vect) { ... }
    void btn_Handler(void) { ... }
    float calc_RPM(void) { ... }
    static char Read_RawData(void) { ... }
    void Do_Average(void) { ... }
    void Get_Next_Measurement(void) { ... }
    void Zero_Sensor_1(void) { ... }
    void Zero_Sensor_2(void) { ... }
    void Dev_Control(char Activation) { ... }
    char Load_FLASH_Setup(void) { ... }
    void Save_FLASH_Setup(void) { ... }
    void Store_DataSet(void) { ... }
    float bytes2float(char bytes[4]) { ... }
    void Recall_DataSet(void) { ... }
    void Sensor_init(void) { ... }
    void uC_Sleep(void) { ... }

    In that order, the functions were declared in a source file. And now we will separate them and group them according to the tasks to be solved:

    ?? functions that implement subject logic:

    • float calc_RPM (void) {...}
    • void Do_Average (void) {...}
    • void Get_Next_Measurement (void) {...}
    • void Zero_Sensor_1 (void ) {...}
    • void Zero_Sensor_2 (void) {...}

    functions that serve the hardware platform:

    • ISR (TIMER1_vect) {...} *
    • ISR (INT2_vect) {...}
    • void uC_Sleep (void) {...}
    functions that respond to button presses:

    • void btn_Handler (void) {...}
    • void Dev_Control (char Activation) {...}
    function that reads data from a hardware analog-to-digital converter:

    • static char Read_RawData (void) {...}
    functions that write values ​​to long-term storage:

    • char Load_FLASH_Setup (void) {...}
    • void Save_FLASH_Setup (void) {...}
    • void Store_DataSet (void) {...}
    • float bytes2float (char bytes [4]) {...}
    • void Recall_DataSet (void) {...}
    a function that does not do what its name implies:

    • void Sensor_init (void) {...}

    Having looked at other files of this application, I found many obstacles that hinder the understanding of the code. I also found that organizing files implies the only way to test this code is directly inside the target device. Almost every bit of this code knows what is related to a specialized microprocessor architecture, using the “advanced” C1 language constructs that bind the code to a specific set of tools and a microprocessor. This code has no chance to serve for a long time if it is decided to transfer the product to another hardware platform.

    The application works: the engineer passed the test for professional suitability. But it cannot be said that it has a clean embedded architecture.

    Hardware binding - bottleneck

    There are many special problems that developers of embedded systems have to deal with who are not familiar to developers of conventional software. For example, a limited amount of memory, time limits for performing operations, limited I / O, non-traditional user interfaces, as well as the presence of sensors and contacts that connect to the outside world. In most cases, hardware develops in parallel with software and firmware. You, as an engineer developing code for such systems, may not have a place to run the code. But this is not the worst - the resulting equipment may have its own flaws, which slows down software development more than usual.

    Yes, embedded software has its own characteristics, and embedded engineers are special people. But the development of embedded systems is not so special that the principles described in this book cannot be applied to embedded systems.

    One of the special problems of embedded systems is its close dependence on equipment. When an embedded code is structured without applying the principles and techniques of a clean architecture, one often encounters a scenario where the code can only be tested on the target hardware. If this equipment is the only place where testing is possible, such close contact begins to slow you down.

    Pure Embedded Architecture - Supporting Testing Architecture

    Let's see how some architectural principles apply to embedded software and firmware, and how they help get rid of tight hardware bindings.


    The division into levels can be done in different ways. Let's start with the three-level organization depicted in Fig. 29.1. Below is the level of equipment. As Doug warns, due to technology improvements and according to Moore’s law, the equipment will change. Some components become obsolete and are replaced by new components that consume less power, or have higher performance, or are cheaper. Whatever the reason, as an embedded systems engineer, I would not want to do more than necessary when the inevitable change of equipment finally happens.


    The division between the equipment and the rest of the system is an objective reality, at least after the definition of equipment (Fig. 29.2). This is where problems often arise when trying to pass an aptitude test. Nothing prevents hardware knowledge from infecting all code. If you do not exercise caution when structuring the code and not limit the leakage of information about one module into another, the code will be difficult to change. I’m talking not only about the case when the equipment changes, but also about the situation when you need to fix a mistake or make a change at the request of the user.


    Mixing software and firmware is an anti-pattern. Code demonstrating this anti-pattern will resist change. In addition, changes are fraught with dangers, often leading to unforeseen consequences. Even minor changes require complete regression testing of the system. If you have not created tests with external equipment, get ready to conduct manual testing, and then expect new messages about detected errors.

    Hardware is a part.

    The line between the software and the firmware is usually not visible as clearly as the line separating the code and the hardware (Fig. 29.3).

    One of the tasks of an embedded software developer is to strengthen this line. The border between the software and the firmware (Fig. 29.4) is called the Hardware Abstraction Layer; HAL. This is not a new idea: it was implemented on personal computers in the pre-Windows era.



    A HAL layer exists for the software above it, and its API must adapt to the needs of that software. For example, firmware can store bytes and byte arrays in flash memory, and an application needs to store and read name / value pairs using some kind of storage mechanism. The software does not have to worry about the details of storing name / value pairs in flash memory, on a spinning disk, in the cloud or in main memory. The Hardware Abstraction Layer (HAL) provides the service and does not disclose to the software how it works. Implementing flash support is a part that must be hidden from software.

    Another example: LED control is tied to the GPIO bit. The firmware can provide access to the GPIO bits, and the HAL layer can have the Led_TurnOn function (5). This is a rather low-level layer of hardware abstraction. Let's see how to increase the level of abstraction in terms of software / product. What information does the LED report? Suppose that turning on the LED indicates a low battery. At some level, the firmware (or platform support package) can provide the Led_TurnOn (5) function, and the HAL layer can provide the Indicate_LowBattery () function. In this way, the HAL layer expresses the purpose of the service for the application. In addition, levels may contain sublevels. This is more like a repeating fractal pattern than a limited set of predefined levels. GPIO I / O assignments are details,

    »More information on the book can be found on the publisher’s website
    » Table of Contents
    » Excerpt

    For Khabrozhiteley 20% discount on coupon - Clean architecture

    Also popular now: