Thanks to visit codestin.com
Credit goes to www.scribd.com

0% found this document useful (0 votes)
49 views197 pages

CMSIS RTOSv2

The document provides an overview of CMSIS-RTOS2, detailing its features, configuration, and benefits for Cortex-M hardware. It discusses the transition from bare metal to RTOS development, emphasizing the productivity gains and structured software design it offers. Additionally, it covers thread management, the CMSIS RTOS2 API, and the importance of understanding processor modes and privilege levels in RTOS applications.

Uploaded by

Roy Zhao
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
49 views197 pages

CMSIS RTOSv2

The document provides an overview of CMSIS-RTOS2, detailing its features, configuration, and benefits for Cortex-M hardware. It discusses the transition from bare metal to RTOS development, emphasizing the productivity gains and structured software design it offers. Additionally, it covers thread management, the CMSIS RTOS2 API, and the importance of understanding processor modes and privilege levels in RTOS applications.

Uploaded by

Roy Zhao
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 197

CMSIS-RTOS2

Trevor Martin
CMSIS-RTOS2

Introduction

Cortex-M hardware support for an RTOS

CMSIS RTOS2 API

CMSIS RTOS2 configuration

Design Techniques

Design Study

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 2
Effort

Bare Metal RTOS

Complexity

▪ At the beginning there will be more effort caused by using an RTOS. Once
you are familiar with RTOS based development there are big increases in
productivity

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 3
Why use a Real-Time Kernel?

▪ More sophisticated software


design
▪ Structured code development
▪ Object orientated design
▪ Improved project management
▪ Code reuse
▪ Multitasking support
▪ Supports auto code generation
tools

▪ With ARM Cortex you can!

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 4
Cortex-M3 Processor Overview

Central Core:
Wake-Up Interrupt Controller: Integrated Nested Vectored Interrupt 1.25 DMIPS/MHz
for Low Power Stand by Controller and SYSTICK Timer 1 Cycle Multiply
Operation
Hardware Divide

Memory Protection Embedded Trace


Unit (MPU) Macrocell (ETM) for
8-Region Instruction Trace

Instrumentation Trace
Debug Access Port: Macrocell (ITM ) for
JTAG or Serial Wire Data Trace via Single
Wire Output

Data Watch Point and


Trace Unit (DWT) Flash Patch &
4x Data Watchpoints & Breakpoint Unit
Event Monitors 8x Hardware
Breakpoints

1x AHB-Lite Buses
2x AHB-Lite Buses
SYSTEM (SRAM & Fast Peripherals)
I_CODE (Instruction Code Bus)
1x APB Bus
D_CODE (Data / Coefficients Code Bus)
ARM Peripheral Bus (Internal & Slow Peripherals)

optional blocks, please consult your silicon manufacturers data sheet

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 5
CMSIS

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 6
CMSIS-RTOS2 Features

Wait functions
Virtual Timer
Threads

Mutex Event Flags

Scheduler Thread
Semaphore
Flags
Memory Pool ISR Support

Message queue

▪ The CMSIS-RTOS2 Kernel provides a scheduler and additional objects and services
− Scheduler
− Objects
− Semaphores,Event Flags,Mutex,Threads,Message passing
− Services
− Timers, Memory management, ISR support
2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 8
SYSTICK Timer

▪ Simple 24 Bit down counter


▪ 4 Registers
− CTRL - Control and Status
− LOAD – Reload Value
− VAL – Current Value
− CALIB - Calibration Value

▪ Exception Vector #15


▪ Accesible from Privileged Mode
− Can be protected from user application
▪ Makes porting OS and software easier, because SYSTICK timer will be
the same across different Cortex-M products

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 9
Converting from bare metal to an RTOS project

▪ Select CMSIS:RTOS2:Keil RTX5 in the RTE


▪ Configure the RTOS in RTX_Config.h
▪ Add the CMSIS OS include file to your C source to access the RTOS2 API
− #include <cmsis_os2.h>

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 11
Building your first program

▪ Start the Pack Installer


▪ Select the boards\rtos tutorial
▪ Copy exercise 1 First project in the examples tab

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 12
Building your first program

▪ This is a minimal project


− We have selected new Project
− In the device database the STM32F103RB has been chosen as the
target device
− This configures the IDE, compiler, linker and debugger

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 13
Building your first program

▪ Open the Run-Time Environment (RTE)


▪ Select the following components
− CMSIS::CORE
− CMSIS::RTOS2:RTX5
− Device::Startup
▪ Next press the Resolve Button (lower left hand corner)
▪ Finally press the OK button to close the RTE

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 14
Building your first program

▪ The components will be added to the project as shown above


− The green diamonds are the software component packages
− The files with Yellow keys are the (write protected) runtime code
− The remaining files are configuration files

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 15
Building your first program

▪ The configuration files can be viewed as


C code or graphical pick lists
▪ The view is controlled by the tabs at the
bottom of the editor

− Startup_stm32f10x_md.s
− Configures the stack and heap
− System_xxxxx.c
− Configures the system clocks
− RTE_Device.h
− Configures the peripheral physical
interfaces
− rtx_config.c
− We will examine the RTX configuration
file later in the workshop

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 16
Building your first program

▪ We can add the CMSIS-RTOS2 startup code


− Select the source group folder
− Right click, select “Add new Item”
− In “User code template” select main function
2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 17
Building your first program

▪ Add a second code template


− This time select “CMSIS-RTOS2 Thread”

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 18
Building your first program

extern int Init_Thread (void);


/*----------------------------------------------------------------------------
* Application main thread
*---------------------------------------------------------------------------*/
void app_main (void *argument) {
Init_Thread ();
for (;;) {}
}

▪ Now open Main.c


▪ Add the extern for the thread initialising code as shown above
▪ Add the thread initialising code to main as shown above

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 19
Building your first program

*** Using Compiler 'V5.06 update 4 (build 422)', folder: 'C:\Keil_v5\ARM\ARMCC\Bin‘


Rebuild target 'Target 1‘
compiling Thread.c...
compiling RTX_Config.c...
assembling startup_stm32f10x_md.s...
compiling main.c...
compiling system_stm32f10x.c...
linking...
Program Size: Code=7864 RO-data=488 RW-data=5520 ZI-data=1632 ".\CMSISrtxFirstProject.axf"
- 0 Error(s), 0 Warning(s).
Build Time Elapsed: 00:00:02

▪ Build the code


− Press F7 or press the icon on the toolbar

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 20
Simulator

▪ The MDK-ARM includes a legacy simulator


− The CPU and microcontroller peripherals are simulated
− This is an ideal debugger to use when learning about an RTOS

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 21
Building your first program

▪ Start the debugger by pressing the Icon on the toolbar

▪ This will start the simulator and run the code to Main

• Open thread.c and set a breakpoint in the Thread function


• Run the code (F5)

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 22
Building your first Project

▪ CMSIS documentation can be accessed from within the RTE or by right


clicking on the CMSIS folder

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 23
Building your first program

▪ Spend a few minutes exploring the debugger

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 24
Processor Mode

▪ Handler Mode
− Used to handle exceptions. The processor returns to Thread mode when it has finished
exception processing.

▪ Thread Mode
− Used to execute application software. The processor enters Thread mode when it comes
out of reset.
− In Thread mode, the CONTROL register controls whether software execution is privileged
or unprivileged, see CONTROL register. In Handler mode, software execution is always
privileged.
− RTX5 uses processor modes

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 25
Privilege Levels

▪ Unprivileged
The software:
− has limited access to the MSR and MRS instructions, and cannot use the CPS instruction
− cannot access the system timer, NVIC, or system control block
− might have restricted access to memory or peripherals.
− Unprivileged software executes at the unprivileged level

▪ Privileged
− The software can use all the instructions and has access to all resources.

Not available in Cortex-M0 / Cortex-M1

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 26
Cortex M Processor Stacks

R0
▪ In addition to the different operating modes
R1 the Cortex M processors can support two
R2
R3 stacks
R4
R5 − Main Stack
R6
R7
− Configured at startup

R8
R9
Process Stack
R10
− Configured by the user application code
R11
R12
R13 (MSP) R13 (PSP)
R14 (LR)
PC
PSR

PRIMASK
FAULTMASK*
BASEPRI*

CONTROL

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 27
Configuring the Cortex Processor

Thread mode privilege level

CPU Control register 1 0

Active stack pointer

▪ The CPU CONTROL register is used to configure the operating mode and
enable the second stack pointer

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 28
Privilege, Modes and Stacks Summary

Operations Stacks
(privilege out of reset) (Main out of reset)

Handler Privileged execution Main Stack Used by


- Processing of exceptions Full control OS and Exceptions

Privileged or
Thread Main or Process
- No exception is being processed
Unprivileged
- Normal code execution

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 29
Exercise

▪ Return to the last exercise


▪ Start the debugger
▪ Observer how the operating mode changes as
the code executes

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 30
CMSIS RTOS2 API

▪ Thread management
▪ Time management
▪ ThreadFlags
▪ EventFlags
▪ Semaphores
▪ Mutex
▪ Messages
▪ Memory Pool

▪ All RTOS have a similar set of core features

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 31
CMSIS RTOS2 osStatus codes

Error Code Description


osOK Operation completed successfully.

osError Unspecified RTOS error: run-time error but no other error


message fits.
osErrorTimeout Operation not completed within the timeout period.

osErrorResource Resource not available.

osErrorParameter Parameter error.

osErrorNoMemory System is out of memory: it was impossible to allocate or


reserve memory for the operation.
osErrorISR Not allowed in ISR context: the function cannot be called
from interrupt service routines.
osStatusReserved

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 32
Threads - The RTOS building block

▪ Each thread is a C function


− Each thread contains an while loop that never terminates
▪ Conceptually all the tasks are running in parallel
− Independent units of execution

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 33
Concurrency

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 34
Threads – Program structure

Send

PROCESS / Task
Receive

Message

▪ With an RTOS we design our program in terms of data flow


▪ The RTOS provides a framework for application development

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 35
Threads - Timeslice

▪ The CMSIS RTOS scheduler is responsible for controlling the execution of


Threads to a scheduling algorithm
− Round robin
− Preemptive
− Cooperative

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 36
Threads Control block and ‘stack’

Thread Control Thread


Block Stack

Priority & State Context

Thread

▪ Each thread is allocated a ‘stack’ space for its data


▪ There is a global default size
− The default can be overridden to create custom stack sizes

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 37
Threads Control block and ‘stack’

Thread Control Thread


Block Stack

Priority & State Context

Thread

▪ The RTOS Scheduler maintains a Thread Control block


− This holds all of the run time information about the Thread

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 38
Threads - States

Thread State Description


Running One Thread Running on the CPU
Ready Threads Ready to Run
Waiting Blocked Threads waiting for an RTOS event

▪ Only one Thread at a time will be running


▪ The highest priority ready task will be the next to be scheduled
▪ If all ready task have equal priority then round robin scheduling will be
used.
▪ If a Thread is waiting for an RTOS Object to complete it will be in a
blocked waiting state

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 39
Thread Lifecycle

Waiting

Ready

Inactive
Run

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 40
Thread

__NO_RETURN void Thread1 (void*argument) ;


void Thread1 (void*argument) ; __NO_RETURN void Thread1 (void*argument)
void Thread1 (void*argument) {
{ for(;;)
for(;;) {
{ …..
….. }
} }
}

▪ The thread must never terminate


− Tasks run as infinite loops
▪ __NO_RETURN is a macro declared in cmsis_os.h
− “Use this attribute to reduce the cost of calling a function that never returns”

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 41
Thread

osThreadId_t t_thread1,t_thread2,t_thread3;

▪ Each Thread has a unique ID


− The ID is assigned by the RTOS when the task is created
▪ The Thread ID is a handle used to manage the running tasks

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 42
Threads -Management

Thread Management functions


osThreadId_t osThreadNew (os_thread_func_t func, void *argument, const osThreadAttr_t *attr))
osThreadId_t osThreadGetId (void)
osThreadState_t osThreadGetState (osThreadId_t thread_id)
osStatus_t osThreadSetPriority (osThreadId_t thread_id, osPriority_t priority)
osPriority_t osThreadGetPriority (osThreadId_t thread_id)
osStatus_t osThreadYield (void)
osStatus_t osThreadSuspend (osThreadId_t thread_id)
osStatus_t osThreadResume (osThreadId_t thread_id)
osStatus_t osThreadDetach (osThreadId_t thread_id)
osStatus_t osThreadJoin (osThreadId_t thread_id)
__NO_RETURN void osThreadExit (void)
osStatus_t osThreadTerminate (osThreadId_t thread_id)
uint32_t osThreadGetStackSize (osThreadId_t thread_id)
uint32_t osThreadGetStackSpace (osThreadId_t thread_id)
uint32_t osThreadGetCount (void)
uint32_t osThreadEnumerate (osThreadId_t *thread_array, uint32_t array_items)

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 43
Threads – Priority Levels

CMSIS RTOSv2 priority levels


osPriorityIdle

osPriorityLow

osPriorityLow 1-7

osPriorityBelowNormal

osPriorityBelowNormal 1-7

osPriorityNormal

osPriorityNormal 1-7

osPriorityHigh

osPriorityHigh 1-7

osPriorityRealTime

osPriorityRealTime 1-7

osPriorityError

▪ Each thread also has a priority


▪ The priority determines which thread is scheduled to run
▪ The thread priority is assigned when the thread is created.
▪ It may also be changed dynamically

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 44
Threads Creation

osThreadId_t led_ID1;

static const osThreadAttr_t ThreadAttr_LED2 = {


“Name_String", //Human readable Name for debugger
Attribute_bits
Control_Block_Memory,
Control_Block_Size,
Stack_Memory,
Stack_Size,
Priority,
TrustZone_ID,
reserved
};

led_ID1 = osThreadNew(nameOfFunction, argument,&ThreadAttr_LED2);

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 45
Starting the CMSIS RTOS
void app_main (void *argument)
{

T_led_ID1 = osThreadNew(led_Thread1, NULL, &ThreadAttr_LED1);


T_led_ID2 = osThreadNew(led_Thread2, NULL,&ThreadAttr_LED2);
osDelay(osWaitForever);
while(1);
}

int main (void) {

// System Initialization
SystemCoreClockUpdate();
LED_Initialize();

osKernelInitialize(); // Initialize CMSIS-RTOS


osThreadNew(app_main, NULL, NULL); // Create application main thread
if (osKernelGetState() == osKernelReady) {
osKernelStart(); // Start thread execution
}

while(1);
}

▪ Main(void) creates the initial thread and starts the RTOS


− May also initialize the microcontroller peripherals
− The RTOS uses the SystemCoreClock variable defined by CMSIS-Core
− Call SystemCoreClockUpdate() to ensure it is set to the correct value

▪ app_main() may continue as a thread or it may be terminated


2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 46
Exercise

▪ Return to the pack installer


− Copy Exercise 2 Threads
▪ This project creates two threads which are used to flash separate LED’s
▪ The existing code does not run as expected examine the program
execution in the debugger and fix the problem

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 47
Memory allocation

▪ Global Memory Pool


− Memory fragmentation
− Default

▪ Object specific memory pools


− Fixed memory blocks
− Time deterministic

▪ Static Object memory


− Safe
Global Memory Pool

▪ The default configuration allows you to specify a global memory pool


− All RTOS objects are allocated resources from this memory pool
− Will suffer memory fragmentation as different types of object are created and
destroyed
− Object creation and destruction will not have deterministic timing
Custom Stack size
static const osThreadAttr_t ThreadAttr_LED2
={
“Name_String",
Attribute_bits
Control_Block_Memory,
Control_Block_Size,
Stack_Memory,
Stack_Size,
Priority,
TrustZone_ID,
reserved
};

▪ You can override the default stack size for a given thread
− In the thread attributes set the stack_size to the required size
Object Specific memory pool

▪ Objects can be placed on an object specific memory pool


− This must be enabled and the maximum number of objects is fixed
Static Memory allocation

os_thread_t led_thread_tcb_1;

uint64_t led_thread_stk_1[64];

const osThreadAttr_t worker_attr_1 = {


“LED1",
NULL,
&led_thread_tcb_1,
sizeof(led_thread_tcb_1),
&led_thread_stk_1[0],
sizeof(led_thread_stk_1),
osPriorityAboveNormal,
0
};

▪ A thread may be statically allocated


▪ Thread memory consists of
▪ a Thread control Block used by the RTOS
▪ Thread stack to hold the thread data
Memory allocation definitions

#include <rtx_os.h>

#define os_ThreadCbSize sizeof(os_thread_t)


#define os_TimerCbSize sizeof(os_timer_t)
#define os_EventFlagsCbSize sizeof(os_event_flags_t)
#define os_MutexCbSize sizeof(os_mutex_t)
#define os_SemaphoreCbSize sizeof(os_semaphore_t)
#define os_MemoryPoolCbSize sizeof(os_memory_pool_t)
#define os_MessageQueueCbSize sizeof(os_message_queue_t)

▪ Definitions for different memory objects are held in rtx_os.h


Memory protection unit

◼ The MPU can control access to privileged and unprivileged regions


◼ Not part of the RTX but can be configured to match an RTX project.

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 54
Exercise Static memory allocation

▪ Return to the pack installer


− Copy exercise 3 Memory Allocation
▪ This project demonstrates how to use static memory allocation for threads
▪ Use Static memory allocation for safety critical/security applications

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 55
Attributes – Joinable and Detached

static const osThreadAttr_t ThreadAttr_LED2


={
“Name_String",
Attribute_bits Attribute mask Description
Control_Block_Memory, osThreadJoinable Thread is created in a join-able
Control_Block_Size, state.
Stack_Memory, osThreadDettached Thread is created in a detached
Stack_Size, state (default).
Priority,
TrustZone_ID,
reserved
};
os_Status_t osThreadJoin (osThreadId thread_id)

▪ Threads may be created as ‘Detached’ or ‘Joinable’


− A thread may wait for a joinable thread to terminate before continuing
− This allows a thread to wait until a task has been completed before
using the results

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 56
Exercise Joinable Threads

▪ Return to the pack installer


− Select and copy Exercise 4 Joinable Threads
▪ This project demonstrates creating threads configured as ‘joinable’ The
main thread then waits until the joinable thread has terminated before
continuing
▪ What would you use joinable threads for?

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 57
Threads

▪ There may be up to 1000 active threads


▪ CMSIS RTOS allows you to have multiple instances of the same thread
▪ With a global or object memory pool you just need to create the thread
multiple times
▪ With static memory allocation you must provide memory for each instance

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 58
Exercise

▪ Return to the pack installer


− Select and copy Exercise 5 Multiple Instance
▪ This project creates several thread instances from the same base code
▪ Consider how this is done for each different memory model

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 59
Time Management

▪ CMSIS RTOS provides several timing services


− Wait Functions
− Virtual timer
− Idle task

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 60
Delay

▪ Within a task you can delay a function for a specific number of system
ticks

− void osDelay (uint32_t ticks)

▪ It is very important to appreciate the difference between the osDelay


function and a simple delay loop

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 61
Software interrupt

16 0

Op code Ordinal

▪ The SVC instruction raises an exception and jumps to an ISR


− This allows unprivileged code to make a call to a privileged function
− This mechanism is used to call CMSIS RTOS2 API functions

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 63
Software interrupt

Vector Table

SVC vector

Supervisor Call routines

SVC 0

SVC #1 SVC Handler


Lookup table SVC 1
Supervisor call

SVC 2

Thread mode Handler mode

▪ By encoding a number into the ‘ordinal’ section of the SVC instruction you
can call different privileged functions

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 64
RTOS objects

− The API for each RTOS object will do two things


− Provide a method for that function
− Run the RTOS scheduler to decide what code should be executing

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 65
Kernel Time functions

uint64_t osKernelTickCount(void)

uint32_t osKernelGetTickFreq(void)

uint32_t osKernelGetSysTimerCount(void)

uint32_t osKernelGetSysTimerFreq(void)

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 66
DelayUntil

▪ Within a task you can delay a function until a specific OS tick count is
reached

− void osDelayUntil (uint64_t tickCount )

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 67
Exercise

▪ Return to the Pack installer


− Select and copy Exercise 6 Timer Management
− This project demonstrates the use of the wait functions to block threads
for deterministic periods

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 68
Delay ‘Jitter’

▪ The delay methods are counting RTOS scheduler ticks


− Lower bound = delay value -1
− Upper bound = delay value

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 69
Virtual Timer

▪ CMSIS-RTOS2 also allows you to define an unlimited number of virtual


timers

▪ When a timer expires a callback function is called and code associated


with the timer may be run

▪ A virtual timer may be a periodic timer or a one shot timer

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 70
Virtual Timer - Timer API

osTimerId_t osTimerNew (os_timer_func_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr)

const char * osTimerGetName (osTimerId_t timer_id)

osStatus_t osTimerStart (osTimerId_t timer_id, uint32_t ticks)

osStatus_t osTimerStop (osTimerId_t timer_id)

uint32_t osTimerIsRunning (osTimerId_t timer_id)

osStatus_t osTimerDelete (osTimerId_t timer_id)

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 71
Virtual Timer – Creating a timer

osTimerId_t timer0

static const osTimerAttr_t timerAttr_timer0 = {


"timer_0",
Attribute bits (none),
Control block memory,
Control block size
};

timer0 = osTimerNew(&callback, osTimerPeriodic,(void *)0, NULL);

osTimerStart(timer0, periodInTicks);

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 72
Timer

▪ When the timer expires the nominated callback function is executed.


▪ The timer number is passed as a parameter to the callback
▪ Each timer may have a dedicated callback function
▪ A callback may be used by several timers

void callback(void const *param)

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 73
Timer

▪ The timer thread is only started if you create a timer

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 74
Exercise

▪ Return to the pack installer


− Select and copy Exercise 7 Virtual Timer
▪ This project demonstrates how to configure and use several virtual timers
and callback functions
− What is the difference between osDelay and timers?
− What would you use timers for?

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 75
Idle Thread

void os_idle_demon (void) {


for (;;) {
;
}
}

▪ If no task is running the CMSIS RTOS2 will enter an idle task


▪ The default idle task is stored in RTX_Config.c
▪ Typically power management code can be added here

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 76
Exercise

▪ Return to the Pack installer


− select and copy exercise 8 Idle thread
▪ Examine the project code
▪ Build the project
▪ Start the code running in the debugger
▪ Open the performance analyser
− View\Analysis windows\Performance analyser
▪ The code is spending all its time in the idle loop
▪ Quit the debugger and open RTX_Config.c
▪ Uncomment the _wfi() instruction
▪ Rebuild and restart the debugger
▪ Run the code and see the change in the performance analyser

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 77
Suspend and resume

Function Description
uint32_t osKernelSuspend(void) Suspends the scheduler
osKernelResume(uint32_t ticks) Restarts the scheduler

▪ To lower power consumption further we can disable the sysTick timer to


enter a lower power mode
▪ A low power timer (RTC) can be used to wake up the system
− However to maintain the real time aspect of the system we must know
the sleep period in RTOS ticks

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 78
Suspend and resume

Function Description
uint32_t osKernelSuspend(void) Suspends the scheduler
osKernelResume(uint32_t ticks) Restarts the scheduler

▪ osKernelSuspend will stop the sysTick and return the maximum allowable
sleep period
▪ osKernel Resume updates the scheduler with the actual sleep period in
ticks

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 79
Synchronisation

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 80
Intertask communication

▪ CMSIS-RTOS2 has the following objects that allow inter task communication
− Thread Flags
− Event Flags
− Semaphores
− Mutex
− Message queue
− Memory pool

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 81
Thread Flags

▪ CMSIS-RTOS2 signals are used to trigger execution states between


threads
▪ The Thread Flags are automatically created as part of the Thread control
block

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 82
Thread Flags API

int32_t osThreadFlagsGet (void)

int32_t osThreadFlagsSet ( int32_t flags)

int32_t osThreadFlagsClear ( int32_t flags)

int32_t osThreadFlagsWait ( int32_t flags, uint32_t options, uint32_t timeout)

▪ A set of thread flags is created along with each new thread


− A thread can block until a pattern of flags is set
− When the pattern is matched it will move to the READY state
− Any other thread may set or clear a given threads flags

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 83
Thread Flags

for(;;;)
for(;;;)
{
{
……..
……..
osThreadFlagsSet (T_led_ID1,0x01);
osThreadFlagsWait (0x03,osFlagsWaitAny,osWaitForever);
…….
}
}

▪ CMSIS RTOS Thread Flags are used to trigger execution states between
threads

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 84
Thread Flags

Int32_t osThreadFlagsWait (int32_t flags,uint32_t options,uint32_t timeout)

▪ Returns pattern of flags set, negative value is an error

Option Description
osFlagsWaitAny Wait for any flag (Default)
osFlagsWaitAll Wait for all flags
osFlagsNoClear Do not clear flags that are
being waited on

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 85
Thread Flags

▪ Thread may set one or more event flags in any given thread

int32_t osThreadFlagsSet (osThreadId_t thread_id, int32_t flags)

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 86
Thread Flags

▪ A thread may clear its own thread flags

int32_t osThreadFlagsClear ( int32_t flags)

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 87
Thread Flags

▪ A thread can see which of its flags are set

int32_t osThreadFlagsGet (void)

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 88
Exercise

▪ Return to the pack installer


− Select and copy Exercise 10 Thread Flags
− This project demonstrates the use of thread flags to synchronise
execution between two threads

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 89
Pend exception

RTOS RTOS RTOS

SysTick SVC SysTick

Thread Thread Thread Thread

◼ The CMSIS-RTOS2 code is accessed by


◼ systick interrupt
◼ SVC exception
◼ These are interrupts running in privileged mode

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 90
PEND interrupt

RTOS RTOS RTOS RTOS

SysTick
ADC ISR SysTick SVC SysTick

Delay
ADC Thread Thread Thread Thread

▪ If a user interrupt is raised it may be delayed by the RTOS code

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 91
PEND Interrupt

RTOS Entry code

SysTick
ADC ISR

RTOS
ADC

Pend

Thread Thread

◼ When we enter the RTOS scheduler we can check is another ISR is pending
◼ If this is the case we can make the PEND interrupt active and quit the RTOS
ISR
◼ This allows the USER ISR to run
◼ When the user ISR finishes the PEND interrupt will run and resume execution
of the RTOS code
2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 92
Integrating ISR’s with an RTOS

▪ RTOS interrupt handling


− Allows to separate the application into tasks that run independently
− Message passing eliminates critical shared memory buffers
− Each Thread has an own stack area
− Interrupt communication with thread flags and messages.

ISR B level 0

ISR A level 1

Thread to service ISR B

Thread to service ISR A

Round Robin Threads

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 93
Servicing ISR

▪ In CMSIS-RTOS2 an ISR routine should only signal a thread and then


terminate

− void IRQ_Handler (void)


{
osThreadFlagsSet(T_adc_ID,0x01); //Signal Task 3 with a thread flag
ADC1->SR &= ~(1 << 1); //Clear the peripheral interrupt flag
}

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 94
ISR/Thread Flags overhead

▪ Using this technique on an LPC4357 @160Mhz


− Entry to the Interrupt routine 75nsec
− Time to first line of service code in the Thread is just under 7µsec

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 95
Exercise Interrupt Thread Flag

▪ Return to the pack installer


− Select and copy Exercise 11 ISR & Thread Flags
− This project demonstrates the use of thread flags to synchronise
execution between an ISR and a high priority thread

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 100
Event Flags

Thread 1

Thread 2 Thread 3

osEventFlagsNew

osEventFlagsSet Event Flags Object osEventFlagsWait osEventFlagsWait

Thread 1 Thread 2 Thread 3

▪ An Event Flag object is similar to Thread Flags but is a global object


that may be used by multiple threads
Event Flags-API

Function
osEventFlagsId_t osEventFlagsNew (const osEventFlagsAttr_t *attr)

int32_t osEventFlagsGet (osEventFlagsId_t ef_id)

int32_t osEventFlagsSet (osEventFlagsId_t ef_id, int32_t flags)

int32_t osEventFlagsClear (osEventFlagsId_t ef_id, int32_t flags)

int32_t osEventFlagsWait (osEventFlagsId_t ef_id, int32_t flags, uint32_t options, uint32_t timeout)

osStatus_t osEventFlagsDelete (osEventFlagsId_t ef_id)

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 102
Event Flags

osEventFlagsId_t myEventFlag;

static struct osEventFlagsAttr_t MyEventFlagsAttribute {


“Name_String”
Attribute_Bits (None)
Control block memory
Control block size
};

myEventFlag = osEventFlagsNew (& MyEventFlagsAttribute);

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 103
Exercise Event Flags

▪ In the Pack installer select and copy Exercise 12 Event Flags

▪ This exercise demonstrates the use of event flags


▪ Several threads are waiting on a flag pattern which is set by a master trigger
thread
▪ There is an error in the use of event flags in this project.
▪ Find the error and correct it

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 104
Semaphores

▪ A Semaphore token may be acquired by one or more threads for the


purpose of synchronisation or mutual exclusion

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 105
Exclusive access instructions

Thread A Thread B Thread C

write read
write

◼ In a multi threaded program several threads may try to access a common


resource (ie memory buffer)
◼ This can easily lead to program errors
◼ As we will see later semaphores and mutex are used to prevent this

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 106
Semaphore API

osSemaphoreId_t osSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr)

const char * osSemaphoreGetName (osSemaphoreId_t semaphore_id)

osStatus_t osSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout)

osStatus_t osSemaphoreRelease (osSemaphoreId_t semaphore_id)

uint32_t osSemaphoreGetCount (osSemaphoreId_t semaphore_id)

osStatus_t osSemaphoreDelete (osSemaphoreId_t semaphore_id)

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 107
Semaphore

osSemaphoreId_t sem1;

static const osSemaphoreAttr_t semAttr_SEM1 = {


"SEM1",
attribute_bits,
control_block_memory,
control_block_start
};

Sem1 = osSemaphoreNew(maxCount,initalCount,&semaphoreAttributes);

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 108
Semaphores

While(1) While(1)
{ {
…….. ……..
osSemaphoreAcquire(sem1, osWaitForever); ……. osSemaphoreAcquire(sem1, osWaitForever); …….
……. …….
osSemaphoreRelease(sem1); osSemaphoreRelease(sem1);
} }

▪ A Semaphore token may be acquired by one or more threads for the


purpose of synchronisation or mutual exclusion

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 109
Semaphore

▪ Once a semaphore has been initialised threads request a token from the
semaphore to run and then return the token when they are finished

int32_t osSemaphoreAcquire(osSemaphoreId_t semaphore_id,uint32_t ticks)


Halts a thread until a semaphore is available

osStatus osSemaphoreRelease(osSemaphoreId_t semaphore_id)


Sends a token to a semaphore from a thread

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 110
Semaphore

▪ CMSIS RTOS implements counting semaphores


▪ The number of tokens is not bounded
− You can initialise the semaphore with a number of tokens
− During operation additional tokens may be created or deleted
▪ It is up to your software to manage the tokens available to a system

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 111
Semaphore

▪ Semaphore uses
− Controlling shared resource access
− Memory barrier
− synchronizing events
− Reference text ‘Little book of Semaphores‘ Downey

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 112
Exercise

▪ Return to the Pack installer


− Select and copy exercise 14 signalling semaphore
− This project demonstrates the basic configuration and use of a
semaphore

− Select and copy exercise 15 semaphore rendezvous


− This project demonstrates using two semaphores to synchronise
execution of two threads

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 113
Mutex

▪ A Mutex is a special case of a Semaphore


− The Mutex token is persistent
− It is Binary

▪ A MUTEX ( Mutual exclusion) is used to enforce access to a shared resource.

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 114
Mutex API

Mutex
osMutexId_t osMutexNew (const osMutexAttr_t *attr)
const char osMutexGetName (osMutexId_t mutex_id)
osStatus_t osMutexAcquire (osMutexId_t mutex_id, uint32_t timeout)
osStatus_t osMutexRelease (osMutexId_t mutex_id)
osThreadId_t osMutexGetOwner (osMutexId_t mutex_id)
osStatus_t osMutexDelete (osMutexId_t mutex_id)

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 115
Mutex

osMutexId_t uart_mutex;

static const osMutexAttr_t osAttribute_Uart {


“Name”,
Attribute Bit Description
Attr_bits,
osMutexRecursive Same thread can consume mutex multiple times
Control_block memory,
osMutexPrioInherit When a thread owns a mutex it cannot be preempted
Control_block Size by a higher priority thread

} osMutexRobust Notify threads that acquire a mutex if previous owner


has been terminated

uart_mutex = osMutexNew(&osMutex);

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 116
Mutex

▪ A Mutex (mutual exclusion) The threads can then acquire and release the mutex

osStatus osMutexWait (osMutexId mutex_id, uint32_t ticks)


osStatus osMutexRelease (osMutexId mutex_id)

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 117
Mutex

void uart_Thread1 (void *argument) {


uint32_t i;
for (;;) {
osMutexAcquire(uart_mutex, osWaitForever);
for( i=0;i<10;i++){
SendChar('1');
}
SendChar('\n'); SendChar('\r');
osMutexRelease(uart_mutex);
}
}
void uart_Thread2 (void *argument) {
uint32_t i;
for(;;){
osMutexAcquire(uart_mutex, osWaitForever);
for( i=0;i<10;i++){
SendChar('2');
}
SendChar('\n'); SendChar('\r');
osMutexRelease(uart_mutex);
}
}

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 118
Mutex

▪ Thread deletion safety


− A thread must not be deleted while it is controlling a Mutex
− This will lock out the resource to all other tasks
− Use osMutexRobust to protect against this

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 119
Exercise

▪ Return to the Pack installer


− Select and copy exercise 17 Mutex
− This project demonstrates the use of a mutex to grant access to a user
peripheral

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 120
Passing data between Threads

▪ So far we have looked at Thread flags, Event Flags, Semaphores and


Mutex for intertask communication
▪ None of these methods pass any form of data
▪ The CMSIS RTOS provides a powerful message system for exchanging
data between threads
▪ The messaging provides support for fixed and variable length messages

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 121
Message Queue

Message queue

Thread Thread
1 2

Queue of variables or pointers

▪ A message queue provides a FIFO pipe between threads


▪ You can send ‘C’ variables and pointers

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 122
Message Queue API

osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr)

const char * osMessageQueueGetName (osMessageQueueId_t mq_id)

osStatus_t osMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout)

osStatus_t osMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout)

uint32_t osMessageQueueGetCapacity (osMessageQueueId_t mq_id)

uint32_t osMessageQueueGetMsgSize (osMessageQueueId_t mq_id)

uint32_t osMessageQueueGetCount (osMessageQueueId_t mq_id)

uint32_t osMessageQueueGetSpace (osMessageQueueId_t mq_id)

osStatus_t osMessageQueueReset (osMessageQueueId_t mq_id)

osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id)

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 123
Message Queue

osMessageQueueId_t Q_LED;

static const osMessageQueueAttr_t queueAttr_Q_LED = {


“NAME_STRING",
attribute bits (none),
control block memory,
control block size,
data storage memory,
data storage size
};

Q_LED = osMessageQueueNew(maxNumberMssg,mssgWidth,&queueAttr_Q_LED );

▪ The Message Queue is declared with


− Maximum number of messages
− Width of each message in bytes

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 124
Message Queue

uint32_t dataIn;

osMessageQueuePut(Q_LED,&dataIn,osPriorityNormal,osWaitForever);

uint32_t dataOut;
uint8_t priority;

osMessageQueueGet(Q_LED,&dataOut,&priority,osWaitForever);

▪ Data can be placed into a queue from any thread


▪ The receiving thread will wait until data arrives
▪ Messages can be assigned a priority and will be delivered in priority order

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 125
Exercise

▪ In the pack installer


− Select and copy Exercise 18 Message queue
− This project configures a message Queue to send data between two
threads

▪ In the Pack Installer


− Select and copy Exercise 19 Extended message queue
− This project configures a message queue to send more complex data
between two threads

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 126
Memory pool

▪ A memory pool is a form of fixed block memory allocation


▪ A set of user defined buffers are allocated and de-allocated as required by
the user application
▪ The RTOS manages the buffer assignment
▪ The memory pool is a global memory object

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 127
Memory Pool API

osMemoryPoolId_t osMemoryPoolNew (uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr)


typedef struct {
const char * float voltage;
osMemoryPoolGetName (osMemoryPoolId_t mp_id)
float current;
void * osMemoryPoolAlloc
uint32_t counter (osMemoryPoolId_t mp_id, uint32_t timeout)
} message_t;
osStatus_t osMemoryPoolFree (osMemoryPoolId_t mp_id, void *block)

uint32_t osPoolDef(mpool, 16, message_t);


osMemoryPoolGetCapacity (osMemoryPoolId_t mp_id)
osPoolId mpool;
uint32_t osMemoryPoolGetBlockSize (osMemoryPoolId_t mp_id)

uint32_t mpool = osPoolCreate(osPool(mpool));


osMemoryPoolGetCount (osMemoryPoolId_t mp_id)

uint32_t osMemoryPoolGetSpace (osMemoryPoolId_t mp_id)

osStatus_t osMemoryPoolDelete (osMemoryPoolId_t mp_id)

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 128
Creating a Memory Pool

osMemoryPoolId_t mpool;

typedef struct
{
uint8_t canData[8];
} message_t;

static const osMemoryPoolAttr_t memorypoolAttr_mpool ={


"memory_pool",
Attribute bits (none),
Control block memory,
Control block size,
Data Memory,
Data size
};

mpool = osMemoryPoolNew(16, sizeof(message_t),&memorypoolAttr_mpool );

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 129
Memory Pool

message_t *message;

message = (message_t*)osMemoryPoolAlloc(mpool,osWaitForever); //Allocate a memory pool buffer

for(index =0;index<8;index++)
{
message->canData[index] = testData; //populate buffer with data
}

......................
osMemoryPoolFree(mpool, message);

▪ The memory blocks can be allocated, used and then freed back to the
pool
▪ Management of the blocks is done by the RTOS

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 130
Zero copy mailbox

Message queue

Thread Thread
1 2

pointers to memory blocks

alloc free

Memory Pool – formatted memory blocks

▪ A message queue and a memory pool can be combined to make a zero


copy mailbox system

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 131
Exercise Zero copy mailbox

▪ Return to the Pack installer


− Select and copy exercise 20 Mailbox
− This project configures a memory pool and a message queue to
efficiently transfer complex data between threads

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 132
Kernel Information

osStatus_t osKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size)

osKernelState_t osKernelGetState (void)

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 133
TrustZone

▪ TrustZone introduces two new processor states


− Secure State
− Non Secure State
− Each state has its own Handler and Thread mode
TrustZone Programmers Model

Secure MPU
Secure SysTick
Secure System Control Block
Security Attribute Unit
Trust zone

tz_context.h
TZ_InitContextSystem_S
TZ_AllocModuleContext_S
TZ_FreeModuleContext_S
TZ_LoadContext_S
TZ_StoreContext_S

▪ CMSIS-Core provides a set of standard functions that are used to save


the RTOS context when it makes calls to functions in the secure zone
▪ This allows an application in Non Secure mode to run an RTOS and
access functions in secure mode

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 136
Trust Zone

▪ A Trust Zone project is designed as two


separate projects
− The processor boots in Secure mode
− The partition header file is used to define
the secure and non secure regions
− CM33_s_CMSE_lib.o provides the
interface between the two separate
projects
− It is generated by the secure project

4/11/2019 137
Exercise

▪ Return to the Pack installer


− Select and copy exercise 18 TrustZone
− This exercise configures two projects
− One project configures the device in Secure mode and hands over to Non
Secure mode
− The second project runs the RTOS in Non secure mode and makes calls to
functions in secure mode

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 138
Running critical code

void osKernellLock(void)
void osKernelUnlock(void)

▪ The RTOS scheduler may be stopped to run critical code


▪ This ensures thread code runs atomically
▪ Interrupts are still enabled
▪ This feature must only be used for small amounts of code

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 139
Configuration

▪ As its name implies RTX_Config.c contains the operating system


configuration parameters
▪ The system section allows you to configure
− The global memory pool
− Tick frequency ( default 1 msec)
− The scheduling method
− The ISR Fifo queue

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 140
Configuration

▪ Thread configuration
− Can enable an object memory pool
− Default stack size
− Debug options
− Stack checking
Stack watermark ( for maximum memory usage)
Thread operating mode

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 141
Configuration

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 142
Co Operative multitasking

▪ If the Round Robin multitasking thread switching is disabled


− You must pass control by calling the kernel services
− osStatus osThreadYield (void)
− When you call osThreadYield() execution will be passed to the next equal
priority thread

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 143
Test Driven Development

▪ TDD is part of the development process


▪ A Developer is required to first write a test case for a new software
function
▪ Then you write the required code to pass the test
▪ Finally refactor the code to production standards
TDD Benfits

▪ Increases Software Quality


− Increased confidence in the code base
▪ Helps software integration
▪ Provides a faster time to Market
− Remove bugs early at low cost
▪ 2005 study found
− Developers who wrote more tests were more productive
− Code quality increase linearly with number of tests written

▪ http://nparc.cisti-icist.nrc-
cnrc.gc.ca/npsi/ctrl?action=shwart&index=an&req=5763742&lang=en
In a Nutshell

▪ 3 rules
− You are not allowed to write any production code unless it is to
make a failing unit test pass.

− You are not allowed to write any more of a unit test than is sufficient
to fail; and compilation failures are failures.

− You are not allowed to write any more production code than is
sufficient to pass the one failing unit test.
Developer Test Frameworks

▪ Two commonly used frameworks


− Unity
− C based
− unity.sourceforge.net

− CppUTest
− C\C++
− www.cpputest.org
Unity in MDK-ARM

▪ Unity framework is available as a pack


− Hitex::Utilities
− Configured for Cortex-M
− Uses the Instrumentation trace
Adding the Test Framework

▪ Select the test framework


▪ Configure the STDIO channel to use the ITM
Test Component

▪ Unity is added as a project component


Project Structure

▪ Define two build targets


− Test build only includes the test framework and the code under test
− Application build only includes the project code
Project structure

▪ The development folder is included in both builds


▪ Place the code under test here
Test Templates

▪ Adding the test framework


− The test case files are available as templates
Test Main

▪ Test cases are added as test groups


− Allows you to manage and structure the test cases
Test Group

▪ The testGroup. C contains each collection of tests


− Unity provides a wide range of TEST_ASERTS
Automation

▪ One click build and test


− Build
− Download
− Execute the tests
− Log the results
Testing RTOS Threads

▪ RTOS threads can be tested as ‘Objects’


− The test framework can apply test data through the RTOS API calls
Testing RTOS Threads
Exercise

▪ Unity Test Framework


− Select and copy the exercise 22 Testing
− This example demonstrates how to use the unity test framework to
create test cases for C functions and RTOS threads

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 159
Low power Management

Power
Cortex-M
management Sleep Deep

▪ Cortex-M processor enters sleep mode and asserts sleepDeep signal


▪ The power management unit (PMU) places the microcontroller into a
selected low power mode
▪ The PMU will support several levels of low power mode
▪ Very Low power modes result in a loss of program state
▪ Our power management code must differentiate between runtime low
power and standby low power

4/11/2019 160
Low Power management

▪ osSuspend returns the number of ticks a device may be in a low power state
▪ It will return 0xFFFFFFFF for an infinite low power state
− If all the threads block waiting for an input
▪ When we detect this state the system can be placed in the lowest power state

4/11/2019 161
Watchdog Management

▪ In a bare metal system ( super loop and interrupts) a watchdog timer is


typically ‘fed’ as you go round the super loop
▪ In a multithreaded system it is less clear how to feed a watchdog

▪ Create a global variable and mutex


▪ Each thread is assigned a bit

4/11/2019 162
Low Power management

Set the watchdog flag for T1


Send Message to T1

T1 T2

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 163
Watchdogs

T1 T2

WDog

▪ Create a watchdog thread which runs periodically


▪ Each thread has a counter
▪ If the thread watchdog flag is set increment task
counter
▪ If the thread watchdog flag is clear reset the counter
▪ If a counter maximum is reached stop serving the
watchdog
2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 164
Real Time DSP with an RTOS

▪ RTX: Message + Mailbox System buffers processing peaks


− Interacts with Tasks or Interrupt Service Routines
− Keeps a system responsive even with high workload
Real Time DSP with an RTOS

▪ This technique has an initial latency while the first block is processed
Exercise

▪ Return to the Pack installer


− Select and copy exercise 23 Real Time
− This project adds the CMSIS DSP library and demonstrates how to
integrate real time data processing with event driven code

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 167
Middleware

▪ Keil middleware components require CMSIS-RTOS


▪ Each middlelware component creates RTOS threads
▪ Easy to configure and manage complex platforms
▪ Intergrates with silicon vendor tools and libraries
Exercise

▪ Return to the Pack installer


− Select and copy exercise 21 Middleware
− This project creates a webserver to run on an evaluation board
− Your instructor will talk you through the middleware and RTOS
integration

4/11/2019 169
Design Rules

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 170
Design Rules

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 171
Design Rules

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 172
Design Rules

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 173
Design Rules

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 174
Design Rules

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 175
Design Rules

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 176
Design Rules

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 177
Modbus Gateway

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 178
Modbus Gateway

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 179
Exercise

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 180
Exercise

▪ Design study

Design a lab instrument for Embedded systems programmers


Hardware
ADC,DAC,LCD,Touchscreen,GPIO
Software Libraries
CMSIS-DSP
EmWin Graphics library
File System Component
Features
Multimeter
Oscilloscope
Spectrum Analyser
Logic Analyser

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 181
Exercise

▪ Design study

− Vehicle GPS system


− Read NMEA sentence via a serial port
− This data is sent by the GPS every second. It consists of a formatted
string terminated by a checksum and a carriage return
− Decode the ASCII data into Date, Time, Lat, Long
− Display the information on a text LCD display
− Compare the current position against a database of speed camera
locations
− If you are approaching a speed camera provide an audible warning
− Monitor some user interface buttons which set switch the unit on\off set
the buzzer volume

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 182
Project Architecture

▪ Project architecture is as important as functionality


− Architecture includes the layout ( modules) of the source code
− The source code must be written to be “test friendly”

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 183
▪ Source code layout is generally poor in embedded systems middleware
− Functionality – Good
− Use of the ‘C’ language - Good
− MISRA C
− PC-Lint
− But in many projects
− A single source file may contain
− Interrupt code
− Application functions
− Peripheral driver code for different peripherals
− Large numbers of include files and defines

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 184
Project Definition

Requirements

Units of Functional
Drivers
concurrency components
( Peripherals)
(threads) (modules)

▪ Alongside the project requirements we can define


− Threads
− Components
− Drivers
▪ Create standard forms for use during initial customer project meeting
− Create requirements document template
− Create Architecture document template

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 185
Main

▪ The main module shall contain the minimum possible amount of code
− This allows main to be easily removed for testing
− You shall not modify code under test ( ie comment code out)

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 186
System header file

System parameters Example


RTOS definitions Thread Priorities
Thread stack allocation
RTOS Timer
Message queue fifo size
Interrupt definitions IRQ Priority qroup
IRQ priority
Project definitions System switches
Enumerated types

▪ System.h shall hold all project wide definitions


− The file shall use the configuration wizard annotations

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 187
Threads

▪ Threads build up the application functionality


▪ Threads represent a “Unit of concurrency”
− Tasks that can happen in parallel
▪ Threads may only call component functions
− Threads shall not access peripheral driver code directly
− Threads shall not access peripheral registers directly

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 188
Supervisor thread

▪ A supervisor thread is used for


− System configuration at startup
− Watchdog management
− Power management
− Error handling
− Reusable code

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 189
RTOS

▪ Always use an RTOS


− Especially for simple projects
− Bare metal is dead

▪ Use CMSIS-RTOS2
− Standard API
− Supported by Keil RTX, FreeRTOS

▪ Use CMSIS Zone


− Integrates memory protection with low effort
− Provides execution isolation for RTOS threads

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 190
Component

▪ Software component
− A set of related functions encapsulated in a single repository (module)
− Breaks the complexity into manageable parts
− Provides a standard interface to the thread code
− Interfaces to the hardware through the driver layer

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 191
Software components

▪ Example Software components


− GUI Library
− Protocol stack
− DSP functions
− Keyboard scanner

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 192
Software components

▪ A software component shall


− Provide a well defined API
− This may be extended but shall not be redefined
− Support Interrupts and custom functions using callbacks
− Not access functions in another component
− Access driver functions only
− Shall not access MCU registers directly
− Portable
− Testable

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 193
▪ Functional isolation allows
− Development and test before integration into the main project code
− Create IP for reuse
− Create, document and test once
− Increased productivity
− Increased reliability
− Enhanced IDE Support
− Configuration Wizard Annotations
− Keil component viewer
− Keil Event Recorder
− Pack installer

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 194
Header files

Module Description

<component>.c Source code of the module functions

<component>_conf.c Source code of user defined functions

<component>.h Public header file

<component_conf>.h Private header file with configuration options

− Only functions shall be exposed


− Data can only be accessed by helper functions
− The public header file shall contain doxegen documentation for the public
functions
− May vary depending on the level of the project

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 195
Header files
▪ There shall be a standard layout for header files

#include “system.h”

#include “myHeader_conf.h”

#include “component1.h”
#include “component2.h”

#include <stdio.h>

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 196
▪ The drivers use a custom CMSIS Driver profile
− Defined and maintained in house
− Most of the initial work involves
− Creating the profile documentation
− Creating the profile template
− Then you can create a standard driver for any MCU
− Minimal runtime overhead

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 197
▪ CMSIS- currently provides support for
− USART
− SPI
− SAI
− I2C
− USB HOST and Device
− FLASH NAND and NOR
− Ethernet
− CAN
− MCI
▪ Initially develop profiles for
− Timer
− ADC
− DAC

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 198
CMSIS-Driver API

Function Description

<peripheral>_GetVersion Return the current driver and API version.

<peripheral>_Initialize Installs the IRQ callback, configures the GPIO secondary functions.

<peripheral>_uninitialize Returns the peripheral,clocks and GPIO to default state.

<peripheral>_PowerControl Sets the peripheral power mode ie full power, low power, standby.

<peripheral>_Control Provides the main control interface to the peripheral. Configures the
operating mode, allows updating peripheral features during run-time.

<peripheral>_custom Additional functions as required by the peripheral ie


ADC_getConversion

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 199
RTOS Validation

▪ CMSIS-RTOS-Validation test suite


− ARM defined test suite for MDK-ARM
− Validates the RTOS functionality on a given target

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 200
CMSIS-Driver Validation

▪ CMSIS-Driver Validation test suite


▪ ARM defined test suite for MDK-ARM

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 201
CMSIS-Driver Validation

▪ Easy to extend framework for custom profiles


− Develop the tests once then use for all future drivers
− Provides a test suite for drivers under development

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 202
▪ Component testing
− Unity test framework for developer test
− Tessy for formal unit test

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 203
Application
project

Component + Component + Component+


test framework test framework test framework

Driver mock functions

Driver development project + validation framework

▪ Each box is a microvision project

2014-07-11 Copyright © Hitex Development Tools 2014. All rights reserved. Page 204

You might also like