文章版权归原作者所有! (www.MegaEntry.com)
关键词:嵌入式系统;IAR;ARM;中断控制 引言 在项目开发,特别是中小型项目开发中,为了降低开发难度和开发成本,常选择不加载操作系统的方案。本文选择IAR嵌入式开发平台,在不加载操作系统的前提下,使用C语言(约95%)和汇编语言(约5%),对以ATMEL公司的AT91M40800芯片(ARM7TDMI内核)为主芯片的工业控制系统进行了软件开发。![]() |
![]() |
MegaEntry 网络社区与信息交流平台!
-Z(CODE)INTVEC=00-3F -DRAMSTART=2010000 -DRAMEND=207FFFF //RAM的地址段 -D_USR_STACK_SIZE=20000 //栈的大小 -D_SVC_STACK_SIZE=50 -D_FIQ_STACK_SIZE=100 -D_ABT_STACK_SIZE=50 -D_UND_STACK_SIZE=50 -D_IRQ_STACK_SIZE=1000 -D_HEAP_SIZE=2000 //堆的大小 启动代码设计 通常C语言是从main函数开始执行的,在没有操作系统的情况下,对main函数的初始化工作由启动代码来完成,包括硬件初始化、堆栈初始化、各种寄存器的初始化等。 在完成所有的初始化工作以后,用一条跳转指令进入C程序的main函数,程序的控制权转移到C程序。MegaEntry 网络社区与信息交流平台!
驱动程序设计 系统的软件框架如图2所示。驱动程序包括设备驱动程序、中断程序以及中断服务程序。首先以Flash驱动设计为例。根据Flash的Datasheet及硬件设计,有以下定义: #define FLASH_BASE ((volatile USHORT *)(0x01000000)) /*FLASH的基地址*/ /*定义flash的操作代码*/ #define FLASH_SEQ_ADD1 (0x5555) #define FLASH_SEQ_ADD2 (0x2AAA) #define FLASH_CODE1 ((USHORT)(0xAA)) #define FLASH_CODE2 ((USHORT)(0x55)) #define ID_IN_CODE ((USHORT)(0x90)) #define ID_OUT_CODE ((USHORT)(0xF0)) #define WRITE_CODE ((USHORT)(0xA0)) #define CHIP_ERASE_CODE ((USHORT)(0x10)) 然后编写FLASH功能函数。下面的函数用于验证FLASH的设备ID号: -ramfunc-farfunc BOOL FLASH_Test(void) {MegaEntry 网络社区与信息交流平台!
//输入命令序列,manuf_code表示生产编号,device_code表示设备编号 USHORT manuf_code,device_ code; *(FLASH_BASE + FLASH_ SEQ_ADD1) = FLASH_CODE1; *(FLASH_BASE + FLASH_ SEQ_ADD2) = FLASH_CODE2; *(FLASH_BASE + FLASH_ SEQ_ADD1) = ID_IN_CODE; //读取生产编号和设备编号 manuf_code = *FLASH_BASE ; device_code = *(FLASH_BASE + 1) ; //退出产品认证模式 *(FLASH_BASE + FLASH_ SEQ_ADD1) = ID_OUT_CODE; //判断读出的生产编号和设备编号是否正确 return ((manuf_code== 0x001f)&&(device_code==0x00c0)); } 中断发生时,ARM内核运行状态会由一般模式(System & User)进入其它几种模式(包括FIQ、IRQ等),因此需要保护正在运行的现场(r0~r12通用寄存器),同时将ARM状态寄存器(CPSR和SPSR)入栈。中断程序使用汇编语言保护寄存器,而中断服务程序可以使用C语言编写。这里以控制步进电机运动的定时器中断为例: tc0_handler stmfd sp!, {r14}MegaEntry 网络社区与信息交流平台!
;保护寄存器入栈 mrs r14, SPSR stmfd sp!, {r14} mrs r14, CPSR stmfd sp!, {r0-r12,r14} IMPORT Interrupt_Tc0 ldr r0,=Interrupt_Tc0 ;此处跳转进入C语言中断服务程序Interrupt_Tc0( ) mov lr,pc bx r0 IntExit ;中断服务程序完毕 ldmia sp!,{r0-r12,r14} ;恢复现场 msr CPSR_cxsf, r14 ldmia sp!,{r14}文章版权归原作者所有! (www.MegaEntry.com)
msr SPSR_cxsf,r14 ldmia sp!, {r14} subs pc,lr,#4 值得注意的是,ARM的除法运算采用软件除法方式,会用到r14寄存器,所以也必须加以保护,在中断服务程序完毕后恢复现场,将寄存器依次出栈。 结语 在本系统的开发过程中有如下体会: 1、尽量少用占用大量存储空间的变量(如int buffer[4096]),系统开销太大,可能造成系统崩溃。 2、慎重使用malloc()这样的内存分配函数。如果使用,一定要在使用完毕后调用free()函数释放内存空间,否则容易造成内存泄漏,甚至系统崩溃。 3、要注意IAR编译器的所有警告信息,仔细查看警告信息的意义。 4、一些经常调用且需要快速处理的模块,考虑使用汇编完成。 5、生成 Release版本目标代码时,Release目录下的exe目录内即为目标文件,而List目录内的*.map文件包含了目标文件内存分配的具体情况,可以根据里面的信息判断内存分配是否存在问题。 按照以上开发方式开发出的某款工控产品,经过了严格测试后,已经推向市场,其可靠性和稳定性均得到了验证