1 MCU对于异常/中断向量表和服务程序的存储结构
传统的MCU包含三种存储,ROM,RAM,Flash(Flash是泛指Non-volatile存储,包含eFlash,Nor flash,Nand flash,EEPROM,RAM等一些列存储)。这三类存储在MCU设计中负责不同的功能,ROM主要负责最初的程序烧写和第一级引导,Flash包含Bootloader和OS以及APP,RAM主要是运行过程中的堆栈,以及变量,数据等。 关于异常和中断,在8系列处理器中中断属于一种特殊的异常,所以经常会出现在一起描述,异常主要指的是CPU自身定义的一系列需要及时响应的事件,往往这些事件的产生会影响CPU的正常执行,比如说发生总线访问错误,执行非法指令等。异常的响应需要设置当前PSR上的EE位。异常在异常/中断向量表中使用0~31号。中断往往是系统中设备产生的事件,需要CPU及时处理,比如定时器中断,UART数据接收中断等,中断的响应需要设置当前PSR上的EE位,VIC的中断使能寄存器,设备的中断使能寄存器。中断在异常/中断向量表中使用32号之后,根据实际支持的中断数来确定表项的结尾。 本次介绍主要介绍和异常,中断相关的几种存储方式,在传统的处理器设计中,中断和异常是需要通过异常/中断向量表作为索引的,根据不同的应用场景会出现一张或者多张一场异常/中断向量表,下面就几种主要的场景做一下简单的分析:
1.1 异常/中断向量表仅存放在ROM中
此类应用场景往往比较简单,且程序相对固定,实际使用场景非常少,因为ROM本身的特性呈现出无法修改的属性,所以一旦异常/中断向量表确定之后,后续就无法进一步修改,程序开发需要根据这个异常/中断向量表中的地址作为异常服务程序和中断服务程序起始地址。异常/中断向量表根据VBR(vector base register)寄存器来实现索引,例如:芯片上电时,复位之后VBR默认为0,则此时异常/中断向量表默认指向0地址(一般为ROM起始地址),所以上电复位异常的入口,即程序入口地址就存放在0地址上,如下图的黄色部分Reset_handler。
1.2 异常/中断向量表存放在ROM和FLASH中
此类应用往往ROM功能比较简单,一般不需要再ROM程序中产生异常,异常/中断向量表主要实现复位异常。在程序进入到FLASH中之后可以由用户自定义异常/中断向量表和异常服务程序,优点是相对直接异常/中断向量表放在ROM中的会比较灵活,所有地址的修改只需要重新编译之后就可以实现,也可以通过程序直接注册,完成异常服务程序和异常/中断向量表的链接。 当需要两张或者以上的异常/中断向量表的时候,在向量表切换的时候需要通过维护VBR(vector base register)寄存器来完成两张异常/中断向量表的切换,例如:芯片上电时,复位之后VBR默认为0,则此时异常/中断向量表默认指向0地址(一般为ROM起始地址),所以上电复位异常的入口,即程序入口地址就存放在0地址上,如下图的黄色部分Reset_handler。当VBR寄存器被修改之后,例如改成Exp Base Addr,则此时异常/中断向量表被指向到Exp Base Addr地址所对应的位置,如果此时发生2号异常,则会从绿色地址获取2号异常的服务程序入口,即Exp#2_handler。此时0地址上的异常/中断向量表不再起做用,此处需要特殊标注的是对于复位异常,因为芯片复位之后的起始状态VBR寄存器是0,所以复位异常是不会被重定向,永远只会从0地址获取入口,除此之外的所有异常和中断时可以被重定向到其他的地址上去,也就是意味这Exp Base Addr上的Reset_handler是永远不会起作用的。
2 带TEE的MCU对于异常/中断向量表和服务程序的存储结构
带TEE的MCU的基本存储结构和普通MCU一致,即ROM,Flash,RAM。由于引入TEE的概念,在传统MCU的基础上会增加一个新的运行模式,即TEE。TEE下需要维护其自身的异常/中断向量表和对应的异常服务程序,基本结构和1.2章节中描述的结构一致。 TEE下响应REE的中断,需要提前设置好REE下的PSR的EE和IE位,设置好VIC中的中断使能寄存器,并且将对应的中断设置成非安全中断,设置对应设备的中断使能,满足以上条件的情况下,TEE下就可以响应REE的中断。 REE下响应TEE的中断,需要提前设置好TEE下的PSR的EE和IE位,设置好VIC中的中断使能寄存器,并且将对应的中断设置成安全中断,设置对应设备的中断使能,满足以上条件的情况下,TEE下就可以响应REE的中断。 目前TEE-Lite的体系架构不支持在TEE下响应REE的异常以及在REE下响应TEE的异常,所以这部分不在这里展开。 在芯片默认启动的时候,除了VBR寄存器为0之外,芯片一般处于TEE模式下,所以ROM中使用的一般为TEE的异常/中断向量表,当程序进入到flash之后,需要重新注册TEE的异常/中断向量表,方式如1.2章节描述,完成这部分之后可以在TEE下正常响应TEE的中断和异常(需要完成相关中断和异常的使能,不在此处详细描述)。 如果需要响应REE的中断,(编译时已经完成REE的异常/中断向量表的编译链接)则有两种实现方式:1、使用WSC指令,从TEE切换到REE中,然后修改REE的VBR,指向到对应的REE Exp Base Addr,即可以在REE下响应REE的中断和异常。该方式也支持在TEE下响应REE的中断。 2、在TEE下修改REE的VBR,直接关联REE的Exp Base Addr,此时可以在TEE下响应REE的中断,也可以REE下响应REE下的异常和中断
原文作者:兼信
点击查看原文