新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > 中断调用方式的ARM二次开发接口设计

中断调用方式的ARM二次开发接口设计

作者: 时间:2013-11-11 来源:网络 收藏
中断调用方式的ARM二次开发接口设计
图4 基于GNU工具链的开发模式图
  这里选用EABI版本,其基本操作命令如表1所列。CortexM3内核在地址0x00000000处存放一个向量表,向量表的第0个单元即地址0x00000000处存放的是堆栈顶的地址。CortexM3复位后即从该处取出数据,用以初始化MSP寄存器。向量表中的内容是32位的地址,这些地址是异常服务程序的入口地址,其中向量表的第一个单元即地址0x00000004处存放的是复位向量,也就是说CortexM3复位后,执行该向量(可理解为函数指针)指向的复位代码[4],代码如下:
__attribute__ ((section(".stackarea")))
static unsigned long pulStack[STACK_SIZE];
表1 win20080331 GNU 工具链的命令名称
中断调用方式的ARM二次开发接口设计
  这一句定义了一个pulStack数组,程序把这个数组作为了堆栈区。这条语句使用了__attribute__ ((section(".stackarea"))),把数组定位在了.stackarea这个段中。
typedef void (* pfnISR)(void);
__attribute__ ((section(".isr_vector")))
pfnISR VectorTable[]={
  (pfnISR)((unsigned long)pulStack + sizeof(pulStack)),
  ResetISR, //初始化堆栈
  NMIException, //复位句柄
  HardFaultException
};
  定义了一个数组VectorTable,作为向量表,定位于.isr_vector段中。通过链接脚本的控制,这个表将放在正文区的最开始,正文区又将从Flash开始存放,这样这个向量表就会起到存放在0x00000000开始的地址空间的效果。向量表的第0个单元是((unsigned long)pulStack+sizeof(pulStack)),这是数组的最后一个元素,因为CortexM3的堆栈是向下增长的。 向量表的第1个单元是ResetISR,它指向复位处理的代码也是整个程序的入口。本程序用它来实现启动代码的功能。
extern unsigned long _etext;
extern unsigned long _data;
extern unsigned long _edata;
extern unsigned long _bss;
extern unsigned long _ebss;
void ResetISR(void){
  unsigned long *pulSrc, *pulDest; //将保存于Flash中的初始化数据复制到SRAM中
  pulSrc=_etext;
  for(pulDest=_data; pulDest _edata;){
    *pulDest++=*pulSrc++;
    } // 将.bss段清零
  for(pulDest=_bss; pulDest_ebss;){
    *pulDest++=0;
  }
  main(); //最后调用main进入主程序
}
  这段代码用到了通过连接器赋值的几个变量值。_etext的值为正文段结尾处的地址,这之后的Flash空间是初始化的数据值,应该复制到SRAM中去。_data、_edata的值分别为数据段的开始和结尾处的地址,这部分应该是SRAM的地址。
  这部分代码的主要功能就是将保存于Flash中的初始化数据复制到SRAM中。然后将.bss段清零。最后调用main进入到我们的主程序。
3.2 Gcc二次开发接口设计中的关键技术点
(1) 连接器中SysCallLib地址的赋值
  连接器所做的工作简单地讲就是把所有目标文件相应的段连接到一起,并把目标文件中的“变量地址”、“函数地址”重新定位至正确的地址空间。通过在SECTIONS段中添加函数PROVIDE来声明函数地址,代码如下:
SECTIONS{
  PROVIDE(SysCallLib= 0x08005935);
  /*对于Cortex器件来说,启动代码的开始段VectorTable一般存储在.isr_vector段中*/
  .isr_vector :{
    . =ALIGN(4);
    KEEP(*(.isr_vector)) /*启动代码*/
    . = ALIGN(4);
  } >FLASH
}
(2) 用户程序Flash空间和SRAM空间的设定
  对于STM32系列芯片来说向量表、.text和.rodata就应该放到从0x08000000开始的Flash、.data、.bss和堆栈,就应该定位至从0x20000000开始的SRAM中。 但是对于用户程序,这些地址空间都需要重新设定。这些定位都可以通过链接脚本进行控制。
MEMORY{
  FLASH(rx) :
  ORIGIN=0x08000000, LENGTH=0x20000
  SRAM (rwx):
  ORIGIN=0x20000000, LENGTH=0x5000
}
  这些语句说明了Flash和SRAM开始的地址以及大小。只需要修改这里,ORIGIN的值即可改变用户程序存储的物理地址,通过修改LENGTH来修改空间大小。
(3) SysCallLib函数的编写
  SysCallLib函数在系统程序中进行编写,主要通过Case语句来实现跳转。形式如下:
  void SysCallLib(unsigned int Index, int *Ret, unsigned char Argc, unsigned int Arg[]);
  通过函数的参数来判断需要调用的系统函数。通过把SysCallLib函数作为过渡函数来为用户编写全新的API函数,用户使用起来更加方便,以LCD显示图片的函数为例,代码如下:
void mLCD_DisplayImage(unsigned char x, unsigned char y, const unsigned char *ImagePt, unsigned char ImageXSize, unsigned char ImageYSize ){
  int RetVal;
  unsigned int Arg[5];
  unsigned char Argc=5;
  Arg[0]=x;
  Arg[1]=y;
  Arg[2]=(unsigned int)ImagePt;
  Arg[3]=ImageXSize;
  Arg[4]=ImageYSize;
  SysCallLib(_SYSCALL_LCD_DIS_IMAGE, RetVal, Argc, Arg);
}
  用户只需调用简单的API函数mLCD_DisplayImage即可在LCD上显示图片。

c语言相关文章:c语言教程



上一页 1 2 下一页

关键词: ARM Funtion 中断

评论


相关推荐

技术专区

关闭