| 
 | 
 
最近在跑“建立一个属于自己的AVR 的RTOS”中的例子,环境为:WinAVR-20100110编译, Proteus7.5 SP3仿真,MEGA16的芯片。跑了一个通过子程序退出“RET”命令将人工堆栈中的函数地址赋给PC的例子,出错。程序如下: 
#include <avr/io.h> 
 
 void fun1(void) 
 { 
 unsigned char i=0; 
 while(1) 
 { 
 PORTB=i++; 
 PORTC=0x01<<(i%8); 
 } 
 } 
 
 unsigned char Stack[100]; //建立一个100 字节的人工堆栈 
 
void RunFunInNewStack(void (*pfun)(),unsigned char *pStack) 
 { 
 *pStack--=(unsigned int)pfun>>8; //将函数的地址高位压入堆栈, 
*pStack--=(unsigned int)pfun; //将函数的地址低位压入堆栈, 
SP=(unsigned int)pStack; //将堆栈指针指向人工堆栈的栈顶 
__asm__ __volatile__("RET \n\t"); //返回并开中断,开始运行fun1() 
 } 
 
 int main(void) 
 { 
 RunFunInNewStack(fun1,&Stack[99]); 
 } 
 
工程与仿真环境见附件 
 
 仿真报错:PC=0X7C02  应该是溢出了,我看了下fun1的PC应该是0x007C。我的理解是入栈的函数高位应该是00,低位应该是7C,可是出栈的时候错配了,变成了0x7C00,这个在debug中的PC中验证了。我把高位和低位入栈顺序改变,程序可以找到fun1的0x007C,正常运行。不过这应该是不对的,因为AVR中的入栈顺序应该是先高在低,这里是弹出到PC时错配了。 
 问题是如何修改? 
 这个问题不解决,后面跑RTOS的时候,任务堆栈每次都错配,任务调度没法执行。 
 谢谢! 
 
 |   
 
 
 
 |