51操作系统学习笔记(四):建立一个属于自己的AVR的RTOS(2)

mac2022-06-30  68

承接51操作系统学习笔记(三):建立一个属于自己的AVR的RTOS(1),在avr中调试一下下面的程序.

为了加深学习应用,决定把代码全部输一遍,比复制的学些效果应该好一些吧。

打开Avr studio 4,建立工程,选avr ,atmega128,

程序中用到一个gcc内嵌汇编的语句:

__asm__ __volatile__("RET \n\t");

参见关于“gcc内嵌汇编”的教程。

还有就是注意堆栈的设置:

100个单元的堆栈,&Stack[99]是第100单元的地址,第100单元放函数地址高8位,第99单元放函数地址低8位,然后sp指向第98单元。

 

原文:

/********************************************/

 

第二篇: 人工堆栈在单片机的指令集中,一类指令是专门与堆栈和PC指针打道的,它们是     rcall   相对调用子程序指令     icall   间接调用子程序指令     ret     子程序返回指令     reti    中断返回指令        对于ret和reti,它们都可以将堆栈栈顶的两个字节被弹出来送入程序计数器PC中,一般用来从子程序或中断中退出。其中reti还可以在退出中断时,重开全局中断使能。     有了这个基础,就可以建立我们的人工堆栈了。     例: #i nclude <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=pStack;                            //将堆栈指针指向人工堆栈的栈顶   __asm__ __volatile__("RET \n\t");    //返回并开中断,开始运行fun1() } int main(void) {    RunFunInNewStack(fun1,&Stack[99]); }      RunFunInNewStack(),将指向函数的指针的值保存到一个unsigned  char的数组Stack中,作为人工堆栈。并且将栈顶的数值传递组堆栈指针SP,因此当用"ret"返回时,从SP中恢复到PC中的值,就变为了指向fun1()的地址,开始运行fun1().     上面例子中在RunFunInNewStack()的最后一句嵌入了汇编代码 "ret",实际上是可以去除的。因为在RunFunInNewStack()返回时,编译器已经会加上"ret"。我特意写出来,是为了让大家看到用"ret"作为返回后运行fun1()的过程。

 

/*********************************************/

 

转载于:https://www.cnblogs.com/proteus/archive/2011/11/30/2269768.html

相关资源:JAVA上百实例源码以及开源项目
最新回复(0)