主题 : RVDS的链接问题。混合编程时,C语言的函数间的调用 复制链接 | 浏览器收藏 | 打印
从裸机开始!
级别: 新手上路
UID: 52881
精华: 0
发帖: 5
金钱: 25 两
威望: 5 点
综合积分: 10 分
注册时间: 2011-07-27
最后登录: 2014-10-30
楼主  发表于: 2011-08-28 21:23

 RVDS的链接问题。混合编程时,C语言的函数间的调用

先说下背景,同时也为某些跟我处境一样的朋友提供一种运行裸机程序的方法:我用的是tiny6410开发板,因为是笔记本所以暂时用不了串口,而Jlink也出了点问题连接不上,所以只能这样:将启动模式调成SD 卡启动,然后将编译生成的二进制文件中的内容用winhex工具拷贝到SDHC卡的倒数第1042扇区开始处(这里就是SDHC卡存放BL1的位置,普通SD卡的是倒数第18扇区),插入SD卡槽 再上电就可以看到裸机程序运行了。

我遇到的问题是这样的,当我在工程里只添加一个汇编文件的时候,程序可以正常运行,代码如下(摘自本论坛某贴),功能是实现流水灯:

rGPKCON0     EQU 0x7F008800;S3C6410GPK端口配置寄存器0(GPK0-GPK7)                        
                        AREA    LED1,CODE,READONLY    ; 声明代码段LED1
                        ENTRY                ; 标识程序入口
                        CODE32                ; 声明32位ARM指令            
START
                        ldr r0,=rGPKCON0;给寄存器R0赋值GPK端口配置寄存器0的地址
loop
                        ldr r1,=0x00010000;打开GPK4针脚.GPKCON0寄存器,从左到右第一位是7第二位是6第三位是5第四位是4.
                        str r1,[r0];由于寄存器R0中储存内容为GPK端口配置寄存器0的地址,所以寄存器R1的内容会写入GPK端口配置寄存器0
                        bl delay;跳转到延迟函数位置执行程序,并且记下当前PC指针数据到r14(lr)寄存器以备返回
                        ldr r1,=0x00100000;打开GPK5针脚指令
                        str r1,[r0];写指令
                        bl delay;延迟
                        ldr r1,=0x01000000;打开GPK6针脚指令
                        str r1,[r0];写指令
                        bl delay;延迟
                        ldr r1,=0x10000000;打开GPK7针脚指令
                        str r1,[r0];些指令
                        bl delay;延迟
                        b loop;跳转到loop标签,达到程序无限循环
delay
                        ldr r3,=0x4ffff;将要延迟的时间(循环次数)写入
tag
                        sub r3,r3,#1;可以理解为r3=r3-1
                        cmp r3,#0x0;判断寄存器r3是否等于0
                        bne tag;b为arm跳转指令ne为条件码(不相等)即:寄存器r3不等于0则跳转到tag标记
                        mov pc,lr;将bl指令处储存的地址写入pc程序指针寄存器达到跳转的效果        
                        END


然后我试了试添加一个汇编文件后再添加一个c源文件,这时候就遇到了问题,先看代码吧。
汇编源文件的代码:

                        AREA    LED1,CODE,READONLY
                        IMPORT   xmain
                        ENTRY               
                        CODE32                                                         
START
                          b xmain
                          END


c源文件代码:


/*GPK4-GPK7分别控制四个User LED*/
#define GPKCON0 (*(volatile unsigned *)(0x7F008800))//GPK低8位的配置寄存器
#define GPKDATA (*(volatile unsigned *)(0x7F008808))
void delay(int);
void xmain()
{
 GPKCON0=0x11110000; //GPK4-GPK7设置为输出
 while(1)
 {
 GPKDATA=0x000000f0;//灯灭
 delay(20);
 GPKDATA=0x0;  //灯亮
 delay(20); 
 }  
}
void delay(int b)//延时函数的定义
{
 int a=400000;
 while(b--)
 while(a--);
}
                         
                        


这样的话,这个工程仍然可以可以编译和连接。但是生成的文件拷入SD卡后,却不见程序运行,灯连亮都不亮。
不过如果我把C文件里的delay函数删除掉,并在原来需要调用delay函数的地方用一段有延时功能的代码代替的话,编译之后的程序就又可以运行了,可以看到几个灯一块闪烁。
这是为什么呢?
难道混合编程的时候C语言函数不允许相互间调用吗?还是如果调用的话需要在RVDS里先做一些设置?这应该是跟ARM的链接器有关系吧,链接的时候会遵循一些规则而我没有注意到?
哪位高手能帮忙解决一下