Multithreaded embedded systems. Yes, the functional people are absolutely correct that shared mutable state is evil. If that's the world you live in, though, you need to deal with it effectively. You need to have thread 1 able to respond to an external event by changing shared state that thread 2 sees, but in a controlled way so that thread 2 never sees an inconsistent state.
Now, there is a place for pure functions in that environment. But making decisions based on state can run so thoroughly through the code that "functional core" leaves very little core.
"Multithreaded embedded systems" is not saying much.
My initial hunch is that you've got a lot of existing code that passes and mutates big global state objects around. Still, even your description clearly highlights an issue that is there regardless of whether you want to push for a "functional core": "decisions based on state ... run so thoroughly through the code" _will_ come back and bite you.
It also highlights an easy way to decouple those into simpler functional parts: identify which part of the state is really needed in each part, and only pass that in, and have it return an updated state: basically, the only change you are making is turning the implicit parameters into explicit function arguments and return values. Turning the entire codebase around will be tricky, of course. But perhaps you can switch over chunks of it as the units are readied as you go along.
Of course, if you've got a lot of data that would be expensive to copy around, you might want to keep some of the logic for mutating that non-functional, but you could still decouple that thus making it have a functional core too.
Here's a router for television signals. It's got 100 different video sources, 80 different destinations, and "layers" (you can route audio differently from video, though you usually route them together).
You have 6 or so different sources of control (different panel systems, automation systems that use serial interfaces, other automation that uses Ethernet). Each of those is a different thread.
All those different sources of control need to see the same image of what's connected to what. So when one thread makes a change, it has to change for all the threads.
You could think about separating that state into parts, but does that really gain you anything? If you've got 80 variables that behave identically instead of one 80-element array, are you really ahead?
Now, there is a place for pure functions in that environment. But making decisions based on state can run so thoroughly through the code that "functional core" leaves very little core.