Error: Undefined external "_OS_ENTER_CRITICAL::?relay" referred in OSMutex ( E:\work\Internet_IC_Reader\openOS51\IAR_OpenOS-51\Debug\Obj\OSMutex.r51 )
OS_ENTER_CRITICAL 我的这个程序是在汇编文件 S51里面编写的,但是C语言找不到他。
PUBLIC _OS_ENTER_CRITICAL 汇编语言已经做了 全局定义处理。在工程中已经设置了汇编语言的预编译路径,在调到他的C 文件里也用
extern OS_ENTER_CRITICAL 对其做了外部函数声明,但是还是不行! 请各位做过IAR下混合编程的老师给我指点一下,谢谢
直接看 IAR->Help->C/C++ compiler Reference guide
里面有Mixing C and assembler的章节。进入CRITICAL, 汇编不行,为什么不用C 来写?
也可以尝试 INLINE ASSEMBLER,比如:
void foo(void)
{
while (!flag)
{
asm("MOV C,0x98.0"); /* SCON.R1 */
asm("MOV flag,C");
}
}
An assembler routine that will be called from C must:
●Conform to the calling convention
●Have a PUBLIC entry-point label
●Be declared as external before any call, to allow type checking and optional promotion of parameters, as in these examples:
extern int foo(void);
or
extern int foo(int i, int j);
最后提到了一种有意思的方法,先用C写,再转换成汇编
One way of fulfilling these requirements is to create skeleton code in C, compile it, and study the assembler list file.
CREATING SKELETON CODE
The recommended way to create an assembler language routine with the correct interface is to start with an assembler language source file created by the C compiler. Note that you must create skeleton code for each function prototype.
The following example shows how to create skeleton code to which you can easily add the functional body of the routine. The skeleton source code only needs to declare the variables required and perform simple accesses to them. In this example, the assembler routine takes an int and a char, and then returns an int:
extern int gInt;
extern char gChar;
int Func(int arg1, char arg2)
{
int locInt = arg1;
gInt = arg1;
gChar = arg2;
return locInt;
}
int main()
{
int locInt = gInt;
gInt = Func(locInt, gChar);
return 0;
}
Note:
In this example we use a low optimization level when compiling the code to show local and global variable access. If a higher level of optimization is used, the required references to local variables could be removed during the optimization. The actual function declaration is not changed by the optimization level.
COMPILING THE CODE
In the IDE, specify list options on file level. Select the file in the workspace window. Then choose Project>Options. In the C/C++ Compiler category, select Override inherited settings. On the List page, deselect Output list file, and instead select the Output assembler file option and its suboption Include source. Also, be sure to specify a low level of optimization.
Use these options to compile the skeleton code:
icc8051 skeleton.c -lA .
The -lA option creates an assembler language output file including C or C++ source lines as assembler comments. The . (period) specifies that the assembler file should be named in the same way as the C or C++ module (skeleton), but with the filename extension s51. Also remember to specify the code model, data model, and calling convention you are using, a low level of optimization, and -e for enabling language extensions.
The result is the assembler source output file skeleton.s51.
Note:
The -lA option creates a list file containing call frame information (CFI) directives, which can be useful if you intend to study these directives and how they are used. If you only want to study the calling convention, you can exclude the CFI directives from the list file.
感谢 TY 的答复, 问题找到了,我在文件中用了个宏定义,#define OS_ENTER_CRITICAL() extern void _OS_ENTER_CRITICAL()
在宏定义中没有加 extern ,在其他的地方做的函数外部声明,没有关联上,我是没有理解宏定义,造成了麻烦