如何将用户堆栈指针的值保存到IRQ模式的变量中

时间:2011-08-23 00:33:05

标签: operating-system arm

我正在尝试为ARM处理器构建简单的小型抢占式操作系统(用于试验ARM架构)。

我的TCB有指向正确线程堆栈的指针,我正在我的dispatch()方法中更新/读取 - 类似这样的东西(混合C和汇编)

asm("
  ldr r5, =oldSP
  ldr sp, [r5]
");
myThread->sp = oldSP;
myThread = getNewThread();
newSP = myThread->sp
asm("
  ldr r5, =newSP
  str sp, [r5]
");

当我从用户模式(显式调用)调用此dispatch()时,一切正常 - 线程正在丢失并获得处理器。

但是,我正在尝试构建抢占式操作系统,因此我需要定时器IRQ来调用调度 - 这是我的问题 - 在irq模式下,r13_usr寄存器被隐藏,所以我无法访问它。我也无法改为SVC模式 - 它也隐藏在那里。

我看到的一个解决方案是切换到用户模式(在我输入调度方法之后),更新/更改sp字段并切换回irq模式以继续我离开的位置。这可能吗?

另一个解决方案是尝试不再次进入IRQ模式 - 我只需要处理硬件事物(在定时器外围设置正确的状态位),调用dispatch()(仍处于irq模式),其中我将屏蔽定时器中断,切换到用户模式,执行上下文切换,取消屏蔽定时器中断并继续。恢复的线程应该在它被挂起的地方继续(在进入IRQ之前)。它是否正确? (这应该是正确的,如果中断,处理器将r4-r11和lr推入用户堆栈,但我认为我错了......)

谢谢。

3 个答案:

答案 0 :(得分:2)

我想我可能在这里回答了类似的问题: "ARM - access R13 and R14 from Supervisor Mode"

在您的情况下,只需使用“IRQ模式”而不是“主管模式”,但我认为同样的原则适用。

长&如果你从IRQ切换到用户模式,这是一个单向陷阱门,你不能简单地在软件控制下切换回IRQ模式。

但是通过操纵CPSR并切换到系统模式,您可以获得r13_usr然后切换回上一个模式(在您的情况下,IRQ模式)。

答案 1 :(得分:0)

通常你在启动时设置所有这些,各种堆栈寄存器,处理程序等。如果有理由进入用户模式并退出它,你可以从用户模式使用swi并让swi处理程序执行无论你想在用户模式下做什么,或者任务切换到svc模式处理程序或类似的东西。

答案 2 :(得分:0)

您使用哪种ARM变体?在像Cortex_M3这样的现代变体上,您有MRS / MSR指令。这样,您可以通过将它们移入/移出通用寄存器来访问MSP和PSP寄存器。

CMSIS甚至将__get_MSP()和__get_PSP()定义为C函数,以及它们的__set [...]对应物。

编辑:这似乎仅适用于Thumb-2。对不起噪音。