You are on page 1of 97

Chapter 7

Exceptions and Interrupts


7.1 Overview of Exceptions and
Interrupts

• Interrupts are events typically generated by hardware


(e.g., peripherals) that cause changes in program flow
(e.g., to provide service to a peripheral).

• When a peripheral or hardware needs service from the


processor, typically the following sequence would occur:
Contd.
1. The peripheral asserts an interrupt request to the
processor

2. The processor suspends the currently executing task

3. The processor executes an Interrupt Service Routine


(ISR) to service the peripheral, and optionally clear the
interrupt request by software if needed

4. The processor resumes the previously suspended task


Contd.
• In addition to interrupt requests, there are other events that
need services from processor and are called them
“exceptions.”

• In ARM terminology, an interrupt is one type of exception.


Other exceptions in Cortex-M processors included fault
exceptions and System exceptions to support the OS.

• Cortex-M processors having Nested Vectored Interrupt


Controller (NVIC) for exception handling.
& Fault
IRQs

• The Cortex-M3 and Cortex-M4 NVIC supports up to


240 IRQs (Interrupt Requests). Most of the IRQs are
generated by peripherals such as timers, I/O ports,
and communication interfaces (e.g., UART, I2C).

• As opposed to ARM7TDMI, there is no FIQ (Fast


Interrupt) in the Cortex-M processor. However, the
interrupt latency of the Cortex-M3 and Corex-M4 is
very low, only 12 clock cycles, so this does not cause
problems.
Overview of fault exceptions
Electronic systems can go wrong from time to time.
Problems could be bugs in the software, or they can be caused by
external factors such as:
• Unstable power supply
• Electrical noise (e.g., noise from power lines)
• Wearing out of components caused by repetitive programming
• Radiation (e.g., cosmic rays)
•Usage issues (e.g., end users didn’t read the manual) or invalid
external data input

All these issues could lead to failure in the programs running on the
processors.
Contd.
• Cortex-M processors have a efficient fault exception
mechanism. If a fault is detected, a fault exception is
triggered and one of the fault exception handler is executed.

The fault exception handlers can be used in a number of ways:


• Carry out self-reset or Shut down the system safely
• Inform users or other systems that it encountered a problem
• Other remedial actions can be carried out to fix the problem if
possible (e.g., executing a floating point instruction with
floating point unit turned off can cause an error, and can be
easily solved by turning the floating point unit on)
7.2 Exceptions Types

• The Cortex-M processors provide a supports for a number


of system exceptions and external interrupts.

• Exceptions are numbered 1-15 for system exceptions and


16 and above for peripheral interrupts.

• Most of the exceptions have programmable priorities,


and a few system exceptions have fixed priority.
Contd.
• By default, all the faults trigger the HardFault
exception.

• Cortex-M3 and Cortex-M4 processors have three


additional configurable fault exceptions:
MemManage (Memory Management) Fault
Bus Fault
Usage Fault

• These exceptions are triggered only if they are enabled,


These exceptions are called configurable fault
exceptions, and have programmable priority levels.
Usage Fault
• A usage fault is an exception that occurs because of a
fault related to instruction execution. This includes:
• Execution of an undefined instruction (trying to execute
co-processor instructions when the co-processor unit is
disabled).

• User trying to perform unaligned memory access using


load and store multiple instructions

(iii) Divide by zero


Memory Management Fault
• A memory management fault is an exception that occurs
because of a memory protection related fault.

• The MPU or the fixed memory protection constraints


determines this fault, for both instruction and data
memory transactions.

• Program execution from memory region that is defined


as non-executable causes this fault.
• Writing to a read-only region
Bus Fault
• Bus Fault exception occurs if an access is attempted for
an address that is in reserved or Processor is having
wrong privilege level

• Invalid memory region

• Wrong size of data transfer, that is a byte write to a


word-only peripheral register
Hard Fault
• When the Cortex-M processor comes out of reset, only the hard
fault and its handler is enabled. If a usage, bus, or memory
manager fault is raised and the exception for these faults is not
enabled, then the fault will “escalate” to a hard fault.

• A hard fault is an exception that occurs because of an error during


exception processing, or because an exception cannot be
managed by any other exception mechanism.

• Hard faults have a fixed priority of -1, meaning they have higher
priority than any exception with configurable priority.
Registers of Programmable Model
PRIMASK, FAULTMASK, and
BASEPRI registers
• Used for exception or interrupt masking.
• These special registers are also used to mask
exceptions based on priority levels.

• They can only be accessed in the privileged access


level. By default, they are all zero, which means the
masking (disabling of exception/interrupt) is not
active.
Contd.
• The PRIMASK register is a 1-bit wide interrupt mask
register. When set, it blocks all exceptions apart from
the Non-Maskable Interrupt (NMI) and the HardFault
exception.

• The most common usage for PRIMASK is to disable


all exceptions for a time critical process. After the
time critical process is completed, the PRIMASK needs
to be cleared to re-enable interrupts.

• MRS r0, PRIMASK ;


• MSR PRIMASK, r0 ;
Contd.
• The FAULTMASK register is very similar to
PRIMASK, but it also blocks the HardFault
exception, which effectively raises the current
exception priority level to -1.

• FAULTMASK can be used by fault handling


code to suppress the triggering of further
faults (only several types of them) during fault
handling.
Contd.
• MRS r0, FAULTMASK ;
• MSR FAULTMASK, r0 ;
Contd.
• In addition, the Change Processor State (CPS)
instruction allow the value of the PRIMASK and
FAULTMASK to be set or cleared with a simple
instruction.

• CPSIE i ; Enable interrupt (clear PRIMASK)


• CPSID i ; Disable interrupt (set PRIMASK)
• CPSIE f ; Enable interrupt (clear FAULTMASK)
• CPSID f ; Disable interrupt (set FAULTMASK)
Contd.
• To allow more flexible interrupt masking,
the BASEPRI used, which masks exceptions
based on priority level.

• The width of the BASEPRI register depends


on how many priority levels are implemented
in the design, which is determined by the
microcontroller vendors.
Registers of Programmable Model
Contd.
• Most Cortex microcontrollers have 8
programmable exception priority levels or 16
levels, and in these cases the width of BASEPRI
will be 3 bits or 4 bits, respectively.
• When BASEPRI is set to 0, it is disabled.
• When it is set to a non-zero value, it blocks
exceptions that have the same or lower priority
level, while still allowing exceptions with a higher
priority level to be accepted by the processor.
Example
• For example, if only 4-bits are implemented
for priority-level registers, BASEPRI can be
programmed as
0x00, 0x20, 0x40,0x60……….

• MOVS R0, #0x60


• MSR BASEPRI, R0 ; Disable interrupts with
priority levels 0x60-0xFF.
Exception Entry
• The block of data that are pushed to the stack memory
at exception entrance is called a stack frame.

• The exception mechanism needs to save R0 to R3, R12,


LR, return address and PSR at exception entrance
automatically on the stack, and restore them at
exception exit. This is under the control of the
processor’s hardware.
Contd.
• In addition, since the value of the return address (PC) is not
stored in LR, the exception mechanism puts an
EXC_RETURN code in LR at exception entry, which is used
during exception return.

• Link Register (LR) is updated to a code called


EXC_RETURN.

• This value is 32-bit, and the upper 27 bits are set to 1. Some of
the lower 4 bits are used to hold status information about the
exception sequence.(e.g., which stack was used for stacking)
Contd
• The Cortex-M3 and Cortex-M4 processors have multiple
bus interfaces.
• In parallel to the stacking operation, the processor can
also start the vector fetch (typically through the I-CODE
bus), and then start the instruction fetch.
• As a result, the Harvard bus architecture allows the
interrupt latency to be reduced because the stacking
operation and accesses of vector fetch and subsequently
instruction fetches can take place in parallel.
Contd.
Contd.
• Note that the exact order of stack accesses during
stacking is NOT the same order as the registers in the
stack frame.
• The Cortex-M3 processor stacks the PC and xPSR first,
before other registers in the register banks so that the PC
can be updated sooner with the vector fetch.
Exception Exit
• The exception return mechanism is triggered using a
special return address called EXC_RETURN. When
this value is written to the PC with one of the allowed
exception return instructions (BX LR), it triggers the
exception return sequence.
• When the exception return mechanism is triggered, the
processor accesses the previously stacked register
values in the stack memory during exception entrance
and restores them back to the register bank. This is
called unstacking.
Contd.
• To reduce the time required for the unstacking operation,
the return address (PC) value is accessed first, so that
instruction fetch can start in parallel with the rest of the
unstacking operation.
10.1 OS Supported Features
• The Cortex-M processors are designed with OS support in mind.
Currently there are over 30 different embedded OSs (including
many RealTime OS, or RTOS) available for Cortex-M
microcontrollers. A number of features are implemented in the
architecture to make OS implementation easier and more
efficient.
• SVC and PendSV exceptions: These two exception types are
essential for the operations of embedded OSs such as the
implementation of context switching.
• Shadowed stack pointer: Two stack pointers are available. In
systems with an embedded OS or RTOS, the exception handlers
use the MSP, while the application tasks use the PSP.
Contd.
• In systems with high-reliability requirements, the
application tasks can be running in unprivileged access
level, and some of the hardware resources can be set up
to be accessed in privileged level only.

• This allows the interrupt handler code full access to the


chip without the risk that it may be corrupted by the
application code.

• However, at some point, if the application code will


need to access protected resources which are only
accessible in the handler mode only.
Contd.
• To allow this to happen, the Thumb-2 instruction set
has an instruction called Supervisor Call (SVC).

• When this instruction is executed, it raises a supervisor


exception that moves the processor from executing the
application code in thread/unprivileged mode to an
exception routine in handler/privileged mode.
Application code can access the protected resources.
SVC
• The SVC (Supervisor Call) exceptions are important to
OS designs. SVC is exception type 11, and has a
programmable priority level.
• The SVC exception is triggered by the SVC instruction.
SVC Exception
• Each of the functions (Test.c) is designed to be called
with an SVC instruction so that all of these functions
run in handler mode and access protected resources.

• In order to convert the arithmetic functions from standard


functions to software interrupt functions, we need to
change the way the function prototype is declared.

• In the ARM compiler there is a function qualifier __svc.


Contd.
• The __svc qualifier defines the function as an SVC function
and defines the ordinal number of the function. The ordinals
used must start from zero and grow upward contiguously to a
maximum of 256.
• res = add (74, 27);

• int __svc(0) add (int i1, int i2); declare as SVC function

int __SVC_0 (int i1, int i2) ; function definition


{ return (i1 + i2); }
Pass up to four parameters with return values.
• Import user SVC functions here.
IMPORT __SVC_0
IMPORT __SVC_1
IMPORT __SVC_2
IMPORT __SVC_3
SVC_Table
• Insert user SVC functions here
DCD __SVC_0
DCD __SVC_1 ;
DCD __SVC_2 ;
DCD __SVC_3 ;
• To enable each ordinal, necessary to build a lookup table.
• Import the label used for each supervisor function and then add the function labels to
the SVC table.
• When the code is compiled, the labels will be replaced by the entry address of each
function.
SVC Fault Handler
• First, the SVC Handler reads the link register to
determine stack pointer (MSP/PSP) and the operating
mode.
• Then it reads the value of the return address from the
appropriate stack.

• We can then read the memory location holding the SVC


instruction and extract the ordinal value. This number
is then used as an index into a lookup table to load the
address of the function that is being called.
Check Validity of SVC Number
• The size of the SVC table is loaded into the LR. The
SVC ordinal is compared to the table size to check
whether it is less than the SVC table size and hence a
valid number.

• If it is valid, the function address is loaded into R12


from the SVC table and the function is called. If the
ordinal number has not been added to the table, the code
will jump to a trap called SVC_DEAD.
• This way the individual threads can access the protected
resources by making SVC calls to the OS.

• SVC instruction is used to allow a user program to call the


operating system in order to request services related to
system internals such as the process involving main memory
access, the process involving network hardware access etc.
Contd.
• When a user program wants to use certain hardware, it
generates the SVC exception using SVC instructions, and
then the software exception handler in the operating
system is executed and provides the service to the user
application requested.
• In this way, access to hardware is under the control of
the OS, which can provide a more robust system by
preventing the user applications from directly accessing
hardware.
Contd.
• This mechanism provides the basis of a supervisor/user split
where an OS is running in privileged mode and acts as a
supervisor to application threads running in unprivileged
thread mode.

• Supervisor call provides the services of the operating system


to the user programs via Application Program Interface(API).

• Embedded system can be more robust and secure, because the


application tasks cannot gain unauthorized access to
critical hardware.
Contd.
• Supervisor calls provide interfaces between the
operating system and the system processes. The
majority of the operations that interact with the
system require permissions that are not available to
user-level processes.
10.2 Shadow Stack Pointer
• Main Stack Pointer (MSP) is the default stack pointer. It is used
in the Thread mode when the CONTROL bit[1] (SPSEL) is 0,
and it is always used in Handler mode.
• Processor Stack Pointer (PSP) is used in Thread mode when the
CONTROL bit [1] (SPSEL) is set to 1.
• In systems with an embedded OS or RTOS, the exception
handlers (including part of the OS kernel) use the MSP, while
the application tasks use the PSP. This arrangement has several
benefits:
• If an application task encounters a problem that leads to a stack
corruption, the stack used by the OS kernel and other tasks is
still likely to be intact, thus helping to improve system reliability.
Contd.
• To use the process stack, put OS in Handler mode (software
exception handler in the operating system is executed), and
program the PSP directly, then use an exception return
sequence to “jump” into the application Task

• LDR R0,=PSP_TOP ;
MSR PSP, R0 ; Set PSP to the top of a process stack
MRS R0, CONTROL ; Read current CONTROL
ORRS R0, R0, #0x2 ; Set SPSEL
MSR CONTROL, R0 ; write to CONTROL
OS with Context Switching
• In embedded OS, the processing time is divided into a
number of time slots. For a system with only two tasks, the
two tasks are executed alternatively.
• The execution of an OS kernel can be triggered by:
• Execution of SVC instruction from application tasks. For
example, when an application task is stalled because it is
waiting for some data or event, it can call a system service
to swap in to another task.
• Periodic SysTick exception.
Contd.
• Inside the OS kernel code, the task scheduler can decide if
context switching should be carried out. The task scheduler is
triggered by a SysTick exception, and each time it decides to
switch to a different task.

• All of the Cortex-M processors contain a standard timer.


This is called the Systick timer and is a 24-bit
countdown timer with auto reload. Once started the
Systick timer will count down from its initial value. Once
it reaches zero it will raise an interrupt and a new count
value will be loaded from the reload register.
SysTick Timer
• The Cortex-M processors have a small integrated timer
called the SysTick (System Tick) timer. It is integrated as a
part of the NVIC and can generate the SysTick exception
(exception type #15).

• The SysTick timer is a simple decrement 24-bit timer, and can


run on processor clock frequency In modern operating
systems, a periodic interrupt is needed to ensure that the OS
kernel can invoke regularly; for example, for task
management and context switching. This enables a processor
to handle different tasks in different time slots.
Block Diagram
Registers
• The counter is enabled by setting bit 0 of the Control and Status
register, the current value register decrements at every processor
clock cycle or every rising edge of the reference clock.
• If it reaches zero, generates the SYSTICK Exception and it will
then load the value from the reload value register and continue.
while (1);
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
{
return (1UL); /* Reload value impossible */
}

SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */


SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick
Timer */
return (0UL); /* Function successful */
}
Contd.
• The main purpose of this timer is to generate a periodic
interrupt for an RTOS.

• A typical OS running on the Cortex-M processor will use


the SVC exception to allow user threads to make calls
to the OS API, and the Systick timer will be used to
generate a periodic exception to trigger the OS
scheduler.
Generate a Periodic SysTick
Interrupt
• CMSIS function : uint32_t SysTick_Config(uint32_t ticks);
• This function sets the SysTick interrupt interval to “ticks,” enables the
counter using the processor clock, and enables the SysTick exception
with the lowest exception priority.
• Clock frequency of 30MHz and we want to generate a SysTick
exception of 1KHz,:
• SysTick_Config (System Core Clock / 1000);

• SysTick_Config (30000); // 30MHz / 1000 = 30000

• The “SysTick_Handler(void)” will then be triggered at a rate of 1


kHz.
Contd.
• The processor design also ensures that the application tasks
running at unprivileged level cannot disable this timer;
otherwise, these tasks could disable the SysTick timer and
lock out the whole system.

• If you do not need an embedded OS in your application, the


SysTick timer can be used as a simple timer peripheral for
periodic interrupt generation, delay generation, or timing
measurement.
Problems can occur when the Systick timer is running at a
high priority. If an interrupt request (IRQ) takes place before
the SysTick exception, the SysTick exception might preempt
the IRQ handler. OS scheduler examines the state of the user
threads and performs a context switch to start a new thread
running. This process can delay execution of the peripheral
interrupt by several hundred cycles.
Example

• If the RTOS systick interrupt is running at a high


priority, it can delay peripheral interrupts making
interrupt handling nondeterministic.
PendSv Exception
• The PendSV exception solves the problem by delaying the
context-switching request until all other IRQ handlers have
completed their processing. To do this, the PendSV is
programmed as the lowest-priority exception.

• Pend_SVC is a second software interrupt, to extend the


support for OS.

• The PendSV Exception is triggered by setting its pending


status by writing to the Interrupt Control and State Register
(ICSR)
Use of PendSV
• Besides context switching in an OS environment, PendSV can
also be used in systems without an OS.

• An interrupt service can need a fair amount of time to process.


If assumed that first portion of the ISR (part of ISR) might
need a high priority (time-critical part). However, if the
whole ISR is executed with a high priority level, other
interrupt services would be blocked out for a long time. In
such cases, we can partition the interrupt service processing
into two halves :
• The first half is the time-critical part that needs to be
executed quickly with high priority. It is put inside the
normal ISR. At the end of the ISR, it sets the pending
status of the PendSV.
• The second half contains the remaining processing work
needed for the interrupt service. It is placed inside the
PendSV handler and is executed with low priority. Hence,
other interrupt requests can be served.
Case Study
Contd.
• NVIC_SetPriority(PendSV_IRQn,2); //set interrupt priorities
• NVIC_SetPriority(ADC1_2_IRQn,1);
• NVIC_EnableIRQ(ADC1_2_IRQn); //enable the ADC
interrupt
• ADC1->CR1 |= (1UL<<5); //switch on the ADC and start a
conversion
• ADC1->.CR2 |= (1UL<<0);//
• ADC1->CR2 |= (1UL<<22);//
• systemCode(); //call some system code with an SVC interrupt
Contd.
• The code initializes the ADC and enables its end of
conversion interrupt. It also changes the Pend_SVC and ADC
interrupt priority from their default options.

• The SVC has priority zero (highest) while the ADC has
priority 1, and the Pend_SVC interrupt has priority 2 (lowest).

• The systemCode function (SVC function) uses an SVC


instruction to raise an exception and move to handler mode.
Contd.
void __svc(0) systemCode (void);
void __SVC_0 (void) {
unsigned int i, pending;
for(i=0; i<100;i++); // time critical section
pending = NVIC_GetPendingIRQ(ADC1_2_IRQn);
if(pending = =1){
SCB->>ICSR |= 1<<28; //set the pending status of Pend_SV
}
else
{
for(i=0; i<100;i++); //non-time critical section
}
}
Contd.
• Inside the system code routine, there is a short loop that
represents the critical section of code that must be run.
While this loop is running, the ADC will finish conversion,
and as it has a lower priority than the SVC interrupt it will
enter a pending state.
• When loop is exist, program test the state of any critical
interrupts by reading their pending bits.
• If a critical interrupt is pending, then the remainder of the
system code function can be delayed. To do this, the
PENDSVSET bit in the ICSR register is set in the SVC
handler .
Contd.

• Once SVC exits, the program enters into the next pending
interrupt.

• Both of the pending interrupts will be tail chained on to the


end of the system service call.

• The ADC has the highest priority so it will be served next.

• Then PendSV handler executes next.


Contd.
1. Task A calls SVC for task switching (for example, waiting for
some work to complete).
2. The OS receives the request, prepares for context switching, and
pends the PendSV exception.
3. When the CPU exits SVC, it enters PendSV immediately and does
the context switch (carries out the context switching within the
PendSV exception).
4. When PendSV finishes and returns to Thread level, it executes Task
B.
5. An interrupt occurs and the interrupt handler is entered.
6. While running the interrupt handler routine, a SYSTICK
exception (for OS tick) takes place.
Contd.
7. The OS carries out the essential operation, then pends the
PendSV exception and gets ready for the context switch.
8. When the SYSTICK exception exits, it returns to the
interrupt service routine.
9. When the interrupt service routine completes, the PendSV
starts and does the actual context-switch operations.
10. When PendSV is complete, the program returns to Thread
level; this time it returns to Task A and continues the
processing.

If the OS decides that context switching is needed, it sets the


pending status of the PendSV, and carries out the context
switching within the PendSV exception.
2.9 The Cortex Microcontroller Software
Interface Standard (CMSIS)
• CMSIS was developed by ARM to allow microcontroller
and software vendors to use a consistent software
infrastructure to develop software solutions for Cortex-
M microcontrollers.
• Currently the Cortex-M microcontroller market
comprises:
- More than 15 microcontroller vendors shipping
Cortex-M microcontroller products.
- More than 10 toolchain vendors
- More than 30 embedded operating systems
Contd.
• CMSIS helps to speed up software
development through the use of standardized
software functions.
• With such a large ecosystem, some form of
standardization of the way the software
infrastructure works becomes necessary to
ensure software compatibility with various
development tools and between different
software solutions.
Contd.
• For example, an embedded software project might involve
software components from many different sources:
- Software developed by in house developers
- Software reused from other projects
- Device-driver libraries from microcontroller vendors
- Embedded Oss
- Other third-party software products such as communication
protocol stacks
Contd.
• In such scenarios, the interoperability of various software
components becomes critical. For all these reasons, ARM
worked with various microcontroller vendors, tools vendors,
and software solution providers to develop CMSIS, a software
framework covering most Cortex-M processors and Cortex-M
microcontroller products.

• CMSIS is a vendor-independent hardware abstraction layer


for the Cortex-M processor series. The CMSIS enables
consistent and simple software interfaces to the processor
and the peripherals, simplifying software re-use, reducing
the learning curve for new microcontroller developers and
reducing the time to market for new devices.
CMSIS files are integrated into device-driver library packages from
microcontroller vendors.
CMSIS-Core
• The CMSIS files are included in the device-driver packages
provided by the microcontroller vendors. So when CMSIS-
compliant device-driver libraries provided by the
microcontroller vendors is used, we are already using CMSIS.
Add header files into search path of the project. This includes:
• A device-specific header file for peripheral registers definitions
and interrupt assignment definitions. (e.g., <device>.h)
• A device-specific header file for functions in device
initialization code (e.g., system_<device>.h)
• A number of processor-specific header files (e.g., core_cm3.h,
core_cm4.h; they are generic for all microcontroller vendors)
CMSIS Core

• The core specification provides a minimal set of functions and


macros to access the key Cortex-M processor registers.

• The core specification also defines a function to configure the


microcontroller oscillators and clock tree in the startup code so
the device is ready for use when you reach main ( ).

• CMSIS-Core e.g. a set of APIs for application or middleware


developers to access the features on the Cortex-M processor
regardless of the microcontroller devices or toolchain used.
CMSIS Core Register Access
CMSIS Interrupt and Exception
Functions
CMSIS Code

• SysTick_Config(SystemCore_Clock / 100);
• NVIC_EnableIRQ (ADC1_2_IRQn);
• NVIC_SetPriorityGrouping (5);
• NVIC_SetPriority (SysTick_IRQn,4);
• NVIC_SetPriority (ADC1_2_IRQn,4);
Equivalent non-CMSIS code.

SysTick->VAL= 0x9000; //Start value for the sysTick counter


SysTick->LOAD= 0x9000; //Reload value
SysTick->CTRL=SYSTICK_INTERRUPT_ENABLE
|SYSTICK_COUNT_ENABLE; //Start and enable interrupt
NVIC->ISER[0]= (1UL <<18); /* enable ADC Interrupt */
NVIC->IP[18] = (2<<6 | 2<<4);
SCB->SHP[11]= (1<<6 | 3<<4);
• Temp=SCB->AIRC;
• Temp &= ~0x
• Temp=Temp|(0xAF0<< )|(0x05<<);
CMSIS RTOS
• The CMSIS RTOS specification provides a standard API for
an RTOS. This is in effect a set of wrapper functions that
translate the CMSIS RTOS API to the API of the specific
RTOS that you are using.
Benefits
• The main advantage is much better software portability and
reusability:
• A project for a Cortex-M microcontroller device can be migrated to
another device from the same vendor with a different Cortex-M
processor very easily. Often microcontroller vendors provide devices
with Cortex-M0/M1/M3/M4 with the same peripheral and same pin
out, and the change required is just replacing a couple of CMSIS
files in the project.
• CMSIS-Core made it easier for a Cortex-M microcontroller project
to be migrated to another device from a different vendor.
Obviously, peripheral setup and access code will need to be modified,
but processor core access functions are based on the same CMSIS
source code and do not require changes.
Contd.
• Since all CMSIS-compliant device drivers have a similar
structure, learning to use a new Cortex-M microcontroller is
much easier.

• The CMSIS code has been tested by many silicon vendors


and software developers around the world. It is compliant with
Motor Industry Software Reliability Association (MISRA).
Therefore it reduces the validation effort required, as there is
no need to develop and test your own processor feature access
functions.
Contd.
• For developers of embedded OS and middleware, the advantage of
CMSIS is significant:
• By using processor core access functions from CMSIS, embedded
OS, and middleware can work with device-driver libraries from
various microcontroller vendors, including future products that are yet
to be released.
• Since CMSIS is designed to work with various toolchains, many
software products can be designed to be toolchain independent.
• Without CMSIS, middleware might need to include a small set of
driver functions for accessing processor peripherals such as the
interrupt controller. Such an arrangement increases the program size,
and might cause compatibility issues with other software products
Contd.
• The aims of CMSIS include:
 Enhanced software reusability - makes it easier to reuse software
code in different Cortex-M projects, reducing time to market and
verification efforts.
 Enhanced software compatibility - by having a consistent software
infrastructure (e.g., API for processor core access functions, system
initialization method, common style for defining peripherals), software
from various sources can work together, reducing the risk in
integration.
 Easy to learn - the CMSIS allows easy access to processor core
features from the C language. In addition, once you learn to use one
Cortex-M microcontroller product, starting to use another Cortex-M
product is much easier because of the consistency in software setup.
Contd.
• Toolchain independent - CMSIS-compliant device
drivers can be used with various compilation tools,
providing much greater freedom.
2.9.2 Areas of standardization in
CMSIS-Core
• The CMSIS files are integrated into device-driver
library packages from microcontroller vendors. Some
of the files in the device-driver library are prepared by
ARM and are common to various microcontroller
vendors.
• The CMSIS-Core standardizes a number of areas:
• Standardized access functions to access processor’s features.
These include various functions for interrupt control using
NVIC, and functions for accessing special registers in the
processors. It is still possible to access the registers directly
if needed, but for general programming using the access
functions.
Contd.
• Standardized definitions for the processor’s peripherals. These
include the registers in the Nested Vector Interrupt Controller
(NVIC), a system tick timer in the processor (SysTick), an
optional Memory Protection Unit (MPU), various
programmable registers in the System Control Block (SCB),
and some software programmable registers related to debug
features.

• Standardized functions for accessing special instructions easily.


The Cortex-M processors support a number of instructions for
special purposes (e.g., Wait- For-Interrupt, WFI, for entering
sleep mode).

• Standardized function names for system exception handlers

You might also like