If you are looking for Runtime memory protection, then only hardware support is a smart option. Hardware is the only way to tamper with poor memory access before it can cause damage. Any software solution will be vulnerable to the very memory errors that it is trying to protect.
With software, you can implement a verification / detection scheme. You can periodically check portions of memory that the current program should not have access, and see if they have been changed (perhaps by CRCing these areas). But, of course, if the rogue program damages the area where the checksums are stored, or where the verification code is held, then all bets are disabled.
Even this software verification solution would be more of a debugging utility than a real-time runtime protection. It is likely that a device without an MMU is a small integrated device that will not have spare cycles for constantly checking the device’s memory.
Typically, devices without an MMU are designed to run a single program without a kernel or anything else, and thus there is no protection. If you need to run several programs and feel that you need protection, you probably need more advanced hardware that supports the features you are looking for.
source share