all:make_test.bin make_test.uue
main.o:main.c
@echo compiling main.c to main.o
armcc -O1 -g+ -c main.c -o main.o
@echo..............
led_api.o:led_api.c
@echo compiling led_api.c to led_api.o
armcc -O1 -g+ -c led_api.c -o led_api.o
@echo..............
led_driver.o:led_driver.c
@echo compiling led_driver.c to led_driver.o
armcc -O1 -g+ -c led_driver.c -o led_driver.o
@echo..............
make_test.axf:main.o led_api.o led_driver.o makefile
@echo linking o file...
armlink main.o led_driver.o led_api.o -ro-base 0x8000 -entry __main -o make_test.axf
@echo..............
make_test.bin:make_test.axf
@echo fromelf alf file
fromelf -bin -output make_test.bin make_test.axf
@echo.............
make_test.uue:make_test.bin
@echo uuencode bin file
uuencode make_test.bin make_test.uue
@echo..........
clean:
@echo deleting all files
-del *.o *.axf *.uue
@echo..........
ARM ADS Semihosting半主机方式:
许多库函数在调试环境下的实现都调用了一种叫semihosting的机制,让代码在ARM目标上运行,让ARM目标将输入输出请求从应用程序代码传递到运行调试器上的主机;通常输入输出设备包括键盘屏幕磁盘等;
__main函数执行流程:
copy RO&RW from load addr to execution addr;
zeroes ZI regions;
Branches to __rt_entry;
__rt_entry函数执行流程:
calls __rt_stackheap_init();
calls __rt_lib_init();
calls main();
calls exit();
ADS调试方案:ADS+AXD+Wiggler JTAG+Banyan.dll;
下载地址:
运行Daemon.exe程序,选detect识别芯片,然后在AXD中选用Banyan.dll,加载程序load image,运行调试;
若ARM板为纯裸机直接用flash烧写工具烧写;有bootloader支持的可以用bootloader烧写命令烧写应用程序,也可下载uue/bin格式应用程序到RAM运行;有linux操作系统可用tftp下载;
===========================================================
easyJTAG的设置: 将easyJTAG的相关文件拷贝到特定的ADS目录下,在AXD中设置target, 选择easyJTAG, 若出错, 则设置connect mode, 选attach, 然后restart, 此时AXD显示空白页面, 此为正常态, 个load image,选择debuginexram里面的axf文件, 即可运行调试. 注意此时保证硬件JTAG连接,bank0-ram, bank1-flash, 另外要注意设置ro_base, rw_base, entry等为正确的地址;
几种ADS目标文件:
DebugInExRam: 片外RAM调试
DebugInChipFlash: 片内flash调试
RelInChip: 片内flash工作模式(加密);
RelOutChip: 片外flash工作模式;
UC/OS程序调试: 确保项目文件里面有ARM, ARM-PC, SOURCE, USRDEF(存放用户文件, 名称可变)几个文件夹, 该程序可在ADS中调试编译;
uClinux程序调试: gdb+gdb-server, 在PC_LINUX下交叉编译, 得到uClinux在arm上运行的代码.下载运行; NFS文件系统, 可以方便的在PC上编辑文件, 不必每次更改都要重新下载;
miniGUI程序调试: 需要miniGUI的资源文件,头文件, 库文件等.
SM2200的boot程序下载, 开发板设置bank0-flash, bank1-ram:
在ADS中运行download项目(是UC/OS项目, 通过串口接收文件), 开启一个超级终端: 38400, 8N1, 无, 选择发送文件(boot.hex);
若在ADS中允许download_net项目(是UC/OS项目, 通过网口接收文件), 连上网线, 设置主机掩码255.255.0.0以便192.168.1.100可以访问192.168.15.25, 开启一个超级终端, 设置网络连接, IP及MASK设置与项目文件main.c中的设置一致,选择发送文件(boot.hex);
SM2200的内核及根文件系统下载,开发板设置bank0-flash, bank1-ram:
在WINDOWS启动一个超级终端,设置好连接参数, reset开发板, 出现FTP选项, 选默认IP, 在PC端启动flashftp软件, 给开发板传/etc, /boot, /usr等文件, 传送完毕后, reset开发板, 则出现uClinux选项, 可启动uClinux.并下载文件到相应目录;
在LINUX启动一个minicom,设置好连接参数, reset开发板, 出现FTP选项, 选默认IP, 在PC端启动gftp软件, 给开发板传/etc, /boot, /usr等文件, 传送完毕后, reset开发板, 则出现uClinux选项, 可启动uClinux.并下载文件到相应目录;
------------------------------------------------------------------------
ARM处理器平台开发工具,分ADS和GNU tool Chain两大类:
ADS, ARM DEVELOPER SUITE, 使得调试ARM程序和普通的应用程序开发类似,可以支持uC/OS-II的编译和调试,缺点是缺乏对Linux的支持,无法编译Linux内核,如果涉及Linux内核的编译和移植,需要用GNU工具;
命令行工具:armcc,armcpp,tcc(Thumb C编译器),tcpp,armasm,armlink, armsd, C++ lib,C lib;
其他辅助工具:fromelf,armar,flash(flash写入工具);
------------------------------------------------------------------------------------
GNU TOOL CHAIN, GCC,GNU COMPILER COLLECTION是GNU项目中最重要的成果,也是自由软件中最为核心的开发工具-编译器;
命令行工具:arm-elf-gcc,arm-elf-g++,arm-elf-as(汇编编译器),arm-elf-ld(链接器),arm-elf-gdb,arm-elf-ar(库文件工具);
其他辅助工具:make,CVS,arm-elf-objcopy(elf转成二进制文件),arm-elf-objdump(elf文件的反汇编),arm-elf-nm(列出elf文件的符号表),arm-elf-readelf(生产elf文件信息及内部各段信息),arm-elf-size(列出elf文件各段的大小及位置),arm-elf-strip(对elf进行瘦身),arm-elf-strings(列出elf文件中字符串常量);
======================================
用法举例:
armasm -g $< -o $@
armcc -O1 -g+ -c $< -o $@
armlink $(OBJS) -ro-base 0x8000 -entry __main -o $(AXF)
fromelf -bin -output $(BIN) $(AXF)
fromelf -c -d -s -o $(LST) $(AXF)
uuencode $(BIN) $(UUE)
=================================================================
几种流行的嵌入式处理器体系:ARM,MIPS,POWERPC
arm-linux-gcc/g++ 编译arm_linux程序;
arm-elf-gcc/g++ 编译2.4内核uclinux程序,生成flt文件;
arm-uclinux-gcc/g++ 编译2.6内核uclinux程序,
SKYEYE工具:用PC资源仿真一个ARM处理器,让uC/OS-II,uClinux,Linux运行在SKYEYE平台上;
嵌入式常用调试方式:打印信息 JTAG调试 远程gdb调试(目标机运行gdb-server) 点灯大法
C语言目标文件的段:CODE,RO DATA,RW DATA,BSS;
===========================================================
内核下载,打补丁:
zcat patch-2.4.19-rmk7.gz | patch -p1 -d linux-2.4.19
bzcat patch-2.4.19-rmk7.bz2 | patch -p1 -d linux-2.4.19
内核裁剪与配置:
make xconfig
make menuconfig
make oldconfig
保存配置文件,方便以后使用:
cp .config arch/arm/config/xxx_config
使用默认配置,只需要运行:
make xxx_config
make oldconfig (只提示用户之前没有配置过的选项)
内核编译与安装:
如果多次编译过内核,要恢复到初始干净状态, make mrproper;
linux内核->
make dep(编译2.4内核时需要)
make (zImage)
uClinux内核->
make lib_only
make user_only
make romfs
内核模块编译:
make modules(编译2.4内核时需要)
产生的文件:
linux:原始的linux内核镜像,elf格式,无压缩;可用SKYEYE调试;
image.ram:压缩后的内核镜像,ARM平台的默认选择,可直接下到板子运行;
SKYEYE的使用:
./skyeye vmlinux->target sim->load->run->b setup_arch
./skyeye -e vmlinux -c skyeye.conf
几种文件格式:
ELF,Excutive Linked File,一种linux系统采用的通用文件格式,支持动态链接;
FLAT,对ELF文件头和段信息进行了简化;
BIN,二进制格式文件,不包含地址定位信息;
HEX,十六进制格式文件,包含地址定位信息;
========================================================
uClinux Image Files:
romfs.img:是通过tools/romfs-inst.sh脚本,生成romfs目录及其下面的文件,通过genromfs打包生成;
linux.text:编译后的内核中text段;
linux.data:编译后的内核中data,ini段;
image.bin = linux.text+linux.data+romfs.img
image.ram:无压缩内核,需要在ram中运行,这是编译生成的无压缩linux内核,可通过arm-elf-objcopy生成二进制映象文件;
image.rom:压缩内核,就是通常linux所生成的zImage文件;
image.rom = gunzip program +gzipped( image.ram );
=======================================================
移植工作的几个要点:
Makefile文件的修改;
源码修改;
发布补丁:diff -Nur linux-2.4.x linux-2.4.x-porting
========================================================
文件系统:
VFS, virtual file system,通过在系统内核和文件系统之间制定一个标准的接口而实现;
Linux支持多种文件系统,常用的有:EXT2,ROMFS,JFFS2,NFS,CRAMFS,YAFFS等;
EXT2,二级扩展文件系统,支持4TB硬盘分区和256字节的长文件名;
相关知识点:索引节点inode, 超级块super block, 3级索引;
ROMFS,是只读文件系统,更节省空间,系统同时需要虚拟盘RAMDISK(ext2格式)支持临时文件和数据文件的存储;
JFFS2,适用于Flash存储设备,提供更好的扇区管理;
YAFFS,专门为NAND flash设计的嵌入式文件系统,适用于大容量存储设备,提供了损耗平衡和掉电保护;
NFS,网络文件系统;
Initrd = Initial RAM Disk
最开始时, 放在RAM中的最小化根文件系统; 可以用于执行复杂的初始化脚本; 也可用于加载私有模块;
制作过程:
mkdir /mnt/initrd
dd if=/dev/zero of=initrd.img bs=1k count=2048
mkfs.ext2 -F initrd.img
mount -o loop initrd.img /mnt/initrd
在目录/mnt/initrd中安装buzybox,拷贝所需的模块,编写linuxrc脚本;
umount /mnt/initrd
gzip -best -c initrd.img>initrd
启动相关的配置文件:
/etc/inittab
/etc/rcS
/etc/fstab
建立NFS:
PC上===>
添加/etc/exports文件:
/home/rootfs 192.168.0.202/32(rw,insecure,sync,no_wdelay,no_root_squash);
启动NFS服务器: /etc/init.d/nfs restart
目标板===>
mkdir /mnt/rootfs; mkdir /mnt/initrd
modprobe nfs;
mount -o nolock,hard,intr -t nfs 192.168.0.200:$rootfs /mnt/rootfs
内核启动时命令行参数:
root=/dev/ram0 rw init=/linuxrc console=ttyS0,115200n8 console=tty0 ramdisk_size=8192 cachepolicy=writethrough
root=/dev/nfs ip=bootp console=ttyS0,115200n8
嵌入式linux系统的构成: boot loader(引导装载器), 内核, 根文件系统;
bootloader的作用,不仅局限于运行内核,还有些扩展功能:
通讯功能,FLASH相关功能,用户接口程序;
make zImage, 编译一个使用gzip算法压缩的内核映象zImage, 另也生成非压缩映象vmlinux;
make bzImage, 'big zImage', 编译一个使用gzip算法,但确保生成的较大内核可以工作;
生成的目标放在arch/arm/boot目录下;
应用程序开发:
uClinux下运行的程序: arm-elf-gcc main.c -elf2flt -o hello
linux下运行的程序: arm-linux-gcc main.c -o hello
将应用程序内嵌到内核中:
uClinux-dist/user/myapp/Makefile改动;
uClinux-dist/user/Makefile添加一行;
uClinux-dist/config/config.in增加选项;
实验:用网络下载uclinux内核
开发板(minicom)===>设置好IP,启动load(开启了tftp-server);
PC===>tftp -v 192.168.0.101(目标板IP),binary,put image.ram,quit;
开发板(minicom)===>接收内核完毕,提示是否运行,选Y,运行内核,启动成功,出现uclinux的shell;
实验:uclinux应用程序开发
开发板===>配置好IP,确保与PC连接正常,进入/tmp(也即/var/tmp)目录;
PC===>安装arm-elf-tools交叉编译器,编辑用户C程序,用命令arm-elf-gcc -elf2flt hello.c -o hello编译;
开发板===>用FTP登陆PC,找到hello文件,切换到binary,get hello,quit,查看当前目录/var/tmp下的hello文件,chmod 755 hello, ./hello,运行成功;
实验:uClinux Kernel配置和编译
PC===>
下载安装GNU Toolchain(arm-elf-tools-20030314.sh)
下载解压uClinux-dist-20040408.tar.gz,进入uClinux-dist目录,
修改linux-2.4.x/arch/armnommu/vmlinux-armv.lds.in,在65行处添加:
/*new part*/
romfs_data = .;
romfs.o
romfs_data_end = .;
注意:等号两边有空格,但.;之间没空格;
修改vendors/Samsung/4510B/Makefile文件,在image目标的第三行,增加一条语句:
{前一条语句:genromfs -v -V "ROMdisk" -f $(ROMFSIMG) -d $(ROMFSDIR) }
arm-elf-ld -r -o $(ROOTDIR)/$(LINUXDIR)/romfs.o -b binary $(ROMFSIMG)
设置内核配置文件,以适应开发板,make menuconfig,硬件设置,Kernel/Library/Defaults Selection库设置;
make dep; make lib_only;
vi config/.config,注释掉25行的# CONFIG_USER_OLD_PASSWORDS=y,防止在下一步出现undefined reference to 'crypt_old'的错误,若已经编译过,需执行rm -rf user/boa/src/ *.o;
make user_only;
make romfs; make; make image;(若报错romfs.o文件没找到, 重复这三步)
也可考虑这样顺序执行:make romfs; make image; make;
此时得到linux-2.4.x/linux和images/image.bin;
用下面命令把linux(elf格式)转成image.ram(bin格式):
arm-elf-objcopy -O binary -R .note -R .comment -S linux image.ram;
实验:uClinux应用程序开发
PC===>cd uClinux-dist/user, mkdir myapp, cd myapp, vi demo.c, 按照固定模式编制Makefile;
在uClinux-dist/user/Makefile的324行添加一行:dir_$(CONFIG_USER_MYAPP_DEMO) += myapp;
vi uClinux-dist/config/config.in,在最后添加:
########################################
mainmenu_option next_comment
comment 'My New Application'
bool 'demo' CONFIG_USER_MYAPP_DEMO
comment "My New Application"
endmenu
########################################
重新编译内核和文件系统,选择Customize Vendor/User Settings,保存退出,出现My New Application选项,选demo;
(对于已经成功编译过的内核)make user_only; make romfs; make;
(修改过应用程序后)make user_only; make romfs; vi roomfs/etc/rc; make image(重新生成romfs.o); make linux(不需要make);
制作image.ram, 下载到开发板, 运行linux, cd bin, ./demo运行(用户程序编译进根文件系统的bin目录); 实验成功;
;boot_a.s
;/****************************************Copyright (c)**************************************************
;** Guangzou ZLG-MCU Development Co.,LTD.
;** graduate school
;**
http://www.zlgmcu.com;**
;**--------------File Info-------------------------------------------------------------------------------
;** File name: Boot_a.s
;** Last modified Date: 2005-02-24
;** Last Version: 1.0
;** Descriptions: zlg/boot v1.0(change all regs but not spsr)
;**
;**------------------------------------------------------------------------------------------------------
;** Created by: Chenmingji
;** Created date: 2005-02-24
;** Version: 1.0
;** Descriptions: The original version
;**
;**------------------------------------------------------------------------------------------------------
;** Modified by:
;** Modified date:
;** Version:
;** Descriptions:
;**
;********************************************************************************************************/
NoInt EQU 0x80
USR32Mode EQU 0x10
FIQ32Mode EQU 0x11
IRQ32Mode EQU 0x12
SVC32Mode EQU 0x13
ABT32Mode EQU 0x17
UND32Mode EQU 0x1b
SYS32Mode EQU 0x1f
;T_bit用于检测进入异常前cpu是否处于THUMB状态
T_bit EQU 0x20
;The imported labels
;引入的外部标号在这声明
IMPORT Regs
;The emported labels
;给外部使用的标号在这声明
EXPORT Start_Boot
CODE32
AREA Boot_a,CODE,READONLY
ENTRY
;取数据中止
Start_Boot
MSR CPSR_c, #(NoInt | ABT32Mode) ; 切换到取数据中止模式
LDR SP, =Regs
LDMFD SP!, {R3}
MSR SPSR_cxsf, R3
MOV R1, SP
MSR CPSR_c, #(NoInt | SYS32Mode) ; 切换到SYS模式
LDMFD R1!, {SP, LR} ; 恢复UND模式SP, LR
MSR CPSR_c, #(NoInt | UND32Mode) ; 切换到UND模式
LDMFD R1!, {SP, LR} ; 恢复UND模式SP, LR
MSR CPSR_c, #(NoInt | SVC32Mode) ; 切换到SVC模式
LDMFD R1!, {SP, LR} ; 恢复SVC模式SP, LR
MSR CPSR_c, #(NoInt | IRQ32Mode) ; 切换到IRQ模式
LDMFD R1!, {SP, LR} ; 恢复IRQ模式SP, LR
MSR CPSR_c, #(NoInt | FIQ32Mode) ; 切换到FIQ模式
LDMFD R1!, {R8-LR} ; 恢复FIQ模式R8-LR
MSR CPSR_c, #(NoInt | ABT32Mode) ; 切换到取数据中止模式
MOV SP, R1
LDMFD SP, {R0-R15}^
END
;/*********************************************************************************************************
;** End Of File
;********************************************************************************************************/
/*boot.h*/
/****************************************Copyright (c)**************************************************
** Guangzou ZLG-MCU Development Co.,LTD.
** graduate school
**
http://www.zlgmcu.com**
**--------------File Info-------------------------------------------------------------------------------
** File Name: boot.h
** Last modified Date: 2004-09-17
** Last Version: 1.0
** Descriptions: zlg/boot v1.0
**
**------------------------------------------------------------------------------------------------------
** Created By: Chenmingji
** Created date: 2004-09-17
** Version: 1.0
** Descriptions: First version
**
**------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Descriptions:
**
********************************************************************************************************/
#ifndef __BOOT_H
#define __BOOT_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef IN_BOOT
/*********************************************************************************************************
** Function name: Boot
** Descriptions: read a:\zlg_boot.ini ane execute it
** Input:none
**
** Output: none
**
** Created by: chenmingji
** Created Date: 2005-02-24
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
extern void Boot(char *file);
#endif
#ifdef __cplusplus
}
#endif
#endif
/*********************************************************************************************************
** End Of File
********************************************************************************************************/
/*boot.c*/
/****************************************Copyright (c)**************************************************
** Guangzou ZLG-MCU Development Co.,LTD.
** graduate school
**
http://www.zlgmcu.com**
**--------------File Info-------------------------------------------------------------------------------
** File name: boot.c
** Last modified Date: 2005-02-24
** Last Version: 1.0
** Descriptions: zlg/boot v1.0
**
**------------------------------------------------------------------------------------------------------
** Created by: Chenmingji
** Created date: 2005-02-24
** Version: 1.0
** Descriptions: The original version
**
**------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Descriptions:
**
********************************************************************************************************/
#define IN_BOOT
#include "config.h"
static uint8 Cmdload(char *Parameter, uint8 PLen);
static uint8 CmdSet(char *Parameter, uint8 PLen);
static uint8 CmdRun(char *Parameter, uint8 PLen);
static uint8 CmdSfr(char *Parameter, uint8 PLen);
static uint8 CmdSfrh(char *Parameter, uint8 PLen);
static uint8 CmdSfrb(char *Parameter, uint8 PLen);
#define REG_CPSR 0
#define USR_R13 1
#define USR_R14 2
#define UND_R13 3
#define UND_R14 4
#define SVC_R13 5
#define SVC_R14 6
#define IRQ_R13 7
#define IRQ_R14 8
#define FIQ_R8 9
#define FIQ_R9 10
#define FIQ_R10 11
#define FIQ_R11 12
#define FIQ_R12 13
#define FIQ_R13 14
#define FIQ_R14 15
#define USR_R0 16
#define USR_R1 17
#define USR_R2 18
#define USR_R3 19
#define USR_R4 20
#define USR_R5 21
#define USR_R6 22
#define USR_R7 23
#define USR_R8 24
#define USR_R9 25
#define USR_R10 26
#define USR_R11 27
#define USR_R12 28
#define ABT_R13 29
#define ABT_R14 30
#define PC_REG 31
uint32 Regs[32];
typedef struct
{
char *RegName;
uint8 Index;
}_REG;
const static _REG RegTable[] =
{
{"CPSR", REG_CPSR},
{"R0", USR_R0},
{"R1", USR_R1},
{"R2", USR_R2},
{"R3", USR_R3},
{"R4", USR_R4},
{"R5", USR_R5},
{"R6", USR_R6},
{"R7", USR_R7},
{"R8", USR_R8},
{"R9", USR_R9},
{"R10", USR_R10},
{"R11", USR_R11},
{"R12", USR_R12},
{"R13", USR_R13},
{"R14", USR_R14},
{"R15", PC_REG},
{"SP", USR_R13},
{"LR", USR_R14},
{"PC", PC_REG},
{"R13_UND", UND_R13},
{"R14_UND", UND_R14},
{"SP_UND", UND_R13},
{"LR_UND", UND_R14},
{"R13_SVC", SVC_R13},
{"R14_SVC", SVC_R14},
{"SP_SVC", SVC_R13},
{"LR_SVC", SVC_R14},
{"R13_IRQ", IRQ_R13},
{"R14_IRQ", IRQ_R14},
{"SP_IRQ", IRQ_R13},
{"LR_IRQ", IRQ_R14},
{"R13_ABT", ABT_R13},
{"R14_ABT", ABT_R14},
{"SP_ABT", ABT_R13},
{"LR_ABT", ABT_R14},
{"R8_FIQ", FIQ_R8},
{"R9_FIQ", FIQ_R9},
{"R10_FIQ", FIQ_R10},
{"R11_FIQ", FIQ_R11},
{"R12_FIQ", FIQ_R12},
{"R13_FIQ", FIQ_R13},
{"R14_FIQ", FIQ_R14},
{"SP_FIQ", FIQ_R13},
{"LR_FIQ", FIQ_R14},
{NULL, 0}
};
typedef struct
{
char *CmdName;
uint8 (* Cmd)(char *Parameter, uint8 PLen);
}_CMD;
const static _CMD CmdData[] =
{
{"LOAD", Cmdload},
{"RUN", CmdRun},
{"SET", CmdSet},
{"SFR", CmdSfr},
{"SFRW", CmdSfr},
{"SFRH", CmdSfrh},
{"SFRB", CmdSfrb},
{NULL, NULL}
};
/*********************************************************************************************************
** Function name: Cmdload
** Descriptions: load data in ram
** Input:Parameter: Parameter string
** PLen: Parameter string length
** Output: TRUE: OK
** FALSE: NOT OK
** Created by: chenmingji
** Created Date: 2005-02-24
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
static uint8 Cmdload(char *Parameter, uint8 PLen)
{
HANDLE Handle;
uint32 Addr, Length;
char Ch;
if (PLen < 1)
{
return FALSE;
}
PLen--;
Parameter++;
sscanf(Parameter, "0X%X", &Addr);
if (Addr >= BOTTOM_OF_USR)
{
return FALSE;
}
Length = BOTTOM_OF_USR - Addr;
do
{
Ch = *Parameter++;
if (Ch == ' ')
{
break;
}
}while (--PLen != 0);
if (PLen == 0)
{
return FALSE;
}
Handle = FileOpen(Parameter, "r");
if (Handle == Not_Open_FILE)
{
return FALSE;
}
FileRead((void *)Addr, Length, Handle);
FileClose(Handle);
return TRUE;
}
/*********************************************************************************************************
** Function name: CmdSet
** Descriptions: Set register cmd
** Input:Parameter: Parameter string
** PLen: Parameter string length
** Output: TRUE: OK
** FALSE: NOT OK
** Created by: chenmingji
** Created Date: 2005-02-24
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
static uint8 CmdSet(char *Parameter, uint8 PLen)
{
const _REG *reg;
char *cp1, *cp2;
char temp;
unsigned int i;
uint32 Data;
if (PLen < 1)
{
return FALSE;
}
Parameter++;
PLen--;
reg = RegTable;
while (reg->RegName != NULL)
{
cp1 = reg->RegName;
cp2 = Parameter;
i = PLen;
do
{
temp = *cp2;
if (temp == ' ' || temp == '=')
{
cp2++;
sscanf(cp2, "0X%X", &Data);
Regs[reg->Index] = Data;
return TRUE;
}
if (temp == 0)
{
break;
}
if (*cp1 == temp)
{
cp1++;
cp2++;
continue;
}
break;
} while (--i != 0);
reg++;
}
return FALSE;
}
/*********************************************************************************************************
** Function name: CmdSfr
** Descriptions: Set 32bit register cmd
** Input:Parameter: Parameter string
** PLen: Parameter string length
** Output: TRUE: OK
** FALSE: NOT OK
** Created by: chenmingji
** Created Date: 2005-02-24
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
static uint8 CmdSfr(char *Parameter, uint8 PLen)
{
uint32 sfr, data;
char Ch;
if (PLen < 1)
{
return FALSE;
}
PLen--;
Parameter++;
sscanf(Parameter, "0X%X", &sfr);
do
{
Ch = *Parameter++;
if (Ch == ' ')
{
break;
}
}while (--PLen != 0);
if (PLen == 0)
{
return FALSE;
}
sscanf(Parameter, "0X%X", &data);
((volatile uint32 *)sfr)[0] = data;
return TRUE;
}
/*********************************************************************************************************
** Function name: CmdSfrh
** Descriptions: Set 16bit register cmd
** Input:Parameter: Parameter string
** PLen: Parameter string length
** Output: TRUE: OK
** FALSE: NOT OK
** Created by: chenmingji
** Created Date: 2005-02-24
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
static uint8 CmdSfrh(char *Parameter, uint8 PLen)
{
uint32 sfr, data;
char Ch;
if (PLen < 1)
{
return FALSE;
}
PLen--;
Parameter++;
sscanf(Parameter, "0X%X", &sfr);
do
{
Ch = *Parameter++;
if (Ch == ' ')
{
break;
}
}while (--PLen != 0);
if (PLen == 0)
{
return FALSE;
}
sscanf(Parameter, "0X%X", &data);
((volatile uint16 *)sfr)[0] = data;
return TRUE;
}
/*********************************************************************************************************
** Function name: CmdSfrb
** Descriptions: Set 8bit register cmd
** Input:Parameter: Parameter string
** PLen: Parameter string length
** Output: TRUE: OK
** FALSE: NOT OK
** Created by: chenmingji
** Created Date: 2005-02-24
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
static uint8 CmdSfrb(char *Parameter, uint8 PLen)
{
uint32 sfr, data;
char Ch;
if (PLen < 1)
{
return FALSE;
}
PLen--;
Parameter++;
sscanf(Parameter, "0X%X", &sfr);
do
{
Ch = *Parameter++;
if (Ch == ' ')
{
break;
}
}while (--PLen != 0);
if (PLen == 0)
{
return FALSE;
}
sscanf(Parameter, "0X%X", &data);
((volatile uint8 *)sfr)[0] = data;
return TRUE;
}
/*********************************************************************************************************
** Function name: CmdRun
** Descriptions: run load code
** Input:Parameter: Parameter string
** PLen: Parameter string length
** Output: TRUE: OK
** FALSE: NOT OK
** Created by: chenmingji
** Created Date: 2005-02-24
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
static uint8 CmdRun(char *Parameter, uint8 PLen)
{
extern uint8 Start_Boot(char *Parameter, uint8 PLen);
ChangeToSYSMode();
Start_Boot(Parameter, PLen);
return 0;
}
/*********************************************************************************************************
** Function name: Readline
** Descriptions: Read line from file
** Input:Buf: store read data
** Handle: file Handle
** Output: string length
**
** Created by: chenmingji
** Created Date: 2005-02-24
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
unsigned int Readline(char *Buf, HANDLE Handle)
{
unsigned int length;
uint8 c, c1;
length = 0;
c1 = '\r' + 1;
while(FileEof(Handle) == 0)
{
if (FileGetCh(&c, Handle) != RETURN_OK)
{
*Buf = 0;
break;
}
if (c >= 'a' && c <= 'z' )
{
c = c + 'A' - 'a';
}
*Buf++ = c;
if (c1 == '\r')
if (c == '\n')
{
length--;
Buf -= 2;
*Buf = 0;
break;
}
length++;
c1 = c;
}
*Buf = 0;
return length;
}
/*********************************************************************************************************
** Function name: Boot
** Descriptions: read a:\zlg_boot.ini and execute it
** Input:none
**
** Output: none
**
** Created by: chenmingji
** Created Date: 2005-02-24
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void Boot(char *file)
{
unsigned int length, i;
const _CMD *cmd;
HANDLE Handle;
char Buf[512];
char *cp1, *cp2;
char temp;
if (file == NULL || *file == 0)
{
file = "a:\\zlg_boot.ini";
}
for (i = 0; i < 32; i++)
{
Regs[i] = 0;
}
Regs[0] = 0xd3;
OS_ENTER_CRITICAL();
Handle = FileOpen(file, "r");
if (Handle == Not_Open_FILE)
{
Reset();
}
while (1)
{
Next:
length = Readline(Buf, Handle);
if (length != 0)
{
cmd = CmdData;
while (cmd->CmdName != NULL)
{
i = length + 1;
cp1 = cmd->CmdName;
cp2 = Buf;
do
{
temp = *cp2;
if (temp == ' ' || temp == 0)
{
if (cmd->Cmd != NULL)
{
cmd->Cmd(cp2, length);
}
goto Next;
}
if (*cp1 == temp)
{
cp1++;
cp2++;
continue;
}
break;
} while (--i != 0);
cmd++;
}
}
else
{
Reset();
}
}
}
/*********************************************************************************************************
** End Of File
********************************************************************************************************/
未收入的重要概念及知识点:
ARM指令条件码,ARM汇编器所支持的伪指令, ARM编程, 汇编程序结构, 汇编与C/C++混合编程;
中断按钮实验(中断处理函数的调用流程),ADS自动执行bat文件,EXT2文件系统详解;
Bootloader程序框架, 标准linux的ARM移植,uClinux的ARM移植,GDBSERVER调试办法;