ARM的第一个裸机程序,点亮LED灯遇到问题

weiwotianyuan 2010-07-31 12:40:48
在这里我真的没有浪费大家时间,我自己先找了好多问题,但是都没有解决。我的程序就是点亮mini2440板子上的LED灯,14灯和23灯交替闪烁,刚开始我自己写的代码不对,找不出毛病,我就试着把自带的代码一点一点拷过来,最后几乎全考过来了,但是就是不能正常运行,几乎和原来的一样,毛病就是只有13灯一直亮着,有时候只有3灯亮,运行一段时间后超级终端上会出现Failed initailizing heap region
Sorry. We can not run vivi的提示,但是运行自带的led灯裸机程序却没有这个问题,我把我的程序和mini2440的程序都贴出,可能是哪里我没有经验就看不到。

mini2440自带的程序:

#include "def.h"
#include "option.h"
#include "2440addr.h"
#include "2440lib.h"
#include "2440slib.h"
//================================

void dely(U32 tt)
{
U32 i;
for(;tt>0;tt--)
{
for(i=0;i<10000;i++){}
}
}


int Main(int argc, char **argv)
{
int i;
U8 key;
U32 mpll_val=0;
int data;

mpll_val = (92<<12)|(1<<4)|(1);

//init FCLK=400M, so change MPLL first
ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);
ChangeClockDivider(key, 12);

//ChangeClockDivider(1,1); // 1:2:4 FCLK:HCLK:PCLK
// rCLKDIVN=0x4; // 1:4:4
//ChangeMPllValue(82,2,1); //FCLK=135.0Mhz
//ChangeMPllValue(82,1,1); //FCLK=180.0Mhz
//ChangeMPllValue(161,3,1); //FCLK=202.8Mhz
//ChangeMPllValue(117,1,1); //FCLK=250.0Mhz
//ChangeMPllValue(122,1,1); //FCLK=260.0Mhz
//ChangeMPllValue(125,1,1); //FCLK=266.0Mhz
//ChangeMPllValue(127,1,1); //FCLK=270.0Mhz

//MMU_EnableICache();
//MMU_EnableDCache();

MMU_DisableICache();
MMU_DisableDCache();


rGPBCON = 0x155555;


data = 0x06;
while(1)
{

rGPBDAT = (data<<5);
dely(120);
data =~data;
}

return 0;
}



我的程序

#include "def.h"
#include "option.h"
#include "2440addr.h"
#include "2440lib.h"
#include "2440slib.h"


//#define GPBCON (*(volatile unsigned *)0x56000010)
//#define GPBDAT (*(volatile unsigned *)0x56000014)
//#define GPBUP (*(volatile unsigned *)0x56000018)

void delay(unsigned int dly);

int Main()
{

U32 mpll_val=0;
U8 key;
int data;

mpll_val = (92<<12)|(1<<4)|(1);

ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);
ChangeClockDivider(key, 12);

//ChangeClockDivider(1,1); // 1:2:4 FCLK:HCLK:PCLK
// rCLKDIVN=0x4; // 1:4:4
//ChangeMPllValue(82,2,1); //FCLK=135.0Mhz
//ChangeMPllValue(82,1,1); //FCLK=180.0Mhz
//ChangeMPllValue(161,3,1); //FCLK=202.8Mhz
//ChangeMPllValue(117,1,1); //FCLK=250.0Mhz
//ChangeMPllValue(122,1,1); //FCLK=260.0Mhz
//ChangeMPllValue(125,1,1); //FCLK=266.0Mhz
//ChangeMPllValue(127,1,1); //FCLK=270.0Mhz

//MMU_EnableICache();
//MMU_EnableDCache();

MMU_DisableICache();
MMU_DisableDCache();

// rGPBCON=0x15400; 先使用上拉电阻试试
rGPBUP=0xfff;






/* while(1)
{
delay(400);
GPBDAT&=~0x20;
delay(400);
GPBDAT|=0x20;
GPBDAT&=~0x40;
delay(400);
GPBDAT|=0x40;
GPBDAT&=~0X80;
delay(400);
GPBDAT|=0x80;
GPBDAT&=~0x100;
delay(400);
GPBDAT|=0x100;
}

return 0;
}*/


data = 0x06;
while(1)
{

rGPBDAT = (data<<5);
delay(120);
data =~data;
}

return 0;
}


void delay(unsigned int dly)
{
unsigned int x,y,j;
for(x=0;x<112;x++);
for(y=0;y<112;y++);
for(j=0;j<dly;j++);
}

我的QQ号,694231918,邮箱 694231918@qq.com 希望有时间的就帮我看看,小弟感激不尽。
...全文
4657 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
hjhcx 2011-12-18
  • 打赏
  • 举报
回复
weiwotianyuan ,回复你之前的一句:“section中填写的是Init 注意大小写。OK,就到这里了!”。我试过了,在section中填写Init和init都可以,我都编译通过并且运行正常了。本人长开始学ARM,希望与大家一起共同学习,相互探讨,共同进步。我的QQ315983881
gududesiling 2010-12-02
  • 打赏
  • 举报
回复
呵呵,谢谢楼主了,困扰我好几天的问题终于解决了,也不知道为什么,为什么用mini2440的人那么多,只有你我遇到了这中状况,真是郁闷呀,还有一个问题就是在section选项中为什么一定要写入init呢,我试着用其他的就不行了,期待楼主解释一下,在此再次谢谢楼主的无私。。。。。
gududesiling 2010-12-02
  • 打赏
  • 举报
回复
�Ǻǣ�лл¥���ˣ������Һü�����������ڽ���ˣ�Ҳ��֪��Ϊʲô��Ϊʲô��mini2440������ô�ֻ࣬����������������״������������ѽ������һ�����������sectionѡ����Ϊʲôһ��Ҫд��init�أ��������������ľͲ����ˣ��ڴ�¥������һ�£��ڴ��ٴ�лл¥������˽����������
weiwotianyuan 2010-07-31
  • 打赏
  • 举报
回复
我找到原因了,就是我没有设置初始化文件,一下是正确的设置方法,从两个人的博客里再选过来,希望遇到同样问题的人能通过我的教训解决问题。摘选如下:

部分设置为:: -info totals -entry 0x30000000 -ro-base 0x30000000 -

first Init.o(Init) 说明:Init.o为Init.S编译生成的目标文件,(Init)为

Init.S中的Init域(AREA Init,CODE,READONLY)。


在ADS编译环境中

第一种:在新建的工程中只有一个主函数(main)的文件,没有init.s初始化文件

的设置情况

1、除了正确设置“Target Settings”和"ARM Assembler" “ARM C Compiler”

选项外 。

2、在"ARM Linker"选项中Output 中RO Base 要填写RAM的地址(0x30000000)

Options Layout选项中一定得要填写Place at beginning of image 中的

Object/symbol 项,在没有编写初始化文件的时候,编译器会自动加入一个初始

化的目标文件一般以工程名为文件名(2440led.o)以便能找到C程序的入口

(main)并且必需以main命名主函数。
后面的Section选 项可以不用填写。

对于第一个人的设置,其实如果你在layout中设置正确后,那个命令自动就填写进去了。对ads的设置也很重要啊!

对于不用那些头文件的,说是ads自动加入一个初始化文件,以工程名为文件名,我还没有试,试完后就填上来,上面同事说那个section可以不写,我试一下,试完了,不填不行,会报错,估计是ads自带的文件不用填写这个,也许它会自己识别,但是对于另外添加的头文件可能必须填写,ads无法识别的缘故吧,反正我不懂汇编,估计是汇编中没有主函数,找不到入口吧!很对不起大家,我试了,如果没有添加任何头文件的话总是报错,找不到头文件,找不到入口,所以我只能解决添加头文件的问题了,我也不知道为什么,猜不出来了。对了,我成功的那个工程,layout中填写的是2440init.o,section中填写的是Init 注意大小写。OK,就到这里了!
weiwotianyuan 2010-07-31
  • 打赏
  • 举报
回复
for循环那处,呵呵,多年不碰单片机了,这么低级的错误我都犯!回头我就试试,但是超级中断为什么会显示那些东西呢,按理说应该不会运行到vivi 啊,谁能推断一下。
brookmill 2010-07-31
  • 打赏
  • 举报
回复
另一处有区别的地方是
rGPBCON = 0x155555;

rGPBUP=0xfff;
这个我就不懂是什么意思了。

其他的地方,这两个程序好像就都差不多一样了。
brookmill 2010-07-31
  • 打赏
  • 举报
回复
这个延时显然有问题:
void delay(unsigned int dly)
{
unsigned int x,y,j;
for(x=0;x<112;x++); 去掉最后这个分号
for(y=0;y<112;y++); 去掉最后这个分号
for(j=0;j<dly;j++);
}
这是依次作3个循环,估计没什么延时效果。而且dly参数起的作用也不对。
应该去掉两个分号,改成3层循环

4,444

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 内核源代码研究区
社区管理员
  • 内核源代码研究区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧