Embedded Software Development for Medical Devices
Software engineering for medical devices are typically process-driven and the standards which guide software development are derived from IEC 62304, “Medical device software — Software life cycle processes.”
One of the benefits of developing software for medical devices is the wide variety of the devices themselves and the technology needed to facilitate ever-increasing innovation to meet such a large industry. Additionally, as the complexity of medical devices increase, new opportunities arise. Some of these new opportunities include advancements in machine learning, cybersecurity, integrated ML MEMS devices, motor control systems, hybrid and multi-core processors, and the list continues.
Below is a sample of just some of the modern and recent technologies I’ve had the opportunity to work with on various projects.
ARM Cortex processors and board subsystems
nRF52 series (Cortex M4F) supporting BLE
API and Driver development
NFC integration
STM32R / STM32S / STM32H
API and Driver development
Secure boot with multi-image handling and mitigation
Motor PWM controller, driver, and API design
Cybersecurity and secure communications
Static and integration testing
i.MX6QXP / i.MX8QXP
BSP customization (IPL, Startup, and new drivers)
Cybersecurity (WolfSSL integration)
Secure boot and signature verification
Hardware-level driver and API development
MEMS sensors
NVMe Memory
USB 2.0 and 3.x hubs
SPI, i2c, UART, i2s, USB stack
Operating systems
Embedded Linux and QNX
One of the greatest benefits in designing medical devices, under contract design, was the wide variety of technologies and operating systems used in each project. These included embedded Linux, QNX, and RTOS (FreeRTOS, VxWorks, and Neutrino). Embedded Linux kernel development I find to be most rewarding due to the capabilities, especially in a multi-core environment. The APIs are well documented, layering with Yocto project is tremendous benefit, and with additions in security, it is a real pleasure to work with. QNX, an RTOS OS, is similar in capabilities, both are “unix-like” although QNX uses a microkernel architecture as opposed to monolithic kernel found in Linux (more on this below). QNX uses korn bash compared to bash in Linux. A lot can be said about individual preference in their comparison, but in general, they’re similar enough.
Driver development, concurrency, CPU binding capabilities, system calls, driver development, abstraction, ioctls, security, R/W, etc., are similar in function (aside from device trees), however, in terms of architecture, differences such as where the drivers run and POSIX API access are key. In Linux, drivers run external to the POSIX API, but within the kernel, whereas in QNX, the drivers are external to the kernel, but with access to the POSIX APIs (with memory-protected processes). While Linux uses a device tree model, QNX allows for direct pin mux control like many microcontrollers.
The main difference is in tradeoff, Linux (non “real time” version) favors performance and utilizes CFS (Completely Fair Scheduling) whereas QNX favors more “crash-tolerant” execution and real-time scheduling.
RTOS
The embedded world couldn’t exist without solid hard real time operating systems. When an x-ray device sends 60 keV of impulse radiation through the human body for 80 milliseconds, plus or minus 50 milliseconds isn’t going to cut it. This is just on example of unlimited solution where RTOS comes in. In many systems and subsystems, applications are small, memory-constrained, possibly battery-operated (i.e. low power and multiple levels of sleep requirements) and thus efficiency comes down to a balance of aspects including cost, features, memory, power, and so on. Some of the RTOS systems I’ve used include FreeRTOS, VxWorks, QNX, and various super light-weight proprietary systems. Like other operating systems, many of the same APIs are available such as locking mechanisms (spinlocks, mutexes, semaphores), system calls, MMUs, device drivers, and multi-core configuration options.
Cybersecurity
Cybersecurity prevention, threat detection, and countermeasures are now part of nearly every project today. In 2013, he FDA released a document, “Content of Premarket Submissions for Management of Cybersecurity in Medical Devices” to provide guidance in design and development. Contained in this document, the essential functional components to cybersecurity were defined as follows:
Identify
Protect
Detect
Respond
Recover
Experience
Signature and Tag verification
SHA256, SSH-RSA, ECDSA
Memory access control techniques
WRP/RDP, PCROP, MPU, RAM protection, and Trust Zones
Cryptography
Asymmetric and Symmetric
Hardware Accelerators
AES, GMAC/CMAC, GCM, CBC
Software-based
WolfSSL
Tamper Protection
i.MX8 series system controller
System controller (SCFW)
PSCI APIs and modified calls
Secure Watchdog Timer
Industry Tools and build setup
PC-Lint++ setup and build integration.
Jenkins setup, maintenance, and project reconfigurations.
System build scripts, linker configurations, and custom Makefile generation.
Industry standard tools; JIRA, Bitbucket, SourceTree, UML generation, VectorCAST