先说下背景,同时也为某些跟我处境一样的朋友提供一种运行裸机程序的方法:我用的是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的链接器有关系吧,链接的时候会遵循一些规则而我没有注意到?
哪位高手能帮忙解决一下