您的位置 首页 主动

单片机multiple中止调用子函数

1、中断里可以调用子函数。2、普通情况下,要保证这个子函数(以及这个子函数调用过的函数)不被其他的函数调用。3、如果这个子函数确实需

1、中止里能够调用子函数

2、一般状况下,要确保这个子函数(以及这个子函数调用过的函数)不被其他的函数调用。
3、假如这个子函数的确需求被其他的函数调用,要将这个子函数做成再入函数。
*一切中止中调用子函数的问题,都是由于函数的再入问题引起的

在KeilC中,假如要在中止中调用其他函数,假如此函数在中止外没有其他程序调用,自然是没有关系,不然需求将被调用的函数设置为可重入,在这种状况下,函数的出入口地址和参数都保存在仓库中.

功用:屏幕显现定位 show_sit
*********************************************/
void show_sit(uchar screen,uchar row,uchar x_sit,uchar y_sit)reentrant{

select_screen(screen);
set_line(row);
set_page(x_sit);
set_column(y_sit);

}

留意:reentrant 要害字

================以下来之网络觉得挺好=======================

让我来告知你答案!一、可重入函数
1)什么是可重入性?
可重入(reentrant)函数能够由多于一个使命并发运用,而不必忧虑数据过错。相反,不行重入(non-reentrant)函数不能由超越一个使命所同享,除非能确保函数的互斥(或许运用信号量,或许在代码的要害部分禁用中止)。可重入函数能够在恣意时间被中止,稍后再持续运转,不会丢掉数据。可重入函数要么运用本地变量,要么在运用大局变量时维护自己的数据。
2)可重入函数:
不为接连的调用持有静态数据。
不回来指向静态数据的指针;一切数据都由函数的调用者供给。
运用本地数据,或许经过制造大局数据的本地复制来维护大局数据。
假如有必要拜访大局变量,记住运用互斥信号量来维护大局变量。
绝不调用任何不行重入函数。
3)不行重入函数:
函数中运用了静态变量,无论是大局静态变量仍是部分静态变量。
函数回来静态变量。
函数中调用了不行重入函数。
函数体内运用了静态的数据结构;
函数体内调用了malloc()或许free()函数;
函数体内调用了其他规范I/O函数。
函数是singleton中的成员函数并且运用了不运用线程独立存储的成员变量。
总的来说,假如一个函数在重入条件下运用了未受维护的同享的资源,那么它是不行重入的。
===============================================================

首要用于多使命环境中,一个可重入的函数简略来说便是能够被中止的函数,也便是说,能够在这个函数履行的任何时间中止它,转入OS调度下去履行其他一段代码,而回来操控时不会呈现什么过错;而不行重入的函数由于运用了一些体系资源,比方大局变量区,中止向量表等,所以它假如被中止的话,或许会呈现问题,这类函数是不能运转在多使命环境下的。

也能够这样了解,重入即表明重复进入,首要它意味着这个函数能够被中止,其次意味着它除了运用自己栈上的变量以外不依赖于任何环境(包含static),这样的函数便是purecode(纯代码)可重入,能够答应有该函数的多个副本在运转,由于它们运用的是别离的栈,所以不会相互搅扰。假如的确需求拜访大局变量(包含static),必定要留意施行互斥手法。可重入函数在并行运转环境中非常重要,可是一般要为拜访大局变量支付一些功用价值。

编写可重入函数时,若运用大局变量,则应经过关中止、信号量(即P、V操作)等手法对其加以维护。

阐明:若对所运用的大局变量不加以维护,则此函数就不具有可重入性,即当多个进程调用此函数时,很有或许使有关大局变量变为不行知状况。

示例:假定Exam是int型大局变量,函数Squre_Exam回来Exam平方值。那么如下函数不具有可重入性。

unsigned int example( int para )

{

unsigned int temp;
Exam = para; //(**)
temp = Square_Exam( );
return temp;
}
此函数若被多个进程调用的话,其成果或许是不知道的,由于当(**)句子刚履行完后,其他一个运用本函数的进程或许正好被激活,那么当新激活的进程履行到此函数时,将使Exam赋与另一个不同的para值,所以当操控从头回到“temp = Square_Exam( )”后,核算出的temp很或许不是料想中的成果。此函数应如下改善。

unsigned int example( int para ) {
unsigned int temp;
[请求信号量操作] //(1)
Exam = para;
temp = Square_Exam( );
[开释信号量操作]
return temp;
}
(1)若请求不到“信号量”,阐明其他的进程正处于给Exam赋值并核算其平方进程中(即正在运用此信号),本进程有必要等候其开释信号后,才可持续履行。若请求到信号,则可持续履行,但其它进程有必要等候本进程开释信号量后,才干再运用本信号。

确保函数的可重入性的办法:
在写函数时分尽量运用部分变量(例如寄存器、仓库中的变量),关于要运用的大局变量要加以维护(如采纳关中止、信号量等办法),这样构成的函数就必定是一个可重入的函数。
VxWorks中采纳的可重入的技能有:
* 动态仓库变量(各子函数有自己独立的仓库空间)
* 受维护的大局变量和静态变量
* 使命变量

————————————————–
在实时体系的规划中,常常会呈现多个使命调用同一个函数的状况。假如这个函数不幸被规划成为不行重入的函数的话,那么不同使命调用这个函数时或许修正其他使命调用这个函数的数据,然后导致不行意料的结果。那么什么是可重入函数呢?所谓可重入函数是指一个能够被多个使命调用的进程,使命在调用时不必忧虑数据是否会犯错。不行重入函数在实时体系规划中被视为不安全函数。满意下列条件的函数多数是不行重入的:
1) 函数体内运用了静态的数据结构;
2) 函数体内调用了malloc()或许free()函数;
3) 函数体内调用了规范I/O函数。

下面举例加以阐明。
A. 可重入函数
void strcpy(char *lpszDest, char *lpszSrc)

{
while(*lpszDest++=*lpszSrc++);
*dest=0;
}

B.不行重入函数1
charcTemp;//大局变量
void SwapChar1(char *lpcX, char *lpcY)

{
cTemp=*lpcX;
*lpcX=*lpcY;
lpcY=cTemp;//拜访了大局变量
}

C.不行重入函数2
void SwapChar2(char *lpcX,char *lpcY)

{
static char cTemp;//静态部分变量
cTemp=*lpcX;
*lpcX=*lpcY;
lpcY=cTemp;//运用了静态部分变量
}

问题1,怎么编写可重入的函数?
答:在函数体内不拜访那些大局变量,不运用静态部分变量,坚持只运用部分变量,写出的函数就将是可重入的。假如有必要拜访大局变量,记住运用互斥信号量来维护大局变量。

问题2,怎么将一个不行重入的函数改写成可重入的函数?
答:把一个不行重入函数变成可重入的仅有办法是用可重入规矩来重写它。其实很简略,只需恪守了几条很简单了解的规矩,那么写出来的函数便是可重入的。
1) 不要运用大局变量。由于其他代码很或许掩盖这些变量值。
2) 在和硬件发生交互的时分,牢记履行相似disinterrupt()之类的操作,便是封闭硬件中止。完结交互记住翻开中止,在有些系列上,这叫做“进入/退出中心”。
3) 不能调用其它任何不行重入的函数。
4) 慎重运用仓库。最好先在运用前先OS_ENTER_KERNAL。

仓库操作触及内存分配,稍不留神就会形成益出导致掩盖其他使命的数据,所以,请慎重运用仓库!最好别用!许多黑客程序就运用了这一点以便体系履行不合法代码然后轻松取得体系操控权。还有一些规矩,总归,时间记住一句话:确保中止是安全的!

实例问题:从前规划过如下一个函数,在代码检视的时分被提示有bug,由于这个函数是不行重入的,为什么?
unsigned int sum_int( unsigned int base )

{
unsigned int index;
static unsigned int sum = 0; //留意,是static类型
for (index = 1; index <= base; index++)
sum += index;
return sum;
}

剖析:所谓的函数是可重入的(也能够说是可猜测的),即只需输入数据相同就应发生相同的输出。这个函数之所以是不行猜测的,便是由于函数中运用了static变量,由于static变量的特征,这样的函数被称为:带“内部存储器”功用的的函数。因而假如需求一个可重入的函数,必定要防止函数中运用static变量,这种函数中的static变量,运用原则是,能不必尽量不必。
将上面的函数修正为可重入的函数,只需将声明sum变量中的static要害字去掉,变量sum即变为一个auto类型的变量,函数即变为一个可重入的函数。
当然,有些时分,在函数中是有必要要运用static变量的,比方当某函数的回来值为指针类型时,则有必要是static的部分变量的地址作为回来值,若为auto类型,则回来为错指针。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/ziliao/zhudong/260774.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部