我有一个小函数,我已经在内核源代码(linux 3.0)中添加了它,它完成了一些任务并且在SVC模式下工作正常。但是在中断模式下(即,通过local_irq_enable
在内核中启用定时器中断时),它不起作用。所以我想在执行我的功能之前切换到SVC模式。我已从其中一个帖子中获取了切换模式的代码。
void myfunction(..some args)
{
unsigned int oldmode = get_cpsr() & 0x1f;
if (oldmode == 18) // Check for IRQ mode
change_mode(MODE_SVC);
// ...My code ....
restore_mode(oldmode);
}
定义如下:
#define MODE_IRQ 0x12
#define MODE_SVC 0x13
#define change_mode(mode) asm("cps %0" : : "I"(mode))
#define restore_mode(mode) \
mode &= 0x1f; \
asm(" msr cpsr, %0\n" : : "r"(mode) : "cc")
static inline unsigned int get_cpsr(void)
{
unsigned int val;
__asm__ __volatile__ (" mrs %0, cpsr\n"
: "=r" (val));
return val;
}
即使在此之后我也没有得到正确的输出。函数执行卡在某处。我调试了它被卡住的地址,它指向 System.map
的这些符号 __exception_text_start
_stext
asm_do_IRQ
我对函数的使用是否正确。你能建议我解决这个问题吗?我在ARMv7板上运行此映像。最后,在更改模式后,我的函数中有调用某些内核API,如printch()
。