新手问题,OS任务切换时RAM的临时数据如何入栈的
这个问题想不通,万望赐教在任务堆栈初始化时就已经分配了各个任务的堆栈首地址,而各个任务的堆栈是连续的,就像 :任务1堆栈底----任务堆栈顶---任务2堆栈底---任务2堆栈顶。任务切换时把PC返回地址 32个寄存器(AVR),等压入栈中,但是如果切换时临时数据多的话,是否保存在RAM中,这些数据也入栈么,又如何入栈呢?如果任务2压入数据太多,会不会把任务1的栈顶给覆盖了?求高手指点一下啊,不胜感激.下面是我看到的SMALLRTOS移植到AVR的部分代码 从本坛贴子(Small RTOS FOR AVR(ATmega16)(第三版))上下载的
#define STACK_END (uint8 *)&OS_STACK;
#define STACK_START (uint8 *)&OS_STACK;
uint8 OS_STACK;
uint8*OSTaskStackBottom;
void OSIdle(void)
{
while(1)
{
MCUCR &= ~((1 << SM0) | (1 << SM1) | (1 << SM2));
}
}
void OSStart(void)
{
uint8 *cp;
uint8 i,temp;
cp=STACK_START;
OSTaskStackBottom = STACK_START;
OSTaskStackBottom =STACK_END;
/* 初始化优先级最高的任务堆栈,使返回地址为任务开始地址 */
*cp-- = (uint8)((uint16)TaskFuction); //返回地址低8位
*cp-- = (uint8)((uint16)TaskFuction>>8); //返回地址高8位
SP = (uint16) cp;
/* 初始化优先级最低的任务堆栈 */
cp = STACK_END;
for(temp=0;temp<34;temp++)
{
*(++cp) = 0;
}
*(++cp) =(uint8)((uint16)OSIdle>>8); // 返回地址高8位
*(++cp) =(uint8)((uint16)OSIdle); //返回地址低8位
OSTaskStackBottom =(uint8 *)cp;
/* 初始化其它优先级的任务堆栈 */
for(i = OS_MAX_TASKS-1; i > 0; i--)
{
for(temp=0;temp<34;temp++)
{
*(++cp) = 0;
}
*(++cp) =(uint8)((uint16)TaskFuction>>8); //返回地址高8位
*(++cp) =(uint8)((uint16)TaskFuction); //返回地址低8位
OSTaskStackBottom =(uint8 *)cp;
}
/* 允许中断 */
Os_Enter_Sum = 1;
OS_EXIT_CRITICAL();
/* 函数返回优先级最高的任务 */
ret();
}
这样是不是每个任务堆栈大小都确定了? 如果任务数量确定了,是不是就可以确定OS_STACK_SIZE的数值了, 要入栈的只是寄存器,超过寄存器数量的临时变量本来就已经存放在所在任务的堆栈中,楼主应当先了解下函数调用时的反汇编,了解下栈的作用。 如果临时变量已经在栈里,那任务栈可用的空间就少了,那上述代码里的初始化的堆栈就不足以压入寄存器了,是吗 那就要看你自己分配的任务栈空间有多少了,自己需要用多少就分配多少,另外最好增加监控函数,监控栈的使用情况.
页:
[1]