Professional Documents
Culture Documents
ARQUITECTURA ARM CORTEX‐M3:
I.1. Introducción:
Las soluciones System‐on‐chip basadas en procesadores embebidos ARM están
pensadas para llegar a diferentes sectores de mercado por lo que deben de dar
cobertura a gran cantidad de posibles aplicaciones.
Por ello ARM tiene varias familias de procesadores basadas en la arquitectura
ARMv7, que se diferencian según las aplicaciones a las que están orientadas:
Cortex‐A, para aplicaciones que corren en sistemas operativos.
Cortex‐R, para sistemas en tiempo real.
Cortex‐M, para aplicaciones con microcontroladores.
A finales del 2005 ARM publica la primera versión del Manual de Referencia de la
familia Cortex‐M3 ó Cortex‐M3 Technical Reference Manual, comenzando así la
comercialización de la nueva familia de procesadores.
El procesador Cortex‐M3 es el primer procesador basado en la arquitectura
ARMv7‐M que ha sido específicamente diseñado para lograr un alto rendimiento en la
relación potencia‐coste para aplicaciones embebidas.
El núcleo del procesador (core) del Cortex‐M3 está basado en una arquitectura de
bus Harvard (memoria de datos y de programa separadas) con 3 niveles en la ejecución
de instrucciones ó 3‐Stage Pipeline. El core incorpora internamente un multiplicador
(de ciclo único) y un divisor con una eficiencia de DMIPS/MHz (Millones de
instrucciones sin coma flotante por segundo).
Además el procesador Cortex‐M3 implementa el set de instrucciones Thumb‐2 que
combinada con características como el almacenamiento de datos no alineados o la
manipulación a nivel de bit, consigue funcionalidades de 32 bits con un coste de
rendimiento equivalente al de los dispositivos actuales de 16 y 8 bits.
I.1.1. Características principales:
Arquitectura ARMv7‐M, optimizada para microcontroladores y
aplicaciones de bajo coste.
Set de instrucciones Thumb‐2. Se consigue una mejor densidad de
código y mayor rapidez de ejecución del mismo.
Estructura jerárquica de los periféricos integrados:
o Núcleo del procesador (core) CM3:
Arquitectura de bus Harvard (memorias de programa y de
datos separadas).
Ejecución de instrucciones con 3‐stage pipeline con
branch speculation.
Controlador de interrupciones vectoriales anidadas
(NVIC).
o Unidad de protección de memoria (MPU):
Unidad de protección de memoria (MPU). Componente
opcional. Separa las tareas en ejecución y protege los
datos.
8 Regiones de protección de memoria divididas a su vez
en otras 8 subregiones.
Las regiones pueden estar comprendidas desde 32 bytes
hasta los 4 Gigabytes de memoria direccionables.
o Embedded Trace Macrocell (ETM):
Componente opcional. Reproduce una traza de
instrucciones en tiempo real.
o Watchpoints y unidad de traza (DWT)
Sirve para implementar breakpoints hardware y
proporcionar estadísticas de la ejecución de
instrucciones.
o Flashpatch y unidad de breakpoint (FPB)
Puede implementar hasta 6 breakpoints en el programa y
2 breakpoints de datos (detienen el programa al
referencia a una determinada variable)
o Puerto de depuración (SW‐DP ó SWJ‐DP)
Depuración configurable a través de puerto serie ó
interface JTAG.
o Multiplicadores de ciclo único e instrucciones de división
Multiplicaciones de 32 bits en un único ciclo.
Operaciones de división con y sin signo entre 2 y 12 ciclos.
o Mapa de memoria preconfigurado.
o 4 Gigabytes de memoria direccionables.
o Manipulación a nivel de bits en bit‐banding:
Acceso directo a datos de tipo bit.
2 Regiones de bit‐banding de 1 Megabyte cada una.
Las operaciones a nivel de bit no pueden ser
interrumpidas por las actividades de otro bus.
o Almacenamiento y acceso a datos no alineados:
Almacenamiento continuo de datos de diferente tamaño.
Acceso a datos en un único ciclo de acceso del core.
o Modos sleep integrados:
Modo sleep now para pasar inmediatamente a modo de
bajo consumo.
Modo sleep exit para pasar a bajo consumo después de
atender a una interrupción.
Capacidad de poner en power saving (modo de bajo
consumo tras transcurrir un determinado tiempo) a otros
componentes del sistema.
I.1.2. Principales ventajas:
Alta funcionalidad
o 1.25 DMIPS/MHz
o El uso del set de instrucciones Thumb‐2 proporciona una mejor
densidad de código y mayor rapidez de ejecución que en otras
familias o tecnologías.
Bajo coste de manufactura por el alto nivel de integración, menor
requerimiento de memoria y reducción de pines para reducir el coste
del encapsulado.
Eficiencia energética.
Mayor facilidad para mantenerse mucho tiempo en el mercado:
o Facilidad de diseño (NVIC, ETM, MPU, depuración integrada).
o Facilidad de desarrollo del software (set de instrucciones Thumb‐
2, NVIC).
Buena elección para migrar diseños basados en 8 ó 16 bits a 32 bits, ya
que el modelo de programación es compatible con la arquitectura
tradicional de ARM
I.1.3. Ejecución de instrucciones (execution pipeline stages):
El núcleo del procesador ejecuta las instrucciones en tres pasos:
Cuando una instrucción en ejecución pasa del primer al segundo paso de ejecución, la
siguiente instrucción pasa al primero y así continuamente en los tres pasos. De esta
manera se consigue acelerar la ejecución de instrucciones.
A continuación se describen los tres procesos:
Fe: Es llevado acabo por la prefetch unit del núcleo del procesador. En este paso
el core carga la instrucción de donde corresponda.
De: Éste es el paso en el que la instrucción se decodifica. Si en este paso la
instrucción decodificada resulta ser un salto condicional se produce un branch
o bifurcación, en donde se ha de elegir la siguiente instrucción a ejecutar (la
que debe entrar en el primer paso). Lo complicado es saber cuál es esta
instrucción cuando aún no se ha ejecutado la anterior. Para ello el procesador
usa una técnica llamada branch prediction ó branch speculation, que consiste
en una circuitería que “predice” la siguiente instrucción a ejecutar. Si resulta
ser correcta el proceso sigue con normalidad, si no se tendrá que pasar por
todo el proceso de nuevo, aumentando el tiempo de ejecución.
Ex: Ejecución de la instrucción. Tras esta fase se conoce si la dirección cargada
tras el branch era correcta o no.
Ésta no pretende ser una explicación detallada del proceso de ejecución de
instrucciones, pues ese no es el tema central del TFC, ni del capítulo, pero basta para
hacerse una idea del proceso.
I.2. Modelo del programador (Programmer’s model):
El procesador lleva implementada la arquitectura ARMv7. Incluye el set de
instrucciones Thumb‐2 de 16 y 32 bits, pero no puede ejecutar instrucciones ARM.
Para mayor información de la arquitectura ARMv7‐M ó del set de instrucciones
Thumb‐2 consultar el documento ARMv7‐M Architecture Reference Manual en la
página web de ARM.
I.2.1. Modos de funcionamiento:
El procesador soporta dos modos de operación:
Threat mode: Entra en este modo tras un reset, aunque también
puede entrar como resultado de un retorno de excepción. El
código puede correr en este modo tenga o no privilegios
(privileged code y unprivileged code respectivamente).
Handler mode: Entra en este modo como resultado de una
excepción. En este modo todo el código es privilegiado
(privileged code).
El procesador, además, puede operar en 2 estados de operación:
Thumb state: ejecución normal, corriendo instrucciones thumb
de 16 y 32 bits.
Debug state: Cuando está depurando.
El procesador soporta los siguientes tipos de datos:
Palabras de 32 bits (words).
Medias palabas de 16 bits (halfwords).
Bytes (8 bits).
I.2.2. Acceso privilegiado y no privilegiado:
El código puede ser ejecutado como privilegiado o no privilegiado. Si se ejecuta
como no privilegiado no se tiene acceso a algunos recursos:
Uso de algunas instrucciones (como CPS, que sirve para el manejo de los
registros de enmascaramiento de interrupciones).
Acceder a la mayoría de registros des “espacio de control del sistema”
(System Control Space, SCS).
El modo Thread es privilegiado tras el reset, pero puede cambiarse a no
privilegiado cambiando el bit de control CONTROL[0] (registro de control de propósito
especial. Tiene 2 bits, uno indica el modo de ejecución de las instrucciones, y el otro
cómo se usará la pila); con la instrucción MSR.
En el Thread mode no se puede cambiar la ejecución del código a privilegiado.
Para ello primero hay que pasar a Handler mode.
I.2.3. Registros:
El procesador tiene los siguientes registros de 32 bits:
R0 R0 – R7: Low registers.
R1
R8 – R12: High registers.
R2
R3 R0 – R12: Registros de propósito general.
R4
R13: Puntero de pila. Puede contener la
R5
dirección sp_main (cuando se ejecuta privileged code) ó
R6
sp_process (cuando se ejecuta unprivileged code).
R7
R8 R14: Link register.
R9
R15: Contador de programa (Program counter).
R10
R11 xPSR: Special purpose program status register.
R12
R13 (SP)
R14 (LR)
R15 (PC)
xPSR
A continuación se detallará el uso de los registros mencionados:
Low registers: Registros del R0 al R7. Son accesibles con todas las
instrucciones que los especifiquen.
High registers: Registros del R8 al R12. Sólo son accesibles a través de
instrucciones de 32 bits (no de 16 bits).
Stack pointer (SP): El registro R13 es usado como puntero de pila. En
Handler mode contiene SP_main (código privilegiado), en Thread mode
puede contener SP_main ó SP_process (código no privilegiado).
Link register (LR): El registro R14 recibe la dirección que retorna el
contador de programa cuando ejecuta las instrucciones de salto BL
(Branch with link) ó BLX (Branch with link and exchange). También
puede usarse como retorno de excepción. Si no se está usando con
nada de lo anterior, puede usarse como registro de propósito general.
Program counter (PC): El registro R15 es el contador de programa
Special purpose program status register (xPSR): El registro xPSR está
formado a su vez por 3 registros a los que se puede acceder de forma
individual (APSR, IPSR, EPSR):
o APSR (Aplication PSR): Contiene los flags de condición. Antes de
entrar una excepción el procesador salva los flags de condición en la
pila. Para acceder a éste registro se usan las instrucciones MSR y
MRS:
N: Resultado negativo o menor que (1), ó positivo o mayor que
(0).
Z: Resultado igual a 0 (1), ó distinto de 0 (0).
C: Hay carry ó borrow (1), o no lo hay (0).
V: Hay overflow (1), o no lo hay (0).
Q: Flag de saturación.
o IPSR (Interrupt PSR): Contiene la Interrupt Service Routine (ISR).
Número de la interrupción que está activada.
o EPSR (Execution PSR): El registro EPSR no es directamente accesible.
2 Eventos pueden identificarlo:
Una interrupción ocurrida durante las instrucciones durante las
instrucciones LDS ó STM.
Ejecución de una instrucción if‐then.
El registro EPSR tiene dos campos solapados:
Interruptable‐Continuable Instruction (ICI): Mantiene la
información requerida en instrucciones de carga ó
almacenamiento múltiple desde el momento en el que ocurre
la interrupción.
If‐then (IT): Contiene los bits de estado para la ejecución de la
instrucción if‐then.
Como los campos ICI e IT están solapados, las cargas ó almacenamientos
múltiples dentro de un bloque if‐then no pueden ser interrupt‐continued.
I.2.4. Formatos de memoria:
El procesador ve la memoria como una serie lineal de bytes numerados en
orden ascendente desde 0.
El procesador puede acceder a las palabras de datos en memoria en formato
Little endian (por defecto en procesadores ARM) ó big endian. En el formato Little
endian el byte de menor dirección en la palabra, es el byte menos significativo de la
palabra. El procesador tiene un pin de configuración (BIGEND) para configurar el
modo. Éste pin es sampleado tras un reset. Cualquier cambio en dicho pin después del
reset es ignorado.
El acceso al System Control Space (SCS), es siempre little endian. Lo mismo
ocurre con el acceso al Private Peripheral Bus (PPB).
I.2.5. Set de instrucciones:
El procesador de la familia Cortex‐M3 puede ejecutar las siguientes instrucciones
Thumb‐2 de 16 y 32 bits:
Instrucciones de 16 bits:
Operation Assembler
Add register value and C flag to register value ADC <Rd>, <Rm>
Add immediate 3‐bit value to register ADD <Rd>, <Rn>, #<immed_3>
Add immediate 8‐bit value to register ADD <Rd>, #<immed_8>
Add low register value to low register value ADD <Rd>, <Rn>, <Rm>
Add high register value to low or high register value ADD <Rd>, <Rm>
ADD <Rd>, PC, #<immed_8> *
Add 4* (immediate 8‐bit value) with PC to register
4
ADD <Rd>, SP, #<immed_8> *
Add 4* (immediate 8‐bit value) with SP to register
4
Add 4* (immediate 7‐bit value) to SP ADD SP, #<immed_7> * 4
Bitwise AND register values AND <Rd>, <Rm>
Arithmetic shift right by immediate number ASR <Rd>, <Rm>, #<immed_5>
Arithmetic shift right by number in register ASR <Rd>, <Rs>
Branch conditional B<cond> <target address>
Branch unconditional B <target_address>
Bit clear BIC <Rd>, <Rm>
Software breakpoint BKPT <immed_8>
Branch with link BL <Rm>
Branch with link and exchange BLX <Rm>
Branch and exchange BX <Rm>
Compare not zero and branch CBNZ <Rn>,<label>
Compare zero and branch CBZ <Rn>,<label>
Compare negation of register value with another register value CMN <Rn>, <Rm>
Compare immediate 8-bit value CMP <Rn>, #<immed_8>
Compare registers CMP <Rn>, <Rm>
Compare high register to low or high register CMP <Rn>, <Rm>
Change processor state CPS <effect>, <iflags>
Copy high or low register value to another high or low register CPY <Rd> <Rm>
Bitwise exclusive OR register values EOR <Rd>, <Rm>
Condition the following instruction IT <cond>
Condition the following two instructions IT<x> <cond>
Condition the following three instructions IT<x><y> <cond>
Condition the following four instructions IT<x><y><z> <cond>
Instrucciones de 32 bits:
Operation Assembler
ADC{S}.W <Rd>, <Rn>,
Add register value, immediate 12-bit value, and C bit
#<modify_constant(immed_12>
Add register value, shifted register value, and C bit ADC{S}.W <Rd>, <Rn>, <Rm>{, <shift>}
ADD{S}.W <Rd>, <Rn>,
Add register value and immediate 12-bit value
#<modify_constant(immed_12)>
Add register value and shifted register value ADD{S}.W <Rd>, <Rm>{, <shift>}
Add register value and immediate 12-bit value ADDW.W <Rd>, <Rn>, #<immed_12>
AND{S}.W <Rd>, <Rn>,
Bitwise AND register value with immediate 12-bit value
#<modify_constant(immed_12>
Bitwise AND register value with shifted register value AND{S}.W <Rd>, <Rn>, Rm>{, <shift>}
Arithmetic shift right by number in register ASR{S}.W <Rd>, <Rn>, <Rm>
Conditional branch B{cond}.W <label>
Clear bit field BFC.W <Rd>, #<lsb>, #<width>
Insert bit field from one register value into another BFI.W <Rd>, <Rn>, #<lsb>, #<width>
Bitwise AND register value with complement of immediate BIC{S}.W <Rd>, <Rn>,
12-bit value #<modify_constant(immed_12)>
Bitwise AND register value with complement of shifted
BIC{S}.W <Rd>, <Rn>, <Rm>{, <shift>}
register value
Branch with link BL <label>
Branch with link (immediate) BL<c> <label>
Unconditional branch B.W <label>
Clear exclusive clears the local record of the executing
processor that an address has had a request for an exclusive CLREX <c>
access.
Return number of leading zeros in register value CLZ.W <Rd>, <Rn>
Compare register value with two’s complement of immediate
CMN.W <Rn>, #<modify_constant(immed_12)>
12-bit value
Compare register value with two’s complement of shifted
CMN.W <Rn>, <Rm>{, <shift>}
register value
Compare register value with immediate 12-bit value CMP.W <Rn>, #<modify_constant(immed_12)>
Compare register value with shifted register value CMP.W <Rn>, <Rm>{, <shift>}
Data memory barrier DMB <c>
Data synchronization barrier DSB <c>
EOR{S}.W <Rd>, <Rn>,
Exclusive OR register value with immediate 12-bit value
#<modify_constant(immed_12)>
Exclusive OR register value with shifted register value EOR{S}.W <Rd>, <Rn>, <Rm>{, <shift>}
Instruction synchronization barrier ISB <c>
Load multiple memory registers, increment after or decrement LDM{IA|DB}.W <Rn>{!}, <registers>
before
Memory word from base register address + immediate 12-bit
LDR.W <Rxf>, [<Rn>, #<offset_12>]
offset
Memory word to PC from register address + immediate 12-bit
LDR.W PC, [<Rn>, #<offset_12>]
offset
Memory word to PC from base register address immediate
LDR.W PC, [Rn], #<+/-<offset_8>
8-bit offset, postindexed
Memory word from base register address immediate 8-bit
LDR.W <Rxf>, [<Rn>], #+/–<offset_8>
offset, postindexed
Memory word from base register address immediate 8-bit LDR.W <Rxf>, [<Rn>, #<+/–<offset_8>]!
offset, preindexed LDRT.W <Rxf>, [<Rn>, #<offset_8>]
Memory word to PC from base register address immediate
LDR.W PC, [<Rn>, #+/–<offset_8>]!
8-bit offset, preindexed
Memory word from register address shifted left by 0, 1, 2, or 3
LDR.W <Rxf>, [<Rn>, <Rm>{, LSL #<shift>}]
places
Memory word to PC from register address shifted left by 0, 1,
LDR.W PC, [<Rn>, <Rm>{, LSL #<shift>}]
2, or 3 places
Memory word from PC address immediate 12-bit offset LDR.W <Rxf>, [PC, #+/–<offset_12>]
Memory word to PC from PC address immediate 12-bit offset LDR.W PC, [PC, #+/–<offset_12>]
Memory byte [7:0] from base register address + immediate
LDRB.W <Rxf>, [<Rn>, #<offset_12>]
12-bit offset
Memory byte [7:0] from base register address immediate 8-bit
LDRB.W <Rxf>. [<Rn>], #+/-<offset_8>
offset, postindexed
Memory byte [7:0] from register address shifted left by 0, 1, 2,
LDRB.W <Rxf>, [<Rn>, <Rm>{, LSL #<shift>}]
or 3 places
Memory byte [7:0] from base register address immediate 8-bit
LDRB.W <Rxf>, [<Rn>, #<+/–<offset_8>]!
offset, preindexed
Memory byte from PC address immediate 12-bit offset LDRB.W <Rxf>, [PC, #+/–<offset_12>]
Memory doubleword from register address 8-bit offset 4,
LDRD.W <Rxf>, <Rxf2>, [<Rn>, #+/–<offset_8> * 4]{!}
preindexed
Memory doubleword from register address 8-bit offset 4,
LDRD.W <Rxf>, <Rxf2>, [<Rn>], #+/–<offset_8> * 4
postindexed
Load register exclusive calculates an address from a base
register value and an immediate offset, loads a word from LDREX<c> <Rt>,[<Rn>{,#<imm>}]
memory, writes it to a register
Load register exclusive halfword calculates an address from a
base register value and an immediate offset, loads a halfword LDREXH<c> <Rt>,[<Rn>{,#<imm>}]
from memory, writes it to a register
Load register exclusive byte calculates an address from a base
register value and an immediate offset, loads a byte from LDREXB<c> <Rt>,[<Rn>{,#<imm>}]
memory, writes it to a register
Memory halfword [15:0] from base register address +
LDRH.W <Rxf>, [<Rn>, #<offset_12>]
immediate 12-bit offset
Memory halfword [15:0] from base register address immediate
LDRH.W <Rxf>, [<Rn>, #<+/–<offset_8>]!
8-bit offset, preindexed
Memory halfword [15:0] from base register address immediate
LDRH.W <Rxf>. [<Rn>], #+/-<offset_8>
8-bit offset, postindexed
Memory halfword [15:0] from register address shifted left by
LDRH.W <Rxf>, [<Rn>, <Rm>{, LSL #<shift>}]
0, 1, 2, or 3 places
Memory halfword from PC address immediate 12-bit offset LDRH.W <Rxf>, [PC, #+/–<offset_12>]
Memory signed byte [7:0] from base register address +
LDRSB.W <Rxf>, [<Rn>, #<offset_12>]
immediate 12-bit offset
Memory signed byte [7:0] from base register address
LDRSB.W <Rxf>. [<Rn>], #+/-<offset_8>
immediate 8-bit offset, postindexed
Memory signed byte [7:0] from base register address
LDRSB.W <Rxf>, [<Rn>, #<+/–<offset_8>]!
immediate 8-bit offset, preindexed
Memory signed byte [7:0] from register address shifted left by
LDRSB.W <Rxf>, [<Rn>, <Rm>{, LSL #<shift>}]
0, 1, 2, or 3 places
Memory signed byte from PC address immediate 12-bit offset LDRSB.W <Rxf>, [PC, #+/–<offset_12>]
Memory signed halfword [15:0] from base register address + LDRSH.W <Rxf>, [<Rn>, #<offset_12>]
immediate 12-bit offset
I.3. Mapa de memoria:
La siguiente tabla muestra las diferentes interfaces que tienen que ser direccionadas,
para acceder a las diferentes zonas de memoria:
I.3.1. Banda de bits ó bit‐banding:
En el mapa de memoria se pueden observa 2 zonas de bit‐banding, donde se
pueden manipular datos de tamaño bit. Cada banda de bits está formada por 2
regiones.
En la zona Bit band region es donde se almacenan los bits, teniendo cada una 1
Mbyte de capacidad. A cada uno de estos bits le corresponde una palabra (32 bits)
de la zona Bit band Alias, por lo que ésta tiene una capacidad de 32 Mbytes.
La forma de calcular qué palabra corresponde a cada bit, viene dada por la
siguiente fórmula:
bit_word_offset = (byte_offset x 32) + (bit_number × 4)
bit_word_addr = bit_band_base + bit_word_offset
Donde:
• Bit_word_offset es la posición del bit en la bit ban region.
• Bit_word_addr es la dirección de la palabra en la bit‐band alias region
correspondiente al bit de la bit‐band region.
• Bit_band_base es la dirección de comienzo de la bit‐band alias region.
• Byte_offset es el nº de byte que contiene el bit en la bit band region.
• Bit_number es la posición (0‐7) del bit en el byte donde se encuentra.
Se puede ver mejor gráficamente en el siguiente ejemplo:
Acceso directo a la alias región: Escribir en la alias región tiene el mismo efecto
que modificar el bit de la bit‐band región. El bit[0] de la palabra
correspondiente, cambia el bit de la bit‐band región correspondiente. Los bits
[31..1] no tienen ningún efecto en la bit‐band región. Cuando se lee una
palabra de la alias región se retorna el bit[0] correspondiente y los bits [31..1]
son 0.
Acceso directo a la bit‐band region: Se puede acceder mediante operaciones de
lectura ó escritura normales.
I.4. Excepciones:
El procesador y el controlador de interrupciones vectoriales anidadas (NVIC)
priorizan y manejan todas las excepciones. Las excepciones pueden ser manipuladas
en handler mode. Cuando se produce una excepción el estado del procesador es
almacenado automáticamente en la pila, y de la misma forma es automáticamente
cargado desde la pila cuando finaliza la rutina de atención a la interrupción ó Interrupt
Service Routine (ISR).
El vector es traído en paralelo cuando se guarda el estado del procesador (ambos
procesos se realizan al mismo tiempo), de manera que se ahorra tiempo en la
ejecución de la interrupción. El procesador soporta una técnica llamada tail chaining
para permitir interrupciones anidadas, evitando nuevos estados de push (guardado del
estado de la interrupción de menor prioridad) y pop (restauración del estado de la
interrupción de menor prioridad). Ambas acciones tienen que guardar o cargar datos
de/a 8 registros.
Principales características:
Guardado y restaurado automático del estado (push: guardado de registros
de estado en la pila antes de entrar en el ISR. Pop: Carga de los anteriores,
después de que finalice dicha ISR, si no hay un anidamiento de otra
excepción de mayor prioridad).
Lectura automática de la tabla de vectores que contiene la dirección de la
ISR en la memoria de programa ó en SRAM. Se hace en paralelo con el
guardado del estado.
Soporte de tail‐chaining.
Repriorización dinámica de interrupciones.
Clousely‐coupled interface: Interface que liga directamente el core y el NVIC
para reducir el tiempo de procesamiento de interrupciones.
Número configurable de interrupciones (de 1 a 240).
Número configurable de niveles de prioridad de interrupción (de 3 a o bits,
es decir, de 8 a 256 niveles).
Pilas (principal y de proceso) y privilegios separados para modos handle y
thread.
Control de la transferencia del ISR usando las convenciones de llamada
c/c++ standard ARM Architecture Procedure Call Standard (AAPCS);
disponible en la página web de ARM.
Prioridad enmascarable para soportar regiones críticas.
Nota: El número de interrupciones y el número de bits de los niveles de interrupción
son configurables durante la implementación. El software sólo puede elegir cómo usar
ambas cosas.
I.4.1. Tipos de excepciones:
En el procesador existen distintos tipos de excepciones. Un fault o fallo es una
excepción provocada por un error producido por una instrucción en ejecución (como
por ejemplo intentar dividir entre 0).
En la siguiente tabla se muestran los distintos tipos de excepciones:
I.4.2. Prioridad de excepciones:
Pre‐emption: Ocurre cuando una nueva excepción entrante tiene una prioridad
superior a la excepción que se estaba ejecutando en ese momento, entonces se
dice que la ISR entrante está “anidada”.
Cuando entra una nueva excepción el procesador guarda automáticamente el
estado del procesador en la pila (push). Al mismo tiempo, en paralelo, se trae el
vector correspondiente a la excepción entrante.
Cuando el procesador invoca una excepción, se el procesador pasa al puntero
de pila (Stack Pointer, ó SP) 8 registros en el siguiente orden: R0‐R3, R12, LR
(R14), Contador de programa (PC), xPSR . El SP se decrementa en 8 palabras,
para completar la stack push quedando la pila:
La ejecución de la primera instrucción de la ISR entrante comienza cuando el
estado del procesador es salvado.
Los pasos que se siguen cuando ocurre una excepción, se muestran en la
siguiente tabla:
Proceso de pre‐empt:
Tail chaining: Es un mecanismo usado cuando un ISR de mayor prioridad
interrumpe a otro de menor prioridad. Disminuye el tiempo de transición de un
ISR al otro sustituyendo los paso de push y pop por 6 ciclos de reloj.
Return: Al terminar de ejecutarse todas las excepciones se restaura el estado
del procesador desde la pila, indicando el estado que tenía antes de darse la
primera excepción. Si durante la restauración del estado aparece otra
excepción, la restauración es abandonada, ocurre el tail‐chaining y se continúa
según el procedimiento normal.
Mapa de flujo del retorno de excepción:
Late arriving: Es un mecanismo usado para acelerar el estado de pre‐emption.
Se da cuando una excepción de mayor prioridad interrumpe a otra, y cuando se
está guardando el estado de ésta, interrumpe otra más. Se ejecuta entonces la
de mayor prioridad (el estado de las otras dos es el mismo) y se aplica el
procedimiento normal.
I.4.2.1. Niveles de prioridad:
El NVIC soporta la asignación de niveles de prioridad. Se pueden asignar
niveles de prioridad de 0 a 255, siendo el menor nivel el de mayor prioridad.
Para saber cómo hacerlo, hay que mirar en el capítulo dedicado al NVIC.
Si interrumpen dos excepciones de igual prioridad, entonces la prioridad
viene determinada por defecto por el menor número de interrupción.
I.4.2.2. Agrupaciones de prioridad:
Para incrementar el control sobre sistemas con una gran cantidad de
interrupciones, el NVIC puede soportar grupos de prioridad.
Para ello se usa el campo PERIGROUP en el Aplication Interrupt and Reset
Control Register y los registros de prioridad de interrupción (PRI).
Cada interrupción se corresponde con un PRI (1 Byte) y en el PERIGROUP se
establece cuántos bits de cada PRI son asignados al grupo y cuantos a la
interrupción (de ese grupo).
I.4.3. Privilegios y pilas:
El procesador soporta dos pilas diferenciadas: process stack ó pila de proceso
(se puede configurar el thread mode para usar esta pila) y main stack ó pila principal
(se usa en handle mode).
El uso de una pila u otra es independiente del modo de privilegio, es decir que
se pueden dar los cuatro casos posibles. Del modo de privilegio depende:
Poder usar determinadas instrucciones (como MSR).
Accedes a los registros SCS.
Acceder a determinadas regiones de memoria o a memoria relacionada con la
MPU.
I.4.4. Exit:
Al terminar la última excepción de una ISR, carga el PC con el valor que tenía LR
cuando entró la excepción. Cuando se retorna de una excepción el puede ocurrir:
Tail‐chaining si interrumpe una excepción de mayor prioridad.
Retorna a la ISR anterior de menor prioridad.
Retorna al thread mode si no hay ninguna ISR pendiente (cuando entra
una ISR, se pasa automáticamente a handle mode).
Secuencia a seguir al terminar una excepción:
I.4.5. Reset:
El NVIC es reseteado cuando también se resetea el procesador. Entonces ocurre lo
siguiente:
La posición 0 de la tabla de vectores proporciona el vector de reset, que contiene 4
valores:
Dirección más alta de la pila.
Localización de la rutina de reset.
Localización de NMI e ISR.
Localización del ISR de Hard fault.
Una rutina normal de reset debería realizar las siguientes acciones:
Las acciones que están entre corchetes son opcionales.
I.4.6. Transferencia de control a la interrupción:
El procesador transfiere el control a la ISR según las siguientes reglas:
I.4.7. Excepciones por errores en ejecución (Abort model):
Cuatro eventos pueden ocasionar un fallo ó fault:
Una carga de instrucción ó tabla de vectores que ocasiona error de bus.
Error de bus al acceder a datos.
Detección interno de error. El fault status register del NVIC indica la causa del
fallo.
Fallo en la MPU (por intentar acceder a una región de memoria privilegiada, sin
privilegio, por ejemplo).
Hay 2 tipos de fallos:
Hard faults: Sólo el reset y el NMI pueden provocarlo.
Local faults: Se categorizan según su causa. Sin embargo un local fault puede
llegar a ser un Hard fault cuando:
o Se produce un nuevo fallo del mismo tipo que se está tratando.
o Se produce un nuevo fallo de prioridad igual o mayor al que se está
tratando.
o Se produce una excepción de igual o mayor prioridad.
o Local faults no están habilitados.
Tabla de tipos de local faults según su causa:
I.4.7.1. Registros de estado de fallo (fault status registers) y registros de
dirección de fallo (fault address registers).
Cada fallo tiene un registro de estado de fallo ó fault status register con un flag
para este fallo. Hay:
Tres registros de estado de fallo configurables, que se corresponden por
cada fault handler (usage fault, bus fault, memManage).
Un hard fault status register.
Un debug fault status register.
Habrá un set en el bit correspondiente de uno de los cinco registros de estado,
según la causa que haya provocado el fallo.
Hay 2 registros de dirección de fallo ó fault address registers (FAR):
Bus fault address register (BFAR).
Memory fault address register (MFAR).
Un flag en el correspondiente registro indica cuándo la dirección en el registro
de dirección de fallo es válida.
Tabla de registros:
I.4.7.2. Niveles de activación:
Cuando no hay excepciones activas el procesador está en thread mode. Cuando
se da una ISR ó fault handler está activo, el procesador entra en handler mode.
La siguiente tabla muestra los privilegios y pilas de los niveles de activación:
La siguiente tabla resume las reglas de transición para todos los tipos de
excepciones, tipo de código y tipo de pila:
I.5. Temporización y reset:
I.5.1. Temporización:
El procesador tiene 3 relojes descritos en la siguiente tabla:
FCLK y HCLK están sincronizados y ambos deben tener la misma frecuencia
cuando el procesador no está en modo sleep.
El procesador tiene integrados componentes para la depuración y traza. Su
macrocélula puede tener algunos (o todos) de los siguientes relojes:
SWCLKTCK es el reloj para la interface de depuración en el dominio del SWJ‐DP
(Serial Wire JTAG‐Debug Port). En modo JTAG es equivalente a TCK (señal de
reloj por la que se rige un sistema de depuración JTAG).
DBGCLK es el reloj para la interface de depuración en el dominio del SW‐DP.
TRACECLKIN es el reloj de referencia para al unidad de interface del puerto de
traza (TPIU).
Ninguno de éstos relojes están sincronizados ni entre ellos, ni con ningún otro.
El procesador también tiene una entrada STCLK. Éste puerto no es un reloj, sino una
referencia para el contador SysTick (temporizador del sistema embebido en la propia
arquitectura) y puede ser menor que la mitad de la frecuencia de FCLK.
I.5.2. Reset:
El procesador tiene 3 entradas de reset, descritas en la siguiente tabla:
Con éstas señales se pueden resetear distintas partes del diseño de forma
independiente. Se pueden ver las distintas combinaciones en la siguiente tabla:
Además se puede resetear SW‐DP con DBGRESETn. Éste reset está sincronizado
con DBGCLK.
Durante el funcionamiento normal (sin que el procesador se resetee), si el
puerto SWK‐DP no está siendo usado, el valor de nTRST es indiferente.
I.6. Alimentación:
El procesador usa gated clocks para desactivar bloques funcionales que no se
están usando. Esto se traduce en distintos sleep modes que pueden detener el Cortex‐
M3 y algunos relojes del sistema para obtener grandes reducciones de energía.
Escribiendo en el registro de control del sistema (sistem control register) se
pueden controlar los diferentes estados de alimentación (o de consumo de energía). La
siguiente tabla muestra los distintos sleep modes soportados:
El procesador exporta la siguientes señales para indicar cuándo está sleeping:
SLEEPING: Ésta señal se activa cuando está en modo sleep‐now ó sleep‐on‐exit,
e indica que el reloj del procesador puede ser detenido.Al recibir una nueva
interrupción ó evento (en el caso de WFE), el NVIC anula ésta señal, sacando al
core del sleep mode.
SLEEPDEEP: Ésta señal se declara cuando estando en modo sleep‐now ó sleep‐
on‐exit el bit sleepdeep del system control register está set. Ésta señal se lleva al
administrador de reloj (clock manager) y puede provocar el ahorro de gran
cantidad de energía.
I.6.1. Wake‐up Interrupt Controller (WIC):
El NVIC del Cortex‐M3 tiene una lógica que determina cuándo una interrupción
puede interrumpir a otra, según su prioridad. Ésta función también debe realizarse
durante WFE, WFI y sleep‐on‐exit, es decir, cuando el core debe volver a la ejecución
de instrucciones normal, tras el sleep.
Para aplicaciones de ultra‐low power es deseable reducir la potencia estática y
dinámica del procesador mientras se está dando el estado de very‐sleep‐mode. Esto
puede hacerse deteniendo relojes o incluso dejando de alimentar al procesador.
Cuando no existe esta alimentación, el NVIC es incapaz de priorizar ó detectar
interrupciones.
El WIC es capaz de manejar una lógiza de detección de interrupciones que
pueda emular el comportamiento del NVIC. El pequeño tamaño del WIC asegura el
respeto a los bajos requerimientos de consumo de energía deseados.
Sin embargo, a diferencia del NVIC, el WIC no tiene lógica de priorización. El
WIC lleva implementado un rudimentario sistema de enmascaramiento de
interrupciones. Además el WIC es totalmente invisible de cara al usuario final.
I.7. Nested Vectored Interrupt Controller (NVIC):
El controlador de interrupciones vectoriales anidadas ó NVIC facilita la baja
latencia en las excepciones y en el manejo de interrupciones, controla la distribución
de la alimentación e implementa los registros de control del sistema.
El NVIC soporta hasta 240 interrupciones dinámicas repriorizables con hasta
256 niveles de prioridad. El NVIC y el core están directamente interconectados para
tener una baja latencia de procesado de interrupción. El NVIC mantiene el
conocimiento de las interrupciones anidadas al activar el tail‐chaining de una
interrupción a otra.
Sólo puede accederse al NVIC en modo privilegiado, sino ocurre error de bus.
Todos los registros del NVIC son accesibles a nivel de malabra, media palabra ó byte.
I.7.1. Mapa de registros:
La mayor parte del SCS (System Control Space) está ocupado por los registros
correspondientes al NVIC. En esta tabla se muestra cómo esta repartido el NVIC dentro
del SCS:
I.7.2. Descripción de registros:
Éste registro sirve para leer el número de líneas de interrupción (interrupt lines) que el
NVIC soporta. El nº de líneas de interrupción se especifica en grupos de 32 (0-32, 33-64, 65-
96, …, 225-256). Hay que tener en cuenta que el procesador puede soportar hasta 240
interrupciones externas.
Dirección: 0xE000E004
I.7.2.2. Registro de control auxiliar (auxiliary control register):
Éste registro puede desactivar determinados aspectos de funcionalidad dentro
del procesador.
Dirección: 0xE000E008
Acceso: lectura/escritura
I.7.2.3. Registro de control y de estado SysTick (SysTick Control and
Status Register):
Éste registro se utiliza para habilitar las características SysTick. El SysTick es el
timer del sistema, que rige su sincronismo.
Dirección: 0xE000E010
Acceso: lectura/escritura
I.7.2.4. Registro de valor de recarga del SysTick (SysTick Reload Value
Register):
Sirve para especificar el valor de comienzo del SysTick a cargar cuando dicho
contador llega a 0. Puede tomar un valor entre 1 y 0x00FFFFFF. Un valor de comienzo
igual a 0 es posible, pero sin ningún efecto. Esto es porque la interrupción del SysTick y
el COUNTFLAG no se activan hasta que se pasa del 1 al 0.
Dirección: 0xE000E014
Acceso: lectura/escritura
I.7.2.5. Registro de Valor actual de SysTick (SysTick Current Value
Register):
Con este registro se puede ver el valor actual del SysTick. Si intenta escribirse
algo en él, pasa a valer automáticamente 0.
Dirección: 0xE000E018
Acceso: lectura/escritura - clear
I.7.2.6. Registro del valor de calibración del SysTick (Systick Calibration
Value Register).
Informa acerca del escalado para llegar a la velocidad requerida, usando divisor
y multiplicador.
Dirección: 0xE000E01C
Acceso: lectura
I.7.2.7. Registros Set‐Enable de interrupción (Interrupt Set‐Enable
Registers):
Se usa para habilitar (sólo habilitar) interrupciones, y determinar cuáles están
actualmente activadas. Son 8 palabras en las que cada bit representa una interrupción
(1=enable, 0=disable). Si se cambia el bit correspondiente a la interrupción que se está
ejecutando en ese momento, no afecta a dicha interrupción (afectará a la próxima vez
que se tenga que ejecutar).
Dirección: 0xE000E100-0xE000E11C
Acceso: lectura/escritura
I.7.2.8. Registros Clear‐enable de interrupción (Interrupt Clear‐Enable
Registers):
Se usa para deshabilitar (sólo deshabilitar) interrupciones, y determinar cuáles
están actualmente desactivadas. Son 8 palabras en las que cada bit representa una
interrupción (1=disable, 0=enable). Si se cambia el bit correspondiente a la
interrupción que se está ejecutando en ese momento, no afecta a dicha interrupción
(afectará a la próxima vez que se tenga que ejecutar).
Dirección: 0xE000E180-0xE000E19C
Acceso: lectura/escritura
I.7.2.9. Registro Set‐Pending de interrupción (Interrupt Set‐Pending
Register):
Se usa para forzar las interrupciones (habilitadas) en estado de “pendiente” (no
activa) o ver cuáles están en ese momento en ese estado (el estado “pendiente”
implica que tienen que ejecutarse según su turno de prioridad). Intentarlo con una
instrucción en ejecución ó deshabilitada, no tiene ningún efecto.
Dirección: 0xE000E200-0xE000E21C
Acceso: lectura/escritura
I.7.2.10. Registro Clear‐Pending de interrupción (Interrupt Clear‐Pending
Register):
Se usa para sacar las interrupciones del estado “pendiente”. Intentarlo con una
instrucción en ejecución ó deshabilitada, no tiene ningún efecto. Para ello se hace un
Set en el bit correspondiente (Son 8 registros de 32 bits, cada bit corresponde a una
interrupción).
Dirección: 0xE000E280-0xE000E29C
Acceso: lectura/escritura
I.7.2.11. Registro de bit activo (Active bit register):
Su lectura indica qué interrupción está activada. Cada flag (bit) se corresponde
con una determinada interrupción (son 8 registros de tamaño palabra).
Dirección: 0xE000E300-0xE000E31C
Acceso: lectura/escritura
I.7.2.12. Registros de prioridad de interrupción (Interrupt Priority
Registers):
Se usan para asignar una prioridad de 0 a 255 a cada una de las interrupciones
disponibles. La prioridad es descendente (0=mayor prioridad, 255=menor prioridad).
La prioridad es guardada a partir del byte de menor peso (en una palabra hay 4 bytes,
cada uno correspondiente a la prioridad de una interrupción). Si hay menos de 8 bits
de prioridad, se almacenará en los bits de mayor peso de cada byte. Cada registro de
prioridad (1 byte) es nombrado como PRI_n (n=1..240).
Dirección: 0xE000E400-0xE000E41F
Acceso: lectura/escritura
Nota: Si se configuran grupos de prioridad de interrupciones (muy útiles de cara a un
sistema con gran cantidad de interrupciones), los bits de cada byte se dividen en bits
del grupo de interrupciones y los demás para especificar la propia interrupción. El
número de bits empleados para cada cosa, son configurados en el Application Interrupt
and Reset Control Register que se verá en el apartado I.7.2.16
La siguiente tabla muestra la organización de los registros PRI_n de las 32 primeras
interrupciones:
I.7.2.13. Registro de información de CPU (CPI ID Base Register):
La lectura de este registro devuelve el ID number, la versión y los detalles de
implementación del core.
Dirección: 0xE000ED00
Acceso: Sólo lectura
I.7.2.14. Registro de estado de control de interrupción (Interrupt control
State Register):
Se usa para:
Activar una interrupción no‐enmascarable pendiente (Non‐Mascarable
Interrupt, NMI).
Activar una SVC pendiente (SuperVisor Call, instrucción SVC).
Activar una interrupción SysTick pendiente.
Chequear excepciones pendientes.
Chequear el número de vector de mayor prioridad de excepción
pendiente.
Chequear el número de vector de excepción activa.
Dirección: 0xE000ED04
Acceso: lectura/escritura ó sólo lectura
I.7.2.15. Registro de offset de tabla de vectores (Vector Table Offset
Register):
Éste registro se usa para determinar el offset de la tabla de vectores y
determinar si ésta se encuentra en RAM ó en memoria de programa.
Dirección: 0xE000ED08
Acceso: lectura/escritura
I.7.2.16. Registro de control de reset e interrupción de la aplicación
(Application Interrupt and Reset Control Register):
Éste registro se usa para varios fines:
Determinar la codificación endian de los datos.
Borrar toda la información del estado en el que se encuentra el
procesador para depurar, ó recuperarse de un hard failure.
Ejecutar un reset del sistema.
Cambiar el número de bits designados a grupos e interrupciones de
prioridad (en el byte PRI_n).
Dirección: 0xE000ED0C
Acceso: lectura/escritura
I.7.2.17. Registro de control del sistema (System Control Register):
Se usa para funciones de consumo de energía:
Señala al sistema cuándo el procesador puede entrar en estado de low
power.
Controla cómo el procesador entra y sale de los estados de low power.
Dirección: 0xE000ED10
Acceso: lectura/escritura
I.7.2.18. Registro de control de configuración (Configuration Control
Register):
Este registro puede:
Habilitar NMI, hard faults, y configurar FAULTMASK para que ignore bus
faults.
Localizar divisiones por 0 y accesos no alineados.
Habilitar el acceso del usuario al registro Software Trigger Exception
Register.
Controlar la entrada a thread mode.
I.7.2.19. Registros de prioridad del sistema (System Handler Priority
Registers):
Se usan los tres registros de prioridad del manejo del sistema para configurar la
prioridad de:
Administración de memoria.
Fallo de bus (bus fault).
Usage fault.
Monitorización del sistema (debug monitor).
SVC.
SysTick.
PendSV.
Los System Handlers son un tipo especial de exception handlers que pueden
tener cualquier nivel de prioridad. La mayoría pueden ser enmascarados. Cuando están
desactivados, los fallos son siempre tratados como hard faults.
I.7.2.20. Registro de estado y control del System Handler (System Handler
Control and Status Register):
Sirve para:
Activar/desactivar los System Handlers.
Determinar el estado de dependiente de bus fault, mem manage fault y
SVC.
Determinar el estado activo de los System Handlers.
Si se da una condición de fault cuando su fault Handler está desactivado, se
produce un hard fault.
Dirección: 0xE000ED24
Acceso: lectura/escritura
Valor tras el reset: 0x00000000
Los bits activos indican si algún System Handler está activo. Ésta información es
usada para la depuración y para application handlers.
Hay que tener mucho cuidado en la manipulación de éste registro.
I.7.2.21. Registros de estado de fallo configurable (Configurable Fault
Status Registers):
Éste registro se usa para obtener información de fallos locales.
Usage Fault Status Register: Indica la causa del fallo de acceso a
memoria.
Bus Fault status Register: Indica la causa de fallo de acceso a bus.
Memory Manage Fault Register: Puede indicar varias cosas
o Combinación ilegal de EPSR e instrucción.
o Carga ilegal del PC.
o Estado ilegal del procesador.
o Error al decodificar una instrucción.
o Intentar usar una instrucción del coprocesador.
o Acceso no alineado ilegal.
I.7.2.22. Registro de estado de Hard Fault (Hard Fault Status Register):
Éste registro sirve para obtener información de eventos que han activado el
Hard Fault Register.
Dirección: 0xE000ED2C
Acceso: lectura/escritura-uno-para-borrar
I.7.2.23. Registro de estado de debug fault (Debug Fault Status register):
Sirve para monitorizar:
Solicitaciones externas de depuración.
Lectura de vectores.
Si se alcanza algún Watchpoint de datos.
Si se alcanza algún Breakpoint de ejecución de instrucciones.
Detención de solicitaciones.
Dirección: 0xE000ED30
Acceso: lectura/escritura-uno-para-borrar
I.7.2.24. Registro de dirección de fallo de administración de memoria
(Memory Manage Fault address Register):
Sirve para leer la dirección donde se encuentra lo que ha causado el fallo de
memoria.
Dirección: 0xE000ED34
Acceso: lectura/escritura
Sirve para leer la dirección donde se encuentra lo que ha causado el fallo de
bus.
Dirección: 0xE000ED38
Acceso: lectura/escritura
I.7.2.26. Registro de estado de fallo auxiliar (Auxiliary Fault status
Register, AFSR):
Sirve para determinar información adicional del fallo del sistema.
Dirección: 0xE000ED3C
Acceso: lectura/escritura-clear
Los flags del están mapeados directamente en las entradas del procesador
AUXFAULT y un único cambio a nivel alto en un pin externo puede causar que el
correspondiente bit del AFSR se ponga a ‘1’. Sólo puede ser borrado escribiendo ‘1’ en
el bit correspondiente del AFSR. Cuando alguna de estas acciones ocurre no se
produce ninguna excepción. Si se necesitase expresamente una excepción, entonces es
posible usar una para este fin.
I.7.2.27. Registro de interrupción Software Trigger (Software Trigger
Interrupt register):
Sirve para cambiar el estado de una interrupción a “pendiente” mediante un
“disparo”.
Dirección: 0xE000EF00
I.7.3. Interrupciones por nivel VS interrupciones por pulso:
El procesador soporta interrupciones por nivel o por pulso. Una interrupción
por nivel es válida hasta que es borrada cuando se accede a la ISR. Una interrupción
por pulso es una variante del modelo por flanco. El flanco debe ser sampleado en el
flanco de baja del reloj del Cortex‐M3.
Para interrupciones por nivel si la señal no ha entrado antes del retorno de la
rutina de interrupción (no es la siguiente de mayor prioridad) la interrupción intenta
reactivarse. Esto significa que la interrupción intentará entrar tras repetidas
invocaciones (hasta que sea la de mayor prioridad).
Una interrupción por pulso puede ser validada durante la ISR para que la
interrupción pueda estar pendiente y activarse al finalizar la ISR anterior. El diseño de
la aplicación debe asegurar que un segundo pulso (de otra interrupción) no llega antes
de que el primer pulso sea activado. Las interrupciones por pulso son más usadas para
señales externas y para señales muestreadas ó periódicas.
I.8. Unidad de protección de memoria (Memory Protection Unit, MPU):
Es un componente opcional para la protección a memoria. El procesador
soporta el estándar ARMv7 Protected Memory Siste Architecture (PMSAv7).
La MPU proporciona:
Protección de regiones.
Solapación de regiones protegidas con prioridad ascendente (7=mayor
prioridad, 0=menor prioridad).
Permisos de acceso.
Exportar atributos de memoria al sistema.
Malos emparejamientos (mismatches) y violación de accesos en la MPU dan como
resultado MemManage Fault Handler.
Se puede usar la MPU para:
Cumplir las reglas de privilegio.
Separar procesos.
Cumplir las reglas de acceso.
La MPU tiene los siguientes registros:
I.8.1. Descripción de registros de la MPU:
I.8.1.1. Registro de tipo de la MPU (MPU Type Register):
Sirve para ver cuántas regiones soporta la MPU. Se leen los bits[15..8] (parte
alta) para determinar si la MPU está presente.
Dirección: 0xE000ED90
Acceso: Sólo lectura
I.8.1.2. Registro de control de la MPU (MPU Control register):
Sirve para:
Activar MPU.
Activar el mapa de memoria predeterminado.
Activar la MPU cuando se activa un hard fault, NMI ó FAULTMASK
(registro especial de enmasaramiento de interrupciones).
Cuando la MPU está habilitada, al menos una región del mapa de memoria está
habilitada. Cuando la está deshabitada, se usa el mapa de memoria predeterminado
como si la MPU no estuviera presente.
Dirección: 0xE000ED94
Acceso: Lectura/escritura
I.8.1.3. Registro de número de región de la MPU (MPU Region Number
register):
Sirve para seleccionar qué regiones de protección son accesibles. Entonces
escribe en el MPU Region Base Address Register ó en el MPU Attributes and Size
Register para configurar las características de la región de protección.
Dirección: 0xE000ED98
Acceso: Lectura/escritura
I.8.1.4. Registro de dirección base de la MPU (MPU Region Base Address
Register):
Sirve para escribir la dirección base de una región. También puedes invalidar el
contenido del MPU Region Number Register y especificarlo en un campo de éste
mismo registro.
Dirección: 0xE000ED9C
Acceso: Lectura/escritura
I.8.1.5. Registro de tamaño y atributos de región de la MPU (MPU región
Attribute and Size register):
Sirve para controlar los accesos de la MPU. Está dividido en dos partes de
media palabra cada una. Se puede acceder a cada parte forma individual o a ambas
partes usando accesos de operaciones de tamaño palabra.
El tamaño de la región de memoria protegida depende de número de región
especificado:
I.8.2. Acceso a la MPU usando los alias registers ó registros de alias:
Se puede optimizar la velocidad de carga de los registros de la MPU usando los
registros de alias. Hay 2 tipos de registros de alias: MPU Alias n Region Base Address
Register y MPU Alias n Region Attribute and Size Register; con n=1, 2, 3.
No se pueden usar estos registros de alias para leer el contenido de las
regiones, ya que el número de región debe ser escrito.
I.8.3. Sub‐regiones:
Las regiones son divididas en 8 sub‐regiones del mismo tamaño. Las sub‐
regiones no son soportadas para tamaños de región de 128 bytes o menos.
En el MPU Region attribute and Size Register hay un campo de 8 bits llamado
Sub‐Region Disable (SRD) , en el que cada bit se corresponde con una de las ocho sub‐
regiones. De esta manera se pueden desactivar independientemente cualquiera de las
8 sub‐regiones.
I.8.4. Interrupciones al actualizar la MPU:
Una región de la MPU puede contener datos críticos. Ésto es porque usa más
de un bus para realizar las operaciones, lo que normalmente requiere de dos palabras.
Entonces una interrupción podría “partir” las dos palabras, proporcionan información
incoherente.
Se pueden dar dos casos:
La interrupción se produce cuando se va actualizar la MPU. El problema es que
la rutina lea, modifique ó escriba ya que podría modificar la configuración de
otra región. El programador debería desactivar las interrupciones antes de cada
rutina actualización.
La interrupción se puede producir cuando se está actualizando una región en
uso, o que han sido actualizados sus campos de dirección base o tamaño.
Puede ocurrir que se modifique otra región. El programador debería desactivar
las interrupciones antes de cada rutina actualización.
En elcaso de tener un sistema operativo estándar esto no suponen problema, ya que
están preparados para éste tipo de situaciones.
En otros casos lo más recomendable es programar la MPU en el código de arranque,
donde las interrupciones están todavía desactivadas.