0

今日は少し問題がありますが、元はスタックにあると思います。

これは私の問題です:

次のように 3 つのユーザー タスクを宣言します。

void task1Function(void) {
    print_uart0("-usertask : First task is started...\r\n");
    while(1){
        //syscall(1);
    }
}

void task2Function(void) {
        print_uart0("-usertask : Second task is running...\r\n");
        //syscall(); /* To return in the kernel's mode */
        while(1){

        }
}

 void task3Function(void) {
            print_uart0("-usertask : Third task is running...\r\n");
            //syscall(); /* To return in the kernel's mode */
            while(1){

            }
    }

私は構造が以下の3つのタスクの配列を持っています:

typedef struct
{

    unsigned int *sp;
    unsigned int registers[12];
    unsigned int lr;
    unsigned int pc;
    unsigned int cpsr;
    unsigned int mode;
    unsigned int num;
    void *stack;
    int stacksize;

    int priority;
    int state;                    /* Running, Ready, Waiting, Suspended */

    /* Next and previous task in the queue */
    struct taskstruct *qnext, *qprev;
}taskstruct;

ここで私のタスクの初期化:

void init_task(taskstruct * task, void (*function)(void) ){
    task->sp = (unsigned int*)&function;
    task->registers[0] = 0; // r0
    task->registers[1] = 0; // r1
    task->registers[2] = 0; // r2
    task->registers[3] = 0; // r3
    task->registers[4] = 0; // r4
    task->registers[5] = 0; // r5
    task->registers[6] = 0; // r6
    task->registers[7] = 0; // r7
    task->registers[8] = 0; // r8
    task->registers[9] = 0; // r9
    task->registers[10] = 0; // r10
    task->registers[11] = 0; // r11
    task->registers[12] = 0; // r12
    task->lr = 0;
    task->pc = 0;
    task->cpsr = 0;
    task->mode = 0x10;
}

init_task(&task[0],&task1Function);
init_task(&task[1],&task2Function);
init_task(&task[2],&task3Function);

しかし、task[0].sp を activate 関数に渡すと、起動されるのは常に最後に宣言されたタスク (つまり 3 番目) です。

.global activate
activate:

LDR r12, [r0]
/*STMFD sp!,{r1-r11,lr}*/
NOP

msr CPSR_c, #0x10 /* User mode with IRQ enabled and FIQ disabled*/
mov pc, r12

ユーザースタックに問題があり、それぞれに異なるスタックをセットアップする必要があると思いますが、そうですか? この場合、どのように進めればよいか誰か教えてもらえますか?

よろしく、ヴィンセント

4

2 に答える 2

2

はい、あなたは正しいです。

スタックの状態はタスクの合計状態の一部であるため、タスクごとに個別のスタックが必要です。

次のようなものを追加できます

uint32_t stack[512];

もちろん、タスクを切り替えるときtaskstructに、それに応じてタスクポインターを設定/復元します。このコンテキストで十分な詳細を提供することは困難です。

于 2013-02-26T13:59:35.760 に答える
0

「わかりましたが、どうすればスタック タスクを割り当てることができますか? ' - malloc します。

taskstruct の最後にスタック スペースを追加することで、malloc を節約できます。現在のメンバーはすべて固定サイズであるため、malloc の合計サイズを簡単に計算できます。

これらのタスカーの難点は、割り込みエントリを正しく取得することです。割り込みハンドラがタスクの状態を変更する必要があり、スケジューラを介して終了する必要がある場合。これは、ネストされた割り込みで特に楽しいです。それでは頑張ってください!

于 2013-02-27T12:10:52.600 に答える