新闻中心

EEPW首页>嵌入式系统>设计应用> 三星SAM8系列S3C825A型单片机及其软件设计

三星SAM8系列S3C825A型单片机及其软件设计

作者: 时间:2011-12-30 来源:网络 收藏

  该开始环境集成有基于通用指令集的重定位宏汇编器,且内嵌C语言预处理程序,可接受所有的C语言宏定义。而集成的IAR XLINK连接器支持灵活的代码段和数据段重定位,并可根据重定位模块提供的信息将若干个应用程序所需要的可重定位代码模块文件组装成一个程序,从而产生可执行的目标代码。此外,环境中的C-SPY调试器具有多种测试分析功能,支持单步调试,控制程序运行到指定位置(Go to Cursor/Go to Label/Go to Address),调试返回(Go to Return)、实时跟踪变量、寄存器(Register Groups)、存储器(Memory)等,这些都在很大程序上提高了开发效率。

  3 混合编程的软件设计

  在对SAM8系列进行软件开发过程中,用C语言编程具有开发周期短、可读性强、可移植性好和修改方便等优点,但是C程序反汇编生成的汇编代码往往较长。若直接用汇编语言编程,虽然编制的程序较短,但开发周期长,修改也不方便,所以,较好的解决方法是把程序的框架或主体部分用C语言编写,而将执行效率要求较高的部分用汇编语言来编写。下面主要介绍针对SAM8系列进行混合编程的软件设计方法。

  3.1 IAR C语言编译器的函数参数传送规则

  IAR C语言编译器规定函数参数传递有2种方式,即寄存器传递和堆栈传递。传递顺序是从左至右,具体采用哪种方式传递取决于函数参数的类型。

  IAR C语言编译器把的寄存器分成2组,其中高速暂存器组(R10-R15)中的函数参数由左至右依次传入R15至R10,直至这些寄存器点满,而其余函数参加由堆栈来传递。由迂些寄存器是暂存器,用完就释放掉,所以应用过程中不用保护。第二组为普通寄存器(R1、R4-R9),这组寄存器主要用作寄存器变量和保存中间变量,应用过程不必须对其进行保护,但在C语言函数编写中可以不体现,而由编译器自动完成。

  当函数参数为以下2种类型时,应当选用堆栈方式传递:第一种是传递参数为struct或union大于4字节的参数类型。第二种是长度可变函数的未命名参数类型。

  函数参数通常放在由堆栈指针指定的位置为起始的主存储器中,被调用函数的参数则由左至右依次存放在被指定的堆栈中,当被调用函数返回调用函数时,堆栈自动清零,主存储器空间被释放,以供下次供传递函数使用。

  函数返回值可根据其类型放在R15或R15:R14寄存器对中。若返回值是struct或union类型,则返回R15中的值是存放返回结果的堆栈指针起始位置。

  C语言编译器也是编译中断函数时会自动保护所用到的寄存器(包括R10-R15),状态寄存器FLAGS的保护也是在中断处理过程中自动完成的。中断过程中用到的寄存器都使用PUSH Rn的指令进行保护,而采用POP Rn指令恢复。当用IRET指令自动恢复状态寄存器FLAGS时,可以从中断中返回。

  3.2 对汇编语言函数的约定

  对于一个可以被C语言函数调用的汇编程序来说,使用时必须满足以下3点:

  (1)符合C语言参数传递规则;

  (2)有PUBLIC函数入口标志;

  (3)在C语言函数中用extern声音为外部函数。

  参加传递规则和C语言函数一样,所不同的是,要在汇编语言函数编写过程中具体体现出来。

  4 应用实例

  明确了以上调用规则,混合编程就比较容易了,归纳起来有以下几点:

  (1)在C语言源文件中用“extern”关键字导入被汇编语言源文件导出的标号;

  (2)在汇编语言源文件用“PUBLIC”关键字把标号导出到C语言源文件;

  (3)在汇编语言中用“EXTERN”关键字导入被C语言函数源文件导出的关键字;

  (4)用C语言把标号导出给汇编语言,这一步不需要关键字;

  (5)把编辑好的C语言和汇编语言源文件导入设计系统,并用各自调用函数的指令调用。

  下面以笔者在校音器设计中用到的2个例子来具体说明。

  4.1 C语言和汇编语言相互调用

  在该例中,用C语言函数main()调用汇编语言函数get_rand()以得到一个随机数,接着,用汇编语言函数get_rand()调用C语言库函数rand()再得到一个整型机随机数,然后用调用C语言函数mult()的方法把这个随机值的高位乘以main()函数传递给自己的实参,同时把乘积值返回给main()参数。

/****C语言源程序****/#includeios3c825a.h>/*头文件*/extern unsigned char get_rand (unsigned char seed);/* 汇编语言原型声明*/void main(void)/*主函数*/{unsigned char seed;unsigned char value;/*定义变量*/WTCON=0xa0; /*关闭watch dog*/Seed=0x05;Value=get_rand(seed); /*调用汇编语言函数,得到一个随机数*/While(1); /*程序结束*/}/**加法子程序,供汇编语言调用**/unsigned char add(unsigned char x,unsigned chary){return (x+y);}/****C语言源程序结束 ****//****汇编语言源程序 ****/#include ios3c825a.h> ;头文件EXTERN rand ;C语言库函数EXTERN add ;用户自定义C函数PUBLIC get_rand ;导出函数名给C函数调用Get_rand:PUSH R9 ;普通C函数入栈保护LD R9,R15;C函数传递参数给R15,暂时存储在R9CALL rand ;调用C库函数得到一个随机数,作为add的第一实参,存储在R15LD R14,R9;C函数传递的参数,作为add的第二实参,存储在R14CALL add ;add返回的值存储在R15中POP R9 ;add出栈恢复寄存器内定RETEND/**** 汇编语言源程序结束 ****/

  4.2 汇编语言写中断服务程序

  为了提高系统响应速度,设计时往往要求中断服务程序的执行时间较短,执行速度较快。因此,最好的方法就是用汇编语言编写中断服务程序。但要注意以下2点:

  (1)中断函数不传递参数和返回结果;

  (2)中断过程中用到的寄存器都要进行保护。

  本例中用汇编语言编写看门狗定时器的中断服务程序,而用C语言编写主程序。

/****C语言主程序****/#includeios3c825a.h> /*头文件*/extern void in0(void); /*中断函数声明*/void main(void){CLKCON=0X98; /*开中断*/IMR=0X10; /*IRQ4使能*/WTCON=0X84;/*看门狗定时器设为0.25秒*/P2CONL=0X03; /*P2.0为输出*/IPH=0X00;IPL=0XD6; /*中断函数所对矢量位置*/CLKCON=0X18; /*关中断*/while(1);}/****C语言主程序结束****//****汇编语言编写的中断程序****/#include ios3c825a.h> ;头文件public 'int0' ;中断函数声音RSEG WATCHT:CODE:RROT (1),0X00D6 ;中断矢量在代码段中的绝对位置Int0:PUSH R1 ;寄存器保护LD R1,#01H ;给PORT2寄存器赋值,使连接P2.1的LED定时发头POP R1;寄存器恢复IRET;中断返回END/****汇编语言编写的中断程序逻辑****/

  5 结束语

  以上方法已经应用于笔者参与设计的校音器设计中并取得良好的效果。但也要注意调试过程中编译器选项的设置对程序运行结果有一定的影响,因此,对SAM8系统中不同的核,一定要选用不同的内核版本号,否则,寄存器传递的参数可能会错位,从而导致参数传递错误,给调试带来不便。


上一页 1 2 下一页

评论


相关推荐

技术专区

关闭