Rapid Embedded Systems
Rapid Embedded Systems
Arm is committed to making the language we use inclusive, meaningful, and respectful. Our goal is to remove and
replace non-inclusive language from our vocabulary to reflect our values and represent our global ecosystem.
Arm is working actively with our partners, standards bodies, and the wider ecosystem to adopt a consistent approach
to the use of inclusive language and to eradicate and replace offensive terms. We recognise that this will take time. This
course contains references to non-inclusive language; it will be updated with newer terms as those terms are agreed
and ratified with the wider community.
Contact us at education@arm.com with questions or comments about this course. You can also report non-inclusive
and offensive terminology usage in Arm content at terms@arm.com.
Register banks
ALU
Microprocessor
Instructions
Single Multiple
System Bus
Microcontroller
Source: https://developer.arm.com/ip-products/subsystem/corstone-foundation-ip/cortex-m-system-design-kit
8 © 2019 Arm Limited
From a Processor to an Embedded System
• Embedded system
• Typically implemented using MCUs
• Often integrated into a larger mechanical or electrical system
• May have real-time constraints
Embedded
System
• Diagnostics
• Help service personnel determine problems quickly
• Sequencing
• Step through different stages based on environment and system
Input:
Inputs: Wheel rotation
Functions:
- Wheel rotation indicator Mode key
- Speed measurement
- Mode key
- Distance measurement
Output:
Constraints: - Liquid crystal display
- Size
- Cost Use low-performance
- Power and energy microcontroller: Output:
- 9-bit, 10 MIPS Display speed and
- Weight distance
Constraints:
Use high-performance
- Reliability in harsh microcontroller:
environment
- E.g. 32-bit, 3 MB flash
- Cost memory, 50-300 MHz
- Size
• Energy harvesting
ASIC high ($500K/ very low hard tiny – 1 die very low low extremely fast
mask set)
Programmable logic – low to mid mid easy small low medium to high very fast
FPGA, PLD
Microprocessor + memory low to mid mid easy small to medium low to moderate medium moderate
Software Running on
+ peripherals
Generic Hardware
Microcontroller (int. low mid to low easy small low medium slow to moderate
memory & peripherals)
Embedded PC low high easy medium moderate to high medium to high fast
• Programming language
• Programmed in the C language rather than Java (resulting in smaller and faster code – less expensive
MCU)
• Some performance-critical code may be in assembly language
• Operating system
• Typically no OS, but instead a simple scheduler
• If OS is used, it is likely to be a lean RTOS
In the upcoming labs, we will learn some fundamentals of developing for embedded
systems. This will be achieved using an easy-to-start MCU design suite – the Mbed
platform.
• Software programming
– Programming basics: C/C++ programming
– Introducing the Mbed platform
– Learn to use software libraries: Mbed API
• Arm
• The company that designs Arm-based processors
• Arm does not manufacture, but it licenses designs to semiconductor partners who add their own intellectual
property (IP) on top of Arm’s OP, which they then fabricate and sell to customers
• Arm also offers IP other than processors, such as physical IPs, interconnect IPs, graphics cores and development
tools
Cortex-R4
• Cortex-R series (Real-time) Cortex-R5
Cortex-R Cortex-R7
Cortex-R8
• High performance and reliability for real-time applications
Cortex-R52
• Applications include automotive braking systems, powertrains
Cortex-M0
Cortex-M7
Cortex-M0+
• Cortex-M series (Microcontroller) Cortex-M Cortex-M1
Cortex-M23
Cortex-M33
Cortex-M3
• Cost sensitive solutions for deterministic microcontroller applications Cortex-m35P
Cortex-M4
• Applications include microcontrollers, smart sensors
• SecurCore series for high security applications SecurCore SC000 Processor
SC300 Processor
IP libraries SoC
Cortex-A9 Cortex-R5 Cortex-M4 Arm
ROM RAM
processor
Arm7 Arm9 Arm11
System bus Arm-based
DRAM ctrl FLASH ctrl SRAM ctrl SoC
Peripherals
AXI bus AHB bus APB bus
• Smaller code
• Lower silicon costs
• Ease of use
• Faster software development and reuse
• Embedded applications
• Smart metering, human interface devices, automotive and industrial control systems, white goods,
consumer products and medical instrumentation
Cortex-M4 Armv7E-M Harvard Entire Entire 1 cycle Yes Yes Yes Optional
Cortex-M7 Armv7E-M
Harvard Entire Entire 1 cycle Yes Yes Yes Optional
• Enhanced determinism
• The critical tasks and interrupt routines can be served quickly in a known number of cycles
• Harvard architecture
• Separated data bus and instruction bus
• Instruction set
• Includes the entire Thumb-1 (16-bit) and Thumb-2 (16/32-bit) instruction sets
• Supported interrupts
• Non-maskable interrupt (NMI) + 1 to 240 physical interrupts
• 8 to 256 interrupt priority levels
• Enhanced instructions
• Hardware divide (2-12 cycles)
• Single-cycle 16, 32-bit MAC, single-cycle dual 16-bit MAC
• 8, 16-bit SIMD arithmetic
Cortex-M4 Processor
Interrupts and Nested Cortex-M4 Core
power control Vectored Embedded
Interrupt Floating Point Trace
Controller Unit (FPU) Macrocell
(NVIC)
Wake-up
Interrupt
Controller
Memory
(WIC) Flash Data
Protection
Patch Watchpoint
Unit (MPU)
Time
15 © 2019 Arm Limited
Cortex-M4 Block Diagram
• Nested vectored interrupt controller (NVIC)
• Up to 240 interrupt request signals and an NMI
• Automatically handles nested interrupts, such as comparing priorities between interrupt requests and the current
priority level
• Debug subsystem
• Handles debug control, program breakpoints, and data watchpoints
• When a debug event occurs, it can put the processor core in a halted state, so developers can analyse
the status of the processor, such as register values and flags, at that point
• Cortex-M4 registers
– Register bank
16x 32-bit registers (thirteen are used for general-purpose)
– Special registers
R5
General purpose
R6
register
R7
R8
R9
R10 High
Registers
R11
R12 MSP
SP R13(banked) Main SP
LR R14 PSP
PC R15 Process SP
Special registers Program Status Registers (PSR) x PSR APSR EPSR IPSR
PRIMASK Application Execution Interrupt
PSR PSR PSR
Interrupt mask register FAULTMASK
BASEPRI
Stack definition CONTROL
PUSH POP
• Low registers (R0-R7) can be accessed by any instruction
Low
• High registers (R8-R12) sometimes cannot be accessed e.g. by some Thumb Stack Address
(16-bit) instructions
SP
High
PC
• R13: Stack Pointer (SP)
Heap
• Used for saving the context of a program while switching between tasks Code
• Cortex-M4 has two SPs: Main SP, used in applications that require privileged
access e.g. OS kernel and process SP, used in base-level application code
(when not running an exception handler)
PUSH POP
Stack Address
• Automatically incremented by four at each operation (for 32-
bit instruction code), except branching operations SP
High
PC
Heap
• A branching operation, such as function calls, will change the
PC to a specific address, while saving the current PC to the LR
Code
Current PC Current LR
PC LR
1. Save current Main Main
PC to LR Program Program
Code region
Code region
code Load PC with the code
LR
address in LR to
return to the main
2. Load PC with program
the starting
address of the
subroutine subroutine
subroutine Current PC
PC
APSR N Z C V Q Reserved
• IPSR
• Interrupt service routine (ISR) number: current executing ISR number
• EPSR
• T: Thumb state: always one since Cortex-M4 only supports the Thumb state
• IC/IT: Interrupt-continuable instruction (ICI) bit, IF-THEN instruction status bit
PRIMASK Reserved
FAULTMASK
FAULTMASK Reserved
BASEPRI
BASEPRI Reserved
CONTROL Reserved
• Program data
• How is data stored in RAM?
• Data types
• Accessing data using C and assembly
• Programming language
• Embedded systems are usually programed using C (or C++) language and assembly language.
• Arm-based tools can compile the C code or the assembly code to the executable file, which can be executed by Arm-based
processors.
• A completely integrated program code can also be referred as a program image or an executable file.
Easy handling of complex data structures No direct control over stack usage
Allows direct control to each instruction step and Takes a longer time to learn
all memory
Assembly Allows direct access to instructions that cannot be Difficult to manage data structure
generated with C
Less portable
Off-line Compilation
C Code
Compile Processor
Assembly Code Fetch
Instruction Fetch
Assemble Decode
Object Code Libraries
Link Execute
Program Image
armcc armasm
.O Files
.S Files
C/C++
C/ C++
Object C/C++
C/ C++
Libraries
Link
armlink &
armmar .AXF File
.LIB file
Image
Executable
.BIN File
.HEX File
Binary
Disassembly File
6 © 2019 Arm Limited
Compiler Stages
• Pre-processing
• Replaces macros, defined by an initial hash-tag (#) in the code
• Parser
• Reads in C code
• Code Generator
• Creates assembly code step-by-step from each node of the intermediate code
Address
External RAM
Peripherals
Mainly used for data memory, e.g., on-chip 0x3FFFFFFF
SRAM, SDRAM SRAM Region 512MB
0x20000000
0x1FFFFFFF
Mainly used for program image, e.g., on-chip Code Region 512MB
0x00000000
FLASH
Global Memory Space
variables
• Stack: contains the temporary data for local variables,
parameter passing in function calls, registers saving Memory
Address
during exceptions, etc.
• Heap: contains the pieces of memory spaces that are Heap
Grow
Upwards
dynamically reserved by function calls, such as
‘alloc()’ and ‘malloc ()’
Static
Data
Low
• The table in the next slide shows the implementation of different data types
0 to 4294967295
int, int32_t, uint32_t, long Word -2147483648 to 2147483647
0 to 264-1
long long, int64_t, uint64_t Double word -263 to 263-1
ExecFuncPtr exception_table[] = {
(ExecFuncPtr)&Image$$Arm_LIB_STACK$$ZI$$Limit, /* Initial SP */
(ExecFuncPtr)__main, /* Initial PC */
NMIException,
HardFaultException,
MemManageException,
BusFaultException,
UsageFaultException,
0, 0, 0, 0, /* Reserved */
SVCHandler,
DebugMonitor,
0, /* Reserved */
PendSVC,
SysTickHandler
/* Configurable interrupts start here...*/
};
#pragma arm section
• Read-Modify-Write operation
– Read the real data address (0x20000000)
– Modify the desired bit (retain other bits unchanged)
– Write the modified data back
• Bit-band operation
– Directly set the bit by writing ‘ 1’ to address 0x2200000C, which is the alias address of fourth bit of the 32-bit
data at 0x20000000
;Read-Modify-Write Operation
;Bit-band Operation
LDR R1, =0x20000000 ;Setup address
LDR R1, =0x2200000C ;Setup address
LDR R0, [R1] ;Read
MOV R0, #1 ;Load data
ORR.W R0, #0x8 ;Modify bit
STR R0, [R1] ;Write
STR R0, [R1] ;Write back
• Alternatively, C macros can be used to easily access bit-band alias, for example:
#define RAM_Data1 *((volatile unsigned long *)(0x20000000))
#define bit-band(data_addr, bit) ((data_addr & 0x0F0000000) + 0x2000000 +
((data_addr & 0xFFFFF)<<5)+(bit<<2))
#define Data_Addr (data_addr) *((volatile unsigned long*)(data_addr))
• Register R0, R1, R2, R3, R12, and LR could be changed; hence, it is better to save them to the stack.
• Input parameters must be stored in the correct registers, for example, registers R0 to R3 can be used
for passing four parameters.
• If registers R4 to R11 need to be changed, they must be stacked and restored in the assembly function
• If another function is called inside the assembly function, the LR needs to be saved on the stack and
used for return
_asm int add_asm( int k1, int k2, int k3, int k4) {
void main {
int x;
x = add_asm (11,22,33,44); // call assembly function
…
}
• Goal: to change the colour of the RGB LED when the switch is pressed
• Need to add an external switch
– Resistor is internal – a pull-up resistor
• A better option is an interrupt, i.e., using special hardware in the MCU to detect and run
ISR in response. An interrupt is:
• Efficient: the code runs only when necessary
• Fast: it’s a hardware mechanism
• Scalable:
– ISR response time doesn’t depend on most other processing
– Code modules can be developed independently
Hardwired CPU
response activities
Interrupt routine
Main code
Time
• Main code will light LEDs according to count value in binary sequence (Blue: 4, Green: 2, Red: 1)
• Main code will toggle its debug line each time it executes
• ISR will raise its debug line (and lower main’s debug line) whenever it is executing
Thread
Mode
MSP or PSP
Exception Starting
Processing Exception
Completed Processing
Handler Mode
MSP
Reset:
NMI_IRQHandler:
…
IRQ0_Handler:
IRQ1_Handler:
SP value reduced
since registers have been
pushed onto stack.
• Modes
• Thread Mode: entered on reset Port Module
• Handler Mode: entered on executing an exception
Arm Cortex
Next Module NVIC
Core
• Privilege level
Another Module
• Stack pointers
• Main Stack Pointer, MSP
• Process Stack Pointer, PSP
• CMSIS-CORE API
• void __enable_irq() - clears PM flag
• void __disable_irq() - sets PM flag
• uint32_t __get_PRIMASK() - returns value of PRIMASK
• void __set_PRIMASK(uint32_t x) - sets PRIMASK to x
• Why do we care?
• This is overhead, which wastes time and increases as the interrupt rate rises
• This delays our response to external events, which may or may not be acceptable for the application, such as
sampling an analog waveform
• Now each C source read of a variable (e.g. status register) will result in an assembly language LDR
instruction.
• Failure Case
• Preemption enables ISR to interrupt other code and possibly overwrite data
• Must ensure atomic (indivisible) access to the object
– Native atomic object size depends on processor’s instruction set and word size
‘Anomalous behavior due to unexpected critical dependence on the relative timing of events. Result of
example code depends on the relative timing of the read and write operations.’
• Critical section
‘A section of code which creates a possible race condition. The code section can only be executed by one
process at a time. Some synchronization mechanism is required at the entry and exit of the critical section to
ensure exclusive use.’
• Digital IO examples
• Using LED
• Using 7-segment display
• Using infrared emitter/detector
• Different logic can, however, have different meanings in different contexts depending
on the interpretation we give to different voltage levels
https://students.cs.byu.edu/~clement/cs224/labs/L06a-
• Change ratio between on and off times within one
periodic cycle
morse/images/PWM_duty_cycle.jpg
• Duty-cycle: ton / (ton + toff)
= ton / tcycle
• Application
• Control of voltage-sensitive components such as LEDs or
servos
MUX
the pin control register (PCR). Pin Pad
Clk
MUX
Bus Interface
• Port Mode Register (MODER) - configure the I/O direction mode (input/output/alternate/analog)
• Output Type Register (TYPER) – configure the output type of the I/O port (push-pull/open-drain)
• Output Speed Register (OSPEEDR) – configure the I/O output speed (2/25/50/100 MHz)
• Pull-Up/Pull-Down Register (PUPDR) – configure the I/O pull-up or pull-down (no pull-up, pull-down/pull-up/pull-down)
• Input Data Register (IDR) – contain the input value of the corresponding I/O port
• Output Data Register (ODR) – can be read and written by software (ODR bits can be individually set and reset by writing to the BSRR)
• Bit Set/Reset Register (BSRR) – can be used for atomic bit set/reset
• Configuration Lock Register (LCKR) – used to lock the configuration of the port bits when a correct write sequence is applied to bit 16
RCC_AHB1ENR |= 0x02;
GPIOB_MODER |= 0x00100000;
GPIOB_PUPDR |= 0x00200000;
GPIOB_OSPEEDR |= 0x00200000;
GPIOB_ODR |= 0x0400;
• This solution is fine for simple applications. However, if multiple instantiations of the same type of peripheral are available at the
same time, we will need to define registers for each peripheral, which makes code maintenance difficult
• On the other hand, since each register is defined as a separate pointer, each register access requires a 32-bit address constant. As a
result, the program image will consume a larger memory space.
• For example:
typedef struct {
volatile unsigned int MODER;
volatile unsigned int OTYPER;
volatile unsigned int OSPEEDR;
volatile unsigned int PUPDR;
volatile unsigned int IDR;
volatile unsigned int ODR;
volatile unsigned int BSRRL;
volatile unsigned int BSRRH;
volatile unsigned int LCKR;
volatile unsigned int AFR[2];
} GPIO_TypeDef;
• With further modification, the functions developed for one peripheral can be shared between multiple instantiations by passing the
base pointer to the function, for example:
• We will take a look at some examples and see how they compare to the low-level
equivalent
• The DigitalOut interface is used to configure and control a digital output pin by setting the pin to a logic level of 0 or
1.
• Any number of Arm Mbed pins can be used as a DigitalIn or DigitalOut, for example:
int main() {
if (mybutton)
Led_out = 1;
}
• There is also the DigitalInOut interface, which is a bidirectional digital pin, we can use this interface to read the value
of a digital pin when set as an input(), as well as write the value when set as an output().
14 © 2019 Arm Limited
DigitalIn Class Reference
• The BusOut API allows you to combine a number of DigitalOut pins to write to them at once
• Useful for writing to multiple pins together as a single interface instead of individual pins.
• Any number of Arm Mbed pins can be used as a BusIn or BusOut, for example:
#include "mbed.h"
int main() {
while(1) {
for(int i=0; i<16; i++) {
myleds = i;
wait(0.25);
}
}
}
https://os.mbed.com/docs/mbed-os/v5.15/apis/busout.html
17 © 2019 Arm Limited
BusIn Class Reference
Function Name Description
BusIn (PinName p0, PinName p1=NC … PinName p15=NC) Create a BusIn, connected to the specified pins.
BusIn (PinName pins[16]) Create a BusIn, connected to the specified pins.
int read () Read the value of the input bus.
void mode (PinMode pull) Set the input pin mode.
int mask () Binary mask of bus pins connected to actual pins (not NC
pins). If bus pin is in NC state make corresponding bit will
be cleared (set to 0), else bit will be set to 1.
operator int () A shorthand for read().
DigitalIn& operator[] (int index) Access to a particular bit in random-iterator fashion.
Vcc 3.3V
Digital Output
ID ID
R R
LED
LED
Digital Output
GND
Digital output sources current to LED Digital output sinks current from LED
R
R
Development Portable
Tools Drivers
Mbed
OS
Management Integrated
Services Security
IoT
Connectivity
IoT
Connectivity
• Working with boards based on the Mbed HDK allows for an efficient start to working
with the Mbed platform
• The DAPLink debug probe is connected to the host computer via USB and connects to the target system
through a standard Cortex debug connecter
Mbed Studio
Mbed CLI
• No prior-installation or set-up
required to work with Mbed
Reference: https://os.mbed.com/docs/mbed-os/v5.14/tools/developing-mbed-cli.html
• Greentea
• Automated testing tool for Arm Mbed OS development
• Pair with 'UNITY' and 'utest' frameworks
• https://os.mbed.com/docs/mbed-os/v5.15/tools/greentea-testing-applications.html
• Icetea
• Automated testing tool for Arm Mbed OS development
• Typically used for local development and automation in a continuous integration environment
• https://os.mbed.com/docs/mbed-os/v5.15/tools/icetea-testing-applications.html
• Process of flashing boards, running the tests, and generating reports is automated by
the test system
17 © 2019 Arm Limited
Mbed Enabled Platforms
• The Arm® Mbed Enabled™ program outlines a set of functionality and requirements that must be met in order to
become “Mbed Enabled”. This can cover development boards, modules, components, and interfaces
• This benefits developers as they are assured that the platforms they choose to work with can perform certain
functions/provide certain performance
• It is also beneficial to the vendors as it allows their products more exposure when certified, and enables their
product to become more familiar with developers in the Mbed eco-system
High-level Low-level
• Advantages: • Advantages:
• Higher productivity (less development time) • More optimized code and memory efficient
• Portability across devices • Less translation time for source to machine
• Resulting code that is easier code to read and code
maintain
• Directly talk to hardware
• Allows reuse of code
• Rapid prototyping of applications
• Disadvantages:
• Disadvantages: • Less portability from one device to another
• Less optimized code • Resulting code is more difficult for others to
• Additional translation time for source to machine read, reuse, and maintain
code • Low productivity
• Another level of abstraction to deal with
• Mbed API
• Blinky example using Mbed API functions
High-level
Control GPIO using Mbed API
GPIO Registers
Low-level
• Note that the Mbed API is programmed using the object-oriented language C++, which originated from C
language with object-oriented features such as classes.
• Deep knowledge of C++ is not necessary to use the Mbed API. However, many tutorials and books can help you
learn C++ if you wish.
23 © 2019 Arm Limited
Cortex Microcontroller Software Interface Standard (CMSIS)
• CMSIS: Cortex Microcontroller Software Interface Standard
• A vendor-independent hardware abstraction layer for the Cortex-M processor series
• Provides a standardized software interface, such as library functions, which help control the processor more easily, e.g.
configuring the Nested Vectored Interrupt Controller (NVIC)
• Improves software portability across different Cortex-M processors and Cortex-M based microcontrollers
Cortex-M0
Cortex-M
Arm Cortex-M
Cortex-M3
Processor
Cortex-M4
• Easier to reuse the same code between different Cortex-M based microcontrollers
void NVIC_SetPendingIRQ (IRQn_Type IRQn) Sets the pending status of interrupt or exception to 1.
void NVIC_ClearPendingIRQ (IRQn_Type IRQn) Clears the pending status of interrupt or exception to 0.
uint32_t SysTick_Config(uint32_t ticks) Initialize and start the SysTick counter and its interrupt
• Analog input
• Digital-to-analog converter
• Analog output
• Analog-to-digital converter
• ADC range
• Resolution and quantization
• Sampling frequency
• Processors are digital devices. To interface with analog signals, these have to be converted into digital signals and vice
versa
Reference Voltage: Vr
Bit0 +
Bit1 +
Bit2 Analog Voltage
Digital Input D Bit3
Bit4 8-bit DAC Output: Vo
Bit5 -
Bit6
Bit7
Control Signals
source: http://www.vias.org/mikroelektronik/da_converter.html
Output
voltage DAC Output
7 Vr / 23
6 Vr / 23
5 Vr / 23
4 Vr / 23
3 Vr / 23
2 Vr / 23
1 Vr / 23
0 Vr / 23
000 001 010 011 100 101 110 111 110 101 100 011 010 001 000 001 010 011 100 101 110 111
Binary input
6 © 2019 Arm Limited
Analog-Digital-Conversion-System
• An ADC-System usually consists of three stages:
• Multiplexer: reduces the number of required ADC components at the expense of conversion speed
• Sample-and-hold: keeps the analog signal during the conversion constant. Time discretization!
• ADC: converts the analog into digital signal
Reference Voltage Vr
Input Channels
Input Bit0
Analog input 1 Voltage Bit1
Vi Bit2
Analog input 2 Sample-
and- Bit3 Digital
Analog input 3 8-bit ADC Output D
hold Bit4
Bit5
Analog input 4 Bit6
Multiplexer Bit7
Control signals
Reference Voltage
Vr
Bit0
Input Bit1
Voltage Vi Bit2
8-bit ADC Bit3 Digital
Bit4
Bit5 Output D
Bit6
Bit7
Control Signals
feedback converter
here: delta-sigma
flash converter
9 © 2019 Arm Limited
slope converter source:
http://www.skillbank.co.uk/SignalConversion/adc.htm
ADC Range
• ADCs have minimum and maximum permissible input values, which determine the range of an ADC.
• The range and the resolution of the ADC are linked to the reference voltage and the physical principle of
the ADC.
æ V ö
• Flash converter and feedback converter: D = int ç i 2 n ÷
è Vref ø
tchargeVi
• Slope converter: D int
tclockVref
• Vi: input voltage; Vref: reference voltage; n: digital resolution in bit; tcharge: charging time;
tclock: reference clock
111
110
101
Quantization
100 error
011
010
Actual input
001
000
1/8Vr 2/8Vr 3/8Vr 4/8Vr 5/8Vr1/8 6/8Vr 7/8Vr Vr
Input voltage
• According to the Shannon-Nyquist sampling theorem, the sampling frequency must be at least double
that of the highest frequency in the incoming signal.
• For example, the accepted standard range of audible frequencies is in the range of 20 to 20,000 Hz,
approximately, so standard audio CDs are sampled and played at 44.1kHz.
• Reduced sampling frequency will result in signal aliasing effect as shown below:
• For example, the following functions are provided to input an analog signal:
float read () Read the input voltage, represented as a float in the range [0.0, 1.0]
unsigned short read_u16 () Read the input voltage, represented as an unsigned short in the range [0x0,
0xFFFF]
#include "mbed.h"
int main() {
while (1){
if(ain > 0.3) {
led = 1;
} else {
led = 0;
}
}
}
void write (float value) Set the output voltage, specified as a percentage (float)
void write_u16 (unsigned short value) Set the output voltage, represented as an unsigned short in the range [0x0,
0xFFFF]
float read () Return the current output voltage setting, measured as a percentage (float)
#include "mbed.h"
int main() {
while(1) {
for(float i=0.0; i<1.0; i+=0.1) {
signal = i;
wait(0.0001);
}
}
}
• Mbed OS 5: https://os.mbed.com/docs/mbed-os/v5.14/introduction/index.html
A timer register
• Is incremented or decremented at a fixed frequency
• Is driven by the output from the prescaler, often referred to as “ticks”
A capture register
• Loads the current value from the timer register upon the occurrence of certain events
• Can also generate an interrupt upon events
A compare register
• Is loaded with a value, which is periodically compared with the value in the timer register
• If the two values are the same, an interrupt can be generated.
Capture Register
Event source
Capture enable
Prescaler 2 Interrupt event
Time
Logic 0
The implementation of the three operation modes can differ among various devices
• Since the Mbed API is high-level platform-independent, you do not need to directly access low-level registers. The
specification of registers are usually documented in the user guide of the hardware platform
#include "mbed.h"
Timer t;
int main() {
t.start();
printf("Hello World!\n");
t.stop();
printf("The time taken was %f seconds\n", t.read());
}
• Note that timers are based on 32-bit int microsecond counters, which means:
• Only time up to a maximum of 2^31-1 microseconds i.e., 30 minutes, can be registered
• For longer times, you should consider the time()/Real time clock
static void irq (uint32_t id) The handler registered with the underlying timer interrupt
Ticker flipper;
DigitalOut led1(Output Pin 1);
DigitalOut led2(Output Pin 2);
void flip() {
led2 = !led2;
}
int main() {
led2 = 1;
// the address of the function to be attached (flip) and the interval (2 seconds)
flipper.attach(&flip, 2.0);
• In the Mbed API, the PWM functions are separated from the timer classes
Void write (float value) Set the ouput duty-cycle, specified as a percentage (float)
float read () Return the current output duty-cycle setting, measured as a percentage (float)
void period (float seconds) Set the PWM period, specified in seconds (float), keeping the duty cycle the same
void period_ms (int ms) Set the PWM period, specified in milliseconds (int), keeping the duty cycle the same
void period_us (int us) Set the PWM period, specified in microseconds (int), keeping the duty cycle the same
void pulsewidth (float seconds) Set the PWM pulsewidth, specified in seconds (float), keeping the period the same
void pulsewidth_ms (int ms) Set the PWM pulsewidth, specified in milliseconds (int), keeping the period the same
void pulsewidth_us (int us) Set the PWM pulsewidth, specified in microseconds (int), keeping the period the same
#include "mbed.h"
int main() {
while(1) {
for(float p = 0.0f; p < 1.0f; p += 0.1f) {
led = p;
wait(0.1);
}
}
}
• I2C bus
• I2C protocol
• Mbed I2C API
1
1
0
0
1
1
1
1 0 1 1 1 0 0 1 1
1
1 0 1 1 1 0 0 1 1
0
0
0
0
1
1
Serial communication Parallel communication
• On the other hand, the conversion between serial and parallel data may consume extra overheads.
• UART communication
• Converts data from parallel to serial
• Sequential data is transferred through serial cable
• Receives the sequential data and reassembles it back to parallel
tx rx
device1 device2
rx tx
• In the next 8 clock cycles, 8 bits are sent sequentially from the transmitter
• In the end, the data wire is pulled up high to indicate the end of transfer
Start bit Bit 0 Bit 1 Bit 2 Bit 3 Bit 4 Bit 5 Bit 6 Bit 7 Stop bit
Start bit Bit 0 Bit 1 Bit 2 Bit 3 Bit 4 Bit 5 Bit 6 Bit 7 Parity Stop bit
… … …
Serial (PinName tx, PinName rx, const char *name=NULL) Create a Serial port connected to the specified transmit and receive pins
void baud (int baudrate) Set the baud rate of the serial port
Void format (int bits=8, Parity parity=SerialBase::None, int
Set the transmission format used by the serial port
stop_bits=1)
int readable () Determine if there is a character available to read
void attach (void(*fptr)(void), IrqType type=RxIrq) Attach a function to call whenever a serial interrupt is generated
• Baud rate: There are a number of standard baud rates ranging from a few hundred bits per seconds, to megabits per second.
The default setting for a serial connection on the mbed microcontroller is 9600 baud
• Data length: Data transferred can be either 7 or 8 bits long. The default setting for a serial connection on the mbed
microcontroller is 8 bits
• Parity: An optional parity bit can be added. The parity bit will be automatically set to make the number of 1's in the data either
odd or even. Parity settings are odd, even or none. The default setting for a serial connection on the mbed microcontroller is for
the parity to be set to none
• Stop bits: After data and parity bits have been transmitted, 1 or 2 stop bit(s) is/are inserted to ‘frame’ the data. The default
setting for a serial connection on the mbed microcontroller is for one stop bit to be added
• The default settings for the mbed microcontroller are described as 9600 8N1, and this is common notation for serial port
settings
• With the support of the UART peripheral, a number of standard IO functions can be
directly used, such as:
int getc( FILE *stream ) Read a character from the stream, an EOF indicates the end of file is reached
Prints both text string and data, according to format and other arguments passed to
int printf( const char *format, ... )
printf()
• The following example first prints a string to the host PC, and then receives/sends
characters from/to the PC via UART:
#include "mbed.h"
int main() {
pc.printf("Hello World!\n");
while(1) {
pc.putc(pc.getc() + 1);
}
}
• Each peripheral has its own chip select line (CS) select select select
select select
Serial Serial
D2 D1 D0 data data D2 D1 D0
out in
D Q D Q D Q D Q D Q D Q
Clock Clock
Clock
Serial Data D7 D6 D5 D4 D3 D2 D1 D0
void frequency (int hz=1000000) Set the spi bus clock frequency
virtual int write (int value) Write to the SPI Target and return the response
• The SPI Interface can be used to write data words out of the SPI port, returning the data received back
from the SPI target.
• The SPI clock frequency and format is configurable. In addition to the frequency, the controller must also
configure the mode defined as the clock polarity and phase with respect to the data (see
http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus).
• The default settings of the SPI interface are 1MHz, 8-bit, Mode 0.
int main() {
// Chip must be deselected
cs = 1;
// Setup the spi for 8 bit data, high steady state clock,
// second edge capture, with a 1MHz clock rate
spi.format(8,3);
spi.frequency(1000000);
// Select the device by setting chip select low
cs = 0;
// Send 0x8f, the command to read the WHOAMI register
spi.write(0x8F);
// Send a dummy byte to receive the contents of the WHOAMI register
int whoami = spi.write(0x00);
printf("WHOAMI register = 0x%X\n", whoami);
// Deselect the device
cs = 1;
}
Controller SDA
(microcontroller) SCL
Clock in Data in
1 2 3 4
MSB LSB MSB LSB
SCL
1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9
Start signal Calling address R/W Ack Data byte No Ack bit Stop
bit signal
I2C (PinName sda, PinName scl) Create an I2C Controller interface connected to the specified pins
void frequency (int hz) Set the frequency of the I2C interface
int read (int address, char *data, int length, bool repeated=false) Read from an I2C target
int read (int ack) Read a single byte from the I2C bus
int write (int address, const char *data, int length, bool
Write to an I2C target
repeated=false)
int write (int data) Write single byte out on the I2C bus
#include "mbed.h“
int main() {
char data[2];
//Write operation
data[0] = 0x00; //Register address
data[1] = 0x0A; //Data to be written
i2c.write(addr, data, 2); //Write data to the register
//Read operation
data[0] = 0x02; //Register address
i2c.write(addr, data, 1); //Set register address
i2c.read(addr, data, 2); //Read data from the register
}
User application
Operating System
OS shell
OS kernel
Fault tolerance
Managing file System
and error
systems security
detection
Multitasking
Task
and job
coordination
accounting
Allocating
Scheduling
memory Managing IOs
tasks
resources
Protecting and
securing
information
• Multi-user OS
• Allows multiple users to access it at the same time
• Batch operating OS
– Users prepare their jobs offline
– Similar jobs submitted by different users are batched together and run as a group
– Aims to maximize processor usage – less interaction with user applications
• Time-sharing OS
– Processor’s time is shared among multiple users
– More interaction with user applications
• Embedded OS
• Designed to be used in embedded computer systems
• Limited resources such as memory, IOs, clock speed
• Compact and energy efficient
• Real-Time OS
• Multitasking OS targeted at real-time applications, with real-time constraints
• Must quickly and predictably respond to events
Real-time (definition): Real-time guarantees the completion of a process within a defined time interval.
Real-time does not make any statement about the total time duration or the processing speed.
• Event-driven RTOS
– Pre-emptive task scheduling
– An event of higher priority needs to be served first
– Processes data more responsively
• Time-sharing RTOS
– Non-pre-emptive task scheduling
– Tasks are switched on a regular clocked interrupt, and on events, e.g., round robin scheduling
– Tasks are switched more often, giving a smoother multitasking
– However, unnecessary task switching results in undesired overheads
• Task scheduling
• Usually, only one task per CPU can run at any one time.
• To efficiently switch between tasks, usually a task scheduler is used. Various scheduling algorithms
exist, including:
– Cooperative scheduling: no pre-emption, tasks can end themselves in a cooperative manner
– Pre-emptive scheduling: tasks can be interrupted by other tasks of higher priorities
– ‘Earliest deadline first’ approach: the task with the earliest deadline is served first
• Examples of RTOS include LynxOS, OSE, Windows CE, FreeRTOS, Arm Keil RTX, etc.
• CMSIS-RTOS API :
• Common API for real-time operating systems
• Foundation of the official Mbed RTOS
• Provides a standardized programming interface that is portable to many RTOSs
• Hence enables software templates, middleware, libraries, and other components that can work across
various supported RTOS systems
• The following slides show how to use some mbed RTOS API features, such as threads, mutexes, and
semaphores
•Running: The thread that is currently running is in the Running state. Only one thread
at a time can be in this state.
•Ready: Threads that are ready to run are in the Ready state. Once the Running thread
has terminated or is Waiting, the next Ready thread with the highest priority becomes
the Running thread.
•Waiting: Threads that are waiting for an event to occur are in the Waiting state.
•Inactive: Threads that are not created or terminated are in the Inactive state. These
threads typically consume no system resources.
int32_t signal_set (int32_t signals) Set the specified Signal Flags of an active thread
#include "mbed.h"
#include “rtos.h"
int main() {
Thread thread1(led2_thread);
while (true) {
led1 = !led1;
Thread::wait(500);
}
}
Mutex stdio_mutex;
int main() {
Thread t2(test_thread, (void *)"Th 2");
Thread t3(test_thread, (void *)"Th 3");