|
通过BASEPRI寄存器可以设置关闭受到uCOS-III管理的中断。
而其它不受控制的中断可以像裸机一样使用,让这些中断可以得到及时响应,降低中断延迟时间。
- /*
- *********************************************************************************************************
- * KERNEL AWARE IPL BOUNDARY
- *
- * Note(s) : (1) Determines the IPL level that establishes the boundary for ISRs that are kernel-aware and
- * those that are not. All ISRs at this level or lower are kernel-aware.
- *
- * (2) ARMv7-M: Since the port is using BASEPRI to separate kernel vs non-kernel aware ISR, please
- * make sure your external interrupt priorities are set accordingly. For example, if
- * CPU_CFG_KA_IPL_BOUNDARY is set to 4 then external interrupt priorities 4-15 will be kernel
- * aware while priorities 0-3 will be use as non-kernel aware.
- *********************************************************************************************************
- */
- #define CPU_CFG_KA_IPL_BOUNDARY 4u
复制代码
现在的开关中断实现:
- #define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(CPU_CFG_KA_IPL_BOUNDARY << (8u - CPU_CFG_NVIC_PRIO_BITS));} while (0)
- #define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU BASEPRI priority level. */
- #ifdef CPU_CFG_INT_DIS_MEAS_EN
- /* Disable interrupts, ... */
- /* & start interrupts disabled time measurement.*/
- #define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \
- CPU_IntDisMeasStart(); } while (0)
- /* Stop & measure interrupts disabled time, */
- /* ... & re-enable interrupts. */
- #define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \
- CPU_INT_EN(); } while (0)
- #else
- #define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */
- #define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */
- #endif
复制代码
具体实现:
- ;********************************************************************************************************
- ; CRITICAL SECTION FUNCTIONS
- ;
- ; Description : Disable/Enable Kernel aware interrupts by preserving the state of BASEPRI. Generally speaking,
- ; the state of the BASEPRI interrupt exception processing is stored in the local variable
- ; 'cpu_sr' & Kernel Aware interrupts are then disabled ('cpu_sr' is allocated in all functions
- ; that need to disable Kernel aware interrupts). The previous BASEPRI interrupt state is restored
- ; by copying 'cpu_sr' into the BASEPRI register.
- ;
- ; Prototypes : CPU_SR CPU_SR_Save (CPU_SR new_basepri);
- ; void CPU_SR_Restore(CPU_SR cpu_sr);
- ;
- ; Note(s) : (1) These functions are used in general like this :
- ;
- ; void Task (void *p_arg)
- ; {
- ; CPU_SR_ALLOC(); /* Allocate storage for CPU status register */
- ; :
- ; :
- ; CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */
- ; :
- ; :
- ; CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */
- ; :
- ; }
- ;
- ; (2) Increasing priority using a write to BASEPRI does not take effect immediately.
- ; (a) IMPLICATION This erratum means that the instruction after an MSR to boost BASEPRI
- ; might incorrectly be preempted by an insufficient high priority exception.
- ;
- ; (b) WORKAROUND The MSR to boost BASEPRI can be replaced by the following code sequence:
- ;
- ; CPSID i
- ; MSR to BASEPRI
- ; DSB
- ; ISB
- ; CPSIE i
- ;********************************************************************************************************
- CPU_SR_Save
- CPSID I ; Cortex-M7 errata notice. See Note #2
- PUSH {R1}
- MRS R1, BASEPRI
- MSR BASEPRI, R0
- DSB
- ISB
- MOV R0, R1
- POP {R1}
- CPSIE I
- BX LR
- CPU_SR_Restore
- CPSID I ; Cortex-M7 errata notice. See Note #2
- MSR BASEPRI, R0
- DSB
- ISB
- CPSIE I
- BX LR
复制代码
|
|