You are on page 1of 50

I.

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 

ADD <Rd>, SP, #<immed_8> * 
Add 4* (immediate 8‐bit value) with SP to register 

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> 

Multiple sequential memory word loads  LDMIA <Rn>!, <registers> 


Load memory word from base register address + 5-bit immediate offset  LDR <Rd>, [<Rn>, #<immed_5> * 4] 
Load memory word from base register address + register offset  LDR <Rd>, [<Rn>, <Rm>] 
Load memory word from PC address + 8-bit immediate offset  LDR <Rd>, [PC, #<immed_8> * 4] 
Load memory word from SP address + 8-bit immediate offset  LDR, <Rd>, [SP, #<immed_8> * 4] 
Load memory byte [7:0] from register address + 5-bit immediate offset  LDRB <Rd>, [<Rn>, #<immed_5>] 
Load memory byte [7:0] from register address + register offset  LDRB <Rd>, [<Rn>, <Rm>] 
Load memory halfword [15:0] from register address + 5-bit immediate offset  LDRH <Rd>, [<Rn>, #<immed_5> * 2] 
Load halfword [15:0] from register address + register offset  LDRH <Rd>, [<Rn>, <Rm>] 
Load signed byte [7:0] from register address + register offset  LDRSB <Rd>, [<Rn>, <Rm>] 
Load signed halfword [15:0] from register address + register offset  LDRSH <Rd>, [<Rn>, <Rm>] 
Logical shift left by immediate number  LSL <Rd>, <Rm>, #<immed_5> 
Logical shift left by number in register  LSL <Rd>, <Rs> 
Logical shift right by immediate number  LSR <Rd>, <Rm>, #<immed_5> 
Logical shift right by number in register  LSR <Rd>, <Rs> 
Move immediate 8-bit value to register  MOV <Rd>, #<immed_8> 
Move low register value to low register  MOV <Rd>, <Rn> 
Move high or low register value to high or low register  MOV <Rd>, <Rm> 
Multiply register values  MUL <Rd>, <Rm> 
Move complement of register value to register  MVN <Rd>, <Rm> 
Negate register value and store in register  NEG <Rd>, <Rm> 
No operation  NOP <c> 
Bitwise logical OR register values  ORR <Rd>, <Rm> 
Pop registers from stack  POP <registers> 
Pop registers and PC from stack  POP <registers, PC> 
Push registers onto stack  PUSH <registers> 
Push LR and registers onto stack  PUSH <registers, LR> 
Reverse bytes in word and copy to register  REV <Rd>, <Rn> 
Reverse bytes in two halfwords and copy to register  REV16 <Rd>, <Rn> 
Reverse bytes in low halfword [15:0], sign-extend, and copy to register  REVSH <Rd>, <Rn> 
Rotate right by amount in register  ROR <Rd>, <Rs> 
Subtract register value and C flag from register value  SBC <Rd>, <Rm> 
Send event  SEV <c> 
Store multiple register words to sequential memory locations  STMIA <Rn>!, <registers> 
Store register word to register address + 5-bit immediate offset  STR <Rd>, [<Rn>, #<immed_5> * 4] 
Store register word to register address  STR <Rd>, [<Rn>, <Rm>] 
Store register word to SP address + 8-bit immediate offset  STR <Rd>, [SP, #<immed_8> * 4] 
Store register byte [7:0] to register address + 5-bit immediate offset  STRB <Rd>, [<Rn>, #<immed_5>] 
Store register byte [7:0] to register address  STRB <Rd>, [<Rn>, <Rm>] 
Store register halfword [15:0] to register address + 5-bit immediate offset  STRH <Rd>, [<Rn>, #<immed_5> * 2] 
Store register halfword [15:0] to register address + register offset  STRH <Rd>, [<Rn>, <Rm>] 
Subtract immediate 3-bit value from register  SUB <Rd>, <Rn>, #<immed_3> 
Subtract immediate 8-bit value from register value  SUB <Rd>, #<immed_8> 
Subtract register values  SUB <Rd>, <Rn>, <Rm> 
Subtract 4 (immediate 7-bit value) from SP  SUB SP, #<immed_7> * 4 
Operating system service call with 8-bit immediate call code  SVC <immed_8> 
Extract byte [7:0] from register, move to register, and sign-extend to 32 bits  SXTB <Rd>, <Rm> 
Extract halfword [15:0] from register, move to register, and sign-extend to 32
SXTH <Rd>, <Rm> 
bits 
Test register value for set bits by ANDing it with another register value  TST <Rn>, <Rm> 
Extract byte [7:0] from register, move to register, and zero-extend to 32 bits  UXTB <Rd>, <Rm> 
Extract halfword [15:0] from register, move to register, and zero-extend to 32
UXTH <Rd>, <Rm> 
bits 
Wait for event  WFE <c> 
Wait for interrupt  WFI <c> 
 

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 

Memory signed halfword [15:0] from base register address


LDRSH.W <Rxf>. [<Rn>], #+/-<offset_8> 
immediate 8-bit offset, postindexed 
Memory signed halfword [15:0] from base register address
LDRSH.W <Rxf>, [<Rn>, #<+/–<offset_8>]! 
immediate 8-bit offset, preindexed 
Memory signed halfword [15:0] from register address shifted
LDRSH.W <Rxf>, [<Rn>, <Rm>{, LSL #<shift>}] 
left by 0, 1, 2, or 3 places 
Memory signed halfword from PC address immediate 12-bit
LDRSH.W <Rxf>, [PC, #+/–<offset_12>] 
offset 
Logical shift left register value by number in register  LSL{S}.W <Rd>, <Rn>, <Rm> 
Logical shift right register value by number in register  LSR{S}.W <Rd>, <Rn>, <Rm> 
Multiply two signed or unsigned register values and add the
MLA.W <Rd>, <Rn>, <Rm>, <Racc> 
low 32 bits to a register value 
Multiply two signed or unsigned register values and subtract
MLS.W <Rd>, <Rn>, <Rm>, <Racc> 
the low 32 bits from a register value 
Move immediate 12-bit value to register  MOV{S}.W <Rd>, #<modify_constant(immed_12)> 
Move shifted register value to register  MOV{S}.W <Rd>, <Rm>{, <shift>} 
Move immediate 16-bit value to top halfword [31:16] of
MOVT.W <Rd>, #<immed_16> 
register 
Move immediate 16-bit value to bottom halfword [15:0] of
MOVW.W <Rd>, #<immed_16> 
register and clear top halfword [31:16] 
Move to register from status  MRS<c> <Rd>, <psr> 
Move to status register  MSR<c> <psr>_<fields>,<Rn> 
Multiply two signed or unsigned register values  MUL.W <Rd>, <Rn>, <Rm> 
No operation  NOP.W 
ORN{S}.W <Rd>, <Rn>,
Logical OR NOT register value with immediate 12-bit value 
#<modify_constant(immed_12)> 
Logical OR NOT register value with shifted register value  ORN[S}.W <Rd>, <Rn>, <Rm>{, <shift>} 
ORR{S}.W <Rd>, <Rn>,
Logical OR register value with immediate 12-bit value 
#<modify_constant(immed_12)> 
Logical OR register value with shifted register value ORR{S}.W <Rd>, <Rn>, <Rm>{, <shift>} 
Reverse bit order RBIT.W <Rd>, <Rm> 
Reverse bytes in word REV.W <Rd>, <Rm> 
Reverse bytes in each halfword REV16.W <Rd>, <Rn> 
Reverse bytes in bottom halfword and sign-extend REVSH.W <Rd>, <Rn> 
Rotate right by number in register ROR{S}.W <Rd>, <Rn>, <Rm> 
Rotate right with extend RRX{S}.W <Rd>, <Rm> 
RSB{S}.W <Rd>, <Rn>,
Subtract a register value from an immediate 12-bit value
#<modify_constant(immed_12)> 
Subtract a register value from a shifted register value RSB{S}.W <Rd>, <Rn>, <Rm>{, <shift>} 
SBC{S}.W <Rd>, <Rn>,
Subtract immediate 12-bit value and C bit from register value
#<modify_constant(immed_12)> 
Subtract shifted register value and C bit from register value SBC{S}.W <Rd>, <Rn>, <Rm>{, <shift>} 
Copy selected bits to register and sign-extend SBFX.W <Rd>, <Rn>, #<lsb>, #<width> 
Signed divide SDIV<c> <Rd>,<Rn>,<Rm> 
Send event SEV<c> 
Multiply signed words and add signed-extended value to
SMLAL.W <RdLo>, <RdHi>, <Rn>, <Rm> 
2-register value
Multiply two signed register values SMULL.W <RdLo>, <RdHi>, <Rn>, <Rm> 
Signed saturate SSAT.W <c> <Rd>, #<imm>, <Rn>{, <shift>} 
Multiple register words to consecutive memory locations STM{IA|DB}.W <Rn>{!}, <registers> 
Register word to register address + immediate 12-bit offset STR.W <Rxf>, [<Rn>, #<offset_12>] 
Register word to register address immediate 8-bit offset,
STR.W <Rxf>, [<Rn>], #+/–<offset_8> 
postindexed
Register word to register address shifted by 0, 1, 2, or 3 places STR.W <Rxf>, [<Rn>, <Rm>{, LSL #<shift>}] 
Register word to register address immediate 8-bit offset, STR.W <Rxf>, [<Rn>, #+/-<offset_8>]{!}
preindexed Store, preindexed STRT.W <Rxf>, [<Rn>, #<offset_8>] 
Register byte [7:0] to register address immediate 8-bit offset, STRB{T}.W <Rxf>, [<Rn>, #+/–<offset_8>]{!} 
preindexed
Register byte [7:0] to register address + immediate 12-bit
STRB.W <Rxf>, [<Rn>, #<offset_12>] 
offset
Register byte [7:0] to register address immediate 8-bit offset,
STRB.W <Rxf>, [<Rn>], #+/–<offset_8> 
postindexed
Register byte [7:0] to register address shifted by 0, 1, 2, or 3
STRB.W <Rxf>, [<Rn>, <Rm>{, LSL #<shift>}] 
places
Store doubleword, preindexed STRD.W <Rxf>, <Rxf2>, [<Rn>, #+/–<offset_8> * 4]{!} 
Store doubleword, postindexed STRD.W <Rxf>, <Rxf2>, [<Rn>, #+/–<offset_8> * 4] 
Store register exclusive calculates an address from a base
register value and an immediate offset, and stores a word from
STREX <c> <Rd>,<Rt>,[<Rn>{,#<imm>}] 
a register to memory if the executing processor has exclusive
access to the memory addressed.
Store register exclusive byte derives an address from a base
register value, and stores a byte from a register to memory if
STREXB <c> <Rd>,<Rt>,[<Rn>] 
the executing processor has exclusive access to the memory
addressed
Store register exclusive halfword derives an address from a
base register value, and stores a halfword from a register to
STREXH <c> <Rd>,<Rt>,[<Rn>] 
memory if the executing processor has exclusive access to the
memory addressed.
Register halfword [15:0] to register address + immediate 12-bit
STRH.W <Rxf>, [<Rn>, #<offset_12>] 
offset
Register halfword [15:0] to register address shifted by 0, 1, 2,
STRH.W <Rxf>, [<Rn>, <Rm>{, LSL #<shift>}] 
or 3 places
Register halfword [15:0] to register address immediate 8-bit
STRH{T}.W <Rxf>, [<Rn>, #+/–<offset_8>]{!} 
offset, preindexed
Register halfword [15:0] to register address immediate 8-bit
STRH.W <Rxf>, [<Rn>], #+/–<offset_8> 
offset, postindexed
SUB{S}.W <Rd>, <Rn>,
Subtract immediate 12-bit value from register value
#<modify_constant(immed_12)> 
Subtract shifted register value from register value SUB{S}.W <Rd>, <Rn>, <Rm>{, <shift>} 
Subtract immediate 12-bit value from register value SUBW.W <Rd>, <Rn>, #<immed_12> 
Sign extend byte to 32 bits SXTB.W <Rd>, <Rm>{, <rotation>} 
Sign extend halfword to 32 bits SXTH.W <Rd>, <Rm>{, <rotation>} 
Table branch byte TBB [<Rn>, <Rm>] 
Table branch halfword TBH [<Rn>, <Rm>, LSL #1] 
Exclusive OR register value with immediate 12-bit value TEQ.W <Rn>, #<modify_constant(immed_12)> 
Exclusive OR register value with shifted register value TEQ.W <Rn>, <Rm>{, <shift} 
Logical AND register value with 12-bit immediate value TST.W <Rn>, #<modify_constant(immed_12)> 
Logical AND register value with shifted register value TST.W <Rn>, <Rm>{, <shift>} 
Copy bit field from register value to register and zero-extend to
UBFX.W <Rd>, <Rn>, #<lsb>, #<width> 
32 bits
Unsigned divide UDIV<c> <Rd>,<Rn>,<Rm> 
Multiply two unsigned register values and add to a 2-register
UMLAL.W <RdLo>, <RdHi>, <Rn>, <Rm> 
value
Multiply two unsigned register values UMULL.W <RdLo>, <RdHi>, <Rn>, <Rm> 
Unsigned saturate USAT <c> <Rd>, #<imm>, <Rn>{, <shift>} 
Copy unsigned byte to register and zero-extend to 32 bits UXTB.W <Rd>, <Rm>{, <rotation>} 
Copy unsigned halfword to register and zero-extend to 32 bits UXTH.W <Rd>, <Rm>{, <rotation>} 
Wait for event WFE.W 
Wait for interrupt WFI.W 

 
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: 

I.7.2.1. Registro de tipo de control de interrupciones (Interrupt Controller Type


Register): 

É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

 Acceso: Sólo lectura

 Valor tras el reset: Depende del número de interrupciones definidas en la


implementación del procesador.

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

 Valor tras el reset: 0x00000000 

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

 Valor tras el reset: 0x00000000 

 
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

 Valor tras el reset: imprevisible 

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

 Valor tras el reset: impredecible 

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

 Valor tras el reset: STCALIB 

 
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

 Valor tras el reset: 0x00000000 

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

 Valor tras el reset: 0x00000000 

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

 Valor tras el reset: 0x00000000 

 
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

 Valor tras el reset: 0x00000000 

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

 Valor tras el reset: 0x00000000 

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

 Valor tras el reset: 0x00000000 

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

 Valor tras el reset: 0x412FC230 

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

 Valor tras el reset: 0x00000000 

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

 Valor tras el reset: 0x00000000 

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

 Valor tras el reset: 0x00000000 

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

 Valor tras el reset: 0x00000000 

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. 

  Dirección: 0xE000ED18, 0xE000ED1C, 0xE000ED20


 Acceso: lectura/escritura

 Valor tras el reset: 0x00000000 

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. 

  Dirección: 0xE000ED28, 0xE000ED29, 0xE000ED2A


 Acceso: lectura/escritura-uno-para-borrar

 Valor tras el reset: 0x00000000 

En realidad está dividido en tres subregistros:

 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

 Valor tras el reset: 0x00000000 

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

 Valor tras el reset: 0x00000000 

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

 Valor tras el reset: impredecible 


I.7.2.25. Registro de dirección de fallo de bus (Bus Fault Address Register): 

  Sirve para leer la dirección donde se encuentra lo que ha causado el fallo de 
bus. 

  Dirección: 0xE000ED38
 Acceso: lectura/escritura

 Valor tras el reset: impredecible 

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

 Valor tras el reset: 0x00000000 

  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

 Acceso: Sólo escritura

 Valor tras el reset: 0x00000000 

 
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

 Valor tras el reset: 0x00000800 

     

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

 Valor tras el reset: 0x00000000 

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

 Valor tras el reset: Impredecible 

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

 Valor tras el reset: Impredecible 

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.  

   

You might also like