(Nucleus Plus is a non open source operating system, only limited code is provided for reference)
1. Nucleus plus protection mechanism
Nucleus plus kernel uses TC for small code protection_ Protect only in TC_ The interrupt is only turned off during protect operation, so the interrupt response and scheduling of Nucleus Plus kernel is more timely than that of μ C/os-iii and ThreadX; mutex is only used for applications (mutex between threads).
TC_ Protect contains two members. One record gets TC_ Thread pointer TC of protect_ tcb_ Another mark is whether there is a thread waiting for TC_ The variable TC of protect_ thread_ waiting。
2、TC_ Protect acquisition (TCT)_ Protect)
Off interrupt
1624 MRS r1,CPSR // Pickup current CPSR
1625 ORR r1,r1,#LOCKOUT // Place lockout value in
1626 MSR CPSR_cxsf,r1 // Lockout interrupts
Check TC_ Is protect occupied (check TC_ tcb_ Whether the pointer is empty; if it is not occupied, jump to TCT_ Protect_ Available, set TC_ tcb_ The pointer is the pointer of the current thread, and you can turn on the interrupt again. If it is occupied, you will check whether it is occupied. It is similar to the spin lock of Linux kernel, but Nucleus Plus is single core, so the current thread needs to switch out of the CPU.)
1632 TCT_Protect_Loop:
1633 LDR r1,[r0, #0] // Pickup protection owner field
1634 CMP r1,#0 // Is there any protection?
1635 BEQ TCT_Protect_Available // If NU_NULL, no current protection
Set TC_ thread_ Waiting is 1 (indicates that there is a thread waiting for TC)_ PROTECT)
1642 MOV r2,#1 // Build thread waiting flag
1643 STR r2,[r0, #4] // Set waiting field
If TC_ Protect is occupied. Save the context of the current thread and call TCT_ Schedule_ Protected scheduling takes up TC_ Thread of protect (the current thread is the thread with the highest priority and occupies the TC_ The thread of protect has a lower priority. If you don’t actively schedule the thread of low priority, the thread of low priority will never be able to execute, TC_ Protect will never be released)
1648 STR r0,[sp, #-4]! // Save r0 on the stack
1649 STR lr,[sp, #-4]! // Save lr on the stack
1650 MOV r0,r3 // Place current thread into r0
1651 BL TCT_Schedule_Protected // Call routine to schedule the
1652 // owner of the thread
3、TC_ Protect release (TCT)_ Unprotect)
Check TC_ thread_ Whether waiting is 0. If it is 0, no thread is waiting for TC_ Otherwise, there are higher priority threads waiting for TC_ PROTECT(TC_ There is no interrupt in the process from the acquisition of protect to the release of TC_ Before protect, a higher priority thread may be ready to apply for the same TC_ If there is no thread waiting for TCT_ Unprotect, simply set TC_ tcb_ If the pointer is empty, turn on the interrupt; otherwise, call TCT_ Control_ To_ System rescheduling (waiting for TCT)_ The unprotected thread may not be the thread with the highest priority at this time, but the scheduler obtains the highest priority ready thread for execution;
TCT_ Control_ To_ System checks whether the time slice of the current thread is used up; if it is not used up, it will continue to execute the current thread (to avoid frequent thread switching, so TCT is called)_ Control_ To_ TC is not set before system_ tcb_ If the time slice is used up, set TC_ tcb_ Pointer is empty, TC_ thread_ Waiting is 0 (wait for TC before)_ The thread released by protect is no longer waiting for TC_ Protect. After the thread is scheduled, it returns to TCT_ Protect_ Loop is equivalent to calling TCT again_ Protect, reacquire lock (wait for TC for some reason)_ Thread released by protect is suspended, TC_ thread_ The waiting flag cannot always be set to 1, otherwise other threads will release TC_ When protect, it will mistakenly think that there is a thread waiting for TC_ Protect release), call TCT_ Schedule selects the highest priority ready thread for execution. (thread scheduling reference) https://blog.csdn.net/arm7star/article/details/105565769 “NucleusPLUS interrupt processing (based on ARM processor)”
1783 LDR r2,[r0, #4] // Pickup thread waiting flag
1784 CMP r2,#0 // Are there any threads waiting?
1785 BEQ TCT_Not_Waiting_Unpr // If not, just release protection
4. Summary
To some extent, the protect mechanism of nucleus plus can be regarded as priority inversion, that is, high priority threads give up CPU to low priority threads. Nucleus plus does not implement dynamic priority, and protect avoids deadlock.