
Software on its own does not constitute a hazard. As an integral part of a medical device, though, it can contribute to hazardous situations — and those situations are what expose people to harm.

Software copies are identical, which makes the probability of a failure that leads to harm very hard to establish: given the same inputs, code behaves the same way every time. So risk analysis focuses on identifying the anomalies that could cause a hazardous situation, and on how severe the resulting harm would be — not on how likely it is.
In practice this means the probability of software failure is always estimated at 1, that is 100 per cent. For safety-critical designs, that assumption forces hardware-based mitigations into the conversation from the start.
Risk management runs through the entire life cycle, and at every stage the intended use of the device has to be in view. That starts with the system architecture and continues into implementation, where a few things repeatedly matter.
Software handling of safety features should be avoided where it can be, and kept as simple as possible where it cannot — simple enough to test and review properly. Alarms and warnings need care so that a lower alarm state cannot suppress a higher one. The graphical user interface counts too: a misleading GUI can itself lead to a hazardous situation. Senior staff review designs before they propagate to a sprint release, and we take part in the hazard analysis processes our customers have established.
When implementing medical devices the software system is divided into software items, and each item is evaluated for its safety class. Class A means no injury or damage to health is possible. Class B means non-serious injury is possible. Class C means serious injury or death is possible.

When a software item turns out to belong to a high safety class, there are two good moves, and both belong early in the design. Replace it with a hardware component that can carry that function. Or separate it out, so it can be segregated from the rest of the system and its operation does not raise the safety class of everything around it.
Segregation is what keeps the safety-critical parts small, robust and genuinely verifiable — rather than spreading the burden of proof across the whole codebase.

Tell us what you're building and the constraints it has to work within, and we'll come back with an honest view of whether we're the right fit.