EDN首页   博客首页

最新日志

发表于:2009/4/13 16:41:53
标签:无标签

0

Qt资源体系

The Qt Resource System

Qt资源体系采用平台独立机制来存储应用程序执行时的二进制文件。这种机制在应用程序需要一些确定的文件(图标、翻译文件等等)而且又不想冒丢失文件的风险时是有用的。

资源体系依赖于 qmake, rcc (Qt's resource compiler), 和 QFile 的紧密协作。Qt 3 的 qembed 工具和 image collection 机制被废除。

 

Resource Collection Files (.qrc)

与应用程序关联的应用程序由 .qrc 文件来指定,它用XML记录硬盘上的文件和对应的随意指定的资源名称,应用程序通过资源名称来访问资源。

一个.qrc 文件的例子:

 <!DOCTYPE RCC><RCC version="1.0">
 <qresource>
     <file>images/copy.png</file>
     <file>images/cut.png</file>
     <file>images/new.png</file>
     <file>images/open.png</file>
     <file>images/paste.png</file>
     <file>images/save.png</file>
 </qresource>
 </RCC>

 .qrc 文件中列出的资源文件是程序的源码树的一部分。指定的路径是 .qrc 文件所在目录的相对路径。注意,列出的资源文件必须位于 .qrc 文件所在目录或者其子目录下。

资源数据也能被编译进二进制文件中,因此应用程序代码可以立即访问;也可以创建一个二进制资源,稍后在程序中登记了资源体系的代码中指定。

缺省时,程序可以用资源在源码树中的名称加一个 :/ 前缀来访问它。例如,在程序的源码树中是 images/cut.png 的文件可以通过 :/images/cut.png 来访问。但也可以用 file 标签中的 alias 属性来指定:

 <file alias="cut-img.png">images/cut.png</file>

这时该文件可以通过 :/cut-img.png 来访问。也可以在 .qrc 文件中用 qresource 标签的 prefix 属性:它可以为 .qrc 文件中所有文件指定一个前缀:

 <qresource prefix="/myresources">
     <file alias="cut-img.png">images/cut.png</file>
 </qresource>

这时该文件可以用 :/myresources/cut-img.png 访问。

有些资源,像翻译文件和图标,需要随着用户的本地配置而变化。这可以在 qresource 标签的 lang 属性中指定一个合适的本地化字串来实现。例如:

 <qresource>
     <file>cut.jpg</file>
 </qresource>
 <qresource lang="fr">
     <file alias="cut.jpg">cut_fr.jpg</file>
 </qresource>

如果用户的本地化设置是 French (也就是说,QLocale::system().name() returns "fr_FR"),:/cut.jpg 就会引用 cut_fr.jpg 图像。对于其他本地化设置,仍然用 cut.jpg

本地化字串的使用格式参见 QLocale 文档。

 

External Binary Resources

为创建一个外部二进制资源,需要通过向 rcc 传递 -binary 开关来生成资源数据(一般是.rcc扩展名)。然后可以用 QResource API 来注册资源。

例如,一个 .qrc 文件指定的资源数据集可以用下面方法编译:

 rcc -binary myresource.qrc -o myresource.rcc

应用程序中,用下面的代码注册资源:

 QResource::registerResource("/path/to/myresource.rcc");

 

Compiled-In Resources

必须在应用程序的 .pro 文件中指定.qrc 文件, qmake 才能知道并将资源编译进二进制文件。例如:

 RESOURCES     = application.qrc

qmake 将产生make规则来生成一个叫做 qrc_application.cpp 的文件并把它链接到应用程序中。该文件中,图像和其他资源的所有数据被以压缩二进制数据存进静态C++数组中。 .qrc 文件被改变或者它引用的文件中的某一个被改变时, qrc_application.cpp 自动重新生成。若你没有使用 .pro 文件,你也可以手动调用 rcc 或者在你的编译系统中添加创建规则。

点击看大图

通常,Qt直接将数据存储在可执行文件中,甚至在Windows和Mac OS X这些提供资源本地支持的操作系统中也是这样。这可能会在未来的Qt版本中改变。

 

Using Resources in the Application

应用程序中,绝大多数地方都可以用资源路径代替原始文件系统路径。尤其是在 QIcon, QImage, or QPixmap 构造器中可以传递资源路径来代替文件名称:

     cutAct = new QAction(QIcon(":/images/cut.png"), tr("Cu&t"), this);

参见示例Application,它用Qt资源体系存储图标。

在内存中,资源被用资源对象树来描述。该树在启动时自动构建并用QFile来解析资源路径。可以用":/" 初始化的 QDir 来从资源树的根部开始浏览。

Qt资源支持搜索路径列表概念。若用 ":"代替":/"做前缀来引用一个资源,资源将被用搜索路径列表查询。启动时搜索路径列表是空的,调用 QDir::addResourceSearchPath() 可以添加路径。

If you have resources in a static library,必须用.qrc 文件的base name作参数调用 Q_INIT_RESOURCE() 来强制初始化资源。例如:

     int main(int argc, char *argv[])
     {
         QApplication app(argc, argv);
         Q_INIT_RESOURCE(graphlib);
         ...
         return app.exec();
     }

同样地,若你需要显式卸载一个资源集(因插件被卸载或资源失效),需要用与前面相同的base name为参数调用Q_CLEANUP_RESOURCE() 来强制移除资源。

系统分类: 嵌入式   |    用户分类:    |    来源: 转贴

该用户于2009/4/13 16:42:46编辑过该文章

评论(0) | 阅读(202)
发表于:2008/11/13 15:32:31
标签:无标签

0

ARM研发板上USB 摄像头图像采集实现

 研发板上的arm是AT91RM9200,摄像头选用的是网眼的pc350,主控芯片是ov511+。系统内核是2.4,宿主机是fedora core 6,交叉编译器是2.95.3。就是这些家底了,:-)。

一 驱动加载
   
   ov511的驱动,2.4的内核中就有,所以我们只需重新编译内核,将下边的选项都选上,然后重新烧写内核就能了。:-),也就是直接静态加载,我喜欢一劳永逸,:-),试验阶段还是动态的好。
(1)在arm linux的kernel目录下make menuconfig。
(2)首先(*)选择Multimedia device->下的Video for linux。加载video4linux模块,为视频采集设备提供编程接口;
(3)然后在usb support->目录下(*)选择support for usb和usb camera ov511 support。这使得在内核中加入了对采用OV511接口芯片的USB数字摄像头的驱动支持。
(4)保存设置退出。
(5)make dep;make zImage就生成了带有ov511 驱动的内核。
接下来就通过uboot将内核烧到flash里去。这时你将摄像头插上,系统就会提示发现摄像头-ov511+,这说明驱动正常。:-),驱动加载就成功了,下一步就是图像采集了。

二 图像获取

  关于图像采集,我用的是个开源软件,就是德国人做的抓图程式:vgrabbj。

http://vgrabbj.gecius.de/
第一步当然就是down下来,然后交叉编译了,可是不幸的是我们的编译器就是那个伟大的2.95.3里东东不够多,缺少一些库文件了(zlib,jpge,png)。所以我们首先要充实一下自己的家底,交叉编译这三个库文件了。
1.首先安装 zlib 库,这个是后面的库的编译基础。这个是下载地址:
http://www.zlib.net/zlib-1.2.3.tar.gz
  
400多K,去下载吧。
解压 # tar -zxvf zlib-1.2.3.tar.gz
进入zlib-1.2.3目录下
#cd zlib-1.2.3
设置,由于 zlib 库的configure 脚本不支持交叉编译选项,所以我们首先设置CC
# export CC="arm-linux-gcc"
#  ./configure --prefix=/usr/local/arm/2.95.3/arm-linux/ --shared  
注意:prefix就是安装目录,这里设置指向 /usr/local/arm/2.95.3/arm-linux/ 目录,就会自动安装在 /usr/local/arm/2.95.3/arm-linux/ [include,lib] 目录下,千万不要装错目录了,不然后面会未找到这个库的
#  make
# make install
安装完后检查一下目录 /usr/local/arm/2.95.3/arm-linux/ [include,lib] ,如果 include 中没有 zlib.h 之类的头文件,lib 中没有 libz.so.1.2.3 ,那就自己手动拷到这些目录下去,记着拷的时候把所有的 *.h  都需要拷过去,在拷库的时候用 cp ?a libz.* /…./lib  就行,要用上 ?a 选项。这样zlib就搞定了。
2.安装 png 库,这个是用来显示 png 图像的,下载地址:
http://superb-east.dl.sourceforge.net/sourceforge/libpng/libpng-1.0.10rc1.tar.gz


# tar zxf libpng-1.0.10rc1.tar.gz
# cd libpng-1.0.10rc1
Libpng 不提供有效的 configure 脚本,所以只好自己动手改 Makefile 文件了
# cp scripts/makefile.linux  Makefile   //把 Scripts下的一个 makefile 拷出来自己动手改
# vi Makefile    // 自己动手改
CC=arm-linux-gcc    //修改这里
# where "make install" puts libpng.a, libpng.so*, png.h and pngconf.h
prefix=/usr/local/arm/2.95.3/arm-linux     //修改这里
# Where the zlib library and include files are located
#ZLIBLIB=/usr/local/lib
#ZLIBINC=/usr/local/include
ZLIBLIB=/usr/local/arm/2.95.3/arm-linux/lib   //修改这里
ZLIBINC=/usr/local/arm/2.95.3/arm-linux/include  //修改这里
好了,保存,然后去编译吧
#  make
#  make install
如果有错误,检查你前面的步骤哪个没做对 ,:-) 尤其是 zlib 的安装
还是前面说的,检查 /usr/local/arm/2.95.3/arm-linux/ [include,lib] 目录中有成功安装否,如果没有安装成功,那就自己把编译出来的东西拷过去。记着,*.h 和 .so 的文件都要拷。

3.安装 jpeg 库 ,下载地址:
ftp://ftp.uu.net/graphics/jpeg/jpegsrc.v6b.tar.gz
   
# tar -zxvf jpegsrc.v6b.tar.gz
# cd jpeg-6b
# ./configure --help    //能查看他的设置选项
# export CC="arm-linux-gcc"  
# ./configure --prefix=/usr/local/arm/2.95.3/arm-linux/ --enable-shared --enable-static
然后我们需要修改一下makefile文件,因为我的系统的libtool似乎和这个版本配合的不是非常好。下边这些地方是需要注意的,:-),尤其是libtool,如果你的也工作不好的话。
# Where to install the programs and man pages.
prefix = /usr/local/arm/2.95.3/arm-linux
# The name of your C compiler:
CC= arm-linux-gcc
# If using GNU libtool, LIBTOOL references it; if not, LIBTOOL is empty.
LIBTOOL =
# $(O) expands to "lo" if using libtool, plain "o" if not.
# Similarly, $(A) expands to "la" or "a".
O = o
A = a
# library (.a) file creation command
AR= arm-linux-ar rc
# second step in .a creation (use "touch" if not needed)
AR2= arm-linux-ranlib
# make
安装前需要在 arm-linux 下建个目录,不然安装会出错
# mkdir ?p /usr/local/arm/2.95.3/arm-linux/man/man1
# make install    // OK 了
相同,自己去检查一下安装是否成功,:-),库文件终于告一段落了。下边到我们的主角了,vgrabbj。

4.交叉编译vgrabbj
# tar -zxvf vgrabbj-0.9.6.tar.gz
# cd vgrabbj-0.9.6
# ./configure --help
#export CC="arm-linux-gcc"
#mkdir myvgr
#./configure --host=arm-linux --prefix=./myvgr --disable-ftp --disable-timestamp
去掉不必的选项吧,多了不一定能的,:-)。
修改makefile
#vim Makefile
CFLAGS = -g -O2 -Wall -I/home/linux-2.4/include
添加斜体部分,:-)。
[root@localhost vgrabbj-0.9.6]# make
[root@localhost vgrabbj-0.9.6]# make install
好了,这样你就在myvgr中有了一个vgrabbj可执行文件,把他下到研发板上就能采集图像了。

5.vgrabbj的使用
vgrabbj需要两个动态库文件,所以首先拷贝到研发板上,:-)。如下:
[root@(none) lib]$cp -a libpng.so.2 /lib
[root@(none) lib]$cp -a libpng.so.2.1.0.10rc1  /lib
[root@(none) lib]$cd myvgr
[root@(none) myvgr]$ls
bin  etc  lib  man
[root@(none) myvgr]$cd bin
[root@(none) bin]$ls
vgrabbj
[root@(none) bin]$./vgrabbj --help
Usage: vgrabbj [options]
-h                This screen
-c      parse  as config file
-l       Daemonize & sleep  (min. 1!) between images
-L  Daemonize & sleep  between images              
-a                Switch vgrabbj’s auto brightness adjustment (default: off)   
                   You might need to set -F 4, too, if it doesn’t work         
-q       Quality setting (0-100, default: 75), JPEG only              
-i                             
Sets the imagesize of input device to
sqcif=128x96,qsif=160x120,qcif=176x144, sif="320x240", cif="352x288", vga="640x480", svga="800x600", xga="1024x768", sxga="1280x1024", or uxga="1600x1200" (default:352x288)                           
-o  Output format (default:jpg)                                 
-f      Write to  (default: /dev/stdout)                  
-d        Read from  as input (default: /dev/video)            
                                                                             
Example: vgrabbj -l 5 -f /usr/local/image.jpg                                   
         Would write a single jpeg-image to image.jpg approx. every five seconds
                                                                                
[root@(none) bin]$./vgrabbj -f ./1.jpg -d /dev/v4l/video0                       
Could not open configfile ./myvgr/etc/vgrabbj.conf, ignoring                    
Reading image from /dev/v4l/video0                                             
[root@(none) bin]$./vgrabbj -f ./2.jpg -d /dev/v4l/video0                       
Could not open configfile ./myvgr/etc/vgrabbj.conf, ignoring                    
Reading image from /dev/v4l/video0
你把1.jpg,2.jpg拷到宿主机上,就能看到自己的劳动成果了,:-)。

感谢大漠孤狼,关于库的编译,我主要参考了他的文章。当然更有其他大侠的,:-),就不写了。
MiniGUI 1.3.3 移植详解
作者:大漠孤狼   E-Mail:
yuqiang0107@126.com

系统分类: ARM   |    用户分类:    |    来源: 转贴

该用户于2008/11/13 15:32:33编辑过该文章

评论(0) | 阅读(910)
发表于:2008/11/13 14:05:48
标签:无标签

0

FS2410上安装摄像头驱动和构建视频服务器

我的开发板是优龙的FS2410(S3C2410),linux内核2.6.8.1,以下是我成功安装摄像头驱动和构建视频服务器的步骤,摄像头芯片是中芯微电子的301P,属于老芯片了,现在市面上这方面的芯片比较少了,新的芯片(如303)不知能否被支持,有机会试一下。
 

1.移植2410的摄像头驱动

内核环境2.6.8.1

http://mxhaard.free.fr/download.htm下载嵌入式专用的摄像头补丁usb-2.6.8.1.patch.tar.gz

(1)放入内核文件夹/drivers/usb,解压得到usb-2.6.8.1-2.patch

    执行命令:patch -p1 <usb-2.6.8.1-2.patch

    此时会在usb/media下出现目录SPCA5XX

(2)makemenuconfig,注意GCC版本不宜太高(fedora7的GCC版本是4.12,对语法要求比较高,报了很多错,搞得我瀑布汗)

    编辑内核,找到<*>Multimedia device->下的Video for linux

    usb support->目录下<*>选择support for usb和<M>选择spca5xx

(3)make zImage,make module,在Cspca5xx中会出现模块spca5xx.ko,放入NFS共享文件夹

(4)下载焼写

(5)insmod spca5xx.ko,成功加载

 

 

2. 使用servfox构建嵌入式视频服务器

下载servfox,将Makefile中CC改为arm-linux-gcc

 编译,运行servfox –d /dev/video0 –s 640x480 –w 192.168.2.223(服务器IP):7070

 信息:

  servfox version: 1.1.2 date: 07:10:2005 (C)mxhaard@magic.fr

  Waiting .... for connection. CTrl_c to stop !!!!

 注意客户机192.168.2.1(PC)一定要加载V4L驱动videodev(insmod videodev)

 PC 运行spcaview -w 192.168.2.223:7070成功

  信息:

   Spcaview version: 1.1.7 date: 06:11:2006 (C)mxhaard@magic.fr

   using Server 192.168.2.223 Port 7070

 

http://space.taobao.com/2c5dc85eeb21a60639019dd98bb394d0/show_blog-15496157.htm#

系统分类: ARM   |    用户分类:    |    来源: 转贴

该用户于2008/11/13 14:05:51编辑过该文章

评论(0) | 阅读(570)
发表于:2008/11/8 17:17:42
标签:无标签

0

基于优龙FS2410开发板u-boot-1.1.6的移植(NAND FLASH) (三)

首先引用《嵌入式系统 Boot Loader 技术内幕》的一段话:Boot Loader 的设计与实现是一个非常复杂的过程。如果不能从串口收到那激动人心的"uncompressing linux.................. done, booting the kernel……"内核启动信息,恐怕谁也不能说:"嗨,我的 boot loader 已经成功地转起来了!" 我对此深有体会,这就是为什么这篇文章推迟一个星期才出来的原因。

u-boot实现linux内核引导步骤:

1、U-BOOT给linux内核传递合适参数的定义

修改include/configs/fs2410.h如下:

……

……

/************************************************************

 * RTC

 ************************************************************/

#define       CONFIG_RTC_S3C24X0   1

/* allow to overwrite serial and ethaddr */

#define CONFIG_ENV_OVERWRITE

#define CONFIG_BAUDRATE        115200

 

/************************************************************/

/* enable passing of ATAGs       */

#define CONFIG_CMDLINE_TAG  1

#define CONFIG_SETUP_MEMORY_TAGS 1

#define CONFIG_INITRD_TAG       1

 

/***********************************************************

 * Command definition

 ***********************************************************/

#define CONFIG_COMMANDS \

                     (CONFIG_CMD_DFL    | \

                     CFG_CMD_CACHE     | \

                     CFG_CMD_NAND | \

                     /*CFG_CMD_EEPROM |*/ \

                     /*CFG_CMD_I2C    |*/ \

                     /*CFG_CMD_USB  |*/ \

                     CFG_CMD_REGINFO  | \

                     CFG_CMD_DATE  | \

                     CFG_CMD_ELF)

……

……

2、修改UBOOT的2410CPU频率

smdk2410的U-BOOT原来运行频率是202.8M,而FS2410的BIOS里面是200M,所以不修改频率可能会出点问题。按照网上的说法,内核中,在\arch\arm\mach_s3c2410\s3c2410.c 中,fclk = s3c2410_get_pll(MPLLCON, xtal);   //读出来的fclk结果和bootloader的频率不一致。

修改board/fs2410/fs2410.c文件如下:

#define FCLK_SPEED 1

#if FCLK_SPEED==0  /* Fout = 203MHz, Fin = 12MHz for Audio */

#define M_MDIV 0xC3

#define M_PDIV 0x4

#define M_SDIV 0x1

#elif FCLK_SPEED==1  /* Fout = 202.8MHz */

//#define M_MDIV 0xA1

//#define M_PDIV 0x3

//#define M_SDIV 0x1

#define M_MDIV 0x5c  /* Fout = 200MHz */

#define M_PDIV 0x4

#define M_SDIV 0x0

#endif

3、修改include/configs/fs2410.h中的CFG_LOAD_ADDR的地址为0x30007FC0

这是内核的加载地址,board/smdk2410/config.mk文件注释中提到Linux内核希望自己被加载到0x30008000的内存地址,而由于uImage会在kernel镜像之前加上大小为0x40的头文件消息,所以需要减去0x40。

4、制作uImage

在编译内核的时候如果用命令make uImage来生成uImage的话,我发现Load Address 30008000,  Entry Point  30008000,为什么这样我没细研究,所以我用mkimage来生成uImage,做法如下:

[root@localhost tftpboot]#mkimage -n 'linux-2.6.25' -A arm -O linux -T kernel -C none -a 0x30007fc0 -e 0x30008000 -d zImage uImage

Image Name   linux-2.6.25

Created      Thu Jul 3 101845 2008

Image Type   ARM Linux Kernel Image (uncompressed)

Data Size    1556188 Bytes =1556252 kB = 1.5 MB

Load Address 0x30007fc0

Entry Point  0x30008000

 

这里解释一下参数的意义:

        -A == set architecture to 'arch'

        -O == set operating system to 'os'

        -T == set image type to 'type'

        -C == set compression type 'comp'

        -a == set load address to 'addr' (hex)

        -e == set entry point to 'ep' (hex)

        -n == set image name to 'name'

        -d == use image data from 'datafile'

        -x == set XIP (execute in place)

这里我移植的是2.6.25内核,当然也可以:Load Address 0x30008000 、Entry Point  0x30008040

5、固化

       make修改好的u-boot,将u-boot.bin和uImage写入flash相应位置,然后设置u-boot启动命令:

[FS2410]#setenv bootargs root="1f02" init="/linuxrc" console="ttySAC0",115200 devfs="mount"

[FS2410]#setenv bootcmd nand read 0x30007fc0 0x40000 0x1c0000\;bootm 0x30007fc0

[FS2410]#saveenv

Saving Environment to NAND...

Erasing Nand...Writing to Nand... done

好了,可以通过printenv、bdinfo等命令查看自己的u-boot参数了,最后reset一下,如果运气好点的话,就会看到那激动人心的

Uncompressing Linux....................................................... done, booting the kernel.

之后就是一阵洋文飘过……

后记:

s3c2410上移植uboot和linux2.6内核.虽然网上的文章多多,但真正要在自己的板子上跑起来还真是问题多。其间参考了不少网上同行们的文章,受益匪浅。最后我还将调制过程中遇到的问题总结列出,供后人参考。

点击看大图

问题一:Load Address  、Entry Point 设置问题
Starting kernel ...
undefined instruction
pc : [<c30008028>] lr : [<c0f91b14>]
sp : 33f4fc10 ip : 00000001 fp : 33f4fca4
r10: 33f9e70c r9 : 33ece9cd r8 : 33f4ffdcc
r7 : 33f4ffb8 r6 : 00000000 r5 : 00000000 r4 : 00000000
r3 : 30008000 r2 : c0000100 r1 : 000000c1 r0 : 00000000
Flags: nZCv IRQs off FIQs off Mode SVC_32
Resetting CPU ...

点击看大图

引导内核在这里进不去,网上也没一个很好的说法,由上图可知:Load Address 0x30008000 、Entry Point  0x30008000 ,#bootm的时候,显示是的内核前头加上的64byte的信息r1:000000c1 r0:00000000……按照上述制作uImage的方法设Load Address  、Entry Point 就ok。

/************下面引用了网上文章的原话********************************************************/

u-boot  调用 Linux 内核的方法是直接跳转到内核的第一条指令处,也即直接跳转到 MEM_START + 0x8000 地址处。在跳转时,要满足下列条件:

a) CPU 寄存器的设置: R0 = 0 ; R1 =机器类型 ID ,本系统的机器类型 ID = 193 。 R2 =启动参数标记列表在 RAM 中的起始基地址;

b) CPU 模式:必须禁止中断 (IRQs 和 FIQs) ; CPU 必须工作在 SVC 模式;

c) Cache 和 MMU 的设置: MMU 必须关闭;指令 Cache 可以打开也可以关闭;数据 Cache 必须关闭。

系统采用下列代码来进入内核函数:

theKernel = (void (*)(int, int))ntohl(hdr->ih_ep);

theKernel(0, bd->bi_arch_number); 其中, hdr 是 image_header_t 类型的结构体, hdr->ih_ep 指向内核的第一条指令地址,即 Linux 操作系统下的 /kernel/arch/arm/boot/compressed/head.S 汇编程序。 theKernel() 函数调用应该不会返回,如果该调用返回,则说明出错。

//theKernel(0, bd->bi_arch_number); 应该是:
      theKernel (0, bd->bi_arch_number, bd->bi_boot_params);

问题二:Starting kernel ...就没显示了.

点击看大图

郁闷吧,解决了第一个问题,又来了这个问题,什么都没显示了,错在哪呢?

theKernel (0, bd->bi_arch_number, bd->bi_boot_params);没有给内核正确传递参数?经过setenv修改启动参数、修改bi_arch_number的机器ID号,都未果,结果发现,优龙的linux-2.6.8.1-pxt1不能引导,我交叉编译Linux-2.6.25,制作uImage,结果正常启动,至于为什么linux-2.6.8.1-pxt1不能引导,我没做深入分析。

问题三:Uncompressing Linux....................................................... done, booting the kernel   就不动了

我没有遇到,摘用网上解法:一般这个错误有两种原因:
一个内核的commandline ,一个是由于主频设置的问题
1. 通过go启动内核的话参数用的是编译时的..而bootm则是启动的经过处理的uImage(加了一个头)
所以用bootm就会把uboot设置的commandline传给内核..如果是用bootm启动出现bootint the 
kernel没显示了.则应该好好检查一下.可以printenv打印看uboot有没设置对commandline

2.主频问题,就是在MPLLCON这个寄存器的配置上。(board/s3c2410/s3c2410.c)
在VIVI:MPLLCON = 0x0005c040;计算出来的Mpll = 200Mhz
Uboot116:MPLLCON = 0x000a1031;计算出来的Mpll = 202Mhz
 那么,及有可能就是内核已经启动,而波特率不对,使打印出问题
把MPLLCON改成 = 0x0005c040就有显示了.

问题四:Error: unrecognized/unsupported machine ID (r1 = 0x33f4fca8)

点击看大图

分析:

tftp uImage到0x30008000,然后,go 0x30008000,这样uboot没有传参数给内核,go命令是不传递内核参数的所以会有Error: unrecognized/unsupported machine ID (r1 = 0x33f4fca8)这样的错误
一种方法是修改common/cmd_boot.c
/*#if defined(CONFIG_I386)*/          
  DECLARE_GLOBAL_DATA_PTR;        
/*#endif*/                                        
#if !defined(CONFIG_NIOS)
      /*******************add here*******************************/    
if(argc==2)
        rc = ((ulong (*)(int, char *[]))addr) (0, gd->bd->bi_arch_number);
  else      
/*********************add end *****************************/  
          rc = ((ulong (*)(int, char *[]))addr) (--argc, &argv[1]);
解决
还可以在arch/arm/kernel/head.S写死r1
mov    r1, #0xc1

个人建议不修改,用bootm命令。

至此,u-boot-1.1.6 移植完毕,感谢收看!

http://blog.chinaunix.net/u2/74310/showart.php?id=1091939

系统分类: ARM   |    用户分类: 无分类    |    来源: 转贴

评论(0) | 阅读(919)
发表于:2008/11/8 17:16:50
标签:arm  fs2410  u-boot  linux  移植  

0

基于优龙FS2410开发板u-boot-1.1.6的移植(NAND FLASH) (二)

本文实现u-boot的写操作,实验过程中,参考了网上资料,列举如下:    
    《uboot1.1.4移植》网址:
    http://hi.baidu.com/edaworld/blog/item/c40f83a8a2e6d1b5cb130cca.html
    《uboot for s3c2410 nandboot 使用saveenv保存环境变量》网址:
    http://blog.chinaunix.net/u1/56388/showart_438720.html
    《基于smdk2410 开发板u-boot-1.2.0 对 nand flash的支持》PDF文档。

涉及文件:
common/env_nand.c
Driver/nand_legacy/ nand_legacy.c
Include/configs/fs2410.h

具体修改分析:
Lib_arm/board.c
u-boot 运行至第二阶段进入 start_armboot()函数。其中 nand_init()函数是对 nand flash 的最初初始化函数。其调用与 CFG_NAND_LEGACY 宏有关,如果没定义 CFG_NAND_LEGACY 这个宏,就按照start_armboot()调用 drivers/nand/nand.c 中的 nand_init 函数(该函数在 1.1.6 已经被实现), 但还有个 board_nand_init()函数没实现,需自己添加。如果定义了CFG_NAND_LEGACY,就不使用默认的 nand_init,而调用自己写的 nand_init 函数了,这里我们选择第二种方式。

具体步骤如下:
1. 加入 NAND 闪存芯片型号
在/include/linux/mtd/ nand_ids.h 中对如下结构体赋值进行修改:
static struct nand_flash_dev nand_flash_ids[]= {
......
{"Samsung K9F1208U0M",    NAND_MFR_SAMSUNG, 0x76, 26, 0, 3, 0x4000, 0},    /*2008-6-25*/
......
                                           }
这样对于该款 NAND 闪存芯片的操作才能正确执行。

2.  编写 NAND 闪存初始化函数
在/drivers/nand_legacy/nand_legacy.c 中加入 nand_init()函数。
/*08-6-25 START*/
/*-----------------------------------------------------------------------
 * NAND flash basic functions
 * Added by wei jing 2008.6.25
 * Copied from board/mpl/vcma9/vcma9.h & vcma9.c
 */
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
#include <s3c2410.h>


/*----------------------------------------------------------------------*/

typedef enum {
    NFCE_LOW,
    NFCE_HIGH
} NFCE_STATE;

static inline void NF_Conf(u16 conf)
{
    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

    nand->NFCONF = conf;
}

static inline void NF_Cmd(u8 cmd)
{
    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

    nand->NFCMD = cmd;
}

static inline void NF_CmdW(u8 cmd)
{
    NF_Cmd(cmd);
    udelay(1);
}

static inline void NF_Addr(u8 addr)
{
    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

    nand->NFADDR = addr;
}

static inline void NF_SetCE(NFCE_STATE s)
{
    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

    switch (s) {
        case NFCE_LOW:
            nand->NFCONF &= ~(1<<11);
            break;

        case NFCE_HIGH:
            nand->NFCONF |= (1<<11);
            break;
    }
}

static inline void NF_WaitRB(void)
{
    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

    while (!(nand->NFSTAT & (1<<0)));
}

static inline void NF_Write(u8 data)
{
    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

    nand->NFDATA = data;
}

static inline u8 NF_Read(void)
{
    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

    return(nand->NFDATA);
}

static inline void NF_Init_ECC(void)
{
    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

    nand->NFCONF |= (1<<12);
}

static inline u32 NF_Read_ECC(void)
{
    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

    return(nand->NFECC);
}

extern ulong
nand_probe(ulong physadr);


static inline void NF_Reset(void)
{
    int i;

    NF_SetCE(NFCE_LOW);
    NF_Cmd(0xFF);        /* reset command */
    for(i = 0; i < 10; i++);    /* tWB = 100ns. */
    NF_WaitRB();        /* wait 200~500us; */
    NF_SetCE(NFCE_HIGH);
}


static inline void NF_Init(void)
{
#if 0 /* a little bit too optimistic */
#define TACLS   0
#define TWRPH0  3
#define TWRPH1  0
#else
#define TACLS   0
#define TWRPH0  4
#define TWRPH1  2
#endif

    NF_Conf((1<<15)|(0<<14)|(0<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0));
    /*nand->NFCONF = (1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0); */
    /* 1  1    1     1,   1      xxx,  r xxx,   r xxx */
    /* En 512B 4step ECCR nFCE="H" tACLS   tWRPH0   tWRPH1 */

    NF_Reset();
}

void
nand_init(void)
{
    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

    NF_Init();
#ifdef DEBUG
    printf("NAND flash probing at 0x%.8lX\n", (ulong)nand);
#endif
    printf ("%4lu MB\n", nand_probe((ulong)nand) >> 20);
}

#endif /* CONFIG_COMMANDS & CFG_CMD_NAND */

/*08-6-25 END*****************************************************/

/*
 * Exported variables etc.
 */
可以看到 nand_init()调用 NF_Init()函数,使能 nand flash 控制器和 nand flash;调用 NF_Reset()函数置位,NF_WaitRB()查询 nand flash 的状态,最后在调用 nand_probe((ulong)nand)函数探测 nand flash.

3. 修改include/configs/fs2410.h,在上次修改的基础上加上如下代码,定义 NAND 闪存命令层的底
接口函数等:

#define CFG_NAND_LEGACY        1
//#define NFCE_LOW        0
//#define NFCE_HIGH       1
#define CFG_ENV_IS_IN_NAND    1
#define CFG_NAND_BASE        0x4E000000
#define CMD_SAVEENV
#define CFG_ENV_SIZE            0x10000 /* Total Size of Environment Sector */
#define CFG_ENV_OFFSET      0x20000 /*环境变量在NAND FLASH的0x20000处*/
#define CFG_MONITOR_BASE PHYS_SDRAM_1
/*-----------------------------------------------------------------------
 * NAND flash settings
 */
#if (CONFIG_COMMANDS & CFG_CMD_NAND)

#define CFG_NAND_LEGACY
#define CFG_MAX_NAND_DEVICE    1    /* Max number of NAND devices        */
#define SECTORSIZE 512

#define ADDR_COLUMN 1
#define ADDR_PAGE 2
#define ADDR_COLUMN_PAGE 3

#define NAND_ChipID_UNKNOWN     0x00
#define NAND_MAX_FLOORS 1
#define NAND_MAX_CHIPS 1

#define NAND_WAIT_READY(nand)    NF_WaitRB()

#define NAND_DISABLE_CE(nand)    NF_SetCE(NFCE_HIGH)
#define NAND_ENABLE_CE(nand)    NF_SetCE(NFCE_LOW)


#define WRITE_NAND_COMMAND(d, adr)    NF_Cmd(d)
#define WRITE_NAND_COMMANDW(d, adr)    NF_CmdW(d)
#define WRITE_NAND_ADDRESS(d, adr)    NF_Addr(d)
#define WRITE_NAND(d, adr)        NF_Write(d)
#define READ_NAND(adr)            NF_Read()
/* the following functions are NOP's because S3C24X0 handles this in hardware */
#define NAND_CTL_CLRALE(nandptr)
#define NAND_CTL_SETALE(nandptr)
#define NAND_CTL_CLRCLE(nandptr)
#define NAND_CTL_SETCLE(nandptr)

#define CONFIG_MTD_NAND_VERIFY_WRITE    1
#define CONFIG_MTD_NAND_ECC_JFFS2    1

#endif    /* CONFIG_COMMANDS & CFG_CMD_NAND */
 
/*08-6-25***************************************************/
4. 在fs2410.h中打开命令:
/***********************************************************
 * Command definition
 ***********************************************************/
#define CONFIG_COMMANDS \
            (CONFIG_CMD_DFL     | \
            CFG_CMD_CACHE     | \
            CFG_CMD_ENV         | \
            CFG_CMD_NET         | \
            CFG_CMD_PING     | \
            CFG_CMD_NAND     | \         /* 打开 nand flash 命令 */
            /*CFG_CMD_EEPROM |*/ \
            /*CFG_CMD_I2C     |*/ \
            /*CFG_CMD_USB     |*/ \
            CFG_CMD_REGINFO  | \
            CFG_CMD_DATE     | \
            CFG_CMD_ELF)

好了,make一下,看看结果,很不幸运,/env_nand.c:206 undefined reference to 'nand_info'等等问题,如图1所示,原来nand flash 真正的擦除和读写函数使用的是 drivers/nand_legacy/ 目录下面的读写、擦除函数
int nand_legacy_erase(struct nand_chip* nand, size_t ofs,size_t len, int clean);
int nand_legacy_rw(struct nand_chip* nand, int cmd,size_t start, size_t len,size_t * retlen, u_char * buf);
5. 修改saveenv中对nand的读写函数为nand_legacy的读写函数,修改common/env_nand.c如下:

#include <common.h>

#if defined(CFG_ENV_IS_IN_NAND) /* Environment is in Nand Flash */

#include <command.h>
#include <environment.h>
#include <linux/stddef.h>
#include <malloc.h>
#include <nand.h>

#if ((CONFIG_COMMANDS&(CFG_CMD_ENV|CFG_CMD_NAND)) == (CFG_CMD_ENV|CFG_CMD_NAND))
#define CMD_SAVEENV
#elif defined(CFG_ENV_OFFSET_REDUND)
#error Cannot use CFG_ENV_OFFSET_REDUND without CFG_CMD_ENV & CFG_CMD_NAND
#endif

#if defined(CFG_ENV_SIZE_REDUND) && (CFG_ENV_SIZE_REDUND != CFG_ENV_SIZE)
#error CFG_ENV_SIZE_REDUND should be the same as CFG_ENV_SIZE
#endif

#ifdef CONFIG_INFERNO
#error CONFIG_INFERNO not supported yet
#endif

/*  My Add*/
 
int nand_legacy_erase(struct nand_chip* nand,
 
 size_t ofs, size_t len, int clean);

int nand_legacy_rw (struct nand_chip* nand, int cmd,
        size_t start, size_t len,
        size_t * retlen, u_char * buf);

/*  My Add*/
 
extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE];

/* info for NAND chips, defined in drivers/nand/nand.c */
//extern nand_info_t nand_info[];

nand_info_t nand_info[CFG_MAX_NAND_DEVICE];

/* references to names in env_common.c */
extern uchar default_environment[];
extern int default_environment_size;
......
......
#else /* ! CFG_ENV_OFFSET_REDUND */
int saveenv(void)        /* 2008-6-26 by weij */
{
    ulong total;
    int ret = 0;

    puts ("Erasing Nand...");
    //if (nand_erase(&nand_info[0], CFG_ENV_OFFSET, CFG_ENV_SIZE))
    if (nand_legacy_erase(nand_dev_desc+0, CFG_ENV_OFFSET, CFG_ENV_SIZE, 0))
        return 1;

    puts ("Writing to Nand... ");
    total = CFG_ENV_SIZE;
    //ret = nand_write(&nand_info[0], CFG_ENV_OFFSET, &total, (u_char*)env_ptr);
    nand_legacy_rw(nand_dev_desc+0, 0x00 | 0x02, CFG_ENV_OFFSET, CFG_ENV_SIZE, &total, (u_char*)env_ptr);

    if (ret || total != CFG_ENV_SIZE)
        return 1;

    puts ("done\n");
    return ret;
}
#endif /* CFG_ENV_OFFSET_REDUND */
......
......
/*
 * The legacy NAND code saved the environment in the first NAND device i.e.,
 * nand_dev_desc + 0. This is also the behaviour using the new NAND code.
 */
void env_relocate_spec (void)
{
#if !defined(ENV_IS_EMBEDDED)
    ulong total;
    int ret;

    total = CFG_ENV_SIZE;
    //ret = nand_read(&nand_info[0], CFG_ENV_OFFSET, &total, (u_char*)env_ptr);

    ret="nand"_legacy_rw(nand_dev_desc+0, 0x01 | 0x02, CFG_ENV_OFFSET, CFG_ENV_SIZE, &total, (u_char*)env_ptr);

      if (ret || total != CFG_ENV_SIZE)
        return use_default();

    if (crc32(0, env_ptr->data, ENV_SIZE) != env_ptr->crc)
        return use_default();
#endif /* ! ENV_IS_EMBEDDED */
}
#endif /* CFG_ENV_OFFSET_REDUND */
......
......
修改完毕,make一下,看到了期盼的画面如图2、3所示,由于能够saveenv,所以就没有了warning -bad CRC的警告,ping一下,主机能用,ok,tftp一下,Loading: TTTTT,如图4所示,莫惊慌,
《基于smdk2410 开发板u-boot-1.2.0 对 nand flash的支持》PDF文档中,说把某段代码注释掉,其实我的是防火墙关掉就ok,图5、6是tftp优龙自带的S3C2410_BIOS.bin 到RAM然后go的结果。下一篇将完成内核引导……

 
图1

点击看大图

图2、3

点击看大图

点击看大图

4

点击看大图


图5、6

点击看大图

系统分类: ARM   |    用户分类:    |    来源: 转贴

评论(1) | 阅读(877)
发表于:2008/11/8 17:15:23
标签:无标签

1

基于优龙FS2410开发板u-boot-1.1.6的移植(NAND FLASH) (一)

买到开发板之初,就开始移植u-boot,问题多多,加上扳子硬件烧写出了问题,折腾半个多月,放弃,一种挫败感久久不能抹去;偶然间发现扬创开发板“基于u-boot移植修改完善”的utu-bootloader,买之,回来打开光盘一看,暂不提供u-boot移植源代码。凭着职业的冷静,我克制住,和网上的朋友一样,奋战几个夜晚,完成了从NAND FLASH启动、NAND FLASH读写、内核引导。

移植过程中,参考了网上资料,列举如下:    
    《uboot1.1.4移植》网址:
    http://hi.baidu.com/edaworld/blog/item/c40f83a8a2e6d1b5cb130cca.html
    《uboot for s3c2410 nandboot 使用saveenv保存环境变量》网址:
    http://blog.chinaunix.net/u1/56388/showart_438720.html
    《基于smdk2410 开发板u-boot-1.2.0 对 nand flash的支持》PDF文档。
    同时推荐博客:http://blog.chinaunix.net/u1/34474/showart.php?id=363269
      
一、移植前说明:
 
1. 工作环境:
        Fedora 8 ,内核2.6.25
    交叉编译器:
        Arm-linux-gcc 3.3.2
    目标板:
    优龙FS2410,NAND Flash:64M K9F1208,NOR Flash:2M SST39VF1601 (本次移植不包含NOR Flash  支持), RAM 64M ,CS8900Q3
 
2. 下载源码,建立工作目录

    u-boot的源码可以从以下网址下载:
    http://downloads.sourceforge.net/u-boot/u-boot-1.1.6.tar.bz2
    建立工作目录:
    mkdir /uboot
    cd /uboot
    把下载的源码拷贝到该目录,解压;
    tar jxvf u-boot-1.1.6.tar.bz2  
 
二、移植步骤如下:
 
(1)、建立自己fs2410开发板的配置
 
    1)# cp –r board/smdk2410 board/fs2410    
    2)# cp include/configs/smdk2410.h include/configs/fs2410.h
   
fs2410.h是开发板的配置文件,他包括开发板的CPU、系统时钟、RAM、FLASH系统及其他相关的配置信息,由于u-boot已经支持三星的SMDK2410开发板,所以移植的时候直接拷贝SMDK2410的配置文件,做相应的修改即可。由于Uboot对SMDK2410板的NAND Flash初始化部分没有写,即lib_arm/board.c中的start_armboot函数中有这么一句:
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
puts ("NAND:");
nand_init(); /* go init the NAND */
#endif
但是在board/smdk2410目录下源文件中都没有定义nand_init这个函数。所以需要我们补充这个函数以及这个函数涉及的底层操作,NAND Flash的读写操作相对复杂,将在u-boot-1.1.6移植的第二部分介绍。
 
(2). 修改顶层Makefile
 
cd /uboot/u-boot-1.1.6
vi Makefile
找到:
smdk2410_config    :    unconfig
    @$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 NULL s3c24x0
在其后面添加:
fs2410_config    :    unconfig
    @$(MKCONFIG) $(@:_config=) arm arm920t fs2410 NULL s3c24x0
 
各项的意思如下:
arm:        CPU的架构(ARCH)
arm920t:    CPU的类型(CPU),其对应于cpu/arm920t子目录。
fs2410:    开发板的型号(BOARD),对应于board/fs2410目录。
NULL:       开发者/或经销商(vender)。
s3c24x0:    片上系统(SOC)。
(3).  include/configs/fs2410.h:
        
        修改:
        # define   CFG_PROMPT     “SMDK2410 #”
        为:
        # define   CFG_PROMPT     “fs2410 #”  
    这是u-boot的命令行提示符。
(4) 修改board/fs2410/Makefile
    将:
    OBJS    := smdk2410.o flash.o
    改为:
    OBJS     := fs2410.o flash.o
    当然,fs2410下的 smdk2410.c要改成fs2410.c;
(5)依照你自己开发板的内存地址分配情况修改board/fs2410/lowlevel_init.S文件
    
这里我参考了FS2410开发板自带S3C2410_BIOS,代码如下:
#include <config.h>
#include <version.h>


/* some parameters for the board */

/*
 *
 * Taken from linux/arch/arm/boot/compressed/head-s3c2410.S
 *
 * Copyright (C) 2002 Samsung Electronics SW.LEE  <hitchcar@sec.samsung.com>
 *
 */

#define BWSCON    0x48000000

/* BWSCON */
#define DW8             (0x0)
#define DW16             (0x1)
#define DW32             (0x2)
#define WAIT             (0x1<<2)
#define UBLB             (0x1<<3)

#define B1_BWSCON          (DW16)
#define B2_BWSCON          (DW16)
#define B3_BWSCON          (DW16 + WAIT + UBLB)
#define B4_BWSCON          (DW16)
#define B5_BWSCON          (DW16)
#define B6_BWSCON          (DW32)
#define B7_BWSCON          (DW32)

/* BANK0CON */
#define B0_Tacs             0x3    /*  0clk */
#define B0_Tcos             0x3    /*  0clk */
#define B0_Tacc             0x7    /* 14clk */
#define B0_Tcoh             0x3    /*  0clk */
#define B0_Tah             0x3    /*  0clk */
#define B0_Tacp             0x1
#define B0_PMC             0x0    /* normal */

/* BANK1CON */
#define B1_Tacs             0x3    /*  0clk */
#define B1_Tcos             0x3    /*  0clk */
#define B1_Tacc             0x7    /* 14clk */
#define B1_Tcoh             0x3    /*  0clk */
#define B1_Tah             0x3    /*  0clk */
#define B1_Tacp             0x3
#define B1_PMC             0x0

#define B2_Tacs             0x0
#define B2_Tcos             0x0
#define B2_Tacc             0x7
#define B2_Tcoh             0x0
#define B2_Tah             0x0
#define B2_Tacp             0x0
#define B2_PMC             0x0

#define B3_Tacs             0x0    /*  0clk */
#define B3_Tcos             0x3    /*  4clk */
#define B3_Tacc             0x7    /* 14clk */
#define B3_Tcoh             0x1    /*  1clk */
#define B3_Tah             0x0    /*  0clk */
#define B3_Tacp             0x3     /*  6clk */
#define B3_PMC             0x0    /* normal */

#define B4_Tacs             0x1    /*  0clk */
#define B4_Tcos             0x1    /*  0clk */
#define B4_Tacc             0x6    /* 14clk */
#define B4_Tcoh             0x1    /*  0clk */
#define B4_Tah             0x1    /*  0clk */
#define B4_Tacp             0x0
#define B4_PMC             0x0    /* normal */

#define B5_Tacs             0x1    /*  0clk */
#define B5_Tcos             0x1    /*  0clk */
#define B5_Tacc             0x6    /* 14clk */
#define B5_Tcoh             0x1    /*  0clk */
#define B5_Tah             0x1    /*  0clk */
#define B5_Tacp             0x0
#define B5_PMC             0x0    /* normal */

#define B6_MT             0x3    /* SDRAM */
#define B6_Trcd              0x1
#define B6_SCAN             0x1    /* 9bit */

#define B7_MT             0x3    /* SDRAM */
#define B7_Trcd             0x1    /* 3clk */
#define B7_SCAN             0x1    /* 9bit */

/* REFRESH parameter */
#define REFEN             0x1    /* Refresh enable */
#define TREFMD             0x0    /* CBR(CAS before RAS)/Auto refresh */
#define Trp             0x0    /* 2clk */
#define Trc             0x3    /* 7clk */
#define Tchr             0x2    /* 3clk */
#define REFCNT             1113    /* period="15".6us, HCLK="60Mhz", (2048+1-15.6*60) */
/**************************************/

_TEXT_BASE:
    .word    TEXT_BASE

.globl lowlevel_init
lowlevel_init:
    /* memory control configuration */
    /* make r0 relative the current location so that it */
    /* reads SMRDATA out of FLASH rather than memory ! */
    ldr     r0, =SMRDATA
    ldr    r1, _TEXT_BASE
    sub    r0, r0, r1
    ldr    r1, =BWSCON    /* Bus Width Status Controller */
    add     r2, r0, #13*4
0:
    ldr     r3, [r0], #4
    str     r3, [r1], #4
    cmp     r2, r0
    bne     0b

    /* everything is fine now */
    mov    pc, lr

    .ltorg
/* the literal pools origin */

SMRDATA:
    .word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
    .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))
    .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))
    .word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))
    .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))
    .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))
    .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))
    .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
    .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
    .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
    .word 0x32
    .word 0x30
    .word 0x30

(6)测试编译能否成功:
    make fs2410_config
    make
    如果没有问题,在u-boot-1.1.6目录下就生成u-boot.bin,因为到这一步只是做了点小改动,并未涉及敏感问题,测试一下可增加点信心,烧到扳子看到如图1所示。当然也有make不成功的时候,如按照上述步骤编译u-boot-1.1.5的时候,出现“没有规则创建'all'需要的目标'hello_world.srec'”,如图1所示,解决方法:
    把example文件夹下的Makefile中的
    第147行 
    %.srec: % 改成: %.srec: %.o 
    第150行
     %.bin: % 改成: %.bin: %.o
网上还有一种改法,我没试过,不作说明。
(7)在board/fs2410加入NAND Flash读函数,建立nand_read.c,加入如下内容(copy from vivi):
#include <config.h>
#include "linux/mtd/mtd.h"
#include "linux/mtd/nand.h"
 
#define __REGb(x) (*(volatile unsigned char *)(x))
#define __REGi(x) (*(volatile unsigned int *)(x))
#define NF_BASE 0x4e000000
#define NFCONF __REGi(NF_BASE + 0x0)
#define NFCMD __REGb(NF_BASE + 0x4)
#define NFADDR __REGb(NF_BASE + 0x8)
#define NFDATA __REGb(NF_BASE + 0xc)
#define NFSTAT __REGb(NF_BASE + 0x10)
#define BUSY 1
inline void wait_idle(void) {
    int i; 
    while(!(NFSTAT & BUSY))
      for(i=0; i<10; i++);
}
#define NAND_SECTOR_SIZE 512
#define NAND_BLOCK_MASK (NAND_SECTOR_SIZE - 1)
/* low level nand read function */
int
nand_read_ll(unsigned char *buf, unsigned long start_addr, int size)
{
    int i, j;
    if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) {
        return -1; /* invalid alignment */
    }
    /* chip Enable */
    NFCONF &= ~0x800;
    for(i=0; i<10; i++);
     for(i=start_addr; i < (start_addr + size);) {
      /* READ0 */
      NFCMD = 0;
       /* Write Address */
      NFADDR = i & 0xff;
      NFADDR = (i >> 9) & 0xff;
      NFADDR = (i >> 17) & 0xff;
      NFADDR = (i >> 25) & 0xff;
       wait_idle();
       for(j=0; j < NAND_SECTOR_SIZE; j++, i++) {
*buf = (NFDATA & 0xff);
buf++;
      }
    }
     /* chip Disable */
    NFCONF |= 0x800; /* chip disable */
    return 0;
}

(10)修改cpu/arm920t/start.S文件

     2410的启动代码可以在外部的NAND FLASH上执行,启动时,NAND FLASH的前4KB(地址为0x00000000,OM[1:0]=0)将被装载到SDRAM中被称为Setppingstone的地址中,然后开始执行这段代码。启动以后,这4KB的空间可以做其他用途,在start.S加入搬运代码如下: 
...........
...........
copy_loop:
    ldmia    r0!, {r3-r10}        /* copy from source address [r0]    */
    stmia    r1!, {r3-r10}        /* copy to   target address [r1]    */
    cmp    r0, r2            /* until source end addreee [r2]    */
    ble    copy_loop

/*08-6-24********************************************************/
#ifdef CONFIG_S3C2410_NAND_BOOT /*这个一定要放在堆栈设置之前*/
    bl    copy_myself
#endif    /*CONFIG_S3C2410_NAND_BOOT*/
/*08-6-24********************************************************/

#endif    /* CONFIG_SKIP_RELOCATE_UBOOT */

    /* Set up the stack                            */
stack_setup:
..................
    /**************************************************************************
 *
 * copy u-boot    to ram 放在start.S靠后的位置
 *
 *************************************************************************
 */
 #ifdef CONFIG_S3C2410_NAND_BOOT
/*
@ copy_myself: copy u-boot to ram
*/
copy_myself:
    mov   r10, lr
 
    @ reset NAND
    mov    r1, #NAND_CTL_BASE
    ldr    r2, =0xf830        @ initial value
    str    r2, [r1, #oNFCONF]
    ldr    r2, [r1, #oNFCONF]
    bic    r2, r2, #0x800        @ enable chip
    str    r2, [r1, #oNFCONF]
    mov    r2, #0xff        @ RESET command
    strb    r2, [r1, #oNFCMD]
    mov    r3, #0            @ wait 
1:    add    r3, r3, #0x1
    cmp    r3, #0xa
    blt    1b
2:    ldr    r2, [r1, #oNFSTAT]    @ wait ready
    tst    r2, #0x1
    beq    2b
    ldr    r2, [r1, #oNFCONF]
    orr    r2, r2, #0x800        @ disable chip
    str    r2, [r1, #oNFCONF]
 
    @ get read to call C functions
    ldr    sp, DW_STACK_START    @ setup stack pointer
    mov    fp, #0            @ no previous frame, so fp="0"
 
    @ copy UBOOT to RAM
    ldr    r0, _TEXT_BASE
    mov     r1, #0x0
    mov    r2, #0x20000
    bl    nand_read_ll
 
    teq    r0, #0x0
    beq    ok_nand_read
 
bad_nand_read: 
1:    b    1b        @ infinite loop 
     
ok_nand_read:
 
    @ verify
     
    mov    r0, #0
    ldr    r1, _TEXT_BASE
    mov    r2, #0x400    @ 4 bytes * 1024 = 4K-bytes
go_next:
    ldr    r3, [r0], #4
    ldr    r4, [r1], #4
    teq    r3, r4
    bne    notmatch
    subs    r2, r2, #4
    beq    done_nand_read     
    bne    go_next
notmatch:
1:    b    1b
done_nand_read:
     
    mov   pc, r10
 
#endif    
    @ CONFIG_S3C2440_NAND_BOOT
 
DW_STACK_START:
    .word    STACK_BASE+STACK_SIZE-4
 
(11)修改include/configs/fs2410.h文件,添加如下内容:
/*08-6-25***************************************************/
/*-----------------------------------------------------------------------
 *  NAND FLASH BOOT
 */
#define    CONFIG_S3C2410_NAND_BOOT    1
#define    STACK_BASE            0x33f00000
#define    STACK_SIZE                0x8000
#define    UBOOT_RAM_BASE          0x30100000
 
#define    NAND_CTL_BASE            0x4e000000
#define    bINT_CTL(Nb)            _REG(INT_CTL_BASE+(Nb))
 
 
#define    oNFCONF                0x00
#define    oNFCMD                0x04
#define    oNFADDR                0x08
#define    oNFDATA                0x0c
#define    oNFSTAT                0x10
#define    oNFECC                0x14
/*--------------------------------------------------------------------*/
#define NAND_MAX_CHIPS        1

(12)修改board/fs2410/Makefile
OBJS := fs2410.o flash.o nand_read.o
(13)重新编译u-boot
make  fs2410_config
make
13)通过fs2410的NOR FLASH上的BIOS将u-boot.bin烧写到nand flash中就可以从NAND flash启动了
我的u-boot启动信息如图2所示,可以看出:和第一次make的结果一样,u-boot命令依然不能用,也就是说不能用saveenv保存设置,因为我们现在只是完成了u-boot从NAND FLASH的启动工作,添加了
nand_read.c函数,而不能实现写操作,在《基于优龙FS2410开发板u-boot-1.1.6的移植(NAND FLASH) (二)》中将实现u-boot的一些命令,tftp、 saveenv、 go等。

附件:
图1

点击看大图

图2

点击看大图

系统分类: ARM   |    用户分类:    |    来源: 转贴

评论(0) | 阅读(801)
发表于:2008/11/3 16:49:02
标签:无标签

0

chmod命令详细用法

指令名称 : chmod
使用权限 : 所有使用者
使用方式 : chmod [-cfvR] [--help] [--version] mode file...
说明 : Linux/Unix 的档案调用权限分为三级 : 档案拥有者、群组、其他。利用 chmod 可以藉以控制档案如何被他人所调用。
参数 :
mode : 权限设定字串,格式如下 : [ugoa...][[+-=][rwxX]...][,...],其中
u 表示该档案的拥有者,g 表示与该档案的拥有者属于同一个群体(group)者,o 表示其他以外的人,a 表示这三者皆是。
+ 表示增加权限、- 表示取消权限、= 表示唯一设定权限。
r 表示可读取,w 表示可写入,x 表示可执行,X 表示只有当该档案是个子目录或者该档案已经被设定过为可执行。
-c : 若该档案权限确实已经更改,才显示其更改动作
-f : 若该档案权限无法被更改也不要显示错误讯息
-v : 显示权限变更的详细资料
-R : 对目前目录下的所有档案与子目录进行相同的权限变更(即以递回的方式逐个变更)
--help : 显示辅助说明
--version : 显示版本
范例 :将档案 file1.txt 设为所有人皆可读取 :
chmod ugo+r file1.txt 
将档案 file1.txt 设为所有人皆可读取 :
chmod a+r file1.txt 
将档案 file1.txt 与 file2.txt 设为该档案拥有者,与其所属同一个群体者可写入,但其他以外的人则不可写入 :
chmod ug+w,o-w file1.txt file2.txt 
将 ex1.py 设定为只有该档案拥有者可以执行 :
chmod u+x ex1.py 
将目前目录下的所有档案与子目录皆设为任何人可读取 :
chmod -R a+r * 
此外chmod也可以用数字来表示权限如 chmod 777 file
语法为:chmod abc file
其中a,b,c各为一个数字,分别表示User、Group、及Other的权限。
r=4,w=2,x=1
若要rwx属性则4+2+1=7;
若要rw-属性则4+2=6;
若要r-x属性则4+1=7。
范例:
chmod a=rwx file 

chmod 777 file 
效果相同
chmod ug=rwx,o=x file 

chmod 771 file 
效果相同
若用chmod 4755 filename可使此程序具有root的权限

系统分类: 嵌入式   |    用户分类:    |    来源: 转贴

评论(0) | 阅读(192)
发表于:2008/11/2 16:50:52
标签:无标签

1

摄 像 头 浅 谈

一、摄像头简介

摄像头(CAMERA)又称为电脑相机、电脑眼等,它作为一种视频输入设备,在过去被广泛的运用于视频会议、远程医疗及实时监控等方面。近年以来,随着互联网技术的发展,网络速度的不断提高,再加上感光成像器件技术的成熟并大量用于摄像头的制造上,这使得它的价格降到普通人可以承受的水平。普通的人也可以彼此通过摄像头在网络进行有影像、有声音的交谈和沟通,另外,人们还可以将其用于当前各种流行的数码影像、影音处理。

二、摄像头的分类

摄像头分为数字摄像头和模拟摄像头两大类。模拟摄像头可以将视频采集设备产生的模拟视频信号转换成数字信号,进而将其储存在计算机里。模拟摄像头捕捉到的视频信号必须经过特定的视频捕捉卡将模拟信号转换成数字模式,并加以压缩后才可以转换到计算机上运用。数字摄像头可以直接捕捉影像,然后通过串、并口或者USB接口传到计算机里。现在电脑市场上的摄像头基本以数字摄像头为主,而数字摄像头中又以使用新型数据传输接口的USB数字摄像头为主,目前市场上可见的大部分都是这种产品。除此之外还有一种与视频采集卡配合使用的产品,但目前还不是主流。

由于个人电脑的迅速普及,模拟摄像头的整体成本较高等原因, USB接口的传输速度远远高于串口、并口的速度,因此现在市场热点主要是USB接口的数字摄像头。以下主要是指USB接口的数字摄像头。

三、摄像头的工作原理

摄像头的工作原理大致为:景物通过镜头(LENS)生成的光学图像投射到图像传感器表面上,然后转为电信号,经过A/D(模数转换)转换后变为数字图像信号,再送到数字信号处理芯片(DSP)中加工处理,再通过USB接口传输到电脑中处理,通过显示器就可以看到图像了。

注1:图像传感器(SENSOR)是一种半导体芯片,其表面包含有几十万到几百万的光电二极管。光电二极管受到光照射时,就会产生电荷。

注2:数字信号处理芯片DSP(DIGITAL SIGNAL PROCESSING)功能:主要是通过一系列复杂的数学算法运算,对数字图像信号参数进行优化处理,并把处理后的信号通过USB等接口传到PC等设备。

DSP结构框架:

1. ISP(image signal processor)(镜像信号处理器)

2. JPEG encoder(JPEG图像解码器)

3. USB device controller(USB设备控制器)

点击看大图

四、摄像头的主要结构和组件

从摄像头的工作原理就可以列出摄像头的主要结构和组件:

1、 镜头(LENS)

透镜结构,由几片透镜组成,有塑胶透镜(plastic)或玻璃透镜(glass)。

2、 图像传感器(SENSOR)

可以分为两类:

CCD(charge couple device) :电荷耦合器件

CMOS(complementary metal oxide semiconductor):互补金属氧化物半导体

3、 数字信号处理芯片(DSP)

DSP生产厂商较多,市面上较为流行的有:SONIX(松瀚)602A、VIMICRO(中星微)301P、ST(罗技LOGITECH的DSP提供商)、SUNPLUS(SUN+重点发展单芯片的CIF和VGA,但图像质量一般)、OVT(OVT511、OVT519前两年较流行,现有少数产品在市场上)。

4、电源

摄像头内部需要两种工作电压:3.3V和2.5V,因此好的摄像头内部电源也是保证摄像头稳定工作的一个因素。

五、摄像头的一些技术指标

1、 图像解析度/分辨率(Resolution):

●SXGA(1280 x1024)又称130万像素

●XGA(1024 x768)又称80万像素

●SVGA(800 x600)又称50万像素

●VGA(640x480)又称30万像素(35万是指648X488)

●CIF(352x288) 又称10万像素

●SIF/QVGA(320x240)

●QCIF(176x144)

●QSIF/QQVGA(160x120)

2、图像格式(Image Format/ Color space)

RGB24,I420是目前最常用的两种图像格式。

●RGB24:表示R、G、B三种颜色各8bit,最多可表现256级浓淡,从而可以再现256*256*256种颜色。

●I420:YUV格式之一。

●其它格式有: RGB565,RGB444,YUV4:2:2等。

3、自动白平衡调整(AWB)

定义:要求在不同色温环境下,照白色的物体,屏幕中的图像应也是白色的。

色温表示光谱成份,光的颜色。色温低表示长波光成分多。

当色温改变时,光源中三基色(红、绿、蓝)的比例会发生变化,需要调节三基色的比例来达到彩色的平衡,这就是白平衡调节的实际。

4、图像压缩方式

JPEG:(joint photographic expert group)

静态图像压缩方式。一种有损图像的压缩方式。压缩比越大,图像质量也就越差。当图像精度要求不高存储空间有限时,可以选择这种格式。目前大部分数码相机都使用JPEG格式。

5、彩色深度(色彩位数)

反映对色彩的识别能力和成像的色彩表现能力

实际就是A/D转换器的量化精度,是指将信号分成多少个等级。常用色彩位数(bit)表示。

彩色深度越高,获得的影像色彩就越艳丽动人。

6、图像噪音

指的是图像中的杂点干挠。

表现为图像中有固定的彩色杂点。

7、视角

与人的眼睛成像是相成原理,简单说就是成像范围。

8、输出/输入接口

串行接口(RS232/422):传输速率慢,为115kbit/s

并行接口(PP):速率可以达到1Mbit/s

红外接口(IrDA):速率也是115kbit/s,一般笔记本电脑有此接口

通用串行总线USB:即插即用的接口标准,支持热插拔。USB1.1速率可达12Mbit/s,USB2.0可达480bit/s

IEEE1394(火线)接口(亦称ilink):其传输速率可达100M~400Mbit/s

六、摄像头的进一步认识

从摄像头的组成来看决定一个摄像头的品质从硬件上来说主要是:

1、 镜头(LENS)

镜头的组成是透镜结构,由几片透镜组成,一般有塑胶透镜(plastic)或玻璃透镜(glass)。通常摄像头用的镜头构造有:1P、2P、1G1P、1G2P、2G2P、4G等。透镜越多,成本越高;玻璃透镜比塑胶贵。因此一个品质好的摄像头应该是采用玻璃镜头,成像效果就相对塑胶镜头会好。现在市场上的大多摄像头产品为了降低成本,一般会采用塑胶镜头或半塑胶半玻璃镜头(即:1P、2P、1G1P、1G2P等)。

2、 图像传感器(SENSOR)

图像传感器分为两类:CCD(charge couple device) :电荷耦合器件

CMOS(complementary metal oxide semiconductor):互补金属氧化物半导体

CCD的优点是灵敏度高,噪音小,信噪比大。但是生产工艺复杂、成本高、功耗高。

CMOS的优点是集成度高、功耗低(不到CCD的1/3)、成本低。但是噪音比较大、灵敏度较低、对光源要求高。

在相同像素下CCD的成像往往通透性、明锐度都很好,色彩还原、曝光可以保证基本准确。而CMOS的产品往往通透性一般,对实物的色彩还原能力偏弱,曝光也都不太好。所以我们在使用摄像头,尤其是采用CMOS芯片的产品时就更应该注重技巧:

首先不要在逆光环境下使用(这点CCD同),尤其不要直接指向太阳,否则“放大镜烧蚂蚁”的惨剧就会发生在您的摄像头上。

其次环境光线不要太弱,否则直接影响成像质量。克服这种困难有两种办法,一是加强周围亮度,二是选择要求最小照明度小的产品,现在有些摄像头已经可以达到5lux。最后要注意的是合理使用镜头变焦,不要小瞧这点,通过正确的调整,摄像头也同样可以拥有拍摄芯片的功能。

目前,市场销售的数码摄像头中,基本是CCD和CMOS平分秋色。在采用CMOS为感光元器件的产品中,通过采用影像光源自动增益补强技术,自动亮度、白平衡控制技术,色饱和度、对比度、边缘增强以及伽马矫正等先进的影像控制技术,完全可以达到与CCD摄像头相媲美的效果。

受市场情况及市场发展等情况的限制,摄像头采用CCD图像传感器的厂商为数不多,主要原因是采用CCD图像传感器成本高的影响。

3、 数字信号处理芯片(DSP)

在DSP的选择上,是根据摄像头成本、市场接受程度来进行确定。现在DSP厂商在设计、生产DSP的技术已经逐渐成熟,在各项技术指标上相差不是很大,只是有些DSP在细微的环节及驱动程序要进行进一步改进。

4、 图像解析度/分辨率(Resolution):

摄像头的图像解析度/分辨率也就是我们常说的多少像素的摄像头,在实际应用中,摄像头的像素越高,拍摄出来的图像品质就越好,但另一方面也并不是像素越高越好,对于同一画面,像素越高的产品它的解析图像的能力也越强,但相对它记录的数据量也会大得多,所以对存储设备的要求也就高得多,因而在选择时宜采用当前的主流产品。由于受到摄像头价格、电脑硬件、成像效果等因素的影响,现在市面上的摄像头基本在30万像素这个档次上进行销售。
还有就是由于CMOS成像效果在高像素上并不理想,因此统治高像素摄像头的市场仍然是CCD摄像头。

值得注意的一点:有些分辨率的标识是指这些产品利用软件所能达到的插值分辨率,虽然说也能适当提高所得图像的精度,但和硬件分辨率相比还是有着一定的差距的。

七、客户最关心的问题

客户在购买摄像头最关心的是采用什么镜头(当然客户很少有把镜头和图像传感器分开来问的)、最大分辨率、多少万像素、视频传输速度多少帧、接口类型之类的问题。如果摄像头是CMOS镜头、30万像素、最大分辨率为640*480、USB接口、最大传输速度为30帧/秒,客户就基本能够接受,因为这样配置的摄像头是市场上较为流行的。

1、 问:什么是CMOS镜头,而不是CCD的镜头,听说CCD镜头的摄像头效果会好一些?

答:首先采用CCD镜头的摄像头的成本会高出一些,另外在采用CMOS为感光元器件的产品中,通过采用影像光源自动增益补强技术,自动亮度、白平衡控制技术,色饱和度、对比度、边缘增强以及伽马矫正等先进的影像控制技术,完全可以达到与CCD摄像头相媲美的效果。我们的摄像头在软件中均有这些功能,因些您如果不是要求太高的情况,采用CMOS镜头的摄像头是您最佳的选择。

2、 问:都是CMOS镜头、30万像素的摄像头,为什么别人的可以上到的最大分辨率是704×576。

答:这些摄像头的分辨率是插值分辨率,是通过软件来实现,并不是真正硬件分辨率,类似于电脑某些部件通过软件来提高其性能,虽然说也能适当提高所得图像的精度,但实际效果并不好。

3、 问:说明书上标明是最大视频传输帧数是30帧,为什么我在640*480分辨率下测试只有10帧左右?

答:这主要是跟分辨率有关,最大视频传输帧数30帧/秒是在CIF(352*288)分辨率下实现的,而在VGA(640*480)分辨率一般为10帧左右/秒,原因是受到USB接口传输速度的制约,以CIF(352*288)、RGB24图像格式为例,每秒数据流量为:352*288*24*30=72990720(73兆位)=13Mb,经过压缩,由USB口传送到电脑时也有10Mb/秒左右,而USB口传输速率最高峰值也只有12 Mb/秒,因此在VGA分辨率的情况下,10帧/秒是很正常的情况。目前数字摄像头的视频捕获都是通过软件来实现的,对电脑的要求非常高,因此要达到最大视频传输帧数,就要求电脑硬件相应跟上。

4、 问:我的优是数码外星眼M6610在使用过程中,无论清晰度、色彩、亮度方面都很好,只是在物体晃动时会有拖影,图像略显模糊,不知是什么原因?

答:优是数码外星眼设计就是以清晰度、色彩鲜艳为主,速度快相应就牺牲了这些特点,这是因为优是数码考虑在现实运用中,摄像头主要还是用来获取静态图像,比如上网视频聊天,相信你不会在摄像头前不停的晃动吧。如果要解决这面的问题,可以在摄像头应用软件中,将图像的清晰度、色彩饱和度调低一些,就会得到一定的改善。

八、摄像头的未来

根据IT行业硬件发展的“摩尔定律”来看,数字摄像头也同样遵循其发展规律的,相信在未来几年内会发展的很快。从目前市场情况来看,制约摄像头发展的因素主要有以下几个方面的原因:

1、 摄像头市场起步较晚,消费者认知度、接受度较低,所以普及率较低,市场容量增大速度不够快,需要加以一定引导来推动市场消费。

2、 摄像头的实际应用不够广泛,有一定的局限性,目前还是作为一种消费类产品在销售,消费者只是把它作为视频聊天、制作简单的个人影像集、简单的监视系统等的工具。

3、 现在电脑硬件的限制,如电脑显示卡、显示器的分辨率、USB1.1接口速度,就影响高像素摄像的真正普及。

以个人观点来看,数字摄像头的未来发展趋势是:

1、 高像素(50万、80万)、高质量图像传感器(CCD)、高传输速度(USB2.0或其他接口)的摄像头将会是未来的发展趋势;

2、 专业化(只作为专业视频输入设备来使用)、多功能化(附带其他功能,例如附带闪存盘,趋向数码相机方向发展,也可以设想以后的摄像头可以具有扫描仪的功能)等也是将来的发展趋势;

3、 更人性化、更易于使用、更多的实际应用功能才是客户的真正需求。

系统分类: 嵌入式   |    用户分类: 无分类    |    来源: 转贴

评论(1) | 阅读(267)
发表于:2008/10/31 16:08:45
标签:无标签

0

在linux 上安装gcc-3.3.1编译器

   安装之前,必须保证系统中有cc或者gcc等编译器,并且是可用的,或者用环境变量CC指定系统上的编译器。如果系统上没有编译器,不能安装源代码形式的GCC 3.3.1情况,可以在网上找一个与你系统相适应的如RPM等二进制形式的GCC软件包来安装使用。本文介绍的是以源代码形式提供的GCC软件包的安装过程,软件包本身和其安装过程同样适用于其它Linux和Unix系统。

  系统上原来的GCC编译器可能是把gcc等命令文件、库文件、头文件等分别存放到系统中的不同目录下的。与此不同,现在GCC建议我们将一个版本的GCC安装在一个单独的目录下。这样做的好处是将来不需要它的时候可以方便地删除整个目录即可(因为GCC没有uninstall功能);缺点是在安装完成后要做一些设置工作才能使编译器工作正常。在本文中我采用这个方案安装GCC 3.3.1在安装完成后,仍然能够使用原来低版本的GCC编译器,即一个系统上可以同时存在并使用多个版本的GCC编译器。

  按照本文提供的步骤和设置选项,即使以前没有安装过GCC,也可以在系统上安装上一个可工作的新版本的GCC编译器。

  1. 下载

GCC网站上(http://gcc.gnu.org/)或者通过网上搜索可以查找到下载资源。目前GCC的最新版本为 3.3.1。可供下载的文件一般有两种形式:gcc-3.3.1.tar.gz和gcc-3.3.1.tar.bz2,只是压缩格式不一样,内容完全一致,下载其中一种即可。

  2. 解压缩

  根据压缩格式,选择下面相应的一种方式解包(以下的“%”表示命令行提示符):

% tar xzvf gcc-3.3.1.tar.gz

  或者

  % tar jxvf gcc-3.3.1.tar.bz2

  新生成的gcc-3.3.1这个目录被称为源目录,用${srcdir}表示它。以后在出现${srcdir}的地方,应该用真实的路径来替换它。用pwd命令可以查看当前路径。

  在${srcdir}/INSTALL目录下有详细的GCC安装说明,可用浏览器打开index.html阅读。

3. 建立目标目录

   目标目录(用${objdir}表示)是用来存放编译结果的地方。GCC建议编译后的文件不要放在源目录${srcdir]中(虽然这样做也可以),最好单独存放在另外一个目录中,而且不能是${srcdir}的子目录。

  例如,可以这样建立一个叫 gcc-build 的目标目录(与源目录${srcdir}是同级目录):

  % mkdir gcc-build
  % cd gcc-build

  以下的操作主要是在目标目录 ${objdir} 下进行。

4. 配置

   配置的目的是决定将GCC编译器安装到什么地方(${destdir}),支持什么语言以及指定其它一些选项等。其中,${destdir}不能与${objdir}或${srcdir}目录相同。

  配置是通过执行${srcdir}下的configure来完成的。其命令格式为(记得用你的真实路径替换${destdir}):

  % ${srcdir}/configure --prefix=${destdir} [其它选项]

  例如,如果想将GCC 3.3.1安装到/usr/local/gcc-3.3.1目录下,则${destdir}就表示这个路径。

  在我的机器上,我是这样配置的:

  % ../gcc-3.3.1/configure --prefix=/usr/local/gcc-3.3.1 --enable-threads=posix --disable-checking --enable--long-long --host=i386-redhat-linux --with-system-zlib --enable-languages=c,c++,java

  将GCC安装在/usr/local/gcc-3.3.1目录下,支持C/C++和JAVA语言,其它选项参见GCC提供的帮助说明。

  5. 编译

  % make

  这是一个漫长的过程。

  6. 安装

  执行下面的命令将编译好的库文件等拷贝到${destdir}目录中(根据你设定的路径,可能需要管理员的权限):

  % make install

  至此,GCC 3.3.1安装过程就完成了。

  6. 其它设置

  GCC 3.3.1的所有文件,包括命令文件(如gcc、g++)、库文件等都在${destdir}目录下分别存放,如命令文件放在bin目录下、库文件在lib下、头文件在include下等。由于命令文件和库文件所在的目录还没有包含在相应的搜索路径内,所以必须要作适当的设置之后编译器才能顺利地找到并使用它们。

  6.1 gcc、g++、gcj的设置

  要想使用GCC 3.3.1的gcc等命令,简单的方法就是把它的路径${destdir}/bin放在环境变量PATH中。我不用这种方式,而是用符号连接的方式实现,这样做的好处是我仍然可以使用系统上原来的旧版本的GCC编译器。

  首先,查看原来的gcc所在的路径:

  % which gcc

  在我的系统上,上述命令显示:/usr/bin/gcc。因此,原来的gcc命令在/usr/bin目录下。我们可以把GCC 3.3.1中的gcc、g++、gcj等命令在/usr/bin目录下分别做一个符号连接:

% cd /usr/bin

% ln -s ${destdir}/bin/gcc gcc33

% ln -s ${destdir}/bin/g++ g++33

% ln -s ${destdir}/bin/gcj gcj33

  这样,就可以分别使用gcc33、g++33、gcj33来调用GCC 3.3.0的gcc、g++、gcj完成对C、C++、JAVA程序的编译了。同时,仍然能够使用旧版本的GCC编译器中的gcc、g++等命令。

  6.2 库路径的设置

  将${destdir}/lib路径添加到环境变量LD_LIBRARY_PATH中,最好添加到系统的配置文件中,这样就不必要每次都设置这个环境变量了。

  例如,如果GCC 3.3.1安装在/usr/local/gcc-3.1.0目录下,在RH Linux下可以直接在命令行上执行或者在文件/etc/profile中添加下面一句:

  setenv LD_LIBRARY_PATH /usr/local/gcc-3.3.1 /lib:$LD_LIBRARY_PATH

7. 测试

用新的编译命令(gcc33、g++33等)编译你以前的C、C++程序,检验新安装的GCC编译器是否能正常工作。

  8. 根据需要,可以删除或者保留${srcdir}和${objdir}目录。

 

 

http://blog.yesky.com/11/polaris0161/1031511.shtml

系统分类: ARM   |    用户分类:    |    来源: 转贴

评论(0) | 阅读(346)
发表于:2008/6/28 14:46:12
标签:无标签

0

s3c2410之clock

clock部分比较容易,现在按照datasheet的思路梳理一下。

一、对clock的基本认识
    第七部分是“clock & power management”,总结如下:
    1 s3c2410的clock & power management模块包含三个部分:clock control、usb control、power control。现在的关注点是clock control。
    2、s3c2410有两个pll(phase locked loop,锁相环,在高频中学过,可以实现倍频,s3c2410的高频就是由此电路产生的)。其中一个是MPLL,M即为main,用来产生三种时钟信号:Fclk(给CPU核供给时钟信号,我们所说的s3c2410的cpu主频为200MHz,就是指的这个时钟信号,相应的,1/Fclk即为cpu时钟周期)、Hclk(为AHB bus peripherals供给时钟信号,AHB为advanced high-performance bus)、Pclk(为APB bus peripherals供给时钟信号,APB为advanced peripherals bus)。在这里,需要了解一下AMBA system architecture了。这个可以到官方网站www.arm.com下载相关资料。简单的说,AMBA是一种协议,这种协议已经称为片上组织通信的事实上的标准(the de facto standard for on-chip fabric communication)。下面给出英文描述:
    The AMBA protocol is an open standard, on-chip bus specification that details a stategy for the interconnection and management of functional blocks that makes up a system-on-chip(SoC).It facilitates "right-first-time" development of embedded processors with one or more CPU/signal processors and multiple peripherals. The AMBA protocol enhances a resuable design methodology by defining a common backbone for SoC modules.
    需要知道的是,AMBA总线是ARM提出的一种解决方案,它并非唯一的规范,但是因为ARM的广泛使用,AMBA总线也就成为了事实上的规范了。现在AMBA总线最新为AMBA 3 specification版本,包括AMBA 3 AXI Interface、AMBA 3 AHB Interface、AMBA 3 APB Interface、AMBA 3 ATB Interface。而s3c2410还只能支持AMBA 2 specification,这个版本包含AMBA 2 AHB Interface、AMBA 2 APB Interface。也就是在s3c2410的框图中看到的两种总线接口。需要注意的是,这两种总线所连的外设是有区别的。AHB总线连接高速外设,低速外设则通过APB总线互连。显然,对不同总线上的外设,应该使用不同的时钟信号,AHB总线对应Hclk,APB总线对应Pclk。那么事先就应该弄清楚,每条总线对应的外设有那些,这样在设置好时钟信号后,对应外设的初始化的值就要依此而确定了。
    AHB bus上的外设有LCD controller(CONT代表controller,控制器)、USB Host CONT、ExtMaster、Nand CONT和nand flash boot loader、bus CONT、interrupt CONT、power management、memory CONT(sram/nor/sdram等)。
    APB bus上的外设有UART、USB device、SDI/MMC、Watch Dog Timer、bus CONT、spi、iic、iis、gpio、rtc、adc、timer/pwm。
    3、主时钟源来自外部晶振或者外部时钟。复位后,MPLL虽然默认启动,但是如果不向MPLLCON中写入value,那么外部晶振直接作为系统时钟。EDUKIT-III的外部晶振有两个,一是用于系统时钟,为12MHz;一个用于RTC,为32.768KHz。以前实验没有向MPLLCON写入数值,所以系统时钟都是12MHz。从这里也可以发现一个问题,如果外部晶振开始没有焊上,那么系统是无法正常启动的。因为按照上述规则,复位后还没有写入MPLLCON,这时又没有可以使用的时钟源,所以不会启动。也就是硬件完成后,这个12MHz的晶振是一定要焊上的,才能进行后续的硬件测试工作。
二、clock设置的步骤
    首先应该读懂下一段:

Power-On Reset (XTIpll)
Figure 7-4 shows the clock behavior during the power-on reset sequence. The crystal oscillator begins oscillation within several milliseconds. When nRESET is released after the stabilization of OSC (XTIpll) clock, the PLL starts to operate according to the default PLL configuration. However, PLL is commonly known to be unstable after power-on reset, so Fin is fed directly to FCLK instead of the Mpll (PLL output) before the software newly configures the PLLCON. Even if the user does not want to change the default value of PLLCON register after reset, the user should write the same value into PLLCON register by software.


The PLL restarts the lockup sequence toward the new frequency only after the software configures the PLL with a new frequency. FCLK can be configured as PLL output (Mpll) immediately after lock time.

    这个主要是基于PLL的特点。简单的描述就是,上电复位后,几个ms后晶振起振。当OSC时钟信号稳定之后,nRESET电平拉高(这是硬件自动检测过程)。这个时候,PLL开始按照默认的PLL配置开始工作,但是特殊性就在于PLL在上电复位后开始是不稳定的,所以s3c2410设计为把Fin在上电复位后直接作为Fclk,这是MPLL是不起作用的。如果要想是MPLL起作用,那么方法就是写入MPLLCON寄存器值,然后等待LOCKTIME时间后,新的Fclk开始工作。下面把这些步骤分来来描述,软件步骤部分结合程序进行。
    1、上电几个ms后,晶振输出稳定。Fclk=晶振频率。nRESET恢复高电平后,cpu开始执行指令,这完全是硬件动作,不需要软件设置。
    2、第一步软件工作: 设置P M S divider control,也就是设置MPLLCON寄存器。
    关于PMS,可以看Figure 7-2.寄存器MPLLCON的设置呢,其实有一定的规则,并非你想要的每个Fclk频率都可以得到。官方推荐了一个表PLL VALUE SELECTION TABLE,要按照这个进行。否则的话,就需要自己按照公式推算,但是mizi公司并不保证你的设置是合适的。所以,如果想要工作在200MHz,还是按照vivi的推荐值即可。

@ step1: set P M S divider control
        mov r1, #CLK_CTL_BASE
         ldr r2, =vMPLLCON_200
        str r2, [r1, #oMPLLCON]

    其中,MDIV=0x5c,PDIV=0x04,SDIV=0x00.公式Mpll(Fclk)=(m×Fin)/(p×(2^s))【m=MDIV+8, p="PDIV"+2,s=SDIV】
    3、第二步软件工作: 设置CLKDIVN。
    这一步是设置分频系数,即Fclk为cpu主频,Hclk由Fclk分频得到,Pclk由Hclk分频得到。假设Hclk是Fclk的二分频,Pclk是Hclk的二分频,那么分频系数比就是Fclk:Hclk:Pclk=1:2:4.那么Hclk为100MHz,总线时钟周期为10ns。Pclk为50MHz。

@ step2: change clock divider
        mov r1, #CLK_CTL_BASE
        mov r2, #vCLKDIVN
        str r2, [r1, #oCLKDIVN]

    4、第三步软件工作: CLKDIVN的补充设置
  

If HDIVN = 1, the CPU bus mode has to be changed from the fast bus mode to the asynchronous bus mode using following instructions.
MMU_SetAsyncBusMode
        mrc p15,0,r0,c1,c0,0
        orr r0,r0,#R1_nF:OR:R1_iA
        mcr p15,0,r0,c1,c0,0
If HDIVN=1 and the CPU bus mode is the fast bus mode, the CPU will operate by the HCLK. This feature can be used to change the CPU frequency as a half without affecting the HCLK and PCLK.

    看了上段话,只需要翻译出来就可以了。

@ FCLK:HCLK=1:2
.macro MMU_SetAsyncBusMode
         mrc p15, 0, r0, c1, c0, 0
         orr r0, r0, #(R1_iA | R1_nF)
         mcr p15, 0, r0, c1, c0, 0
.endm
         @ step3: set asynchronous bus mode
         MMU_SetAsyncBusMode

    5、第四步软件工作:等待locktime时间,让新的Fclk生效

@ step4: stay locktime
        mov r1, #CLK_CTL_BASE
         ldr r2, =vLOCKTIME
        str r2, [r1, #oLOCKTIME]

    6、对外设的影响
    在这个实验中,主要是有两个需要改变,一个外设是UART,一个外设是SDRAM。
    (1)UART,它是接在APB总线上,所以对应的时钟信号为Pclk,现在为50MHz。如果想要设置波特率为115200bps,那么根据公式UBRDIV0=(int)(PCLK/(bps*16))-1计算,应该为26。如果放到程序中,那么应该注意形式。具体如下:

UBRDIV0 = ((int)(PCLK/16./UART_BAUD_RATE) -1);

    (2)SDRAM,主要的影响因素为刷新频率。前面在SDRAM中没有具体分析,现在可以详细说明。使用了两片HY57V561620CT-H,查看手册其刷新频率为8192 refresh cycles/64ms,所以刷新周期64ms/8192=7.8125us。看寄存器REFRESH的各个位的设置情况:
    ·REFEN[23]:开启自动模式,设为1
    ·TREFMD[22]:设为Auto refresh模式,设为0
    ·Trp[21:20]:看看RAS precharge Time,查看SDRAM手册,发现-H系列此参数至少为20ns,现在Hclk对应的时钟周期为10ns,所以至少应该为2个clock。可以设为00
    ·Tsrc: Semi Row Cycle Time,也就是RAS Cycle Time,至少65ms,所以至少得6.5clock,按照可选值,应该设置为11
    ·Refresh[10:0]:
    公式refresh period = (2^11 - refresh_count +1)/Hclk,由此推导出refresh_count=2^11+1-refresh period*Hclk。带入数值,计算得出1268=0x04f4,这个数值要用四舍五入,减少误差。
    ·其余的保留值,均设置为0

    由此得出该寄存器的值应该为0x008c04f4。

系统分类: 嵌入式   |    用户分类:    |    来源: 转贴

评论(0) | 阅读(271)
234Next >Total , Page /