51上移植UC/OS II 2011年11月12日

来源:互联网 发布:mysql分页 编辑:程序博客网 时间:2024/06/05 23:08

在keil c移植UCOSII有两个比较特殊的地方。1、局部变量的覆盖问题。2、函数的再入性问题。
下面我就这两方面谈一下自己的体会。
1、关于局部变量的覆盖。在PC机上的C编译器,一般是这样,在函数调用时临时给局部变量在堆栈空间中分配地址,函数返回后释放在堆栈中分配的空间。如果一个函数被递归调用,每次调用时局部变量分配的地址空间都不相同,因此不存在局部变量被覆盖的问题。又由于局部变量是分配在堆栈空间因此函数自然就具有再入属性。但在keil c中就不一样了,由于8051系列单片机的堆栈空间小,函数的局部变量是分配在固定的地址空间,在编译时就已经分配好了,而不是在函数被调用时才动态分配。为了提高内存的使用效率keil c默认会进行变量的覆盖分析。也就是根据函数的相互调用关系,把不可能同时被调用的函数的局部变量分配在同一空间,这样既能保证函数的正常执行,又能节约内存空间。
在不具有多任务内核的应用中,在主程序中被调用的函数如果在中断服务程序中也被调用的话,也会存在局部变量覆盖的问题。因为有可能在主程序运行此函数时产生一个中断,在中断服务程序中也调用了同一函数,在中断返回时,函数的局部变量有可能已被修改,主程序接着断点往下运行就可能产生错误。在有多任务内核的应用中,情况就更复杂一些,局部变量覆盖的问题不仅涉及到任务和中断,同时还涉及到任务和任务之间。
2、关于函数的再入性。在keil c中函数的再入性有两个概念。一、函数固有的再入属性。如果函数的行参和局部变量(行参也是局部变量)只使用工作寄存器,也即R0 ~ R7、ACC、 B,那么此函数就具有再入属性。因为不管应用程序中是否具有多任务内核,R0 ~ R7、ACC、 B在中断和任务切换时都会被保护,被中断的函数重新运行时,会恢复被保护的寄存器,因此不会发生错误。二、给函数定义再入属性。在定义函数时用reentrant关键字,keil c会建立一个模拟栈,函数的局部变量在模拟栈中动态的分配。8051系列单片机的功能比PC机差多了,采用这种方式效率极差。

函数如果具有再入性,就不存在局部变量被覆盖的问题;但解决了局部变量覆盖问题,函数不一定就具有再入性。

本人的移植方法的特点:禁止进行覆盖分析,解决了局部变量的覆盖问题。但没有解决函数再入性的问题。解决函数再入性的问题有很多方法。例如:定义具有固有再入属性的函数;使用信号量;关中断等.

原创粉丝点击