网上下的--ARM入门笔记

简单的介绍
打今天起菜鸟的ARM笔记算是开张了,也算给我的这些笔记找个存的地方。

为什么要发布出来?也许是大家感兴趣的,其实这些笔记之所以叫笔记而不是文章,是因为它们完全是本人个人学习经验的总结,而这些经验都来自于其他前辈的无私奉献,在这里对这些乐于发表自己经验的前辈致以由衷的感谢!现在我把这些前辈的文章经过自己的理解写出来一方面是对于他们的尊重,另一方面也希望觉得本人的笔记有参考意义的朋友把这种精神继续传下去。

再次声明,本人确实是个菜鸟,现在手头的板子是自己画的,以RT&ZQ的板子为底版,对部分电路进行了改动。比如加入了SD卡,IIC总线键盘,触摸屏,GPS,GPRS等等。并对LCD接口进行改造,使之完全适合手头的SHARP液晶。把网络,串口,USB这些调试用接口都外扩了,目的是使主板尽量小(目前第一版为了调试方便,主板特意画的比较大)。但是存储部分(RAM ROM)没有做任何变动,在这里对RT&ZQ致谢!

这块板子是本人第二个板子(第一块是个接口板,30根线。)所以走线,设计都经不起推敲,但是同样非常希望大家能够指点!

板子基本元件清单说一下吧,方便其他人参考

CPU:44B0

RAM:HY57V641620

ROM:AM29LV160

NET:8019

USB:D12

KEY:ZLG7290

LCD:SHARP LM7M632

目前为止本人做的工作
1 板子的硬件调试是跟着软件来的

2 ADS AXD调试环境搭建

3 FLSH烧写笔记

4 UBOOT移植笔记

5 UCLINUX编译下载简单笔记

6 字符设备驱动开发

C工程模板使用说明

本模板用于使44B0运行C程序
一般说来汇编用来初始化 之后跳到C入口MAIN函数处

一、关于工程文件

1、本目录下建工程文件(.MCP)
2、工程文件至少包含3个文件44binit.s 44blib_a.s *.c(自己的c文件)
3、44binit.s中开头部分INCLUDE两个文件MEMCFG.S Option.s用于基本设置
注意这两个文件的存放目录,即让INCLUDE找到它们
4、以上文件除自己的c文件之外均为三星公版,不需修改

二、关于CodeWarrior设置
1、DebugRel Setting里一般设置几项
1)Target Setting->Linker里选ARMLinker
用于设置连接
2)Target Setting->Post-Linker选ARM fromELF
用于生成FLASH烧录代码(只在RAM里运行 而不烧录则不用)
3)ARM Linker->RO BASE里添地址
根据板子来,这板子上RAM接的NSCS6,地址0XC000000-0XC7FFFFF;
FLASH接的NSCS0,地址0X00000-0XFFFFF
地址分配原理见44B0数据手册内存管理那章的内存分配图

想在RAM里调试就添0XC000000(比如0XC008000)的地址
但是注意的是地址不要添过界,比如想在RAM里调试却添0X00000000 程序可以 进入C代码 但没法运行

再有
想生成用于烧写得FLASH代码 RO地址就需要设置为0X0000000开始的 而且LAYOUT中也必须设置44BINIT.O为初始加载文件
以上FLASH测试结论经FLASHPGM测试
而且FLASHPGM不支持BIN文件 只支持INTEL得HEX文件
4)RW可以添 可以不添 一般RO解释为数据段,RW解释为数据段
有时高兴了就添上0XC100000(RAM调试时)
5)ARM Linker->OPTION->Image entry point选择0xc000000(RAM调试时)
6)ARM Linker->Layout->Object/Symbol里可以添工程起始程序44BINIT.O 注意是.O不是.S和.0(零)
也可以不添

三、AXD设置
1)按照BANYANGT或者ARM7正确设置调试代理
BANYANGT、ARM7、H-JTAG都是代理,装哪个无所谓,一般认为BANYANGT好,但无论哪个调试之前必须运行代理
2)在option->configure interface里 在session file 选择 44b0.ini 这个文件是初始化44b0寄存器的,必须运行
3)Options->Configue Target里本来有两项,上面上是硬件调试,下面是软件仿真(在电脑上仿真)
用ARM7就改第一项(按照ARM7说明改),用BANYANGT就按照BANYANGT说明在下面再加个BANYANGT的驱动
4)在general标签页选择attach,然后确定,最后在file->save session,关闭AXD(在CodeWarrior里一DEBUG就自动打开)

四、关于JTAG
1)JTAG一般有几种 SDT和WIGGLER 我的是WIGGLER的,两者区别主要在并口25针定义不一样(不算复位脚),与板子上JTAG相连的脚不是区分JTAG类型的标志
只要和44B0对上就行
2)JTAG小板上与44B0大板上JTAH跳线RAM调试时都不用接 烧FLASH才用到
3)网上流传的JTAG小板上也有不用RST信号的版本,无所谓,RST信号不是标准的

五、另外
开始的时候犯了低级错误,没设置OM1 2 3跳线 导致晶体不阵~~~

其他的看万龙的ARM开发板使用手册,写的还不错
模板:user94/mamajinco/upload/825806664.rar


这部分可能过于简单,很少有人写,但是对于不了解ARM开发过程的人真的简单吗?我是菜鸟,在这卡了3天:)
一般说来有几种方法,
1)板子原来的BOOTLOADER程序或者为烧写而编写的专用ADS程序
比较高级而快速的方法,很多现成的开发板都用这种方法(相对来说有实力的公司),此状态下CPU是运行的,所以速度快。
比如ZLG的,但是对于初学或者不准备细研究硬件的人来说就比较麻烦,因为要编写(改写)ADS烧写程序。愿意的人可以看看。
2)FLUTED
和FLASHPGM一样,使用的好象叫边界扫描法,CPU此时并不运行,因此烧写的比较慢。
在这里也不推荐FLUTED这个软件,原因比较简单,麻烦+速度慢。
因为需要编写(改写)两个配置文件,而且是字符界面。倒是有人说这个软件只能在WIN98下用的说法好象不对(现在有可以让2000和XP下用的方法)
喜欢的朋友可以用用
3)FLASHPGM(推荐)
很简单的程序,GUI界面,速度尚好。
设置很简单,在CPU里选对型号,当然是3星的44B0。在FLASH里也一样,39LV160,29LV160都有。
确定好地址,RAM地址我的是0XC000000(BANK7上) FLASH地址0X0(BANK0上)
选完了以后读一下FLASH的ID(左下脚的按钮吧)能读出厂家的ID就行。
然后是烧写了,PROGRAME按钮,注意的是FLASHPGM不支持BIN格式,按照下面方法处理。
再有就是尽量在写之前擦一下,PROGRAME菜单里有个选项,打个钩就OK。
具体烧写方法可以看我总结的另一篇文档,在这里只说说UBOOT相关的。
前面说过UBOOT编译以后产生3个文件
u-boot——ELF格式的文件,可以被大多数Debug程序识别;
u-boot.bin——二进制bin文件,纯粹的U-BOOT二进制执行代码,不保存ELF格式和调试信息。这个文件一般用于烧录到用户开发板中;
u-boot.srec——Motorola S-Record格式,可以通过串行口下载到开发板中。
FLASHPGM不支持BIN格式的,可以烧写u-boot——ELF格式的文件,别看它没扩展名,一样烧写。
还有,如果你懒(和我一样),拿别人现成的BIN文件来烧,FLASHPGM还提供了一个BINTOS19的程序,就在它的安装目录下。具体用法运行它,它自己就告诉你了。

注意:有时(尤其是FLASH里已经有程序的时候)0XC000000会莫名奇妙的提示内存不可以写,有几个方法可以试试:把地址改成0x10000000(好象是缓存地址),之后点EREASE擦除芯片,擦除一般说来是不成功的,最后无论如何都下不去,没关系,这时候关闭擦除对话框,然后0x10000000地址不变,烧FLASH,我一般是烧写一个我自己写的LED测试小程序把内存占上:)。回来这时候再把0X1000000换成0XC000000再按照正常操作,一般可以正常。
这现象的原因就是过去下的程序(多数是不正确的程序)正在运行 占用了RAM与ROM,下个LED测试小程序就是把这几个部分清除掉。
如果以上方法还不正常,可以用另一个程序叫FLASHP就差2个字母:)很好!在这里对这个程序的作者致敬!!
用这个软件擦FLASH,然后再用FLASHPGM烧,原因是FLASHP擦厉害,但写好象有些问题~~

UBOOT 移植操作(1)
[0]目录结构
◆ board:和一些已有开发板有关的文件,比如Makefile和u-boot.lds等都和具体开发板的硬件和地址分配有关。
◆ common:与体系结构无关的文件,实现各种命令的C文件。
◆ cpu:CPU相关文件,其中的子目录都是以U-BOOT所支持的CPU为名,比如有子目录arm926ejs、mips、mpc8260和nios等,每个特定的子目录中都包括cpu.c和interrupt.c,start.S。其中cpu.c初始化CPU、设置指令Cache和数据Cache等;interrupt.c设置系统的各种中断和异常,比如快速中断、开关中断、时钟中断、软件中断、预取中止和未定义指令等;start.S是U-BOOT启动时执行的第一个文件,它主要是设置系统堆栈和工作方式,为进入C程序奠定基础。
◆ disk:disk驱动的分区处理代码。
◆ doc:文档。
◆ drivers:通用设备驱动程序,比如各种网卡、支持CFI的Flash、串口和USB总线等。
◆fs:支持文件系统的文件,U-BOOT现在支持cramfs、fat、fdos、jffs2和registerfs。
◆ include:头文件,还有对各种硬件平台支持的汇编文件,系统的配置文件和对文件系统支持的文件。
◆ net:与网络有关的代码,BOOTP协议、TFTP协议、RARP协议和NFS文件系统的实现。
◆ lib_arm:与ARM体系结构相关的代码。
◆ tools:创建S-Record格式文件 和U-BOOT images的工具。

==========================================================================================
[1]u-boot.1.1.2目录下有Makefile
1)设置编译器
可以看到这一项:
ifeq ($(ARCH),arm)
CROSS_COMPILE = arm-linux-

也就是说这里所用的交叉编译器是arm-linux-gcc,u-boot默认是用这个的,也有用arm-elf-gcc的,arm-elf-tools-20030314.sh,用它来编译,没有问题。如果最后MAKE的时候提示找不到arm-linux-gcc就是这错了,改一下。

arm-elf-gcc是用来编译uClinux内核的工具,arm-linux-gcc用来编译LINUX
2)加进自己板子的项目
搜索B2的这部分文件
B2_config : unconfig
@./mkconfig $(@:_config=) arm s3c44b0 B2 dave

后面加上这部分:
TT_config : unconfig
@./mkconfig $(@:_config=) arm s3c44b0 TT T2T
切记在@./mkconfig $(@:_config=) arm s3c44b0 TT T2T
前面的是Tab来的,TT_config : unconfig也是一样,不能用空格代替,因为它是靠这个来识别命令的

==========================================================================================

[2]在宿主机(PC机)上建立arm-elf-gcc交叉编译环境

1)建立arm-linux-gcc编译环境
在RedHat Linux系统下以root用户登录,
将cross-2.95.3.tar.bz2文件复制到/目录下,
安装:
# tar jxvf cross-2.95.3.tar.bz2
这个命令会在你的/usr/local/arm/2.95.3目录下安装 arm-linux-gcc 交叉编译程序,
然后在PATH变量中添加一项:/usr/local/arm/2.95.3/bin.
[root@localhost root]# export PATH=$PATH:/usr/local/arm/2.95.3/bin


把PATH=:$PATH:/usr/local/arm/2.95.3/bin添加到/ETC/bash_profile文件中

或者
在/etc/bashrc文件中添加一项:
export PATH=:$PATH:/usr/local/arm/2.95.3/bin
之后可以测试一下 echo $PATH

注意:PATH大小写不一样,另外LINUX下大小写是不同的,以后不特别声明。

注意:命令中的参数之间都由单个空格或者TAB隔开,命令前有的有# 代表命令行符,不用输入。

注意:不可在WINDOWS下用winRAR解压u-boot-1.1.2.tar.bz2或u-boot-1.1.2.tar.gz这种文件,会少文件,去LINUX下,另外解压的时候也不用非点用命令行操作,LINUX现在对GUI已经支持的非常好了,比如解压只要右键点文件,选解压到当前文件夹就可以,执行的时候只要双击再选“执行”

注意:我用的VMWARE(虚拟机)装的LINUX,要在LINUX和WIN中间传递文件用VM-》SETTING里的SHARE FOLDER
该功能是把WIN 下的一个文件夹共享给LINUX。
这个功能必须装VMWARE TOOLS才能用,
装VMWARE TOOLS方法:首先在VM-》SETTING里CDROM项里把光驱设置为装入VMWARE安装文件夹下的LINUX工具的.ISO,LUINUX下就出现CDROM了 拷贝 解压 安装不在话下。必须注意的是VMWARE TOOLS在每次重起LINUX之后还必须也重起一下,TMD,谁搞定不用重起告诉我一声
重起的方法:/etc/init.d/vmware-tools restart
就有消息出来了

注意:另外郁闷的是我的WIN与LINUX之间复制文字似乎也不顺畅,干脆在SHARE FOLDER里建立一个TXT,两个系统捣文字玩~~

测试:
把终端关闭,重新打开后执行如下命令:

# arm-linux-gcc –v

建立好交叉编译环境后可以试着编译u-boot了
2)也可以建立arm-elf-gcc
与上面类似,用周立功的编译包直接安装
会在/usr/local/bin下产生arm-elf-gcc只类的文件
然后设置路径
[root@localhost root]# export PATH=$PATH:/usr/local/arm-elf/bin
======================================================================================================
[3] 测试交叉编译器搞好没有
编译个44B0例子 在UBOOT包目录下执行一下命令,以下是编译的包自带的DAVE公司板子B2(名)
1) Make distclean (清除以前编译的痕迹)
2) Make B2_config(B2代表B2板子的,前面见到过)
3) Make
没问题就可以进行下面了
注意:B2默认用arm-linux-gcc编译,要是前面安的arm-elf-gcc的话此时会报错 把UBOOT目录下的MAKEFILE按照前面说的改一下
注意:一般说来还会有个问题,怀疑是编译器的问题 提示什么abi=apcs-gnu只类的找不到吧~~记不住了
改UBOOT目录下config.mk (好象)
文件里改成如下
PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,$(call cc-option,-mabi=apcs-gnu,))
原来的行少了$(call cc-option,-mabi=apcs-gnu,) 具体在哪行忘了 CTRL+F搜索一下
其他应该没问题,有问题GOOGLE搜一下,不是通病就是自己安装的问题了
注意:
MAKE之后会生成三个文件:
u-boot——ELF格式的文件,可以被大多数Debug程序识别;
u-boot.bin——二进制bin文件,纯粹的U-BOOT二进制执行代码,不保存ELF格式和调试信息。这个文件一般用于烧录到用户开发板中;
u-boot.srec——Motorola S-Record格式,可以通过串行口下载到开发板中。

[4]开始配置U BOOT
1)给自己板子个公司起个名,我的公司叫T2T 板子叫TT,刚才那个例子公司名DAVE板子名B2
以B2板子的程序做为模板来做,省很多工作
#cd u-boot-1.1.2//进U BOOT目录
#cd board //进BOARD目录,该目录下存放各种公司的开发板,但44B0的好象只有一种B2
#cp -R dave T2T (复制 并且改名)
#cd T2T
#mv B2 TT (复制 并且改名)
#cd TT
# mv B2.c TT.c
修改TT里面的Makefile, 把B2改成TT,编译时如果报的其它类似找不到B2的错误也是把相应的B2改成TT来处理。
修改T2T/TT/config.mk
  TEXT_BASE = 0x0c1000000
修改T2T/TT/Makefile
  将所有的B2改为TT
2)/include/configs
cp B2.h TT.h依旧是把B2的改个名
注意:DAVE的板子是用44B0的,但还有其他板子用吗?怎么确定只有它用?用以下命令

到board目录查了一下:
#cd u-boot
#cd board
#find . -exec grep -l 44B0 {} \;
结果是:
./dave/B2/B2.c
B2网站是: http://www.dave-tech.it

3)以下文件修改记录

----------------------------------------------------------------------------------------------------
-----------------------------------/include/configs/TT.h-------------------------------------------
----------------------------------------------------------------------------------------------------
#define CONFIG_INIT_CRITICAL 1 这个在cpu/s3c44b0/start.S里面用到,如果你的u-boot程序不是在sdram中调试而是固化到flash中运行的话,这个必不可少。

找到 #define CONFIG_B2 1 改成CONFIG_TT

找到 #define CONFIG_S3C44B0_CLOCK_SPEED 75 主频改成60

找到Size of malloc() pool这部分设置,改成这样。

#define CFG_MONITOR_LEN (256 * 1024) /* Reserve 256 kB for Monitor */

#define CFG_ENV_SIZE (64*1024) /* 1024 bytes may be used for env vars*/

#define CFG_MALLOC_LEN (CFG_ENV_SIZE + 128*1024 )

#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */

#define CFG_ENV_IS_IN_FLASH 1 这个必不可少,如果你想把你的参数保存到flash的话
#define CFG_ENV_ADDR (PHYS_FLASH_1+0x40000) 这个就是你的参数保存在flash里的起始地址了

#define CFG_ENV_OFFSET 0x40000 这个我后来看它源程序发现如果你上一步没有设置它的起始地址的话就会用它来作默认地址的了

#define CONFIG_AUTO_COMPLETE

其它地方没有深究哦,有些好像不要也行,你就试试吧。

找到Hardware drivers部分,这应该是网络芯片设置吧,参考一下这个吧(要看芯片的):

#define CONFIG_DRIVER_RTL8019 这个就要看你的板上用的是什么网卡了(这个是台湾出的,有10M)

#define RTL8019_BASE 0x06000300 这个是网卡相就寄存器的起始地址,有的挂在BANK4上了地址自然是0X08000300

以下部分我试过不要也行,你试下吧

#define RTL8019_BUS32 0

#define CONFIG_SMC_USE_16_BIT

#undef CONFIG_SHOW_ACTIVITY

#define CONFIG_NET_RETRY_COUNT 10 应该是重试的次数吧


#define CONFIG_SERIAL 1

#define CONFIG_BAUDRATE 115200 设置波特率

 


#define CONFIG_COMMANDS ( CONFIG_CMD_DFL | \

CFG_CMD_DATE | \

CFG_CMD_ELF | \

CFG_CMD_NET | \

CFG_CMD_EEPROM | \

CFG_CMD_I2C | \

CFG_CMD_FAT | \

CFG_CMD_JFFS2)

把CFG_CMD_EEPROM改成CFG_CMD_FLASH吧,虽然不改也是可以的,具体没考究。

 


以下是板上env参数设置,看一下吧,其实我觉得了解一下就行的了,只是一些初始设置值,以后可以用命令setenv saveenv来修改的。

#define CONFIG_BOOTDELAY 3 这个就是运行bootcmd之前的等待时间

#define CONFIG_BOOTARGS "devfs=mount root=ramfs console=ttyS0,115200" 引导uClinux的时候传递的参数,不会就先不用管它也行。

#define CONFIG_ETHADDR 00:50:c2:1e:af:fb 网卡的物理地址MAC

#define CONFIG_NETMASK 255.255.255.0 掩码地址,设置过ip的人都应该知道吧

#define CONFIG_IPADDR 192.168.0.30 这是你板上网卡8019的ip地址

#define CONFIG_SERVERIP 192.168.0.10 这是你宿主机的ip地址,以后用tftp下载的时候用到,一定要跟你的宿主机一致才行。

#define CONFIG_BOOTFILE "u-boot.bin" 这个就是你要下载文件的默认名字,注意的是不是UBOOT编译的文件 而是UBOOT下载以后在这个地址执行这个文件,比如这个文件在下LINUX后就常被改成UCLINUC.BIN了

#define CONFIG_BOOTCOMMAND "bootm 0x50000" 这是bootdelay后运行的命令

 


Miscellaneous configurable options部分,参考一下吧:

#define CFG_LONGHELP /* undef to save memory */

#define CFG_PROMPT "TENWAY=>" 这是进入命令模式下的提示符,改个帅一点的吧

#define CFG_CBSIZE 256 /* Console I/O Buffer Size */

#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */

#define CFG_MAXARGS 100 /* max number of command args */

#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */

 


#define CFG_MEMTEST_START 0x0C400000 /* memtest works on */

#define CFG_MEMTEST_END 0x0C800000 /* 4 ... 8 MB in DRAM */

#undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */

#define CFG_LOAD_ADDR 0x0c008000 默认的下载地址

#define CFG_HZ 1000 /* 1 kHz */

#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } 可供选择的波特率

 

 

 

Physical Memory Map部分,比较重要,修改你的sdram和flash的地址和容量。

#define CONFIG_NR_DRAM_BANKS 1 我们只占用了一个Bank用来映射sdram

#define PHYS_SDRAM_1 0x0c000000 sdram的起始地址

#define PHYS_SDRAM_1_SIZE 0x00800000 sdram的容量(8M)

#define PHYS_FLASH_1 0x00000000 flash的起始地址

#define PHYS_FLASH_SIZE 0x00200000 flash的容量(2M)

#define CFG_FLASH_BASE PHYS_FLASH_1 定义多个名字而已,其它地方会用到

注意:
存储容量的计算方法
2M=0x00200000-----------------16进制转换成10进制(用WINDOWS自带的计算机就行)-------------------》2097152
2097152=1024*1024*2

FLASH organization部分,看注释应该知道了吧,参考一下:
/*-----------------------------------------------------------------------
* FLASH organization
*/
#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */
#define CFG_MAX_FLASH_SECT 256 /* 最大支持的SECTOR数量,另外SAM FEI的补丁这里设置了32个 是错误的*/
//#define CFG_MAIN_SECT_SIZE 0x10000 /* main size of sectors on one chip */

#define CFG_FLASH_ERASE_TOUT 4120000 /* Timeout for Flash Erase (in ms) 在前面加个4让它长点 */
#define CFG_FLASH_WRITE_TOUT 1000 /* Timeout for Flash Write (in ms) */
其他地方还没动 以后动的再补上

UBOOT 移植操作(3)

----------------------------------------------------------------------------------------------------
-----------------------------------board/myboard/common/flash.c-----------------------------------
----------------------------------------------------------------------------------------------------
找到这个函数:write_buff

里面有这句话,一共有6处吧?全改了:#ifdef CONFIG_B2

把CONFIG_B2改成上面TT.H文件里面起的名,我的叫CONFIG_TT

关于FLASH的一点疑问:
一直怀疑29LV160和39LV160在U BOOT下是否兼容的问题
看了这段程序后似乎U BOOT是可以自动检测的

----------------------------------------------------------------------------------------------------
-----------------------------------board/T2T/TT/memsetup.S-----------------------------------
-----------------------------------也叫board/T2T/TT/lowlevel_init.S-----------------------------------
----------------------------------------------------------------------------------------------------
按照如下改

* Bank 0 parameter */
.equ B0_Tacs, 0x3 /* 0clk */
.equ B0_Tcos, 0x3 /* 0clk */
.equ B0_Tacc, 0x7 /* 14clk */
.equ B0_Tcoh, 0x3 /* 0clk */
.equ B0_Tah, 0x3 /* 0clk */
.equ B0_Tacp, 0x1 /* 0clk */
.equ B0_PMC, 0x0 /* normal(1data) */
/* Bank 1 parameter */
.equ B1_Tacs, 0x0 /* 4clk */
.equ B1_Tcos, 0x1 /* 4clk */
.equ B1_Tacc, 0x2 /* 14clkv */
.equ B1_Tcoh, 0x1 /* 4clk */
.equ B1_Tah, 0x0 /* 4clk */
.equ B1_Tacp, 0x0 /* 6clk */
.equ B1_PMC, 0x0 /* normal(1data) */

/* Bank 2 parameter - */
.equ B2_Tacs, 0x0 /* 4clk */
.equ B2_Tcos, 0x2 /* 4clk */
.equ B2_Tacc, 0x4 /* 14clk */
.equ B2_Tcoh, 0x2 /* 4clk */
.equ B2_Tah, 0x3 /* 4clk */
.equ B2_Tacp, 0x3 /* 6clk */
.equ B2_PMC, 0x0 /* normal(1data) */

/* Bank 3 parameter */
.equ B3_Tacs, 0x3 /* 4clk */
.equ B3_Tcos, 0x3 /* 4clk */
.equ B3_Tacc, 0x7 /* 14clk */
.equ B3_Tcoh, 0x3 /* 4clk */
.equ B3_Tah, 0x3 /* 4clk */
.equ B3_Tacp, 0x3 /* 6clk */
.equ B3_PMC, 0x0 /* normal(1data) */

/* Bank 4 parameter */
.equ B4_Tacs, 0x3 /* 4clk */
.equ B4_Tcos, 0x3 /* 4clk */
.equ B4_Tacc, 0x7 /* 14clk */
.equ B4_Tcoh, 0x3 /* 4clk */
.equ B4_Tah, 0x3 /* 4clk */
.equ B4_Tacp, 0x3 /* 6clk */
.equ B4_PMC, 0x0 /* normal(1data) */

/* Bank 5 parameter */
.equ B5_Tacs, 0x0 /* 4clk */
.equ B5_Tcos, 0x1 /* 4clk */
.equ B5_Tacc, 0x4 /* 14clk */
.equ B5_Tcoh, 0x1 /* 4clk */
.equ B5_Tah, 0x0 /* 4clk */
.equ B5_Tacp, 0x0 /* 6clk */
.equ B5_PMC, 0x0 /* normal(1data) */

/* Bank 6(if SROM) parameter */
.equ B6_Tacs, 0x3 /* 4clk */
.equ B6_Tcos, 0x3 /* 4clk */
.equ B6_Tacc, 0x7 /* 14clk */
.equ B6_Tcoh, 0x3 /* 4clk */
.equ B6_Tah, 0x3 /* 4clk */
.equ B6_Tacp, 0x3 /* 6clk */
.equ B6_PMC, 0x0 /* normal(1data) */

/* Bank 7(if SROM) parameter */
.equ B7_Tacs, 0x3 /* 4clk */
.equ B7_Tcos, 0x3 /* 4clk */
.equ B7_Tacc, 0x7 /* 14clk */
.equ B7_Tcoh, 0x3 /* 4clk */
.equ B7_Tah, 0x3 /* 4clk */
.equ B7_Tacp, 0x3 /* 6clk */
.equ B7_PMC, 0x0 /* normal(1data) */

/* Bank 6 parameter */
.equ B6_MT, 0x3 /* SDRAM */
.equ B6_Trcd, 0x1 /* 2clk */
.equ B6_SCAN, 0x0 /* 8bit */

.equ B7_MT, 0x3 /* SDRAM */
.equ B7_Trcd, 0x1 /* 2clk */
.equ B7_SCAN, 0x0 /* 8bit */


/* REFRESH parameter */
.equ REFEN, 0x1 /* Refresh enable */
.equ TREFMD, 0x0 /* CBR(CAS before RAS)/Auto *** */
.equ Trp, 0x0 /* 2clk */
.equ Trc, 0x3 /* 0x1=5clk 0x3=11clk*/
.equ Tchr, 0x0 /* 0x2=3clk 0x0=0clks */
.equ REFCNT, 1550

MEMORY_CONFIG:
.long 0x01000102 /* Bank0 = OM[1:0] , Bank1-2 4-7 16bit, ,BANK3 8BIT,Bank2=Nowait,UB/LB*/
.word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC)) /*GCS0*/
.word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC)) /*GCS1*/
.word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC)) /*GCS2*/
.word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC)) /*GCS3*/
.word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC)) /*GCS4*/
.word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC)) /*GCS5*/
.word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN)) /*GCS6*/
.word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN)) /*GCS7*/
.word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT) /*REFRESH RFEN=1, TREFMD=0, trp=3clk, trc=5clk, tchr=3clk,count=1019*/
.word 0x10 /*SCLK power down mode, BANKSIZE 16M/16M*/
.word 0x20 /*MRSR6 CL=2clk*/
.word 0x20 /*MRSR7*/
主要是设置MEMORY_CONFIG里的内容 值得注意的是.long 0x01000102 /* Bank0 = OM[1:0] , Bank1-2 4-7 16bit, ,BANK3 8BIT,Bank2=Nowait,UB/LB*/中设置了各个BANK的位宽,要注意。因为8019有8位的,有16位的,配置错了网络不通
其实就是一些字
有人从地址读出来后是下面这样也可以

MEMORY_CONFIG:
.long 0x11010102
.long 0x600
.long 0x7ffc
.long 0x7ffc
.long 0x7ffc
.long 0x7ffc
.long 0x2610
.long 0x18000
.long 0x18000
.long 0x960459
.long 0x10
.long 0x20
.long 0x20
由于对armsys硬件不是太了解,没有办法,只得看armsys bootloader程序,但每个版本又有差别.因此是用AXD调试看bootlaoder启动后0x1c80000中的值定的.

注意:这个注意是后补上的,因为自己和朋友在做的时候发现网上对这部分分析的人特别少,可能因为理论比较简单,操作起来又比较麻烦吧。
听听菜鸟的方法吧。

首先U BOOT1.1.1和1.1.4版本有个小差别,就是文件名的差别1.1.1叫memsetup.S,1.1.4叫lowlevel_init.S如果把别人用1.1.1编译的直接拿过来也可以,但一定记得在改文件名的同时还一定要在文件里改函数名!就是这个文件最后那部分汇编上面的函数名。不然后来会提示START.S里找不到lowlevel_init。切记

另外,比较重要的这部分究竟代表什么,怎么改。
这个文件实际分3部分,这3个部分实际又是把44B0初始化那几个汇编文件重新组合了,就是ADS在RAM里调试文档里说的,把44B0当单片机用时C语言前面的那写汇编文件,一般说来包括44binit.s MEMCFG.S 44BLIB_A.S Option.s。其中44binit.s MEMCFG.S就包含了内存初始化的参数,按照这两个文件改吧。

再说这3部分
开始是内存设置,在数据手册(英文)4-14页,各个意思就不多说了。说说怎么改,当然得根据你的内存具体改(一句废话)但是有简单的方法,前面提到了,看MEMCFG.S这个文件。

然后是一些移位只类的操作,把各个BANK设置好,其实就是设置一些预定义的字,然后在其他的地方利用这些字设置寄存器。就把这些理解为宏或者就当是个结构体吧(不准确,就帮助理解)。为什么这么设置看看数据手册(英文)4-13页
这部分在怎么改的快?找,哪找?44binit.s里面有,一模一样,不罗嗦了。

最后那部分是这个文件唯一执行的部分
基本不需要改吧(除了有的时候函数名:))
看见0X01C80000还不明白吗?看数据手册(英文)4-3页去吧,有汇编的例子,至于这个32位寄存器为什么这么设置。

别看我这装的明白,就是会对付,别跟我较真,我还也在研究中:)

注意:顺便在这里说说个小问题,有朋友问“为什么原理图上地址线从A1开始,而不是A0”看数据手册(英文)4-4页,因为是16位地~~~
注意:我的8019是连在BANK3上的 而且是8BIT的 所以MEMORY_CONFIG下面第一项里要做设置 要不不好使

----------------------------------------------------------------------------------------------------
-----------------------------------board/T2T/TT/config.mk-----------------------------------
----------------------------------------------------------------------------------------------------
修改最后的TEXT_BASE为把UBOOT加载到RAM的地址,这里添0XC700000,当然添0XC300000也可以 但是如果添0XC300000之前的似乎在下载LINUX的时候会死机,因为地址空间不够


-----------------------------------------------------------------
-----------------------------------cpu/s3c44b0/start.S------
-------------------------------------------------------------------

找到
#if CONFIG_S3C44B0_CLOCK_SPEED==60

ldr r0, =0x70081 /* 60MHz (Quartz=10MHz) 具体怎么算的 可以看我写的计算方法说明*/
#elif CONFIG_S3C44B0_CLOCK_SPEED==75
ldr r0, =0xac042 /* 75MHz */
#else
# error CONFIG_S3C44B0_CLOCK_SPEED undefined
设置一下主频

------------------------------------------------------------------------------
--------------cpu/s3c44b0/serial.c-----------------------------------
--------------------------------------------------------------------------------
找到以下几项
主要是把频率改一下并把分拼设置对
void serial_setbrg (void)
{
DECLARE_GLOBAL_DATA_PTR;

u32 divisor = 0;

/* get correct divisor */
switch(gd->baudrate) {




case 1200:
#if CONFIG_S3C44B0_CLOCK_SPEED==60
divisor = 3124;
#elif CONFIG_S3C44B0_CLOCK_SPEED==75
divisor = 3905;
#else
# error CONFIG_S3C44B0_CLOCK_SPEED undefined
#endif
break;

case 9600:
#if CONFIG_S3C44B0_CLOCK_SPEED==60
divisor = 390;
#elif CONFIG_S3C44B0_CLOCK_SPEED==75
divisor = 487;
#else
# error CONFIG_S3C44B0_CLOCK_SPEED undefined
#endif
break;

case 19200:
#if CONFIG_S3C44B0_CLOCK_SPEED==60
divisor = 194;
#elif CONFIG_S3C44B0_CLOCK_SPEED==75
divisor = 243;
#else
# error CONFIG_S3C44B0_CLOCK_SPEED undefined
#endif
break;

case 38400:
#if CONFIG_S3C44B0_CLOCK_SPEED==60
divisor = 97;
#elif CONFIG_S3C44B0_CLOCK_SPEED==75
divisor = 121;
#else
# error CONFIG_S3C44B0_CLOCK_SPEED undefined
#endif break;

case 57600:
#if CONFIG_S3C44B0_CLOCK_SPEED==60
divisor = 64;
#elif CONFIG_S3C44B0_CLOCK_SPEED==75
divisor = 80;
#else
# error CONFIG_S3C44B0_CLOCK_SPEED undefined
#endif break;

case 115200:
#if CONFIG_S3C44B0_CLOCK_SPEED==60
divisor = 32;/*具体算法和上面主频算法在一个文档里*/
#elif CONFIG_S3C44B0_CLOCK_SPEED==75
divisor = 40;
#else
# error CONFIG_S3C44B0_CLOCK_SPEED undefined
#endif
--------------------------------------------------------------------------
---------board/T2T/TT/TT.C-------------------------------
------------------------------------------------------------
这个没什么好说的,如果你用的是网上流行的原理图,改动基本没有,我的因为加了些东西,所以这个文件改动很多。
但文件里主要就是对44B0各个管脚设置,哪个是IO哪个是TXD、RXD。不多说了,自己看数据手册8-6页,有点耐心。

---------------------------------------------------------------------
------------lib_arm/board.c-----------------------------------
---------------------------------------------------------
好象网卡需要加个INCLUDE
//待补充
这个文件不用修改,在网上找的讲解,顺便提一下

进行各种初始化设置,主要有:
cpu_init CPU相关的设置, 具体在./cpu/s3c44b0/cpu.c中.
board_init 板子相关的设置, 具体在board/wx/wx20/wx20.c 中
interrupt_init中断设置,我们没有用,具体在./cpu/s3c44b0/interrupts.c中
env_init 初始化环境变量, 具体要看用什么介质来存储环境变量,如果用flash来存贮, 程序在common/env_flash.c中.
init_baudrate 设置baud参数
serial_init 串口初始化, 具体在cpu/s3c44b0/serial.c.
console_init_f 控制台设置, 具体在./common/console.c

display_banner 显示标题.[这里可以鼓捣一下,让它输出些个性的东西:)]
dram_init 可用内存配置, 具体在./board/wx/wx20/wx20.c.
flash_init flash初始化,具体./drivers/cfi_flash.c.

接下来就是环境变量初始化, 网络初始化,最后到main_loop,可以运行各种命令.
====================================
[5]烧写FLASH
这部分可能过于简单,很少有人写,但是对于不了解ARM开发过程的人真的简单吗?我是菜鸟,在这卡了3天:)
一般说来有几种方法,
1)板子原来的BOOTLOADER程序或者为烧写而编写的专用ADS程序
比较高级而快速的方法,很多现成的开发板都用这种方法(相对来说有实力的公司),此状态下CPU是运行的,所以速度快。
比如ZLG的,但是对于初学或者不准备细研究硬件的人来说就比较麻烦,因为要编写(改写)ADS烧写程序。愿意的人可以看看。
2)FLUTED
和FLASHPGM一样,使用的好象叫边界扫描法,CPU此时并不运行,因此烧写的比较慢。
在这里也不推荐FLUTED这个软件,原因比较简单,麻烦+速度慢。
因为需要编写(改写)两个配置文件,而且是字符界面。倒是有人说这个软件只能在WIN98下用的说法好象不对(现在有可以让2000和XP下用的方法)
喜欢的朋友可以用用
3)FLASHPGM(推荐)
很简单的程序,GUI界面,速度尚好。
设置很简单,在CPU里选对型号,当然是3星的44B0。在FLASH里也一样,39LV160,29LV160都有。
确定好地址,RAM地址我的是0XC000000(BANK7上) FLASH地址0X0(BANK0上)
选完了以后读一下FLASH的ID(左下脚的按钮吧)能读出厂家的ID就行。
然后是烧写了,PROGRAME按钮,注意的是FLASHPGM不支持BIN格式,按照下面方法处理。
再有就是尽量在写之前擦一下,PROGRAME菜单里有个选项,打个钩就OK。
具体烧写方法可以看我总结的另一篇文档,在这里只说说UBOOT相关的。
前面说过UBOOT编译以后产生3个文件
u-boot——ELF格式的文件,可以被大多数Debug程序识别;
u-boot.bin——二进制bin文件,纯粹的U-BOOT二进制执行代码,不保存ELF格式和调试信息。这个文件一般用于烧录到用户开发板中;
u-boot.srec——Motorola S-Record格式,可以通过串行口下载到开发板中。
FLASHPGM不支持BIN格式的,可以烧写u-boot——ELF格式的文件,别看它没扩展名,一样烧写。
还有,如果你懒(和我一样),拿别人现成的BIN文件来烧,FLASHPGM还提供了一个BINTOS19的程序,就在它的安装目录下。具体用法运行它,它自己就告诉你了。

注意:有时(尤其是FLASH里已经有程序的时候)0XC000000会莫名奇妙的提示内存不可以写,有几个方法可以试试:把地址改成0x10000000(好象是缓存地址),之后点EREASE擦除芯片,擦除一般说来是不成功的,最后无论如何都下不去,没关系,这时候关闭擦除对话框,然后0x10000000地址不变,烧FLASH,我一般是烧写一个我自己写的LED测试小程序把内存占上:)。回来这时候再把0X1000000换成0XC000000再按照正常操作,一般可以正常。
这现象的原因就是过去下的程序(多数是不正确的程序)正在运行 占用了RAM与ROM,下个LED测试小程序就是把这几个部分清除掉。
如果以上方法还不正常,可以用另一个程序叫FLASHP就差2个字母:)很好!在这里对这个程序的作者致敬!!
用这个软件擦FLASH,然后再用FLASHPGM烧,原因是FLASHP擦厉害,但写好象有些问题~~

细小的问题--patch命令的使用
有的时候大家收到的别人移植好的UBOOT了UCLINUC了是以patch包发布的

这里转个写的比较好的patch命令的使用方法

文件:isp1161-2.6.12.patch(在/root下)

--- linux-2.6.12/drivers/usb/Makefile 2005-06-17 22:48:29.000000000 +0300
+++ linux-2.6.12-new/drivers/usb/Makefile 2005-07-27 08:11:47.908336540 +0300

......
......

由于patch文件的首行已经指明了路径,所以根据当前所在的目录,加不同的参数使用patch命令:

1:如果当前的目录是和linux-2.6.12的同级目录:

[root@kcn-110mw]#patch -p0
2:如果当前的目录为 linux-2.6.12/:

[root@kcn-110mw]#patch -p1
3:如果当前的目录为 linux-2.6.12/drivers/:

[root@kcn-110mw]#patch -p2
0,1,2,是指略去的patch文件中的前几级目录

细小的问题---VMWARE安装与使用
mamajinco 发表于 2006-9-6 9:49:00
首先 推荐大家在开发的过程中使用VMWARE虚拟机 安装LINUX
原因比较简单 开发过程中会频繁的在两个系统之间交换 对于没有两个计算机的朋友来说 过于麻烦
对的不说了 说说开发里遇到问题
==================================
一 安装VMWARE虚拟机与LINUX
1 分出个10G左右的地方
我是分个10G的FAT32格式分区来单独做LINUX的区域,推荐分出来的空间大于9G,因为对于新手来说LIXUN要尽量全部安装。
分区尽量是FAT32格式(WINDOWS用的)NTFS听有的朋友说过好象有问题。
推荐计算机内存大于256M,我用的是512M,开VMWARE再开ACROBAT时就会明显慢。
安装后的VMWARE虚拟机基本是3种文件,VMWARE程序文件我安在C盘下了,VMWARE的配置文件(安装后再添加的,比较小)和VMWARE虚拟出的硬盘文件(选10G,该文件就是10G),所以我单独分出个驱存他们。
虚拟机里安装后的操作系统(一般都是LINUX吧,顺便说一下,你也可以按WIN了苹果了操作系统)
2 安装VMWARE虚拟机
VMWARE虚拟机对于WINDOWS来说就是个软件,用这个软件虚拟出个计算机来。对于VMWARE虚拟机里面安装的系统来说自己就独占了一台计算机。
安装没有什么特殊的,我用的是VER5.5,选标准安装,基本一律下一步就搞定。
值得注意的是中间有问你分出来多大硬盘空间,默认是8G ,改成10G吧。
之后是建立VMWARE虚拟机配置文件,根据自己的要求建立,基本不用改什么,就是整错了也可以在后来的SETTING里改。
不多说了。
3 安装LINUX
把LINUX安装盘放光驱里吧,启动虚拟机,自己就检测启动了。
多说一句,到这大家都明白了吧?启动虚拟机就相当于启动一个计算机,光盘自动启动也跟物理上的计算机完全一样。
值得注意的是:如果电脑里安了虚拟光驱可能影响光盘自动启动,如果有问题就把虚拟光驱卸了吧。
安装的时候同样没什么问题,手动分驱,按照内存大小的2倍分出来个SWAP分驱,其余的我分成一个驱,强制为主分驱,挂载点选“/”根目录,分驱格式选EXT3……
多说一句,在分驱里就能看出来了吧?LINUX完全独占了这10G的地方,看不到WINDOWS
二 安装VMWARE-tools

VMWARE-tools还是安装比较好,最起码WIN和LINUX交换文件就方便了
引用别人的文章 加上自己的注释吧
1、以ROOT身份进入LINUX

2、按下 CTRL+ALT组合键,进入主操作系统,点击VMWARE状态栏安装提示,或者点击 SETTING菜单下的ENABLE VMWARE TOOLS子菜单。

3、确认安装VMWARE TOOLS。
这时我们并没有真正的安装上了VMWARE TOOLS软件包,如果您点击菜单:DEVICES,您就会发现光驱的菜单文字变为:ide1:0-> Crogram FilesVMwareVMware WorkstationProgramslinux.iso,这表示VMWARE将LINUX的ISO映象文件作为了虚拟机的光盘

注释:有的时候不能自动挂载,自己要在菜单里光驱项目里选挂载VMWARE安装目录(不是配置文件存储目录,我的在C盘里)里某个目录的linux.iso

4、鼠标点击LINUX界面,进入LINUX。

5、运行如下命令,注意大小写。

mount -t iso9660 /dev/cdrom /mnt

加载CDROM设备,这时如果进入 /mnt 目录下,你将会发现多了一个文件:vmware-linux-tools.tar.gz。这就是WMWARE TOOLS的LINUX软件包,也就是我们刚才使用WINISO打开LINUX.ISO文件所看到的。

注释:在新版本里可以不用命令挂载和卸载了,打开 LINUX.ISO后LINUX桌面会自动弹出光驱标志,双击打开。

cp /mnt/vmware-linux-tools.tar.gz /tmp

将该软件包拷贝到LINUX的 TMP目录下。

umount /dev/cdrom

卸载CDROM。

cd /tmp

进入TMP目录

tar zxf vmware-linux-tools.tar.gz

解压缩该软件包,默认解压到vmware-linux-tools目录下(与文件名同名)。

cd vmware-linux-tools

进入解压后的目录

./install.pl

运行安装命令。

这时install提示你是否需要备份以前的配置文件,建议选择"y"。

等待INSTALL运行完成后,这时键入 START 命令,是不是可以看到漂亮的LINUX图形界面了?

三 使用VMWARE TOOLS
必须注意的是VMWARE TOOLS在每次重起LINUX之后还必须也重起一下,TMD,谁搞定不用重起告诉我一声
重起的方法:/etc/init.d/vmware-tools restart
就有消息出来了

四 文件共享
我用的VMWARE虚拟机装的LINUX,要在LINUX和WIN中间传递文件用VM-》SETTING里的SHARE FOLDER
该功能是把WIN 下的一个文件夹共享给LINUX。
这个功能必须装VMWARE TOOLS才能用。
共享以后在LINUX的MNT目录下就出一个F什么打头的文件夹,进去就是你共享的文件夹名了

细小的问题---arm-linux-gcc与arm-elf-gcc的区别
总看见有人问

arm-linux-gcc为有MMU的LINUX准备的比如2410上的LINUX

arm-elf-gcc为没有MMU的UCLINUX准备的比如44B0上的UCLINUX

就这么简单

闲聊ARM的入门(1)
我的笔记刚公布就有很多朋友来找我,把我当高手,问我“ARM怎么入门”。我不是高手,仍然是菜鸟。

但是回想起自己当时的迷茫,特意写了这篇东西,当作给和我一样的兄弟姐妹的帮助吧。问这个问题的人多半不是已经工作的工程师,而是和我一样是学生,所以这篇笔记就把看家当成我一样的菜鸟,高手勿怪。

首先声明:本人还没有找工作,事实上处于研究生刚毕业,还没开始找工作的空闲时间,44B0只是兴趣所在,打发时间。
所有看法完全是自己的感受,不代表任何他人。错了的观点各位帮我纠正。

再次补充:很多朋友看了上面的话就问我为什么研究生毕业了还不找工作:)说是打发时间,其实是因为研究生的时候带了一个项目,申请提前毕业以后项目还有块尾巴,答应导师把项目做完再走:)就这么简单。男人总点负点责,呵呵

以下问题常被问到,我就想到哪说到哪吧。

一 首先说说ARM的发展
可以用一片大好来形容,翻开各个公司的网站,招聘里面嵌入式占据了大半工程师职位。
广义的嵌入式无非几种:传统的什么51、AVR、PIC称做嵌入式微控制器;ARM是嵌入式微处理器;DSP;FPGA。
客观的讲,工作需求量上DSP的需求比ARM要多,而ARM和FPGA差不多。
DSP因为数字处理与通信领域的空前发展而火暴,小到MP3 射象头,大到我们军品里的控制器,应用面很广。
FPGA的兄弟一般做ANSIC(特殊芯片设计,好象是这么翻译的)。
而ARM单纯说来并不比一个单片机强多少,但是它的独特就在于不断下降的价格和提升的性能。这完全依靠于ARM公司的战略,厉害!!很佩服他们的战略眼光!!
值得注意的是:在找工作中,企业(著名的,小的不算)对单纯的ARM硬件开发工程师并不比单片机重视,很少有大企业的职位里写“从事过ARM开发优先”。
写的多的是什么?“嵌入式LINUX”
到这相信大家看出来了吧,需要的是硬件中的软件。

二 ARM是硬件还是软件
很难说,ARM是硬件,LINUX是软件。
ARM的硬件多半已经模块化了,像我这样把板子改成这样的就算动的多的了,这同样是ARM公司的战略,再次佩服。
实际中的LINUX的开发工作更多,更耗时。从这方面说ARM应该算是软件了。
在找工作中更是这样,举个例子,联想里和ARM最接近的是“BIOS工程师”是软件,MOTO里接近的是嵌入式LINUX工程师是软件。而其他很多公司把嵌入式产品开发归为硬件。
所以,不要讨论这个,好好玩转自己的板子才是关键。实在不爽你就把自己叫“嵌入式开发工程师”

三 要不要买开发板 买哪家
我的答案是“在你个人的学习方法”,但是如果看家是需要看这骗笔记的水平,个人推荐还是买现成的。
1 买
买板子可以把注意力集中在软件开发上,软件开发(尤其是驱动)可以不必担心自己硬件上的问题,我就是以便调试一边写驱动和程序,每次写驱动前就要先确认硬件没问题。
另外,买板子更省钱和时间,我自己做的板子,原理图PCB花了2周以上!制版又15天,回来以后焊接44B0 160个脚!那叫一个麻烦~~花了多少钱呢?2层板,制版费就300块!当然 我把接口都外引了,还做了个20X18的LCD背板,板子比较大。
总体下来 元件+LCD屏+PCB=11XX块!够2410的了。
再有就是买的资料相对来说比较全,但是不要指望有技术支持!都是骗人的,卖你之后就不会理你。

2 做
自己做可以更了解底层硬件,可以按照自己的要求加东西,比如我就加了GPS模块、 GPRS模块 、SD卡模块,扩了个IIC的35个键子的键盘、把LCD接口按照买的LCD改装了,可以用FPC线直接连接。做的很爽的。玩一把吗。

当然,你可以有策略的做,比如像我一样,把RAM和ROM,网络都保持和某现成的板子一样,这样他们的资料你就可以拿过来直接用,给自己留个退路。其他的如SD了 什么的自己做。都达到了~~就是费钱,费时间。
再有就是给做的朋友几点建议:尽量拿到现成的板子,尽量多搜集其他板子的全套资料,一定要拿到一张没问题的原理图。
网上流传的原理图多数是龚俊03年画的,再这里对龚俊表达一下我的敬意!!牛人!
但是那个图有个小BUG,我指的是03版的,后来的没这问题了。8019那地址线和地址有问题。还有人仿照他的PDF图画的SCH,更是漏洞百出!谴责!顺便谴责把龚俊板子偷卖的人。

3 买哪家
个人感觉分3类吧
1)首先是ZLG的,资料非常的全,感觉他是真正想教你怎么开发ARM,而不是像有的公司自己技术都没做好就做个板子出来卖钱。但是最大的不利就是价格太贵!而且主要是PHILIP的,货源比较麻烦~~可能有人说21XX系列的不贵啊,那是总线不外扩的,只能跑UCOS,不能跑UCLINUX。但是说是话,21XX系列才是ARM7的价格性能结合点。ARM7最适合做工业控制,ARM普及,销量都是怎么来的?都是ARM7来的,而44B0是典型的商业片子。但是,这里如果你看中的是为工作做准备,还是选能跑UCLINUX的吧。
但是仍然作为第一个推荐,因为菜鸟时期,合适的资料太重要了!!在这里被ZLG的务实精神感动!你看人家那代码写的。
2)感觉立宇泰的44B0不错
硬件没别的,就是资料比较全的说,不像有些家,原理图直接拿人家的,还错的~~
3)找个最便宜的
好象最便宜的有卖350的吧?也是没别的,就是即省了钱 还省时间搜集资料,至于资料全不全,别计较了~~硬件肯定好使就行吧。

四 要不要有51 AVR等单片机基础
有更好,但没有也无所谓。
两个月以前,我只是看别人做,耳濡目染~~,本科学过单片机,从来没做过。我们这的技术主干做AVR和51,我就跟他们调过C语言程序。你看出来了?我是个不折不扣的菜鸟吧?
但是做这个之前我特意找了ZLG的两本书,看了里面的例子和原理图,这很重要。例程里有汇编有C,都看懂了就OK,不用自己现写

五 开发都需要学习哪些软件
总结起来最主要的有以下几个吧
1 ADS调试用
确切的说是ADS+AXD。ADS里包含AXD。原来都用SDT后来ARM公司停止对SDT支持了,改支持ADS了,还是用ADS吧。
有的人的程序发布的仍然是SDT版本的,但基本都可以找到相应ADS的,新人在这里不要发蒙。ADS是编译器,AXD是调试器。便宜成AXF以后再在ARM的RAM里调试。

2 PLASHPGM
FLASH烧写的软件。AXD在RAM里调试,掉电就没有了,方便程序修改。调试好的程序再下到FLASH里,上电直接运行。
同类的软件还有很多,什么FLUTED了、FLSHP了都是,但FLASHPGM最好,要是有人还问FLASH不支持BIN格式文件的问题就要看我写的PLASHPGM使用了。

3 BANYANT调试代理(不知道名对不,起这么个难记的,我一般都叫它“半羊”因为知道它那几天刚吃了烤羊)
调试代理就是用它帮你使用更简单的JTAG(便宜啊)来实现原本1K才卖的JTAG仿真器的大部分功能。JTAG调试原理看我另一篇笔记。简单的就可以把他理解为你自己做的JTAG的驱动就行了。
调试代理还有很多种,什么H-JTAG了、ARM7了(不知道具体叫什么,就记得可执行文件叫ARM7.EXE)都是,BANYANT比较好。

需要注意的是,没种调试代理安装方法虽然都简单 但都不一样,需要看说明。而且AXD调试之前都要运行。省钱了,就别怕麻烦了。

4 ARM-ELF-TOOLS工具链
里面是UCLINUX开发用的工具比如ARM-ELF-GCC只类的。工具链就是把很多工具打包在一起发布的方便你开发的东西。具体安装方法看我另一篇笔记。
另外如果你开发LINUX就要用ARM-LINUX-TOOLS,不一样,不通用。

5 U-BOOT
大名鼎鼎的BOOTLOADER生成工具,同类的好象还有VIVI(名字很暧昧~~)
生成的BOOTLOADER烧到FLASH里,然后就可以用BOOTLOADER下载 烧写其他了
有了BOOTLOADER才能下UCLINUX。BOOTLOADER就像电脑上的BIOS。当然UCOS的不用这个,用什么我不知道:)
最新版本是1.1.4 具体使用方法看我另一篇笔记吧。

6 UCLINUX包
UCLINUX的源码包,不用多说了吧?建议大家用现成的先体会一下,然后再自己编译,裁剪。因为单独UCLINUX的编辑技术上比较简单,但涉及的方面还是比较广的。

7 VMWARE
老牌的虚拟机软件,在一个机器上虚拟出一个机器装LINUX(PC上用的),省得你来回开关机了。记得装VMWARE-TOOLS,安装方法在我另一篇笔记里。

六 有哪些书推荐
主要推荐ZLG的三本书,有这3本再加网络就不用别的书了,其中主要推荐前2本,3是介绍体系结构的,也不错
1 ARM嵌入式LINUX系统构建与驱动开发,北航版
驱动写的很详细,前期开发介绍也很好
2 ARM 嵌入式系统实验教程(二),北航版
有ZLG2200的原理图,实验程序和注释,了解人家是怎么开发的。
3 ARM嵌入式系统基础教程
最重要的是体系结构,汇编部分介绍,看看吧,增加理论素质。
4 44B0数据手册
写在这里是强调它的重要。

不推荐ZLG早期出的红色皮的ARM什么体系结构~只类的
写的太多,看烦了。

其他的书没了几本,没看见好的,大家有看过的推荐吧。

闲聊ARM的入门(2)
mamajinco 发表于 2006-9-7 9:34:00
七 选UCOS?UCLINUX?LINUX?VXWORKS?还是当单片机用
1 搞开发,工程设计,用UCOS,小巧,多进程,简单,体现了ARM7的精髓。

2 LINUX 正根的嵌入式系统,LINUX消费与通信领域用的比较多,但缺点是必须ARM9才能跑,ARM9的板子自己做就不行了,6层板太贵。买开发板1K达底吧。但是还是推荐选ARM9+LINUX

3 UCLINUX 算投机嵌入式系统:)ARM7上可以跑,由有LINUX近亲,学好好可以比较方便的转向LINUX,像我一样的穷鬼用吧,呵呵

4 VXWORKS
学好后可以找到高薪工作,但工作机会本身并不比LINUX好找。

5 当单片机用
不推荐,虽然我景仰的ZLG一直号召这么干。因为对于学习来说多进程的系统设计才是ARM7的玩头,至少你也要整个UCOS啊:)
有朋友问我先学这个当基础不行吗?那当然可以~~但我当时就用了1周搞定,就是我先的ADS在RAM中调试的笔记。后来我清空FLASH用的小段程序还是当时写的LED闪烁程序呢。另外1周里其中还因为自己过于菜,没把OM设置好导致晶阵不阵
哈哈。这个是必须做的,但一带而过。目标放的远一点。

八 学习要用多长时间
我从菜鸟到现在两个多月,中间被打扰数次。仍然搞定了PCB设计与制版,RAM调试,FLASH下载,UBOOT移植和下载UCLINUX(没剪裁,用现成的),LCD驱动。
再次坦诚的说:我确实比较菜,说这些不是让大家羡慕,只是告诉你们“你们应该比这个更好”
我相信良好的态度+合适的方法+及时的总结=成绩

九 ARM都玩什么
就几点
1 硬件设计
2 系统移植
3 驱动开发
4 应用开发
没了。其中推荐把注意力放在后两个上,3有难度,4比较灵活,最重要的是都是找工作的砝码。

十 我用的什么板子
很多人问我这个问题,我特意写过一个的。再说一次吧。
我是自己做的,RAM、ROM、8019等比较麻烦而当时的自己不理解的都按照龚俊的做的。保持其他不便的情况下做了如下改动。
1 加了串口通信的GPS模块、 GPRS模块
一个UART0,一个UART1,当与要用超级终端时用跳线切换。

2 SD卡,和7843触摸屏
同时挂在SPI总线上,因为SPI只能挂一个设备,同时还做了I/O模拟的准备,把两个设备又通过跳线挂在4个IO上。

3 扩了个IIC的35个键子的键盘
用的ZLG的7290,不占用CPU,最大支持64个键子,只上了35个,其他留接口。

4 把LCD接口按照买的LCD改装了,可以用FPC线直接连接。
所以改动虽然多,但真正很移植了,初期调试有关的并没动,就是为了现在不那么菜的时候做准备:)

十一 开发流程
这里是我的开发流程
1 设计原理图(含WIGGLER的JTAG访真器)
2 设计PCB(含WIGGLER的JTAG访真器)
3 制版
4 焊接电压,确定电压没问题
5 焊接44B0+JTAG电路+WIGGLER的JTAG访真器+周边电路,用BANYANT+仿真器连接,BANYANT提示错误,但可以显示44B0编号,好象是0X0F0F0F0F只类的,说明44B0没问题
6 焊接晶体+RAM+ROM+周边电路,用BANYANT+仿真器连接,可以显示正确的44B0了
7 用BANYANT+仿真器连接,开AXD,在命令行窗口操作RAM,看可不可以修改,可以的话(用内存窗口看RAM地址)RAM就没问题
可以用这个命令“setmem 0xc000000,0xffffffff,32”
我的RAM挂在BANK6上 所以地址是0XC000000,你要是改了就也得改。
8 用我写的《自己写了个C工程模板又写了个使用说明 》里的方法调试程序吧,写个简单的,我当时写个LED闪烁的。看好使不。
9 把程序按照《FLASH烧写总结 》里的烧到FLASH里,测试一下
10 按照《UBOOT 移植操作》移植UBOOT
11 按照《UCLINUX下载简单说明》下个UCLINUX
12 看看驱动开发的方法,自己写个驱动看看
13 还有很多事东西着你玩 呵呵

十二 关于JTAG访真器
JTAG访真器现在用的多是简板的,一个244那种,用的没什么不好。
按照并口定义不同分几种,建议选WIFFLER定义的,因为支持的软件多。这个网上多的是,不多说了。
值得提的是有的JTAG访真器原理图上有跳线用来使能复位信号,这个一般不跳上。就是不用复位信号,因为JTAG协议里本身也可以控制44B0复位。
当然,板子上的复位信号跳线也不用跳。

十三 哪个公司的ARM
这个是问题比较简单。
1 ARM7主要就几个公司的
三星,PHILIP,ATMEL的
ATMEL的有比较便宜的AT91SAM7S32 和AT91SAM7S64 专为8位应用产品量身定做,价格很便宜好象《3刀吧。和PHILIP的21XX差不多,资料太少,项目中选还不错。
其他两家上面说了的不多说了吧

2 ARM9
这个玩2410和2440的多吧,现在2440还比较火啊 可以考虑买个了
但是2410就比较便宜了,作为学习来说反到和不错,推荐整一个:)
其实ARM9用的最多的领域应该是消费电子,比如手机PDA,而这上面用的多的应该是INTEL的和TI的吧。
但是INTEL的TI的入门材料少,价格高,自己看情况定吧。

UBOOT命令总结(转)
很好的UBOOT命令总结,我在起步时就是看的这篇东西,熟悉了以后就用“?”看自带帮助就行:)

Printenv 打印环境变量。

Uboot> printenv
baudrate=115200
ipaddr=192.168.1.1
ethaddr=12:34:56:78:9A:BC
serverip=192.168.1.5
Environment size: 80/8188 bytes

Setenv 设置新的变量

Uboot> setenv myboard AT91RM9200DK
Uboot> printenv
baudrate=115200
ipaddr=192.168.1.1
ethaddr=12:34:56:78:9A:BC
serverip=192.168.1.5
myboard=AT91RM9200DK
Environment size: 102/8188 bytes

Saveenv 保存变量

命令将当前定义的所有的变量及其值存入flash中。用来存储变量及其值的空间只有8k字节,应不要超过。

Loadb 通过串口Kermit协议下载二进制数据。

Tftp 通过网络下载程序,需要先设置好网络配置

Uboot> setenv ethaddr 12:34:56:78:9A:BC
Uboot> setenv ipaddr 192.168.1.1
Uboot> setenv serverip 192.168.1.254 (tftp服务器的地址)
下载bin文件到地址0x20000000处。
Uboot> tftp 20000000 application.bin (application.bin应位于tftp服务程序的目录)

Uboot> tftp 32000000 vmlinux
把server(IP=环境变量中设置的serverip)中/tftpdroot/ 下的vmlinux通过TFTP读入到物理内存32000000处。

Md 显示内存区的内容。

Mm 修改内存,地址自动递增。

Nm 修改内存,地址不自动递增。

Mw 用模型填充内存

mw 32000000 ff 10000(把内存0x32000000开始的0x10000字节设为0xFF)

Cp 拷贝一块内存到另一块

Cmp 比较两块内存区

这些内存操作命令后都可加一个后缀表示操作数据的大小,比如cp.b表示按字节拷贝。

Protect 写保护操作

protect on 1:0-3(就是对第一块FLASH的0-3扇区进行保护)
protect off 1:0-3取消写保护

Erase 擦除扇区。

erase: 删除FLASH的扇区
erase 1:0-2(就是对每一块FLASH的0-2扇区进行删除)

对DataFlash的操作

U-Boot在引导时如果发现NPCS0和NPCS3上连有DataFlash,就会分配虚拟的地址给它,具体为 :
0xC0000000---NPCS0
0xD0000000---NPCS3

run 执行设置好的脚本

Uboot> setenv flashit tftp 20000000 mycode.bin\; erase 10020000 1002FFFF\;
cp.b 20000000 10020000 8000
Uboot> saveenv
Uboot> run flashit

bootcmd 保留的环境变量,也是一种脚本

如果定义了该变量,在autoboot模式下,将会执行该脚本的内容。

Go 执行内存中的二进制代码,一个简单的跳转到指定地址

Bootm 执行内存中的二进制代码

要求二进制代码为制定格式的。通常为mkimage处理过的二进制文件。
起动UBOOT TOOLS制作的压缩LINUX内核, bootm 3200000

Bootp 通过网络启动,需要提前设置好硬件地址。

? 得到所有命令列表

help help usb, 列出USB功能的使用说明

ping 注:只能开发板PING别的机器

usb

usb start: 起动usb 功能
usb info: 列出设备
usb scan: 扫描usb storage(u 盘)设备

kgo 起动没有压缩的linux内核

kgo 32000000

fatls 列出DOS FAT文件系统

fatls usb 0列出第一块U盘中的文件

fatload 读入FAT中的一个文件

fatload usb 0:0 32000000 aa.txt 把USB中的aa.txt 读到物理内存0x32000000处!

flinfo 列出flash的信息

nfs

nfs 32000000 192.168.0.2:aa.txt
把192.168.0.2(LINUX 的NFS文件系统)中的NFS文件系统中的aa.txt 读入内存0x32000000处。

CPU频率计算方法---PLL设置
看见很多朋友不会计算PLL分频和串口频率,整理个笔记发上来

cpu时钟频率和串口波特率的计算公式
S3C44B0的系统时钟设置公式
Fpllo 为系统的主频,此处为60MHz
Fin 为晶振的频率,此处为10MHz
一. 通过PLL输出时钟脉冲频率的计算:
a) Fpllo = (m × Fin)/ (p × 2^s)
b) m = (MDIV + 8) , p = (PDIV + 2), s = SDIV
c) 20MHz < Fpllo < 66MHz
d) Fpllo * 2s < 170MHz (s应该尽可能的大)
e) 1MHz <= Fin/p < 2MHz (最好是Fin/p = 1MHz)
f) 如果PLL打开则:Fpllo = Fout
g) 这样计算出MDIV, PDIV, SDIV的值写入PLLCON寄存器中就可设置Fpllo的输出频率。
根据 d)知道s=1
根据 e)知道p=10
再根据 a)就知道了m=120,注意2^s代表2的s次方
再根据 b)知道MDIV=112, PDIV=8, SDIV=1
根据44B0数据手册5-14页算出 PLLCON=0X70081
注意:PLLCON的结果不为一!比如P可以取8 取7……
注意:PLLCON寄存器是20位的 各个区域中间有空的
比如MDIV是寄存器里19-12位,PDIV是9-4位两个中间有11,10位空,如果用2进制算就添0

不过做过硬件的就知道 大可不必只要把MDIV, PDIV, SDIV用WEINDOWS自带计算机直接由2进制转换成16进制顺序写就行
比如MDIV=112=0x70, PDIV=8=0x08, SDIV=1=0x1
PLLCON寄存器就是0x70081(看到这 连手册都不用翻了吧?:))
还得多说一句 不是0x700801,因为SDIV=1=0x1不是0X01,跟PDIV=8=0x08不一样

S3C44B0的UART波特率计算公式---分频设置
S3C44B0的UART波特率计算公式
MCLK即主频 此处为60MHz
UBRDIVn(又称divisor) = ( (int)(MCLK / (bps * 16) + 0.5) – 1 )
MCLK = Fout = Fpllo
Bps = 1200,9600,19200,38400,57600,115200
例如 主频=60MHz=60000000Hz
串口速度选115200

divisor=取整[60000000/(115200*16) + 0.5] -1 = 32

MINICOM设置
最近的朋友很多问MINICOM设置的问题
把原来写的整理一下 发一下 现成的还行 有朋友问我驱动怎么开发
这个就比较麻烦了:)还是等我过段时间了也把手头的几个驱动搞定了再说

---------正文-------------
MINICOM是LINUX提供的和WEINDOWS超级终端一样的工具,一般用做串口与开发板通信,当然有的板子也用USB,但这里只介绍串口的设置

一 VMWARE虚拟机添加串口(如果没用虚拟机可以跳过这步)
如果在VMWARE虚拟机下 一定要记得先确认这步 要不不好使 很多朋友的问题就在这里!
先关闭虚拟机下的LINUX,然后设置一下虚拟机:在vm-〉settings-〉hardware里添加串口 COM1 COM2都加上吧

二 设置MINICOM
进LINUX系统 开个控制台 字符里输入minicom 就启动了
这时一般还要设置一下
Ctrl+A进入控制界面(Esc返回)按Z进设置
一般设置两个
1 按O(注意:是O不是零)设置第三第四项,分别是串口设置与MODEM设置
串口设置:不用说了吧 进去都看明白了 敲字母 设置相应项目 比如“115200 8-N-1”
MODEM设置:也要设置一下 要不有的看不到东西 把上面两个选项都清空 就是按那行前面的字母(好象是‘A’和什么)然后光标就跳过去了 删之
回车 到开始选第三第四项的菜单 选下面的保存(别忘了保存 菜鸟们常犯)
2 回到刚才按O的界面 看一下P 里面的串口设置对不对
对就不用改了 不对改之

提醒一下:LINUX设备的编号是从0开始的 比如串口1也就是COM1在LINUX里的设备号叫ttyS0
串口设置里面要用到 那里添全部路径也就是"/dev/ttyS0"
好了 就这么简单

uclinux编译文档
user94/mamajinco/upload/1012638628.rarUCLINUX编译的过程是非常折磨人的,我在这整了3天!妈的!把很多公司的都试遍了。第3天的晚上10点搞定了~~

但说真的,很难写下来整体过程,因为跟版本有关,跟各个板子也有关系……

所有的移植都是用2.4做的,谁让咱是菜鸟呢,先从简单的做。
总结几点吧,介绍个现在主流的立宇泰的板子UCLINUX编译方法和我自己拿HFRK的板子提供的UCLINUX改的8019和NFS的方法
一 立宇泰(凭回忆,有些地方当时没记下来)
1下载
arm-elf-tools-20030314.sh//开发工具
uClinux-dist-20040408.tar.gz//源代码包
uClinux-20040408-ARMSYS.rar//立宇泰的补丁
configfiledemo.rar//立宇泰的设置文件

前两个UCLINUX的网站有下的,很快。
后两个立宇泰公司网站有下的,很小,也很快。

2 安装
arm-elf-tools-20030314.sh
在LINUX(我用的VMWARE跑的PC4)下双击,选运行就行,不多说了,有人这里出过问题,提示一个错误,去21IC搜索一下,把一个参数改一下就行。但我的没这个问题。

uClinux-dist-20040408.tar.gz
考到/usr/src/下,右键截压缩到当前目录,也没什么说的。就是记得硬盘要有足够的空间,这个比较大,一般还得有几个备份,得2G左右。

uClinux-20040408-ARMSYS.rar
这个补丁确实不错!!好商家!还共享了,改了一堆文件。
截压缩不说了,得到PARCH文件,拷贝到刚才UCLINUX源代码包目录下,注意,要到uClinux-dist目录里。不是uClinux-dist-20040408.tar.gz目录里。

还不能直接补丁,需要改一下uClinux-dist/vector/Samsung/4510B这个文件夹,直接把名字改成44B0就行了。

打开终端吧,CD到uClinux-dist目录里输入以下命令:
patch -p1 < uClinux-20040408-ARMSYS.patch
注意-P1是数字一不是L字母,命令什么意思就不解释了,GOOGLE一下,有个兄弟专门讲了。
打包到最后会有问题,因为刚才咱们把4510直接改成44B0了嘛,问你问题的时候敲的N吧,退出。
把uClinux-dist/vector/Samsung/44B0里Makefile 和 rc打开,对着uClinux-20040408-ARMSYS.patch改。
具体方法是:双击(这里PC机都默认使用GNOME,比KDE方便,比如双击打开)查看PATCH文件。对着改吧。
补充个语法知识:.patch里面主要有几种符号分别是“+++”“---”"+""-""@@""diff"
每个区域都是diff --- +++ @@四行开始 之后是+ -或者无符号的行,+代表在一个位置加一行,-代表删除一行,什么都不带就什么都不做,用来定位的。
好了,文件最后可以找到 diff uClinux-dist/vector/Samsung/44B0开始的文件了吧?
对着把Makefile 和 rc改了吧。

打完补丁,还得做一件事,把/uClinux-dist/Linux-2.4.x/Driver/Block/blkmem.c改了
#ifdef CONFIG_BOARD_SNDS100
extern char romfs_data[];
extern char romfs_data_end[];
#endif
后加个
#ifdef CONFIG_BOARD_MBA44
extern char romfs_data[];
extern char romfs_data_end[];
#endif

#ifdef CONFIG_BOARD_MBA44
{0, 0xc700000, -1},
#endif
改策成
#ifdef CONFIG_BOARD_MBA44
{0, romfs_data, -1},
#endif

要不编译后的内核运行的时候会有“Kernel panic: VFS: Unable to mount root fs on XXXXX”错误

3 设置
make menuconfig
当然 也可以make Xconfig 但不推荐,虽然显示很好,但速度慢~~
进了菜单,基本就几个键子上 下 左 右 回车 空格。
选什么比较麻烦,建议第一次先用刚才下的configfiledemo立宇泰的设置文件,解压以后是三个文件,分别对应主菜单,内核和用户菜单。
选择Load an Alternate Configuration File
里面输入文件的地址与名称,记得开始的时候说的VMWARE-TOOS共享吧?把这几个文件拷贝到合适的目录下吧,我就放在uClinux-dist-20040408.tar.gz下了。
左右选《EXIT》退出。选保存。

一会自动弹出KERNEL设置菜单,和上面一样Load an Alternate Configuration File,选config_kernel文件。
需要注意的是这里的USB好象不对,因为板子上没整USB(以后再整)就把USB的选项直接去掉了(到USB子菜单下把[*]去了)。
要不会有hcb.c错误。

System Type里要改一下
(Samsung) ARM system type
[*] Set flash/sdram size and base addr
(00800000) (S)DRAM Size
(00200000) FLASH Size
(S3C44B0X-MBA44) Board Implementation

Block devices也改一下
[*] RAM disk support
(4096) Default RAM disk size
(AMD) FLASH type
(AUTO) FLASH size
(AUTO) FLASH bit width

General setup改一下
[*] Timer and CPU usage LEDs
[*] Timer LED
[*] CPU usage LED

其他没说就是别动

左右选《EXIT》退出。选保存

一会自动弹出USER设置菜单,和上面一样Load an Alternate Configuration File,选config_user文件。(语法多整齐)
没有注意了,直接左右选《EXIT》退出。选保存。

说实在的,要是没有这些CONFIG文件,自己改是件很麻烦的事,本人就尝试了自己增加NFS和修改8019(我的板子是自己画的和这个不一样)那叫一个麻烦~~~。建议大家新手还是先把这些顺利的做完了再说改的。

退出以后就是编译了。
4 编译
几大命令
make dep
make clean
make lib_only
make user_only
make romfs
make
顺利的话一次全的执行了,但第3步要是自己鼓捣过在这里就要受苦了,比如后面要讲的把驱动编译进内核里。
这里要说的是,出问题不可怕,但一要做好记录,知道自己改什么,错误可能出现在什么地方,因为报告的错误很可能不是出现错误的位置。二要善于搜索,使用GOOGLE搜索。三 要BBS提问的时候把错误,操作记录都说清楚了,等待高手给你解答。四就是自己要积累看MAKE错误的知识。此外别无他法!

二 好了
我最后用的是HFRK的包,版本是2005311,不用打补丁。但听说所有2005311的包都不用打了,好消息啊。但编译的过程仍然折磨人。
设置与编译的过程仍然和上面一样,这里共项我的CONFIG文件供大家参考吧。就不多说了。
下面说我自己改8019驱动的方法。
8019用的是drivers/net/下的ne.c文件改的。
改之前要差几点:8019是8位还是16位,地址线是怎么对应的(8019是ADDR1对44B0的ADDR几?),8019挂在44B0的哪个BANK上,8019使用哪个中断,中断号多少。

好了,对应的改吧。
先改文件。
drivers/net/ne.c
找到CONFIG_BOARD_MBA44,修改一下中断号dev-irq,改成我们电路中使用的EINT1(中断号24),挂在BANK3上地址0x06000000
……
#elif defined(CONFIG_BOARD_MBA44)
static int once = 0;
if (once)
return -ENXIO;
dev->base_addr = base_addr = 0x06000000;
dev->irq = 24 ;
once++;
……

注意:一定要知道8019地址线是怎么对应的,我的是0对0(8位)但有的朋友8019是7对0,就要改了,但是具体哪个文件忘了,GOOGLE搜索一下吧:)

进make menuconfig里把以下选了
1 General Setup --->
Networking Support

2Networking options --->
Packet socket
TCP/IP networking

3 进Networking device Support---》
4 File system --->
Network device support?

Ethernet (10 or 100Mbit) --->
Other ISA cards
NE2000/NE1000 support
注意:这里通过[ ] 16Bits mode support选择8019工作位,我没选,因为做的是8位的

4 Network Applications --->
arp
ifconfig
inetd
ping
route
好了,之后就是编译了,烧写,然后测试一下PING宿主机,NFS挂一下看看。
注意:宿主机的防火墙要关了,不然PING不通,当然NFS也不行。

好了,编译内核就到这里,因为过于繁琐,只能分部分来简化写了~~大家有问题再交流吧。

搞定UCLINUX移植以后就开始整个最小的程序吧,当然是HELLOWORLD了:)
一 先写个helloworld.c (对于小代码我喜欢先在WINDOW下建个“新建 文本文档.txt”再在里面写代码,然后保存后改名成helloworld.c 注意的是扩展名也要从TXT改成C才行,原来说过,不多说了)
里面写下面等号里的代码:
==================
#i nclude
#i nclude

int main(void)
{
printf("hello world ! I got it!\n");
return 0;
}
==================
不用解释了吧:)

二 然后编写个makefile吧,别总用arm-elf-gcc了。
为以后编写大规模程序打个基础:)
建个makefile(和前面一样,先TXT然后改名,没有扩展名)
=====================
EXEC = helloworld
OBJS = helloworld.o

all: $(EXEC)
$(EXEC): $(OBJS)
$(CC) $(LDFLAGS) -o $@ $(OBJS) $(LDLIBS)

romfs:
$(ROMFSINST) /bin/$(EXEC)
clean:
rm -f $(EXEC) *.elf *.gdb *.o
======================
基本能看明白吧?MAKE的语法比较复杂,就不多讲了,可以看我在前几篇笔记里推荐的ZLG那本书。但幸运的是基本不用自己动手了,LINUX源代码里有很多MAKE 拿来改改吧:)

三 下面就是有朋友问我怎么把程序下到板子里了
一般说来有几种方法。
1 板子挂载宿主机的NFS共享目录,把程序拷贝到/tmp目录(在RAM里)测试一下,但缺点是掉电要消失,只适合做调试时用。
2 做JFFS之类的日志文件系统,和上面一样NFS挂载拷贝过来,JFFS文件系统可以保证掉电不消失,类似U盘里拷贝程序(只是结果类似,原理完全不同)。
3 直接把程序烧写进ROMFS文件系统,这里就只介绍这种。原因有两点 首先 我还没学怎么做JFFS,其次 我还没学怎么做JFFS。哈哈
好了,那开工。

1)在uClinux-dist/user/下建立目录hello
把helloworld.c和makefile拷贝到里面,怎么拷贝不用说了吧?VMWARE-TOOLS共享文件夹吧。

2)修改uClinux-dist/user/makefile

在适当位置 找一行(这句语法扎堆的地方)加
dir_$(CONFIG_USER_HELLO) += hello

3)记住CONFIG_USER_HELLO这个名(自己可以改的 )
在uClinux-dist/config/Configure.help里加(扎堆)下面两行
CONFIG_USER_HELLO
Only print hello world
上面是名(和前面必须一致)下面是注释

4)改uClinux-dist/config/Configure.in里按照扎堆的原则加下面几行
#############################################################################
mainmenu_option next_comment
comment 'Hello World'
bool 'demo' CONFIG_USER_MYAPP_DEMO
endmenu
#############################################################################
#号中间加的就是语法了,基本意思就是在Hello World--->下加个[]demo
编译过内核的都熟悉吧:)

5)像编译内核一样编译了
进内核源代码目录,比如uClinux-dist
make menucinfig
把主菜单选好了,不用说了吧?我的编译内核笔记里有,当然如果不想修改内核就只选上以下这个
Kernel/Library/Defaults Selection --->[*] Customize Kernel Settings (NEW)
意思是修改USER程序
EXIT 保存
然后在Customize Kernel Settings菜单里最后会出现Hello World--->
回车进去以后看见[]demo了吧?
选上

EXIT 保存

6)编译
几大命令~~~
make dep
make clean
make lib_only
make user_only
make romfs
make
之后在生成uClinux-dist/image下有了uclinux_rom.bin

7)烧写到板子里
板子里有UBOOT了吧?
顺序做下面步骤(我在UBOOT编译笔记里写过,再写一次)
A:loadb 0xc500000
B:发送(KERMIT协议)uclinux_rom.bin
C:erase 0x50000 0x1fffff
D:cp 0xc500000 0x50000 文件大小
注意:文件大小就是在传输完uclinux_rom.bin后显示的数字 0X开头=什么的那个0X数字
比如提示是0X0012a7f1=1222641
就0X0012a7f1/4+2=0x4A9FE命令就是:cp 0xc500000 0x50000 0x4A9FE
E:重起板子 就进UCLINUX了


8)板子进到/bin下 看是不是有个helloworld?
执行它就看见“hello world ! I got it!”
注意:因为把文件编写到内核了,所以不是用./helloworld
直接在任何目录下写helloworld就行

最简单的驱动---让LED闪一闪-1
user94/mamajinco/upload/1012942565.rar这几天抽时间做了几个驱动,基本都是字符设备,什么GPS 模块了GPRS模块了LCD了
有很多朋友关心驱动,但更菜的菜鸟居多:)总结了一下 把I/O驱动改成个更简单的LED驱动吧
做的工作非常简单,就是让连在GPC0-GPC2上的LED顺序闪10下
目的就是演示一下驱动过程。

一 先补充一下基础知识 懂的朋友就不用看了

嵌入式驱动的概念

设备驱动程序是操作系统内核和机器硬件之间的接口,设备驱动程序为应用程序屏蔽了硬件的细节,这样在应用程序看来,硬件设备只是一个设备文件,应用程序可以像操作普通文件一样对硬件设备进行操作。设备驱动程序是内核的一部分,它主要完成的功能有:对设备进行初始化和释放;把数据从内核传送到硬件和从硬件读取数据;读取应用程序传送给设备文件的数据、回送应用程序请求的数据以及检测和处理设备出现的错误。

Linux将设备分为最基本的两大类:一类是字符设备,另一类是块设备。字符设备和块设备的主要区别是:在对字符设备发出读/写请求时,实际的硬件I/O一般就紧接着发生了。字符设备以单个字节为单位进行顺序读写操作,通常不使用缓冲技术;块设备则是以固定大小的数据块进行存储和读写的,如硬盘、软盘等,并利用一块系统内存作为缓冲区。为提高效率,系统对于块设备的读写提供了缓存机制,由于涉及缓冲区管理、调度和同步等问题,实现起来比字符设备复杂得多。LCD是以字符设备方式加以访问和管理的,Linux把显示驱动看做字符设备,把要显示的数据一字节一字节地送往LCD驱动器。

Linux的设备管理是和文件系统紧密结合的,各种设备都以文件的形式存放在/dev目录下,称为设备文件。应用程序可以打开、关闭和读写这些设备文件,完成对设备的操作,就像操作普通的数据文件一样。为了管理这些设备,系统为设备编了号,每个设备号又分为主设备号和次设备号。主设备号用来区分不同种类的设备,而次设备号用来区分同一类型的多个设备。对于常用设备,Linux有约定俗成的编号,如硬盘的主设备号是3。Linux为所有的设备文件都提供了统一的操作函数接口,方法是使用数据结构struct file_operations。这个数据结构中包括许多操作函数的指针,如open()、close()、read()和write()等,但由于外设的种类较多,操作方式各不相同。Struct file_operations结构体中的成员为一系列的接口函数,如用于读/写的read/write函数和用于控制的ioctl等。打开一个文件就是调用这个文件file_operations中的open操作。不同类型的文件有不同的file_operations成员函数,如普通的磁盘数据文件,接口函数完成磁盘数据块读写操作;而对于各种设备文件,则最终调用各自驱动程序中的I/O函数进行具体设备的操作。这样,应用程序根本不必考虑操作的是设备还是普通文件,可一律当作文件处理,具有非常清晰统一的I/O接口。所以file_operations是文件层次的I/O接口。

二 开始写了
采用了在代码里加注释的方法,同时把几个文件上传了一下,喜欢的朋友可以下载当作模板。每个文件以==隔开
一共需要写写3个文件,1个驱动头文件,1个驱动文件,一个驱动测试用程序文件
分别是test.h,test.c和ledtest.c

简单说说驱动都做什么,怎么做
1 系统加载驱动
2 应用程序里打开设备(文件)
3 应用程序对设备操作
4 应用程序关闭设备(文件)
5 系统关闭设备

应用程序如何对设备操作?
记得C语言里怎么写文件吗?这里很相象的。对于一般的字符设备(还有块设备,网络设备等等)主要有3个函数(还有很多,可以看)llseek read: write: ioctl: 这里只用ioctl:控制函数,当然也可以使用读写函数操作IO 口,但ioctl:似乎更适合。
具体实现可以看ledtest.c文件了。

test.c中主要有几个函数 分别负责初始化和清除,打开和关闭。以及ioctl对串口寄存器写一些数据。
初始化和清除,打开和关闭函数里都各有一句主要句,已经分别作了注释。只要记住就好了。

对寄存器操作就不单独说了,需要看44B0数据手册了。好了 剩下的看代码吧。
==============================
==========test.h==================
==============================

/****************************************Copyright (c)**************************************************
** FREE
**
**--------------File Info-------------------------------
** File Name: config.h
** Last modified Date: 2006-9-9
** Last Version: 1.0
** Descriptions: User Configurable File
**
**----------------------------------------------------
** Created By: ZLG CHENMINGJI
** Created date: 2006-9-9
** Version: 1.0
** Descriptions: First version
**
**-------------------------------------------------
** Modified by:MAMAJINCO
** Modified date:2006-9-9
** Version:1.0
** Descriptions:在此忠心感谢ZLG的模版 我的高质量编程意识起源于此
**
*****************************************************/
//防止重复包含此文件而设置的宏
#ifndef __CONFIG_H
#define __CONFIG_H

//包含必要的头文件
#i nclude
#i nclude //模块必须包含的头文件
#i nclude /* printk()函数,用于向内核输出信息 */
#i nclude /* 很重要 其中包含了如file_opration等结构 此结构用于文件层接口 */
#i nclude /* 错误代码*/
#i nclude
#i nclude
#i nclude
#i nclude

/********************************/
/* 应用程序配置 */
/********************************/
//以下根据需要改动
//定义主设备号 设备名称

#define LED_MAJOR_NR 231 //231~239 240~255都可以

#define DEVICE_NAME "led" /* name for messaging */

#define SET_LED_OFF 0
#define SET_LED_ON 1

#endif
/************************ End Of File
*********************************************************/


=============END===============

最简单的驱动---让LED闪一闪-2
==============================
============test.c================
==============================

/*************Copyright (c)**************************
** FREE
**
**--------------File Info-----------------------------------------
** File Name: test.c
** Last modified Date: 2006-9-9
** Last Version: 1.0
** Descriptions: User Configurable File
**
**----------------------------------------------------
** Created By: ZLG CHENMINGJI
** Created date: 2006-9-9
** Version: 1.0
** Descriptions: First version
**
**--------------------------------------------------------
** Modified by:MAMAJINCO
** Modified date:2006-9-9
** Version:1.0
** Descriptions:在此忠心感谢ZLG的模版 我的高质量编程意识起源于此
**
***********************************************************/
#i nclude "test.h"//包含驱动头文件


/************************************************************
function announce
******************************************************/
//以下是关键函数的声明
static int led_open(struct inode *inode, struct file *filp);
//打开设备时用的 linux把设备当作文件管理 设备最好在用的时候再打开 尽量不要提前
static int led_release(struct inode *inode, struct file *filp);
static int led_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long param);
//控制函数 这里用于控制LED亮与灭
int led_init(void);//注册时用的 注意 模块注册的越早越好
void led_cleanup(void);//卸载时用的

/*************************************************************
** "全局和静态变量在这里定义"
** global variables and static variables define here

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

static struct file_operations LED_fops = /* 前面基础部分提到的重要结构体了*/
{
owner: THIS_MODULE,

#if 0/*注意:#if 0-#endif里的代码是不编译的,但这里为了驱动模板讲解上的完整性仍然加上了*/
llseek: gpio_llseek,
read: gpio_read,
write: gpio_write,
#endif
ioctl: led_ioctl,//控制函数
open: led_open, //打开函数,打开文件时做初始化的
release: led_release,//释放函数,关闭时调用
};


/**************************************************************
** Function name: led_open
** Descriptions: open device
** Input:inode: information of device
** filp: pointer of file
** Output 0: OK
** other: not OK
** Created by: Chenmingji
** Created Date: 2006-9-9
**-------------------------------------------------------------
** Modified by:mamajinco
** Modified Date: 2006-9-9
**--------------------------------------------------------------
**************************************************************/
static int led_open(struct inode *inode, struct file *filp)
{
/*初始化放在OPEN里*/
(*(volatile unsigned *)S3C44B0X_PCONC) &= 0xffffffc0;
(*(volatile unsigned *)S3C44B0X_PCONC) |= 0xffffffd5; /*GPIO C口0~2 设置为输出*/

(*(volatile unsigned *)S3C44B0X_PUPC) &= 0xffffffc0;/*GPIO C口0~2 设置为上拉*/

MOD_INC_USE_COUNT;
return 0;
}

最简单的驱动---让LED闪一闪-3
*********************************************************
** Function name: led_release
** Descriptions: release device
** Input:inode: information of device
** filp: pointer of file
** Output 0: OK
** other: not OK
** Created by: Chenmingji
** Created Date: 2006-9-9
**-----------------------------------------------------
** Modified by: mamajinco
** Modified Date: 2006-9-9
**--------------------------------------------------------
****************************************************/
static int led_release(struct inode *inode, struct file *filp)
{
MOD_DEC_USE_COUNT;
return(0);
}
/****************************************************
** Function name: led_ioctl
** Descriptions: IO control function
** Input:inode: information of device
** filp: pointer of file
** cmd: command
** arg: additive parameter
** Output 0: OK
** other: not OK
** Created by: Chenmingji
** Created Date: 2006-9-9
**-------------------------------------------------------
** Modified by: mamajinco
** Modified Date: 2006-9-9
**----------------------------------------------------------
***********************************************************/
static int led_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
if( arg > 2 )//判断IO是否属于0-2
return -1;

switch(cmd)
{
case 0://把ARG传来的IO口编号转换成寄存器数据,把相应IO口置低
(*(volatile unsigned *)S3C44B0X_PDATC) |= 0x1 << arg;

break;

case 1://把ARG传来的IO口编号转换成寄存器数据,把相应IO口置高
(*(volatile unsigned *)S3C44B0X_PDATC) &= 0x0 << arg;
break;

default:
return -1;
break;
}
return 0;
}

/**************************************************
** Function name: led_init
** Descriptions: init driver
** Input:none
** Output 0: OK
** other: not OK
** Created by: Chenmingji
** Created Date: 2006-9-9
**------------------------------------------------
** Modified by: mamajinco
** Modified Date: 2006-9-9
**-----------------------------------------------------
*************************************************/
int led_init(void)
{
int result;

result = register_chrdev(231,"led", &LED_fops);
/*关键语句 用于注册
** 注意!这是传统的注册方法 在2.4以上的linux版本中 加入了devfs设备文件系统 使注册更容易 但为了与大部分资料相**同 大家看的方便 这里仍然使用老方法*/
if (result < 0) //用于异常检测
{
printk(KERN_ERR DEVICE_NAME ": Unable to get major %d\n", LED_MAJOR_NR ); //printk用于向内核输出信息
return(result);
}


printk(KERN_INFO DEVICE_NAME ": init OK\n");

return(0);
}

最简单的驱动---让LED闪一闪-4
/*************************************************************
** Function name: led_cleanup
** Descriptions: exit driver
** Input:none
** Output none
** Created by: Chenmingji
** Created Date: 2006-9-9
**--------------------------------------------------------
** Modified by: mamajinco
** Modified Date: 2006-9-9
**-----------------------------------------------------
**************************************************/
void led_cleanup(void)
{
unregister_chrdev(231, "led"); //与register_chrdev配对使用 用于清楚驱动
}

/***********************************************************
** End Of File
****************************************************/


===============END=============

=====================================
=============ledtest.c===============
===================================

/*********************Copyright (c)**************************
** FREE
**
**--------------File Info----------------------------
** File Name: led.c
** Last modified Date: 2006-9-9
** Last Version: 1.0
** Descriptions: User Configurable File
**
**-------------------------------------------------------
** Created By: ZLG CHENMINGJI
** Created date: 2006-9-9
** Version: 1.0
** Descriptions: First version
**
**--------------------------------------------------------
** Modified by:MAMAJINCO
** Modified date:2006-9-9
** Version:1.0
** Descriptions:在此忠心感谢ZLG的模版 我的高质量编程意识起源于此
**
********************************************************/

#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude

void delay(int delay)//延时用函数
{
int i;
for(;delay>0;delay--)
{
for(i=0 ; i < 5000 ; i ++);

}
}

int main()
{
int fd1;
int j;

fd1= open("/dev/led" , O_RDWR);/*打开设备,就象打开文件一样简单*/

if(fd1 == -1)/*异常处理*/
{
printf ( "file can not be open" );
return -1;
}

for (j =0 ; j< 10 ; j ++)/*重复10次*/
{
ioctl(fd1 , 1 , 0);/*GPC0上LED亮*/
delay(1000);
ioctl(fd1 , 0 , 0);/*GPC0上LED灭*/
ioctl(fd1 , 1 , 1);/*GPC1上LED亮*/
delay(1000);
ioctl(fd1 , 0 , 1);/*GPC1上LED灭*/
ioctl(fd1 , 1 , 2);/*GPC2上LED亮*/
delay(1000);
ioctl(fd1 , 0 , 2);/*GPC2上LED灭*/
delay(1000);
}

close (fd1);/*关闭设备(文件)*/
return 0;

}


===============END===============

最简单的驱动---让LED闪一闪-5
三 驱动编译进内核
编译的中对于菜鸟来说需要需要注意几点
1 被打错字,包括上面的函数中也是!
就算各位扔砖头我也得说,因为编译进内核是很费时间的~~而且最重要的是对于菜鸟来说make的错误提示都是一道关,绝对不要自己给自己设置障碍!我们团队里就常有兄弟姐妹出现这样的错误,怎么看怎么对,尤其是从书上抄下来的命令和字符,l和1还有I你怎么分?最后一个是大写的i :)
2 不要用中文文件名 包括ABC(复件)
要不然MAKE出错
3 在各个现成的文件里修改的时候按照原有的格式修改 要不然菜鸟很难保证不犯低级错误
让我想起来了IBM的规律总结测试题:6 13 7 14 8 下一个数字是什么?

好了 开始修改!
===============START==============
uClinux-dist/linux-2.4.x/drivers/char/Makefile
----------------------------------------------
obj-$(CONFIG_C5471_WDT) += wdt_c5471.o之后加
obj-$(CONFIG_TEST) += led.o
================END============

=================START===========
uClinux-dist/linux-2.4.x/drivers/char/Config.in
-----------------------------------------
if [ "$CONFIG_CPU_S3C44B0X" = "y" ]; then
bool 'Samsung S3C44B0X serial ports support' CONFIG_SERIAL_S3C44B0X之后加
bool 'Test LED Driver' CONFIG_TEST
================END=================
=================START=============
uClinux-dist/linux-2.4.x/drivers/char/mem.c
-----------------------------------------
开头的地方扎堆加
#ifdef CONFIG_LEDTEST
extern void led_init(void);
#endif

int __init chr_dev_init(void)之后加
#ifdef CONFIG_TEST
led_init();
#endif
================END==============
=================START============
uClinux-dist/vendors/Samsung/44B0/Makefile
-----------------------------------------
ttypc,c,3,12 ttypd,c,3,13 ttype,c,3,14 ttypf,c,3,15\之后加
\
led,c,231,0 \
================END==============


四 把程序编译进内核
没什么说的了,和过去写的简单的程序一样加 但这里再重复一次

================START============
uClinux-dist/user/Makefile
-----------------------------------------
扎堆加个下面
dir_$(CONFIG_USER_LEDTEST) += LEDtest
=================END===============
================START============
uClinux-dist/config/Configure.help
-----------------------------------------
扎堆加个下面
CONFIG_USER_LEDTEST
Test the LED driver
=================END=============
================START================
uClinux-dist/config/Configure.in
-----------------------------------------
##############################
mainmenu_option next_comment
comment 'LED driver test PG'

bool 'LEDtest' CONFIG_USER_LEDTEST
endmenu

###############################
=================END=============

五 编译 烧写……省略200字 想看的看我写的helloworld编译笔记吧
六 下面的操作在板子上执行
1 cd /dev
2 ls
看见里面有个LED了吧?
3 cd /proc
4 cat devices
看见驱动列表吧?
led 231也应该在里面
5 LEDtest
在任何地方执行这个语句 就可以
之后看GPIO的C口电平吧:)

总结
好了 到今天为止简单的东西都已经整理过了 也感谢大家最近的关注

剩余的部分LCD图形操作 GPRS驱动 有机会再发吧 估计对于菜鸟不是很重要。

有人向我要GPS的驱动 我没给:)其实很简单的UART 但是涉及到本实验室别人的劳动 就不发了。

至于minigui移植本人还一直没时间做 因为准备把SD卡 SPI触摸屏驱动搞定再做 但过了这段时间一定会做的 也是到时候再说吧。

再次声明一下,这个BLOG是因为感谢那些帮助过我的朋友们而建立的,偶然发现有几篇笔记已经被很多网站转载了,大家当然可以随意利用这里的资源,但只有一个要求,希望大家会了以后也把自己的东西共享一下。

其实写了这么多 技术上的很少有创新 多是总结 在这里也感谢那些我提到与没提到的人 因为这里所有的文章都来自于他们的原始积累。

写这些简单的出奇的东西 也无非就是想告诉那些比我还菜的鸟们:这个世界上有高手,但不多。可能你这辈子都见不到几个。那么与其一直敬仰他们不如自己踏踏实实从小做起。在自己的小范围内作到一个点的专家。然后点连成线,线变成知识面……

说实在的,很多人上来QQ就问我“我在做毕业设计 一点头绪也没有”“导师逼我做的……”“高手 帮我讲讲什么是XX”
我不喜欢这些……如果这些朋友不改变这种状态的话,我劝大家还是不要做了。

做东西也好,做项目也罢,态度很重要。有人问我学ARM重要的是什么?我也总结了一下,不应该说学ARM重要是什么,而是做事重要的是什么:把肉都剔掉以后就只有骨头---心系一处,全力以赴。可能这就是大道致简吧。因为我决定做点成绩出来,所以我对实验室的事都很积极;因为我很积极,虽然开始都是些杂活,我同样把它们完成的尽量好;因为我把它们完成的尽量好,领导发现了我;因为领导发现了我,我身上一些东西开始被注意;因为领导发现这些东西了,我被指定做一个小型的4人项目;因为我仍然决定做点成绩,这个项目竟然完成了……频吧?其实除了技术以外,我是个很开朗的人,从我的笔记就可以看出来。

好了,不多说了 每个人都有自己的哲学 是不用写下来的 哲学与技术不一样 技术写下来可以帮助理解 哲学写下来就打折了 哈哈
你看那些哲学高手都什么样?老和尚轻易不说话 一说出来 当……当……

享受奋斗以后一边擦汗一边喝着冰镇啤酒的感觉
mamajinco 发表于 2006-11-11 10:10:00
经过几个月的苦修

拨开乌云见蓝天了~~心情舒畅很多了~~

尽情的享受奋斗以后一边擦汗一边喝着冰镇啤酒的感觉 哈哈

被鄙视了无数次 也鄙视别人无数次之后最大的感觉就是“人生是什么”

“幸福是什么”“满足是什么”……都是狗屎 作为一个工程师来说 整天琢磨这些 也与这些黄澄澄盘旋向上的妙不可言的东西无异了吧 呵呵

最重要的是什么?或者说作为工程师来说 最重要的是什么?

任务……不停的设定更高的目标 然后达到它

以完成不可能完成的任务为荣

工程师的生活是什么 工程师的人生是什么 工程师的幸福是什么

就是看着自己的努力给家人带来的幸福生活

就是不断挑战自己人生目标 在有限的人生里把精力只放在几个点上 然后让它们燃烧

就是和朋友嘴里吟颂着中国几千年来的国骂 喝到半死的 睡上一天 第三天继续前进的幸福

俗吧?就这么俗

捡个优惠时段和女朋友开个KTV大包 唱上1天 晚上回来的路上还停不了 一直哼哼

领着女朋友挤公交绕半个城市 就为了找自己原来喜欢的“大排面” 啃着大排骨对着傻笑

和5个发小一起庆祝我找到好工作 去去了无数次的四川火锅 花上100多

陪老妈呆上一天 听她唠叨老爸年轻时对他不好 听她一边鼓励我好好发展 有舍不得我去北京

陪老爸聊聊天 听他说“其实我做欣赏你的是……”用胳膊肘憝一下健康的老爸 告诉他“搞什么 爷俩还唠这嗑……”

打车跑到玩具批发市场 找了半天 找到金属的变形金刚 回来再租本柯南 关上电话 像猪一样委在床上一下午

去tompda淘二手的智能手机和PDA 突然发现手上都有3个了 还想要新的 被女朋友制止 只好把旧的打磨一下 看起来新一些 继续用

给朋友发发短信 操来操去 最后互祝平安

看着女朋友跑到WATSON买便宜的小玩意 还不要我给她买喜欢了好久 才3XX的靴子 还安慰我说等我一年能拿到16W的时候再说

看着开着吉利的大哥送自己的孩子上学 想起自己家也是买过宝来 开了1年 油太贵了 又没人开 卖了赔6W 但毕竟我家也有过车 还是个小名牌

看着考了博士 有找了研究所工作的女朋友整天还在等消息 还在为论文忙碌 想起来1年前的她还在为我认了个妹妹而吃醋

哈哈 人生不过如此 让别人笑笑 偶尔笑笑别人~~

 






 

 

 

 

转载于:https://www.cnblogs.com/tao560532/archive/2011/12/17/2291262.html

你可能感兴趣的:(嵌入式,驱动开发,操作系统)