有没有办法在用户模式下为 azure-rtos (threadx) 运行 线程?
Is there a way to run thread in USER Mode for azure-rtos (threadx)?
我一直在玩 azure-rtos (THREADX) 并尝试为基于 cortex R5 的系统移植 OS。查看端口文件后,似乎 OS 运行 线程处于主管 (SVC) 模式。
例如,在函数 _tx_thread_stack_build
中,在为线程构建堆栈时,CPSR
的初始化值使得模式位对应于 SVC 模式。这个初始化值稍后用于在跳转到线程入口函数之前初始化CPSR。
以下是函数 _tx_thread_stack_build
的片段,它在线程的堆栈上存储 CPSR 的初始化值。供您参考,请参阅文件 tx_thread_stack_build.S.
.global _tx_thread_stack_build
.type _tx_thread_stack_build,function
_tx_thread_stack_build:
@ Stack Bottom: (higher memory address) */
@
...
MRS r1, CPSR @ Pickup CPSR
BIC r1, r1, #CPSR_MASK @ Mask mode bits of CPSR
ORR r3, r1, #SVC_MODE @ Build CPSR, SVC mode, interrupts enabled
STR r3, [r2, #4] @ Store initial CPSR
...
再举个例子,函数tx_thread_context_restore.S
从IRQ模式切换到SVC模式,保存线程被切换出来的上下文,说明OS这里假设线程是运行 在 SVC 模式下。供您参考,请参阅文件 tx_thread_context_restore.s
以下是被切换线程的函数保存上下文的片段。
LDMIA sp!, {r3, r10, r12, lr} ; Recover temporarily saved registers
MOV r1, lr ; Save lr (point of interrupt)
MOV r2, #SVC_MODE ; Build SVC mode CPSR
MSR CPSR_c, r2 ; Enter SVC mode
STR r1, [sp, #-4]! ; Save point of interrupt
STMDB sp!, {r4-r12, lr} ; Save upper half of registers
MOV r4, r3 ; Save SPSR in r4
MOV r2, #IRQ_MODE ; Build IRQ mode CPSR
MSR CPSR_c, r2 ; Enter IRQ mode
LDMIA sp!, {r0-r3} ; Recover r0-r3
MOV r5, #SVC_MODE ; Build SVC mode CPSR
MSR CPSR_c, r5 ; Enter SVC mode
STMDB sp!, {r0-r3} ; Save r0-r3 on thread's stack
这让我想到了一个问题,有没有办法在 USER 模式下 运行 线程? OS 中的典型情况是线程 运行 处于 USER 模式,而内核和它提供的服务 运行 处于 SVC 模式,而 Azure RT 似乎并非如此OS.
这是设计使然,ThreadX 是一个小型单片内核,其中应用程序代码与内核紧密集成,并且位于相同的地址 space 和模式中。这样可以实现更高的性能和更小的占用空间。您还可以使用 ThreadX 模块,其中可用的 MPU 或 MMU 用于将内核和用户代码分成不同的模式并提供额外的保护,但这会导致性能和占用空间的损失很小。
我一直在玩 azure-rtos (THREADX) 并尝试为基于 cortex R5 的系统移植 OS。查看端口文件后,似乎 OS 运行 线程处于主管 (SVC) 模式。
例如,在函数 _tx_thread_stack_build
中,在为线程构建堆栈时,CPSR
的初始化值使得模式位对应于 SVC 模式。这个初始化值稍后用于在跳转到线程入口函数之前初始化CPSR。
以下是函数 _tx_thread_stack_build
的片段,它在线程的堆栈上存储 CPSR 的初始化值。供您参考,请参阅文件 tx_thread_stack_build.S.
.global _tx_thread_stack_build
.type _tx_thread_stack_build,function
_tx_thread_stack_build:
@ Stack Bottom: (higher memory address) */
@
...
MRS r1, CPSR @ Pickup CPSR
BIC r1, r1, #CPSR_MASK @ Mask mode bits of CPSR
ORR r3, r1, #SVC_MODE @ Build CPSR, SVC mode, interrupts enabled
STR r3, [r2, #4] @ Store initial CPSR
...
再举个例子,函数tx_thread_context_restore.S
从IRQ模式切换到SVC模式,保存线程被切换出来的上下文,说明OS这里假设线程是运行 在 SVC 模式下。供您参考,请参阅文件 tx_thread_context_restore.s
以下是被切换线程的函数保存上下文的片段。
LDMIA sp!, {r3, r10, r12, lr} ; Recover temporarily saved registers
MOV r1, lr ; Save lr (point of interrupt)
MOV r2, #SVC_MODE ; Build SVC mode CPSR
MSR CPSR_c, r2 ; Enter SVC mode
STR r1, [sp, #-4]! ; Save point of interrupt
STMDB sp!, {r4-r12, lr} ; Save upper half of registers
MOV r4, r3 ; Save SPSR in r4
MOV r2, #IRQ_MODE ; Build IRQ mode CPSR
MSR CPSR_c, r2 ; Enter IRQ mode
LDMIA sp!, {r0-r3} ; Recover r0-r3
MOV r5, #SVC_MODE ; Build SVC mode CPSR
MSR CPSR_c, r5 ; Enter SVC mode
STMDB sp!, {r0-r3} ; Save r0-r3 on thread's stack
这让我想到了一个问题,有没有办法在 USER 模式下 运行 线程? OS 中的典型情况是线程 运行 处于 USER 模式,而内核和它提供的服务 运行 处于 SVC 模式,而 Azure RT 似乎并非如此OS.
这是设计使然,ThreadX 是一个小型单片内核,其中应用程序代码与内核紧密集成,并且位于相同的地址 space 和模式中。这样可以实现更高的性能和更小的占用空间。您还可以使用 ThreadX 模块,其中可用的 MPU 或 MMU 用于将内核和用户代码分成不同的模式并提供额外的保护,但这会导致性能和占用空间的损失很小。