如何为ARM上的每个任务定义堆栈

时间:2013-02-26 13:51:43

标签: c assembly arm

今天我有一些问题,我认为起源是关于堆栈的。

这是我的问题:

我声明了三个这样的用户任务:

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){

            }
    }

我有三个任务的数组,其结构如下:

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);

但是当我将任务[0] .sp传递给我的激活函数时,它始终是最后声明的任务(即第三个):

.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

所以我猜我的用户堆栈有问题,我必须为每个堆栈设置不同的堆栈,对不对?在这种情况下,有人可以告诉我如何继续吗?

问候,文森特

2 个答案:

答案 0 :(得分:2)

是的,你是对的。

每个任务必须有单独的堆栈,因为堆栈的状态是任务总状态的一部分。

您可以添加类似

的内容
uint32_t stack[512];

到你的taskstruct,然后在切换任务时相应地设置/恢复任务指针。在这种情况下很难提供足够的细节。

答案 1 :(得分:0)

'好的,但我如何分配堆栈任务? ' - malloc it。

您可以通过在任务结构末尾添加堆栈空间来节省mallocs - 所有当前成员都是固定大小的,因此计算malloc的总大小很容易。

这些任务的硬位正在使中断输入正确,即。当中断处理程序需要更改任务状态,因此必须通过调度程序退出。嵌套中断这一点特别有趣。祝你好运!