Developing Modular Software: IEC 62304 Software Units, Items and Systems
In this blog post we discuss software decomposition, referencing IEC 62304 as a source for good practice, and present a simple example.
Understanding Software Unit, Item, System Definitions
IEC 62304 defines a SOFTWARE ITEM as;
any identifiable part of a computer program, i.e., source code, object code, control code, control data, or a collection of these items.
Further context is needed to understand the definition SOFTWARE ITEM and its relation to the SOFTWARE SYSTEM and SOFTWARE UNIT definitions.
A SOFTWARE SYSTEM is defined as;
integrated collection of SOFTWARE ITEMS organised to accomplish a specific function or set of functions.
And SOFTWARE UNIT is defined as;
SOFTWARE ITEM that is not subdivided into other items.
We can visualise these hierarchical relationships with a UML component diagram (using plantUML);
Looking closely at the standard, an important note can be found below the SOFTWARE UNIT definition;
NOTE The granularity of SOFTWARE UNITS is defined by the manufacturer (see B.3)
Following this, it is the responsibility of the Medical Device Manufacturer to use best engineering judgment when defining the level of decomposition. Section B.3 contains some helpful hints to get a feel for what makes sense here, and experience working on relevant projects will provide further calibration for decomposition granularity.
Modular Decomposition In Functional Safety Standards
Modular decomposition is not a recommendation just limited to software for medical devices. It is also mentioned in various functional safety standards, which provide a useful source of tools and techniques to improve software reliability for critical systems in all domains.
For example, ISO 13849-1 recommends the following for Safety-related embedded software (SRESW);
— modular and structured programming, separation from non-safety-related software, limited module sizes with fully defined interfaces, use of design and coding standards
And likewise, IEC 61508-3 recommends;
The software shall be produced to achieve modularity, testability, and the capability for safe modification.
IEC 61508-3 Annex F.7 provides further commentary on module coupling/cohesion, including different types of module coupling (good and bad) with rationales summarising the practical effects of each.
Reviewing this Annex, we can see the standard covers many benefits of modular decomposition with high cohesion;
Interface coupling, encapsulation — If any changes of a module are required, a large amount of these changes can be done within that module, without affecting other modules.
It also covers the issues with certain coupling methods, such as using data/variables with broad scope;
Global coupling — … subprograms do not indicate, which data are used and from where. It is difficult to understand the subprograms’ functions and to predict the effects of any changes to code.
Simple IEC 62304 Software Decomposition Example
For a device with a single processor (e.g. a small MCU), it is advantageous to keep things simple with one solution being;
Scope each SOFTWARE UNIT to a complimentary interface and module file.
We can then group each SOFTWARE UNIT (in this example using C, complimentary .h and .c files) into folders, each of which represents a SOFTWARE ITEM:
.
├── main.c
├── main.h
├── processor
│ ├── processor.c
│ └── processor.h
├── scheduler
│ ├── scheduler.c
│ └── scheduler.h
└── tasks
├── task_bar.c
├── task_bar.h
├── task_foo.c
└── task_foo.h
So, above we have the following SOFTWARE UNITS;
main
processor
scheduler
task_bar
task_foo
And the following SOFTWARE ITEMS (note some of the folders contain a single C module thus by definition are both SOFTWARE UNITS and SOFTWARE ITEMS, this is OK per the definition above);
main
processor
scheduler
tasks
Our SOFTWARE SYSTEM is the project itself (with the artifact being the final binary), containing all of the above SOFTWARE ITEMS — this is visually represented below.
Note, this is not the only way! And as the standard states, SOFTWARE UNITS are to be defined by the manufacturer. For example, Medical Devices with multiple processors may allocate a SOFTWARE ITEM per processor like below.
Rationale & Conclusion
Structuring our source code in this way;
provides a visually clear and consistent level of decomposition granularity,
does not require any special tooling and is cross (development) platform compatible,
encourages the creation of decoupled, modular code.
And importantly, each SOFTWARE UNIT has its own interface;
allowing for per module unit testing with frameworks such as Unity/Cmock,
providing encapsulation for quasi-global data (per SOFTWARE UNIT),
and enabling the use of advanced techniques such as Test Driven Development (TDD).
If you found this post helpful and would like to know more, or have any feedback please contact us; info(at)caetron.io