I don't care who wrote the program, it is still possible that some sequence of inputs will result in the program running amok. Yes, we are all exceptional programmers but, seriously, any time you branch through a pointer, you are looking for trouble. If the branch table got hosed, who knows where you will wind up?
Indeed - you may end up somewhere you don't want - for example to your function that unlocks the resource and uses it.
In this case, having your function to sanity-check the memory addresses, data, etc., will offer much better protection against accidents.
But most of the time, we just unlock whatever resource when we need it. The result is approximately equally unsafe than not having any "locks" in the first place.
Utilizing the locking features so that they
actually help requires a lot of thought - and when you do that, you'll often note that the locking mechanism is quite lame, and you need to implement something better anyway. On the other hand, powerless safety features do cause two effects, affecting overall code quality and reliability: (1) false sense of security, (2) increased complexity, reducing development time available to make things more robust in the right way.
For example, in many MCU's, for successfull FLASH write operation, you need to supply right control registers with:
- Unlocking keys
- the right control register bits with right settings to enable write access
- then write the data to the right memory area.
Even without unlocking keys, it's extremely unlikely your accidental memory access would first write to the exactly right control register bit (in a totally different memory region; peripheral address space), then to the flash memory region to actually do the write there. So the only way this will happen, is by having runaway program counter (or accidentally calling the wrong function), where your program ends up in the flashing function. And when you are there, requiring the keys won't help the slightest - most likely, you have written the flasher function to unlock the flash in the very same place! Why would you do it elsewhere? You'd
think that it's
safest to unlock
just before accessing
.
You
could utilize the key thing so that there would be some separate code doing the unlocking, and this code would only be called through the interactions of some completely different logic - for example, a separate "enable flashing" pushbutton. But, given that the
final input to actually do some things comes from the end user (for example, requesting a firmware update), the things need to combine at some point, and some actual code will always end up first calling unlock_flash(); then program_flash();. Making it more complex by adding intermediate steps will just hide the problem and make it even worse to debug. And, the KEYs still won't help.
In general, I think that in typical MCU's, these "protection features" are,
in 80% cases, completely irrelevant or harmful,
in 10% cases, might have some use when used correctly
in 10% cases, very usable.
MCU designers are not always very bright-minded. That can be easily seen when you look at the typical peripheral implementations in almost any MCU. There are exceptions of course, but over 50% of the time, developing on any MCU is kind of facepalming: "why on earth did they design it like this..."