s12x中断

来源:互联网 发布:mac彻底删除adobe软件 编辑:程序博客网 时间:2024/05/22 05:04


中断是MCU实时地处理内部或外部事件的一种机制。当某种内部或外部事件发生时,中断系统将迫使CPU暂停正在执行的程序,转而去进行中断中断事件的处理,中断处理完毕后,又返回被中断的程序处,继续执行下去。中断处理的过程一般为关中断(在此中断处理完成前,不处理其他中断)、保护现场、执行中断服务程序、恢复现场、开中断等。在S12X系列的微控制器中都有一个XINT模块,该模块主要用于解析中断请求的优先级并且将中断向量交给CPU(对于S12XS系列而言只有CPU,其他如XE系列还有XGATE,可以完成中断的处理)执行。

S12X 系列将保留现有16位 HCS12 MCU 系列用户目前享有的低成本、低功耗、EMC和编码长度有效性的优势。S12X 系列基于增强的 HCS12 核心,旨在提供高达 25 MHz HCS12 的两到五倍的性能,同时保留与 HCS12 的 PIN 码和编码的高度兼容性。S12X 系列采用提升性能的 XGATE 模块。这种并行处理器模块利用增强 DMA 功能,通过提供外围模块、RAM 和 I/O 端口之间的高速数据处理与传输,卸载 CPU 的任务。XGATE 为 CPU 提供高达80 MIPS 的额外性能,可访问所有外围设备及 RAM 组件。

1.HCS12X 核心 。

- 16位 HCS12X CPU
    1. 向上与 HCS12 指令集兼容
    2. 与 HCS12 相同的中断堆栈和程序员模型
    3. 指令队列
    4. 增强的索引寻址
    5. 增强的指令集
- EBI(外部总线接口)
- MMC(模块映射控制)
- INT(中断控制器)
- DBG(用于监控 HCS12X CPU 和 XGATE 总线活动的调试模块)
- BDM(背景调试模式)

XGATE
- 外围协处理器
- 并行处理器模块通过提供外围模块、RAM 和 I/O 端口之间的高速数据处理和传输卸载 CPU 的任务
- Flash EEPROM、外围模块和 I/O 端口之间的数据传输

PIT 周期性中断定时器
- 四个具有独立暂停期限的定时器
- 暂停期限可在1和224总线时钟周期之间选择

CRG
- 低噪音/低功耗皮尔斯振荡器
- PLL
- COP监视器(Watchdog)
- 实时中断
- 时钟监控器
- 从停止模式快速唤醒

 

XINT相关配置寄存器如下:(1)中断向量基址寄存器(Interrupt Vector Base Register,IVBR)该寄存器用于设定中断向量地址的高位的值,例如位于0xFF10~0xFFFE中断向量的高位地址0xFF,那么IVBR寄存器的值就为0xFF。复位时为0xFF,是为了和先前的S12微控制器兼容。一般情况下这个寄存器不需要设置,只有当中断向量被移动到其他地址的时候,这个寄存器才需要设值。(2)中断请求配置地址寄存器(Interrupt Reqest Configuration Address,INT_CFADDR)这个寄存器和下面的INT_CFDATA0:78个数据寄存器配合使用,用来索引默认的128个中断向量地址。具体的使用会在5.4.4小节的中断编程实例中说明。(3)中断请求配置数据寄存器(Interrupt Reqest Configuration Data Registers,INT_CFDATA0-7INT_CFDATAA0~INT_CFDATA7:8个寄存器中的第7RQST用于设定中断是由CPU处理还是由XGATE处理。RQST=0CPU处理中断;RQST=1XGATE处理中断。对于XS128而言,因为没有XGATE,所以3不需要配置,默认为0。低3PRIOLVL[2:0]用于设定优先级,取值范围为0~7。在XS128中存在有8个等级,其中等级0表示中断关闭,等级1~7,优先级逐步提高,等级7的优先级是最高的。INT_CFDATA0:78个寄存器一次可以设定8个中断向量优先等级,而中断请求配置地址寄存器INT_CFADDR的高4INT_CFADDR[7:4]可以设定=16个地址,那么16*8=128。即INT_CFADDRINT_CFDATA0~7进行组合可以设定128个向量的优先级,这个刚好和S12X系列的中断向量表是对应的。采用这样的一个机制设定优先级是为了和S12系列保持兼容。

中断过程:CPU每执行完一条指令,若程序有开放某些中断及总中断,则CPU按照优先级次序查询中断标志位,若某个中断已发生,则相应该中断请求,当CPU接到一个许可的中断请求,它在相应中断之前要完成当前指令。中断顺序遵守与SWI指令相同的循环顺序,包括:1,在堆栈中保存CPU寄存器---CPU内的寄存器PCYXD CCR依次进栈。 2CCR中的I位置1,即自动关总中断,,防止其他中断进入。3,在目前等待的中断中取出最高优先级中断的中断向量,从相应的中断向量地址取出中断向量送给PC 4,执行中断服务例程,直到中断返回指令RTI,RTI指令从堆栈中依次弹出CCR D X Y PC CPU返回原来中断处继续执行。 5,若中断过程也允许相应新的中断,可在中断服务程序中用CLI指令开放中断。一般不建议这样做。

6HCS12X(简称“S12X”)系列单片机引入了一个协处理器,名为“XGATE”。与普通意义上的浮点协处理器不同,这个协处理器主要用来处理中断。如果采用协处理器来处理μC/OS-II时钟节拍的中断,那么主CPU无需频繁加载中断服务子程序,从而保证μC/OS-II内核的所有函数执行时间都为固定值。这样,μC/OS-II的实时性就得到了保证,还能以提高时钟节拍中断频率的方法提高应用系统定时的精度。

单片机中的协处理器:HCS12X系列单片机中的XGATE协处理器是精简指令集(RISC)结构的处理器,它的工作时钟频率是S12XCPU2倍。主CPU初始化系统时可决定使用或禁用XGATE。若使用,则XGATE在初始化后就独立地运行,并通过双端口RAMCPU交换数据,必要时向主CPU发中断请求。XGATE处理完所有的中断后进入休眠态,停止运行,直到下一次中断发生。XGATE比较适合响应的中断主要是加载频率高的中断,或不带通信缓冲区的I/O中断,例如SCI发送或接收中断、PWM输出中断等。而对于本身带发送、接收缓冲区的中断(如CAN中断、USB中断等),采用协处理器处理中断优势不明显。μC/OS-II的时钟节拍中断是一个频繁发生的中断,所以很适合采用XGATE来响应。以下重点介绍如何用XGATE协处理器响应μC/OS-II的时钟节拍中断。XGATE实现μC/OS-II的时钟节拍μC/OS-II的时钟节拍中断可以采用单片机的实时中断(RealTime InterruptRTI)来实现。当然也可以使用定时器中的计数器来产生时钟节拍,原理相同,方法近似。XGATE负责响应RTI中断,实现时钟节拍,并完成任务延时计数;在任务延时完成后,通知CPU进行任务调度。另外,XGATE还用来响应其他中断,在需要任务调度时通知CPU。主CPU则只负责运行任务(包括系统任务)和任务调度,只有在需要任务调度时才会加载中断服务子程序。使用XGATE来实现时钟节拍的具体设置步骤如下所述。
 RTI中断的控制权交给XGATE,为了将RTI中断交XGATE来处理,系统初始化时需要设置S12X单片机中RTI中断对应的中断控制寄存器。中断控制寄存器组成如下:S12X单片机中,每一个I/O中断都有一个中断控制寄存器与之对应。中断控制寄存器控制相应的中断是由S12X CPU响应还是由XGATE来响应,以及该中断的优先级。中断控制寄存器中,RQST位为1时,中断由XGATE来响应;为0时,中断由S12X CPU响应。为了使用XGATE来响应RTI中断,需要将RTI中断对应的中断控制寄存器的RQST位置1PRIOLVL[20]保存的是对应中断的优先级,值越大,对应中断的优先级越高。如果这3位均为0,那么对应中断会被禁用。设置中断控制寄存器可以调用编译器提供的一个函数ROUTE_INTERRUPT。这个函数需要的参数是对应中断的中断向量相对中断向量表基址(0xFF00)的偏移量,以及中断控制寄存器的值。设置RTI中断控制寄存器的代码如下:ROUTE_INTERRUPT(0xF0, 0x81);其中0xF0RTI中断向量相对中断向量表基址的偏移量,0x81是要设置的中断控制寄存器的值。

XGATE实现μC/OS-II的时钟节拍和S12X CPU实现任务调度,都需要访问与系统的任务控制块链表相关的变量,因此这些变量需要声明为XGATES12X CPU的共享变量。共享变量的声明需要加上“volatile”类型声明,并使用“#pragma”预处理命令将其放在共享内存中。 #pragma DATA_SEG SHARED_DATA
  OS_TCBvolatile*OSTCBCur;//当前任务控制块指针
  OS_TCBvolatile*OSTCBFreeList;//当前空闲任务控制块指针
  OS_TCBvolatile*OSTCBHighRdy;//当前最高优先级任务控制块指针
  OS_TCBvolatile*OSTCBList;//任务控制块链表入口指针
  #pragma DATA_SEG DEFAULT
  在XGATE的程序中,需要使用extern声明这些变量,具体语句如下:
  #pragma DATA_SEG SHARED_DATA
  externOS_TCBvolatile*OSTCBCur;//当前任务控制块指针
  externOS_TCBvolatile*OSTCBFreeList;//当前空闲任务控制块指针
  externOS_TCBvolatile*OSTCBHighRdy;//当前最高优先级任务控制块指针
  externOS_TCBvolatile*OSTCBList;//任务控制块链表入口指针
  #pragma DATA_SEG DEFAULT

XGATE与S12X CPU的指针变量变换
  因为XGATE的内存空间编址与S12X CPU的内存空间编址不一样,所以在指针变量共享时会存在问题。CPU的内存空间和XGATE的内存空间的差别如图1所示。
中断" o:spid="_x0000_i1026">中断" src="file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\msohtmlclip1\01\clip_image001.gif">
图1 S12X CPU与XGATE的内存空间分配对比
  从图1中可以看出,在S12X CPU的寻址空间中,0x1000~0x3FFF为RAM空间;而对XGATE来说,RAM空间的地址范围为0x8000~0xFFFF。如果XGATE的程序直接使用CPU的指针变量,则会导致XGATE访问地址空间0x1000~0x3FFF,该区域对于XGATE是Flash,从而出错。为了正确地共享指针变量,在XGATE中使用S12X CPU的指针变量时,需要对指针变量进行变换。S12X系列中不同单片机成员的地址分配可能有所不同。以MC9S12XDT512单片机为例,其内部共有8 KB非分页RAM,可全都设为S12X CPU和XGATE的共享内存。这8 KB RAM在S12X CPU中的地址为0x2000~0x3FFF;而在XGATE中的地址为0xE000~0xFFFF,地址偏差为0xC000。因此,在XGATE使用S12X CPU的指针变量时,将指针变量的值加偏移量0xC000,就可以在XGATE程序中正常使用。
  下面是XGATE程序中一个指针变量变换的代码:
  LDW R2,(R1,#0);R1中是指针变量的地址,将指针的值放到R2
  ADDH R2,#$C0;将R2增加0xC000
  MOV R1,R2;将变换后的指针放到R1
  LDB R3, (R1,#0);通过变换后的指针访问变量
  在XGATE协处理器中有8个寄存器,编译器使用其中的R1来传递参数,上面程序中的R2、R3是8个寄存器中的另外2个。
2.4 XGATE与S12X CPU的通信
  XGATE处理RTI中断时先完成指针变换,然后遍历μC/OS-II的所有任务控制块链表,对需要延时的任务进行延时计数器减1操作。若无需任务调度,则XGATE回到休眠态,直到响应下一次中断。仅当某任务延时计数器递减到零时,该任务进入就绪态,需要任务调度时才通知S12X CPU进行任务切换。
  在XGATE的中断服务子程序中,中断标志指令SIF用于向S12X CPU发出中断请求。该指令置位中断标志位,请求S12X CPU继续响应本次RTI中断。在XGATE的中断服务子程序中使用SIF指令的代码如下(其中R5是协处理器XGATE的8个寄存器之一):
  CMP R5,#0 ;R5保存进入就绪态且优先级比当前运行任务高的任务数目
  BEQ OUT;如果R5为0,那么无需任务调度
  SIF;如果R5不为0,那么需要通知S12XCPU进行任务调度
  OUT: RTI;中断子程序返回
  由于遍历任务控制块链表和各任务延时计数器减1的操作,以及无需任务调度的RTI中断响应都由XGATE完成了,S12X CPU只需要响应确实需要进行任务调度的RTI中断,使其中断服务子程序大大简化:
  void OSTickISR(void) {//S12X CPU时钟节拍中断服务
    OSIntEnter();//中断嵌套层数加1
    XGIF0_XGIF_78 = 1;//清XGATE中断
    OS_SAVE_SP();//保存当前任务栈
    OSIntExit();//中断嵌套层数减1并进行任务调度
    asm{ rti }//中断返回
  }
  这样,CPU的RTI中断服务子程序所要执行的代码是固定的,每次的运行时间也是固定值,因而μC/OS-II的实时性得到了确切的保证。
  S12X CPU和XGATE的程序流程如图2所示。
中断" o:spid="_x0000_i1025">中断" src="file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\msohtmlclip1\01\clip_image002.gif">
图2 S12X CPU和XGATE的程序流程
2.5 设置XGATE向量表
  为了使XGATE正常响应中断,需要把XGATE的RTI中断服务子程序地址写到XGATE的中断向量表中。XGATE的中断向量表的写法与CPU的中断向量写法类似,只是XGATE的中断子程序可代入一个参数,需要将这个参数也写入中断向量表。
  在XGATE中断向量表的确定位置,写入RTI中断服务子程序地址和参数变量,就可以使XGATE在响应RTI中断时进入RTI中断服务子程序。
  XGATE的中断向量表的写法如下:
  constXGATE_TableEntry XGATE_VectorTable[] = {
  {ErrorHandler, 0x09},//通道9,未使用
  {ErrorHandler, 0x0A}, //通道10,未使用
  …//其他通道,可以选择使用
  {RTI_Handler, (int)OSTCBList},//通道0x78,RTI中断子程和参数,将控制块链表作为参数
  {ErrorHandler, 0x79},//通道0x79,IRQ中断,未使用
  };
  其中,OSTCBList是XGATE响应RTI中断时需要带入的参数,这里这个参数是μC/OS-II任务控制块链表的首地址;XGATE_TableEntry是一个编译器自定义的结构体变量类型;XGATE_VectorTable[]是XGATE的中断向量表。写好XGATE的中断向量表后,使用XGATE实现μC/OS-II时钟节拍的设置过程就完成了。
3 效果测试与分析:S12X CPU的寻址空间中,0x10000x3FFFRAM空间;而对XGATE来说,RAM空间的地址范围为0x80000xFFFF。如果XGATE的程序直接使用CPU的指针变量,则会导致XGATE访问地址空间0x10000x3FFF,该区域对于XGATEFlash,从而出错。为了正确地共享指针变量,在XGATE中使用S12X CPU的指针变量时,需要对指针变量进行变换。S12X系列中不同单片机成员的地址分配可能有所不同。以MC9S12XDT512单片机为例,其内部共有8 KB非分页RAM,可全都设为S12X CPUXGATE的共享内存。这8 KB RAMS12X CPU中的地址为0x20000x3FFF;而在XGATE中的地址为0xE0000xFFFF,地址偏差为0xC000。因此,在XGATE使用S12X CPU的指针变量时,将指针变量的值加偏移量0xC000,就可以在XGATE程序中正常使用。

下面是XGATE程序中一个指针变量变换的代码:
  LDW R2,(R1,#0)R1中是指针变量的地址,将指针的值放到R2
  ADDH R2,#C0;将R2增加0xC000
  MOV R1,R2;将变换后的指针放到R1
  LDB R3, (R1,#0);通过变换后的指针访问变量
  在XGATE协处理器中有8个寄存器,编译器使用其中的R1来传递参数,上面程序中的R2R38个寄存器中的另外2个。XGATES12X CPU的通信:XGATE处理RTI中断时先完成指针变换,然后遍历μC/OS-II的所有任务控制块链表,对需要延时的任务进行延时计数器减1操作。若无需任务调度,则XGATE回到休眠态,直到响应下一次中断。仅当某任务延时计数器递减到零时,该任务进入就绪态,需要任务调度时才通知S12X CPU进行任务切换。XGATE的中断服务子程序中,中断标志指令SIF用于向S12X CPU发出中断请求。该指令置位中断标志位,S12X CPU继续响应本次RTI中断。在XGATE的中断服务子程序中使用SIF指令的代码如下(其中R5是协处理器XGATE8个寄存器之一):CMP R5,#0 R5保存进入就绪态且优先级比当前运行任务高的任务数目,BEQ OUT;如果R50,那么无需任务调度SIF;如果R5不为0,那么需要通知S12XCPU进行任务调度,OUT: RTI;中断子程序返回。由于遍历任务控制块链表和各任务延时计数器减1的操作,以及无需任务调度的RTI中断响应都由XGATE完成了,S12X CPU只需要响应确实需要进行任务调度的RTI中断,使其中断服务子程序大大简化:
void OSTickISR(void)

OSIntEnter();

XGIF0_XGIF_78 = 1;

OS_SAVE_SP    

OSIntExit();    

asm{ rti }

  }

CPURTI中断服务子程序所要执行的代码是固定的,每次的运行时间也是固定值,因而μC/OS-II的实时性得到了确切的保证。
S12X CPUXGATE的程序流程如图2所示。
CPURTI中断服务子程序所要执行的代码是固定的,每次的运行时间也是固定值,因而μC/OS-II的实时性得到了确切的保证。
  S12X CPUXGATE的程序流程如图2所示。2 S12X CPUXGATE的程序流程
2.5
设置XGATE向量表
  为了使XGATE正常响应中断,需要把XGATERTI中断服务子程序地址写到XGATE的中断向量表中。XGATE的中断向量表的写法与CPU的中断向量写法类似,只是XGATE的中断子程序可代入一个参数,需要将这个参数也写入中断向量表。
  在XGATE中断向量表的确定位置,写入RTI中断服务子程序地址和参数变量,就可以使XGATE在响应RTI中断时进入RTI中断服务子程序。
  
XGATE的中断向量表的写法如下:
  constXGATE_TableEntry XGATE_VectorTable[] = {
  {ErrorHandler, 0x09},//通道9,未使用
  {ErrorHandler, 0x0A}, //通道10,未使用
  …//其他通道,可以选择使用
  {RTI_Handler, (int)OSTCBList},//通道0x78RTI中断子程和参数,将控制块链表作为参数
  {ErrorHandler, 0x79},//通道0x79IRQ中断,未使用
  };
  其中,OSTCBListXGATE响应RTI中断时需要带入的参数,这里这个参数是μC/OS-II任务控制块链表的首地址;XGATE_TableEntry是一个编译器自定义的结构体变量类型;XGATE_VectorTable[]XGATE的中断向量表。写好XGATE的中断向量表后,使用XGATE实现μC/OS-II时钟节拍的设置过程就完成了。

原创粉丝点击