I know that Thread-mode software can be privileged or unprivileged, and Handler-mode (exceptions/interrupts) software is always privileged. I need a function that I can call to decide if I'm running privileged or not (because I want to be able to directly access e.g. the basepri register if privileged, or perform an SVC call first if not privileged). In the RTOS I use (SAFERTOS), there is a function "xPortIsPrivilegedMode" that you can call (only from a task i.e. Thread mode SW) as follows:
mrs r0, control
tst r0, #UNPRIVILEGED_BIT /* Is the task running privileged? */
movne r0, #FALSE /* CONTROL[ 0 ] == 1; return false. */
moveq r0, #TRUE /* CONTROL[ 0 ] == 0; return true. */
I have two questions regarding this function:
1. If the task is running unprivileged, how can it access the CONTROL register in the first place to read the unprivileged bit?
2. This function cannot be called from an ISR because, according to the CONTROL register specs from the programming manual of my MCU, the "nPRIV" bit determines the privilege level in Thread mode only, not in handler mode. So an ISR can be running while nPRIV == 1 (unprivileged) because (I think?) the task that was interrupted by the ISR was unprivileged. Thus the function would return "false" when it should have returned "true". How can we generalize a function so that it can be called from both Handler mode and Thread mode?