2

ARM926 でプリエンプティブ OS (ミニマリスト) を使用するのは終わりですが、問題が発生します。

今日、OS を起動し、(独自の stask を使用して) ユーザー モードに切り替え、タイマーの割り込み後に OS モード (SVC) に戻ることができます。

しかし、今日はタイマー割り込み前のコンテキストでユーザー関数に戻ろうとしています。

私がやったこと: 私のinitタスク関数:

init_task(taskstruct * task, unsigned int* stack, void (*function)(void) ){



    stack += STACK_SIZE;// - 16; /* End of stack, minus what we're about to push */
    //stack[0] = 0x10; /* User mode, interrupts on */
    //stack[1] = (unsigned int)function;

    task->sp = stack;

    task->sp[0] = task->registers[0]; // r0
    task->sp[1] = task->registers[1];// = task->sp[3];//0; // r1
    task->sp[2] = task->registers[2];// = task->sp[4];//0; // r2
    task->sp[3] = task->registers[3];// = task->sp[5];//0; // r3
    task->sp[4] = task->registers[4];// = task->sp[6];//0; // r4
    task->sp[5] = task->registers[5];// = task->sp[7];//0; // r5
    task->sp[6] = task->registers[6];// = task->sp[8];//0; // r6
    task->sp[7] = task->registers[7];// = task->sp[9];//0; // r7
    task->sp[8] = task->registers[8];// = task->sp[10];//0; // r8
    task->sp[9] = task->registers[9];// = task->sp[11];//0; // r9
    task->sp[10] = task->registers[10];// = task->sp[12];//0; // r10
    task->sp[11] = task->registers[11];// = task->sp[13];//0; // r11
    task->sp[12] = task->registers[12];// = task->sp[14];//0; // r12
    task->sp[13] = (unsigned int)function;
}

アクティベート機能:

.global activate
activate:
    /* Save kernel state */
    STMFD sp!,{r1-r12,lr}
    NOP
    msr CPSR_c, SYS_MODE /* Sys mode with IRQ enabled and FIQ disabled*/
    mov sp, r0 /* MOVE TO THE STACK USER
    /* LOAD THE TASK'S CONTEXT */
    mov ip, r0
    LDMFD sp!, {r0-ip,lr}
    NOP
    mov pc, lr

その呼び出し:

activate(task[0].sp);
print_uart0("Kernel gets back control ! \n");
print_uart0("Load the next task ! \n");
activate(task[0].sp);

irq_handler で行うこと:

irq_handler:
/* Save the return value */
SUB ip,lr,#4
BL event_irq_handler

/* Save the user task context */
MSR CPSR_c, #INT_OFF|SYS_MODE
MOV lr, ip
STMFD sp!,{r0-ip,lr}
NOP
MOV r0, sp
BL saveTaskContext


/* Load kernel state */
MSR CPSR_c,SVC_MODE
LDMFD sp!,{r1-r12,pc}
NOP

savcontext 関数:

int i = 0;
//char printable = 0x00;
/* UPDATE THE STACK TASK */
for ( i = 0 ; i <= 13 ; i++ ){
    task[0].sp[i] = *(ptr+i);
}

しかし、私の問題は、もう一度 activate(task[0].sp) を呼び出すと、どこにでも分岐し、メイン プログラムが再起動されることです。

どこが間違っていますか?

よろしく、 VincentB

4

2 に答える 2

1

大丈夫です、長い苦労の末、解決策を見つけることができました!

最終的なコードは、元のコードよりもかなり単純です。

irq_handler のコードを変更しただけで、残りのコードは以前の投稿と同じです。

irq_handler:
/* Save the return value */
SUB lr,lr,#4
STMFD sp!, {r0-ip, lr}^ /* Save the user task context */
MOV r0, sp
BL saveTaskContext

BL event_irq_handler


/* Load kernel state */
MSR CPSR_c,SVC_MODE
LDMFD sp!,{r1-r12,pc}
NOP
于 2013-03-03T16:42:52.707 に答える
0

私はただあなたの中で考えます

for ( i = 0 ; i <= 13 ; i++ ){
    task[0].sp[i] = *(ptr+i);
}

このようにすべきですか?

for ( i = 0 ; i <= 13 ; i++ ){
    task[0].sp[i] = (*ptr+i);
}

ptr考えてみます... のアドレスにの値を追加しますが、iよくわかりません

于 2013-03-03T14:51:53.437 に答える