手上有块ZLG的SMARTARM2200(LPC2220)的板子,其中的例子都是基于ADS的,想都移植到IAR上去,同时好好研究下IAR,ARM,uCOSII。我用的IAR版本是IAR EWARM5.3.从Micrium网站上下了uCOSII LPC2148的例子作为模板,修改好的工程可以从http://download.csdn.net/source/1485629上得到。这个工程只含有uCOS及其实例任务,FS,TCP-IP,GUI什么的之后会陆续加入,文章的描述可能与此有差异,如有疑问欢迎与我交流shevsten#gmail.com(#换为@)
启动文件:cstartup.s ;;********************************************************************************************************; EXCEPTION VECTORS & STARTUP CODE;; File : cstartup.s; For : ARM7 or ARM9; Toolchain : IAR EWARM V5.10 and higher;********************************************************************************************************;;开始进行了一些宏定义,供下面的代码调用,如ARM的7种模式对应寄存器值还有LPC2220寄存器地址(之后会用到);********************************************************************************************************; MACROS AND DEFINIITIONS;********************************************************************************************************
; Mode, correspords to bits 0-5 in CPSRMODE_BITS DEFINE 0x1F ; Bit mask for mode bits in CPSRUSR_MODE DEFINE 0x10 ; User modeFIQ_MODE DEFINE 0x11 ; Fast Interrupt Request modeIRQ_MODE DEFINE 0x12 ; Interrupt Request modeSVC_MODE DEFINE 0x13 ; Supervisor modeABT_MODE DEFINE 0x17 ; Abort modeUND_MODE DEFINE 0x1B ; Undefined Instruction modeSYS_MODE DEFINE 0x1F ; System mode ;Extenal bus controller Definitions PINSEL2 DEFINE 0xE002C014BCFG0 DEFINE 0xFFE00000BCFG1 DEFINE 0xFFE00004BCFG2 DEFINE 0xFFE00008BCFG3 DEFINE 0xFFE0000C
;这边使用了DEFINE这个关键字,和EQU相比,其作用域更大,相当于全局的。EQU只在定义的模块内有效,而DEFINE定义的宏在其他文件中同样有效,详情请参考EWARM_AssemblerReference.ENU.pdf。
;ARM异常向量;********************************************************************************************************; ARM EXCEPTION VECTORS;********************************************************************************************************
;SECTION-段声明(也可用RSEG) .intvec-复位及中断向量 CODE-代码段 ;NOROOT表示如果这个段里的标号没引用就被linker舍弃,ROOT则一定不舍弃;如果注释掉PUBLIC __vector_0x14,那么编译后在map文件里就看不到第二行了;__vector 0x80000000 Code Gb cstartup.o [1];__vector_0x14 0x80000014 Code Gb cstartup.o [1];(2)表示字节对齐数,为2的幂,(2)表示4字节对齐,(3)表示8字节对齐
SECTION .intvec:CODE:NOROOT(2)
;声明可以被外部引用的标号 PUBLIC __vector PUBLIC __iar_program_start PUBLIC __vector_0x14;引用外部声明的标号,这些标号定义在os_cpu_a.asm(uCOSII移植文件)中 IMPORT OS_CPU_ARM_ExceptUndefInstrHndlr IMPORT OS_CPU_ARM_ExceptSwiHndlr IMPORT OS_CPU_ARM_ExceptPrefetchAbortHndlr IMPORT OS_CPU_ARM_ExceptDataAbortHndlr IMPORT OS_CPU_ARM_ExceptIrqHndlr IMPORT OS_CPU_ARM_ExceptFiqHndlr
;告诉编译器为arm指令,也可以用CODE32
ARM
;异常向量表
__vector:
;绝对跳转,跳转到相应的异常处理程序,PC总是指向当前指令的下两条指令的地址,即PC的值为当前指令的地址值加8个字节。;所以LDR PC, [PC,#24]跳转到24+8=32字节后,第一行LDR PC, [PC,#24]就是跳转到__iar_program_start(相当于reset_handler) LDR PC, [PC,#24] ; Absolute jump can reach 4 GByte LDR PC, [PC,#24] ; Branch to undef_handler LDR PC, [PC,#24] ; Branch to swi_handler LDR PC, [PC,#24] ; Branch to prefetch_handler LDR PC, [PC,#24] ; Branch to data_handler__vector_0x14: DC32 0 ; Reserved LDR PC, [PC,#24] ; Branch to irq_handler LDR PC, [PC,#24] ; Branch to fiq_handler;DC32指的是定义32位的常量,同理还有DC16 DS32等数据类型 DC32 __iar_program_start DC32 OS_CPU_ARM_ExceptUndefInstrHndlr DC32 OS_CPU_ARM_ExceptSwiHndlr DC32 OS_CPU_ARM_ExceptPrefetchAbortHndlr DC32 OS_CPU_ARM_ExceptDataAbortHndlr DC32 0 DC32 OS_CPU_ARM_ExceptIrqHndlr DC32 OS_CPU_ARM_ExceptFiqHndlr
;********************************************************************************************************; LOW-LEVEL INITIALIZATION;********************************************************************************************************
;定义各种模式STACK,具体大小位置是由linker文件(相当于ADS中的分散加载)决定的,之后在详细介绍。这些STACK都定义在内部RAM中,以CSTACK为例,地址为0x40000040
SECTION FIQ_STACK:DATA:NOROOT(3) SECTION IRQ_STACK:DATA:NOROOT(3) SECTION SVC_STACK:DATA:NOROOT(3) SECTION ABT_STACK:DATA:NOROOT(3) SECTION UND_STACK:DATA:NOROOT(3) SECTION CSTACK:DATA:NOROOT(3);定义text代码段
SECTION text:CODE:NOROOT(2);强制__vector被引用,这样__vector就一定会被link了
REQUIRE __vector;引用外部C main函数 EXTERN ?main
;声明__iar_program_start和lowlevel_init标号 PUBLIC __iar_program_start PUBLIC lowlevel_init
;__iar_program_start内容,实际上就是系统复位后首先运行的代码
__iar_program_start:
;********************************************************************************************************; STACK POINTER INITIALIZATION;********************************************************************************************************
;初始化堆栈指针,就不详细描述了,主要就是对CPSR寄存器的操作,请参考ARM相关资料
MRS r0,cpsr ; Original PSR value BIC r0,r0,#MODE_BITS ; Clear the mode bits ORR r0,r0,#SVC_MODE ; Set SVC mode bits MSR cpsr_c,r0 ; Change the mode LDR sp,=SFE(SVC_STACK) ; End of SVC_STACK
BIC r0,r0,#MODE_BITS ; Clear the mode bits ORR r0,r0,#UND_MODE ; Set UND mode bits MSR cpsr_c,r0 ; Change the mode LDR sp,=SFE(UND_STACK) ; End of UND_STACK
BIC r0,r0,#MODE_BITS ; Clear the mode bits ORR r0,r0,#ABT_MODE ; Set ABT mode bits MSR cpsr_c,r0 ; Change the mode LDR sp,=SFE(ABT_STACK) ; End of ABT_STACK
BIC r0,r0,#MODE_BITS ; Clear the mode bits ORR r0,r0,#FIQ_MODE ; Set FIQ mode bits MSR cpsr_c,r0 ; Change the mode LDR sp,=SFE(FIQ_STACK) ; End of FIQ_STACK
BIC r0,r0,#MODE_BITS ; Clear the mode bits ORR r0,r0,#IRQ_MODE ; Set IRQ mode bits MSR cpsr_c,r0 ; Change the mode LDR sp,=SFE(IRQ_STACK) ; End of IRQ_STACK
BIC r0,r0,#MODE_BITS ; Clear the mode bits ORR r0,r0,#SYS_MODE ; Set System mode bits MSR cpsr_c,r0 ; Change the mode LDR sp,=SFE(CSTACK) ; End of CSTACK
;********************************************************************************************************; ADDITIONAL INITIALIZATION;********************************************************************************************************;这段初始化代码是我添加的,主要用来设置外部总线控制器,使外接的PSRAM等外设能正常工作,这样程序的readwrite段就能在RAM中运行了lowlevel_init:;Initial extenal bus controller. LDR R0, =PINSEL2 LDR R1, =0x0f814914 STR R1, [R0] ; 定义总线速度控制字 LDR R0, =BCFG0 LDR R1, =0x1000ffef STR R1, [R0] LDR R0, =BCFG1 LDR R1, =0x1000ffef STR R1, [R0] LDR R0, =BCFG3 LDR R1, =0x10001460 STR R1, [R0]
;********************************************************************************************************; CONTINUE TO ?main FOR ADDITIONAL INITIALIZATION;********************************************************************************************************
;跳转到C代码中的main函数
LDR r0,=?main BX r0
END