当前位置:首页 > 单片机 > 单片机
[导读]Reentrant Functions可重入函数可重入函数可以被多个进程同时调用。当一个可重入函数执时,其他的处理可以中断这个函数的执行,而开始执行这同一重入函数。一般情况下,Cx51中的函数不能够被同时多次调用或者是重入。

Reentrant Functions可重入函数

可重入函数可以被多个进程同时调用。当一个可重入函数执时,其他的处理可以中断这个函数的执行,而开始执行这同一重入函数。一般情况下,Cx51中的函数不能够被同时多次调用或者是重入。原因是函数的参数和局部变量都放在固定的内存中。函数reentrant属性允许声明可重入的函数,如:

int calc (char i, int b) reentrant {

int x;

x = table [i];

return (x * b);

}

可重入函数可以被多次调用,而且可以同时被两个或两个以上的进程调用。在实时应用或在中断和非中断程序都要调用同一个函数时就需要使用可重入函数。

对于每个可重入函数,根据存储器的模式在内部或外部存储器中模拟了一个可重入堆栈,

(1) SMALL模式下,可重入函数在IDATA区模拟可重入堆栈

(2) COMPACT模式下,可重入函数在PDATA区模拟可重入堆栈

(3) LARGE模式下,可重入函数在XDATA区模拟可重入堆栈

可重入函数使用缺省的存储器模式来决定哪一个存储区用来模拟可重入堆栈。你也可以为一个函数指定存储器模式。

使用reentrant属性声时函数时必须遵循以下规则:

(1)不能使用bit类型的参数。局部bit标量也不可使用。函数的可重入能不包括可位寻址的变量

(2)可重入函数不能从alien函数中调用

(3)可重入函数不能使用alien属性指定来使能PL/M-51参数传递规则。

(4)一个可重入函数可以同时具有其他属性比如using和interrupt,也可能包含存储器模式属性。

(5)返回地址放在8051的硬件堆栈里。任何其他的PUSH和POP操作都会影响8051的硬件堆栈。

(6)使用不同存储器模式的函数可能会混合使用。然而,每个可重入函数都必须有正确的函数原型,而且函数原因中必须包含存储器模式属性。这对调用时库把函数参数入在正确的可重入堆栈中是非常必要的。

(7)三个可能可重入模式都有自己的可重入堆栈和堆栈指针。

模拟的可重入堆栈的构架并不是高效的,但是对于没有适合的寻址方式的8051是很必要的。因此要减少可重入函数的使用。

可重入函数模拟的堆栈有它自己的指针,这些堆栈和指针是与8051的堆栈和指针是相互独立的。堆栈和指针的定义和初始化都在文件STARTUP.A51中

下表详细地显示了三种存储器模式下堆栈指针的汇编变量名称,数据区和大小

Model Stack Pointer Stack Area

SMALL ?C_IBP (1 Byte) 间接访问内部存府器(idata). 最大256 字节

COMPACT ?C_PBP (1 Byte) 按页访问外部数据存储器(pdata).每页最大256 字节

LARGE ?C_XBP (2 Bytes) 访问外部存储器 (xdata).最大64 K字节

可重入函数模拟的堆栈的增长方向是从顶到底的。8051的硬件堆栈是相反的,也就增长方向是从底到顶的。当采用SMALL存储器模式时,模拟的堆栈和8051的硬件堆栈分享了同一片存储区域,但增长方向是相反的。

模拟的堆栈和指针都在Cx51的起始代码文件STARTUP.A51(可以LIB子文件夹中找到)中声明和初始化。必须在初始化代码中指定哪些模拟堆栈要初始化用于可重入函数。也可以起始代码中修改模拟堆栈栈顶的起始地址。

Alien Function (PL/M-51 Interface)

Cx51可以在C程序中调用PL/M-51写的运行时库。在C程序中可以通过声明PL/M-51运行时库是外部的并且使用alien函数类型进行标识,就可访问PL/M-51运行时库了。如:

extern alien char plm_func (int, char);

char c_func (void) {

int i;

char c;

for (i = 0; i < 100; i++) {

c = plm_func (i, c); /* call PL/M func */

}

return (c);

}

也可用C写出能被PL/M运行时库调用的函数。使用alien函数类型来声明C函数就能做到这一点。如:

alien char c_func (char a, int b) {

return (a * b);

}

PL/M-51函数的参数和返回值可能是如下几种类型中的一种:bit, char, unsigned char, int and unsigned int。其他的类型,包括long, float和所有类型的指针,可以在C函数中使用alien类型指定。然而,因PL/M-51不直接支持32位二进制整型和浮点型数据,这些类型都要小心使用。

在PL/M-51中声明的公有变量都可以C程序中通过声明他是外部的就可以用了,这与在C程序中的做法相同。

Real-time Function Tasks实时函数任务

通过使用_task_和_priority_关键字,Cx51编译器支持RTX51FULL和RTX51 Tiny实时多任务操作系统。使用关键字_task_可以把一个函数定义为一个实时任务。使用关键字_priority_可指定一个任务的优先级。如:

void func (void) _task_ num _priority_ pri

num 任务标号:对于RTX51FULL是0-255,对于RTX51Tiny是0-15

pri 任务估先级。

任务函数的返回类型必须是void,参数也必须是void

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

MIKROE增加了图形功能,CLANG支持ARM和RISC-V以及许多其他功能

关键字: 编译器 RISC-V架构 工业自动化

IAR Embedded Workbench for Arm已全面支持恩智浦最新的S32系列,可加速软件定义汽车的车身和舒适性应用的开发

关键字: 电机控制 电动汽车 编译器

这款新编译器专为dsPIC®数字信号控制器 (DSC)优化设计,可为实时应用定制许可选项

关键字: 编译器 数字信号控制器 自动驾驶

C语言编译器是一种用于将C语言源代码转换为可执行程序的软件工具。它的主要功能是将C语言代码翻译成机器语言,以便计算机能够理解和执行。C语言编译器通常包括预处理器、编译器、汇编器和链接器等多个组件,它们协同工作以完成编译过...

关键字: C语言 编译器 Microsoft Visual C++

IAR Embedded Workbench 9.40版本引入了与指针验证和分支目标识别(PACBTI)扩展的无缝兼容性,保护嵌入式应用程序免受各种安全攻击。

关键字: 代码 嵌入式应用程序 编译器

在过去数十年,摩尔定律一直支配着半导体的发展。随着MCU的性能越来越强,嵌入式产品也越来越智能,嵌入式软件也变得越来越复杂。编译器作为嵌入式软件开发的基础工具,将程序员编写的源代码转换为底层硬件可以执行的机器指令。一款优...

关键字: 摩尔定律 嵌入式 软件开发 编译器

Python的创始人是一位荷兰籍的程序员——吉多·范罗苏姆(Guido van Rossum),江湖外号“龟叔”。据说这个外号是由于Guido的开头与龟的拼音gui相同得来的,所以Guido也被程序员们戏称为“龟叔”。在...

关键字: Python 编译器 人工智能

单片机内部有很多的特殊功能寄存器,每个寄存器在单片机内部都分配有唯一的地址,一般我们会根据寄存器功能的不同给寄存器赋予各自的名称,当我们需要在程序中操作这些特殊功能寄存器时,必须要在程序的最前面将这些名称加以声明,声明的...

关键字: C51 数据类型 扩充定义

数据元(Data Element),也称为数据元素,是用一组属性描述其定义、标识、表示和允许值的数据单元,在一定语境下,通常用于构建一个语义正确、独立且无歧义的特定概念语义的信息单元。数据元可以理解为数据的基本单元,将若...

关键字: C51 数据类型

从汇编角度来说,如果“test %al, %al”能改成“test %0x1, %al”就没有匪夷所思的问题了,如此一来应该会降低CPU的效率,毕竟执行指令还需要一个立即数,我没搞过编译器也没设计过CPU,纯属瞎猜,能搞...

关键字: 汇编 CPU 编译器
关闭
关闭