Em OS
Em OS
CPU-independent
Document: UM01001
Software version 3.88
Revision: 0
Date: February 19, 2013
www.segger.com
2 CHAPTER
Disclaimer
Specifications written in this document are believed to be accurate, but are not guar-
anteed to be entirely free of error. The information in this manual is subject to
change for functional or performance improvements without notice. Please make sure
your manual is the latest edition. While the information herein is assumed to be
accurate, SEGGER Microcontroller GmbH & Co. KG (SEGGER) assumes no responsibil-
ity for any errors or omissions. SEGGER makes and you receive no warranties or con-
ditions, express, implied, statutory or in any communication with you. SEGGER
specifically disclaims any implied warranty of merchantability or fitness for a particu-
lar purpose.
Copyright notice
You may not extract portions of this manual or modify the PDF file in any way without
the prior written permission of SEGGER. The software described in this document is
furnished under a license and may only be used or copied in accordance with the
terms of such a license.
© 1995- 2013 SEGGER Microcontroller GmbH & Co. KG, Hilden / Germany
Trademarks
Names mentioned in this manual may be trademarks of their respective companies.
Brand and product names are trademarks or registered trademarks of their respec-
tive holders.
Contact address
SEGGER Microcontroller GmbH & Co. KG
In den Weiden 11
D-40721 Hilden
Germany
Tel.+49 2103-2878-0
Fax.+49 2103-2878-28
E-mail: support@segger.com
Internet: http://www.segger.com
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
3
Manual versions
This manual describes the current software version. If any error occurs, inform us
and we will try to assist you as soon as possible.
Contact us for further information on topics or routines not yet specified.
Print date: February 19, 2013
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
4 CHAPTER
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
5
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
6 CHAPTER
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
7
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
8 CHAPTER
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
9
Assumptions
This document assumes that you already have a solid knowledge of the following:
• The software tools used for building your application (assembler, linker, C com-
piler)
• The C programming language
• The target processor
• DOS command line
If you feel that your knowledge of C is not sufficient, we recommend The C Program-
ming Language by Kernighan and Richie (ISBN 0-13-1103628), which describes the
standard in C-programming and, in newer editions, also covers the ANSI C standard.
How to use this manual
This manual explains all the functions and macros that the product offers. It assumes
you have a working knowledge of the C language. Knowledge of assembly program-
ming is not required.
Typographic conventions for syntax
This manual uses the following typographic conventions:
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
10
emFile
File system
emFile is an embedded file system with
FAT12, FAT16 and FAT32 support. Var-
ious Device drivers, e.g. for NAND and
NOR flashes, SD/MMC and Compact-
Flash cards, are available.
USB-Stack
USB device/host stack
A USB stack designed to work on any
embedded system with a USB control-
ler. Bulk communication and most stan-
dard device classes are supported.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
11
Table of Contents
2 Basic concepts...............................................................................................................23
2.1 Tasks ..................................................................................................... 24
2.1.1 Threads.................................................................................................. 24
2.1.2 Processes ............................................................................................... 24
2.2 Single-task systems (superloop) ................................................................ 25
2.2.1 Advantages & disadvantages ..................................................................... 25
2.2.2 Using embOS in super-loop applications...................................................... 26
2.2.3 Migrating from superloop to multi-tasking ................................................... 26
2.3 Multitasking systems................................................................................ 27
2.3.1 Task switches.......................................................................................... 27
2.3.2 Cooperative task switch............................................................................ 27
2.3.3 Preemptive task switch............................................................................. 27
2.3.4 Preemptive multitasking ........................................................................... 28
2.3.5 Cooperative multitasking ......................................................................... 29
2.4 Scheduling.............................................................................................. 30
2.4.1 Round-robin scheduling algorithm .............................................................. 30
2.4.2 Priority-controlled scheduling algorithm ...................................................... 30
2.4.3 Priority inversion / priority inheritance ........................................................ 31
2.5 Communication between tasks .................................................................. 33
2.5.1 Periodical polling ..................................................................................... 33
2.5.2 Event driven communication mechanisms ................................................... 33
2.5.3 Mailboxes and queues .............................................................................. 33
2.5.4 Semaphores ........................................................................................... 33
2.5.5 Events ................................................................................................... 33
2.6 How task-switching works......................................................................... 34
2.6.1 Switching stacks...................................................................................... 35
2.7 Change of task status............................................................................... 36
2.8 How the OS gains control ......................................................................... 37
2.9 Different builds of embOS ......................................................................... 38
2.9.1 Profiling ................................................................................................. 38
2.9.2 List of libraries ........................................................................................ 38
2.9.3 embOS functions context .......................................................................... 38
4 Tasks .............................................................................................................................41
4.1 Introduction............................................................................................ 42
4.1.1 Example of a task routine as an endless loop............................................... 42
4.1.2 Example of a task routine that terminates itself ........................................... 42
4.2 Cooperative vs. preemptive task switches ................................................... 43
4.2.1 Disabling preemptive task switches for tasks at same priorities ...................... 43
4.2.2 Completely disabling preemptions for a task................................................ 43
4.3 Extending the task context ....................................................................... 44
4.3.1 Passing one parameter to a task during task creation ................................... 44
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
12
6 Resource semaphores.................................................................................................107
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
13
8 Mailboxes.....................................................................................................................135
8.1 Introduction.......................................................................................... 136
8.2 Basics .................................................................................................. 137
8.3 Typical applications................................................................................ 138
8.4 Single-byte mailbox functions.................................................................. 139
8.5 API functions ........................................................................................ 140
8.5.1 OS_CreateMB() ..................................................................................... 141
8.5.2 OS_PutMail() / OS_PutMail1() ................................................................. 142
8.5.3 OS_PutMailCond() / OS_PutMailCond1() ................................................... 143
8.5.4 OS_PutMailFront() / OS_PutMailFront1()................................................... 144
8.5.5 OS_PutMailFrontCond() / OS_PutMailFrontCond1()..................................... 145
8.5.6 OS_GetMail() / OS_GetMail1()................................................................. 146
8.5.7 OS_GetMailCond() / OS_GetMailCond1() .................................................. 147
8.5.8 OS_GetMailTimed()................................................................................ 148
8.5.9 OS_WaitMail()....................................................................................... 149
8.5.10 OS_WaitMailTimed() .............................................................................. 150
8.5.11 OS_PeekMail() ...................................................................................... 151
8.5.12 OS_ClearMB() ....................................................................................... 152
8.5.13 OS_GetMessageCnt() ............................................................................. 153
8.5.14 OS_DeleteMB() ..................................................................................... 154
9 Queues ........................................................................................................................155
9.1 Introduction.......................................................................................... 156
9.2 Basics .................................................................................................. 157
9.3 API functions ........................................................................................ 158
9.3.1 OS_Q_Create() ..................................................................................... 159
9.3.2 OS_Q_Put() .......................................................................................... 160
9.3.3 OS_Q_PutBlocked() ............................................................................... 161
9.3.4 OS_Q_GetPtr()...................................................................................... 162
9.3.5 OS_Q_GetPtrCond()............................................................................... 163
9.3.6 OS_Q_GetPtrTimed() ............................................................................. 164
9.3.7 OS_Q_Purge()....................................................................................... 165
9.3.8 OS_Q_Clear() ....................................................................................... 166
9.3.9 OS_Q_GetMessageCnt() ......................................................................... 167
9.3.10 OS_Q_Delete()...................................................................................... 168
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
14
10 Task events................................................................................................................173
10.1 Introduction ..........................................................................................174
10.2 API functions .........................................................................................175
10.2.1 OS_WaitEvent() .....................................................................................176
10.2.2 OS_WaitSingleEvent() ............................................................................177
10.2.3 OS_WaitEvent_Timed()...........................................................................178
10.2.4 OS_WaitSingleEventTimed() ....................................................................179
10.2.5 OS_SignalEvent()...................................................................................180
10.2.6 OS_GetEventsOccurred() ........................................................................182
10.2.7 OS_ClearEvents()...................................................................................183
14 Stacks ........................................................................................................................219
14.1 Introduction ..........................................................................................220
14.1.1 System stack.........................................................................................220
14.1.2 Task stack.............................................................................................220
14.1.3 Interrupt stack.......................................................................................220
14.1.4 Stack size calculation..............................................................................221
14.1.5 Stack check...........................................................................................221
14.2 API functions .........................................................................................222
14.2.1 OS_GetStackBase() ................................................................................223
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
15
15 Interrupts....................................................................................................................235
15.1 What are interrupts? .............................................................................. 236
15.2 Interrupt latency ................................................................................... 237
15.2.1 Causes of interrupt latencies ................................................................... 237
15.2.2 Additional causes for interrupt latencies.................................................... 237
15.3 Zero interrupt latency ............................................................................ 239
15.4 High / low priority interrupts ................................................................... 240
15.4.1 Using OS functions from high priority interrupts......................................... 240
15.5 Rules for interrupt handlers..................................................................... 242
15.5.1 General rules ........................................................................................ 242
15.5.2 Additional rules for preemptive multitasking .............................................. 242
15.6 API functions ........................................................................................ 243
15.6.1 OS_CallISR() ........................................................................................ 244
15.6.2 OS_CallNestableISR() ............................................................................ 245
15.6.3 OS_EnterInterrupt() .............................................................................. 246
15.6.4 OS_LeaveInterrupt() .............................................................................. 247
15.7 Enabling / disabling interrupts from C....................................................... 248
15.7.1 OS_IncDI() / OS_DecRI() ....................................................................... 249
15.7.2 OS_DI() / OS_EI() / OS_RestoreI().......................................................... 250
15.8 Definitions of interrupt control macros (in RTOS.h)..................................... 251
15.9 Nesting interrupt routines ....................................................................... 252
15.9.1 OS_EnterNestableInterrupt()................................................................... 253
15.9.2 OS_LeaveNestableInterrupt() .................................................................. 254
15.10 Non-maskable interrupts (NMIs) .............................................................. 255
16 Critical Regions..........................................................................................................257
16.1 Introduction.......................................................................................... 258
16.2 API functions ........................................................................................ 259
16.2.1 OS_EnterRegion().................................................................................. 260
16.2.2 OS_LeaveRegion() ................................................................................. 261
18 System variables........................................................................................................277
18.1 Introduction.......................................................................................... 278
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
16
19 System tick.................................................................................................................281
19.1 Introduction ..........................................................................................282
19.2 Tick handler ..........................................................................................283
19.2.1 API functions .........................................................................................283
19.2.1.1 OS_TICK_Handle() .................................................................................284
19.2.1.2 OS_TICK_HandleEx()..............................................................................285
19.2.1.3 OS_TICK_HandleNoHook() ......................................................................286
19.2.1.4 OS_TICK_Config() ..................................................................................287
19.3 Hooking into the system tick....................................................................288
19.3.1 API functions .........................................................................................288
19.3.1.1 OS_TICK_AddHook() ..............................................................................289
19.3.1.2 OS_TICK_RemoveHook() ........................................................................290
21 Profiling ......................................................................................................................299
21.0.1 API functions .........................................................................................300
21.0.1.1 OS_STAT_Sample()................................................................................301
21.0.1.2 OS_STAT_GetLoad()...............................................................................302
21.0.1.3 Sample application for OS_STAT_Sample() and OS_STAT_GetLoad() ............303
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
17
24 Debugging..................................................................................................................345
24.1 Runtime errors ...................................................................................... 346
24.1.1 OS_DEBUG_LEVEL ................................................................................. 346
24.2 List of error codes.................................................................................. 347
24.3 Application defined error codes................................................................ 351
26 Limitations..................................................................................................................355
29 Support ......................................................................................................................363
29.1 Contacting support ................................................................................ 364
30 Glossary.....................................................................................................................365
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
18
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
19
Chapter 1
Introduction to embOS
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
20 CHAPTER 1 Introduction to embOS
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
21
1.2 Features
Throughout the development process of embOS, the limited resources of microcon-
trollers have always been kept in mind. The internal structure of the realtime operat-
ing system (RTOS) has been optimized in a variety of applications with different
customers, to fit the needs of the industry. Fully source-compatible RTOS are avail-
able for a variety of microcontrollers, making it well worth the time and effort to
learn how to structure real-time programs with real-time operating systems.
embOS is highly modular. This means that only those functions that are needed are
linked, keeping the ROM size very small. The minimum memory consumption is little
more than 1 Kbyte of ROM and about 30 bytes of RAM (plus memory for stacks). A
couple of files are supplied in source code to make sure that you do not loose any
flexibility by using embOS and that you can customize the system to fully fit your
needs.
The tasks you create can easily and safely communicate with each other using a
complete palette of communication mechanisms such as semaphores, mailboxes, and
events.
Some features of embOS include:
• Preemptive scheduling:
Guarantees that of all tasks in READY state the one with the highest priority exe-
cutes, except for situations where priority inheritance applies.
• Round-robin scheduling for tasks with identical priorities.
• Preemptions can be disabled for entire tasks or for sections of a program.
• Up to 255 priorities.
• Every task can have an individual priority => the response of tasks can be pre-
cisely defined according to the requirements of the application.
• Unlimited number of tasks
(limited only by the amount of available memory).
• Unlimited number of semaphores
(limited only by the amount of available memory).
• 2 types of semaphores: resource and counting.
• Unlimited number of mailboxes
(limited only by the amount of available memory).
• Size and number of messages can be freely defined when initializing mailboxes.
• Unlimited number of software timers
(limited only by the amount of available memory).
• 8-bit events for every task.
• Time resolution can be freely selected (default is 1ms).
• Easily accessible time variable.
• Power management.
• Unused calculation time can automatically be spent in halt mode.
power-consumption is minimized.
• Full interrupt support:
Interrupts can call any function except those that require waiting for data,
as well as create, delete or change the priority of a task.
Interrupts can wake up or suspend tasks and directly communicate with tasks
using all available communication instances (mailboxes, semaphores, events).
• Very short interrupt disable-time => short interrupt latency time.
• Nested interrupts are permitted.
• embOS has its own interrupt stack (usage optional).
• Frame application for an easy start.
• Debug version performs runtime checks, simplifying development.
• Profiling and stack check may be implemented by choosing specified libraries.
• Monitoring during runtime via UART available (embOSView).
• Very fast and efficient, yet small code.
• Minimum RAM usage.
• Core written in assembly language.
• API can be called from Assembly, C or C++ code.
• Initialization of microcontroller hardware as sources (BSP).
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
22 CHAPTER 1 Introduction to embOS
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
23
Chapter 2
Basic concepts
This chapter explains some basic concepts behind embOS. It should be relativly easy
to read and is recommended before moving to other chapters.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
24 CHAPTER 2 Basic concepts
2.1 Tasks
In this context, a task is a program running on the CPU core of a microcontroller.
Without a multitasking kernel (an RTOS), only one task can be executed by the CPU
at a time. This is called a single-task system. A real-time operating system allows the
execution of multiple tasks on a single CPU. All tasks execute as if they completely
“owned” the entire CPU. The tasks are scheduled, meaning that the RTOS can
activate and deactivate every task.
2.1.1 Threads
Threads are tasks which share the same memory layout. Two threads can access the
same memory locations. If virtual memory is used, the same virtual to physical
translation and access rights are used.
The embOS tasks are threads; they all have the same memory access rights and
translation (in systems with virtual memory).
2.1.2 Processes
Processs are task which their own memory layout. Two processes can not normally
access the same memory locations. Different processes typically have different
access rights and (in case of MMUs) different translation tables.
Processes are not supported by the present version of embOS.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
25
Typically, because no real-time kernel and only one stack is used, both program
(ROM) and RAM size are smaller for small applications. Of course, there are no inter-
task synchronization problems with a superloop application. However, superloops can
become difficult to maintain if the program becomes too large. Because one software
component cannot be interrupted by another component (only by ISRs), the reaction
time of one component depends on the execution time of all other components in the
system. Real-time behavior is therefore poor.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
26 CHAPTER 2 Basic concepts
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
27
Priority
OS_EVENT_Wait()
Interrupt
Interrupt (Rx)
Time OS_EVENT_Wait()
OS_EVENT_Set()
OS_Delay()
Interrupt (Tick)
OS_Delay()
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
28 CHAPTER 2 Basic concepts
ISR
Interrupted task
is completed
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
29
ISR
ISR puts high priority
task in READY state
Interrupted task
Time is completed
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
30 CHAPTER 2 Basic concepts
2.4 Scheduling
There are different algorithms that determine which task to execute, called
schedulers. All schedulers have one thing in common: they distinguish between tasks
that are ready to be executed (in the READY state) and the other tasks that are
suspended for any reason (delay, waiting for mailbox, waiting for semaphore, waiting
for event, and so on). The scheduler selects one of the tasks in the READY state and
activates it (executes the program of this task). The task which is currently executing
is referred to as the running task. The main difference between schedulers is in how
they distribute the computation time between the tasks in READY state.
All tasks are on the same level; the possession of the CPU changes periodically after
a predefined execution time. This time is called timeslice, and may be defined
individually for every task.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
31
OS_Use()
Interrupt activates high prio task
OS_Use()
OS_Delay()
Time OS_Unuse()
OS_Unuse()
The low priority task claims the semaphore with OS_Use(). An interrupt activates the
high priority task, which also calls OS_Use().
Meanwhile a task with medium got ready and runs when the high priority task is sus-
pended.
After doing some operations, the task with medium priority calls OS_Delay() and is
therefore suspended. The task with lower priority continues now and calls
OS_Unuse() to release the resource semaphore. After the low priority task releases
the semaphore, the high priority task is activated and claims the semaphore.
To avoid this kind of situation, the low-priority task that is blocking the highest-prior-
ity task gets assigned the highest priority until it releases the resource, unblocking
the task which originally had highest priority. This is known as priority inherit-
ance.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
32 CHAPTER 2 Basic concepts
OS_Use()
Interrupt activates high prio task
Priority inheritance
OS_Use()
Time OS_Unuse()
OS_Unuse()
With priority inheritance, the low priority task inherits the priority of the waiting high
priority task as long as it holds the resource semaphore. The lower priority task is
activated instead of the medium priority task when the high priority task tries to
claim the semaphore.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
33
2.5.4 Semaphores
Two types of semaphores are used for synchronizing tasks and to manage resources.
The most common are resource semaphores, although counting semaphores are also
used. For details and samples, refer to the Chapter Resource semaphores on
page 107 and Chapter Counting Semaphores on page 121. Samples can also be
found on our website at www.segger.com.
2.5.5 Events
A task can wait for a particular event without using any calculation time. The idea is
as simple as it is convincing; there is no sense in polling if we can simply activate a
task the moment the event that it is waiting for occurs. This saves a great deal of
calculation power and ensures that the task can respond to the event without delay.
Typical applications for events are those where a task waits for data, a pressed key, a
received command or character, or the pulse of an external real-time clock.
For further details, refer to the Chapter Task events on page 173 and Chapter Event
objects on page 185.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
34 CHAPTER 2 Basic concepts
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
35
Task 0 Task n
Task Control Stack Task Control Stack
block block
variables variables
temp. storage temp. storage
ret. addresses ret. addresses
CPU CPU
registers registers
SP SP
Scheduler
CPU
The scheduler deactivates the task to be suspended (Task 0) by saving the processor
registers on its stack. It then activates the higher-priority task (Task n) by loading
the stack pointer (SP) and the processor registers from the values stored on Task n's
stack.
Deactivating a task
The scheduler deactivates the task to be suspended (Task 0) as follows:
1. Save (push) the processor registers on the task's stack.
2. Save the stack pointer in the Task Control Block (TCB).
Activating a task
It then activates the higher-priority task (Task n) by performing the opposite
sequence in reverse order:
1. Load (pop) the stack pointer (SP) from the TCB.
2. Load the processor registers from the values stored on Task n's stack..
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
36 CHAPTER 2 Basic concepts
Not existing
OS_CreateTask()
OS_Terminate()
OS_CreateTaskEx()
Waiting
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
37
Startup code
main()
OS_IncDI()
OS_InitKern()
OS_InitHW()
Additional initialization code;
creating at least one task.
OS_Start()
The main() routine will not be interrupted by any of the created tasks, because those
tasks are executed only after the call to OS_Start(). It is therefore usually recom-
mended to create all or most of your tasks here, as well as your control structures
such as mailboxes and semaphores. A good practice is to write software in the form
of modules which are (up to a point) reusable. These modules usually have an initial-
ization routine, which creates the required task(s) and/or control structures.
A typical main() looks similar to the following example:
Example
/***********************************************************************
*
* main
*
************************************************************************
*/
void main(void) {
OS_IncDI();
OS_InitKern(); /* Initialize OS (should be first !) */
OS_InitHW(); /* Initialize Hardware for OS (in RtosInit.c) */
/* Call Init routines of all program modules which in turn will create
the tasks they need ... (Order of creation may be important) */
MODULE1_Init();
MODULE2_Init();
MODULE3_Init();
MODULE4_Init();
MODULE5_Init();
OS_Start(); /* Start multitasking */
}
With the call to OS_Start(), the scheduler starts the highest-priority task that has
been created in main().
Note that OS_Start() is called only once during the startup process and does not
return.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
38 CHAPTER 2 Basic concepts
2.9.1 Profiling
embOS supports profiling in profiling builds. Profiling makes precise information
available about the execution time of individual tasks. You may always use the profil-
ing libraries, but they induce certain overhead such as bigger task control blocks,
additional ROM (approximately 200 bytes) and additional runtime overhead. This
overhead is usually acceptable, but for best performance you may want to use non-
profiling builds of embOS if you do not use this feature.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
39
Chapter 3
This chapter gives some recommendations on how to use embOS in your applica-
tions. These are simply recommendations that we feel can be helpful when designing
& structuring an application.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
40 CHAPTER 3 Working with embOS
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
41
Chapter 4
Tasks
This chapter explains some basic about tasks and embOS task API functions. It
should be relatively easy to read and is recommended before moving to other chap-
ters.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
42 CHAPTER 4 Tasks
4.1 Introduction
A task that should run under embOS needs a task control block (TCB), a stack, and a
normal routine written in C. The following rules apply to task routines:
• The task routine can either not take parameters (void parameter list), in which
case OS_CreateTask() is used to create it, or take one void pointer as parame-
ter, in which case OS_CreateTaskEx() is used to create it.
• The task routine must not return.
• The task routine should be implemented as an endless loop, or it must terminate
itself (see examples below).
There are different ways to create a task; embOS offers a simple macro that makes
this easy and which is fully sufficient in most cases. However, if you are dynamically
creating and deleting tasks, a routine is available allowing “fine-tuning” of all param-
eters. For most applications, at least initially, using the macro as in the sample start
project works fine.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
43
#include "RTOS.h"
#define PRIO_COOP 10
#define TIME_SLICE_NULL 0
Note: This will entirely disallow preemptive context switches from that particular
task and will therefor affect the timing of higher priority task. You should do this only
if you know what you are doing.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
44 CHAPTER 4 Tasks
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
45
/*********************************************************************
* SEGGER MICROCONTROLLER GmbH & Co KG *
* Solutions for real time microcontroller applications *
**********************************************************************
----------------------------------------------------------------------
File : Start_Extended_OS_TASK.c
Purpose : Skeleton program for OS to demonstrate extended tasks
-------- END-OF-HEADER ---------------------------------------------
*/
#include "RTOS.h"
#include <stdio.h>
/****** Define an own task structure with extended task context *****/
typedef struct {
OS_TASK Task; // OS_TASK has to be the first element
OS_TIME Timeout; // Any other data may follow
char* pString;
} MY_APP_TASK;
/* Variables */
OS_STACKPTR int StackHP[128], StackLP[128]; /* Task stacks */
MY_APP_TASK TCBHP, TCBLP; /* Task-control-blocks */
/*********************************************************************
*
* Task function
*/
static void MyTask(void) {
char* pString;
OS_TIME Delay;
MY_APP_TASK* pThis;
int main(void) {
OS_IncDI(); /* Initially disable interrupts */
OS_InitKern(); /* Initialize OS */
OS_InitHW(); /* Initialize Hardware for OS */
/*
* Create the extended tasks just as normal tasks.
* Note that the first paramater has to be of type OS_TASK
*/
OS_CREATETASK(&TCBHP.Task, "HP Task", MyTask, 100, StackHP);
OS_CREATETASK(&TCBLP.Task, "LP Task", MyTask, 50, StackLP);
/*
* Give task contexts individual data
*/
TCBHP.Timeout = 200;
TCBHP.pString = "HP task running\n";
TCBLP.Timeout = 500;
TCBLP.pString = "LP task running\n";
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
46 CHAPTER 4 Tasks
Timer
main
Task
Description
ISR
Routine
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
47
Timer
main
Task
Description
ISR
Routine
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
48 CHAPTER 4 Tasks
4.4.1 OS_AddOnTerminateHook()
Description
Adds a handler function into a list of functions that are called when a task is termi-
nated.
Prototype
void OS_AddOnTerminateHook (OS_ON_TERMINATE_HOOK * pHook,
OS_ON_TERMINATE_FUNC * pfUser);
Parameter Description
Pointer to a variable of type OS_ON_TERMINATE_HOOK which will
pHook be inserted into the linked list of functions to be
called during OS_TerminateTask().
Pointer to the function of type OS_TERMINATE_FUNC which shall
pfUser
be called when a task is terminated.
Table 4.2: OS_AddOnTerminateHook() parameter list
Additional Information
For some applications, it may be useful to allocate memory or objects specific to
tasks. For other applications, it may be usefull to have task specific information on
the stack.
When a task is terminated, the task specific objects may become invalid.
A callback function may be hooked into OS_TerminateTask() by calling
OS_AddOnTerminateHook() to allow the application to invalidate all task specific
objects, before the task is terminated.
The callback function of type OS_ON_TERMINATE_FUNC gets the ID of the terminated
task as parameter.
OS_ON_TERMINATE_FUNC is defined as:
typedef void OS_ON_TERMINATE_FUNC(OS_CONST_PTR OS_TASK * pTask);
Important
The variable of type OS_ON_TERMINATE_HOOK has to reside in memory as global or
static variable. It may be located on a task stack, as local variable, but it MUST NOT
be located on any stack of any task that might be terminated.
Example
OS_ON_TERMINATE_HOOK _OnTerminateHook; /* Stack-space */
...
void OnTerminateHookFunc(OS_CONST_PTR OS_TASK * pTask) {
// This function is called, when OS_TerminateTask() is called.
if (pTask == &MyTask) {
free(MytaskBuffer);
}
}
...
main(void) {
OS_AddOnTerminateHook(&_OnTerminateHook, OnTerminateHookFunc);
...
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
49
4.4.2 OS_CREATETASK()
Description
Creates a task.
Prototype
void OS_CREATETASK ( OS_TASK * pTask,
char * pName,
void * pRoutine,
unsigned char Priority,
void * pStack);
Parameter Description
Pointer to a data structure of type OS_TASK which will be used as
pTask
task control block (and reference) for this task.
pName Pointer to the name of the task. Can be NULL (or 0) if not used.
pRoutine Pointer to a routine that should run as a task
Priority of the task. Must be within the following range:
Priority 1 <= Priority <=255
Higher values indicate higher priorities.
Pointer to an area of memory in RAM that will serve as stack area
pStack for the task. The size of this block of memory determines the size
of the stack area.
Table 4.3: OS_CREATETASK() parameter list
Additional Information
OS_CREATETASK() is a macro calling an OS library function. It creates a task and
makes it ready for execution by putting it in the READY state. The newly created task
will be activated by the scheduler as soon as there is no other task with higher
priority in the READY state. If there is another task with the same priority, the new
task will be placed right before it. This macro is normally used for creating a task
instead of the function call OS_CreateTask(), because it has fewer parameters and is
therefore easier to use.
OS_CREATETASK() can be called at any time, either from main() during initialization
or from any other task. The recommended strategy is to create all tasks during ini-
tialization in main() to keep the structure of your tasks easy to understand.
The absolute value of Priority is of no importance, only the value in comparison to
the priorities of other tasks.
OS_CREATETASK() determines the size of the stack automatically, using sizeof().
This is possible only if the memory area has been defined at compile time.
Important
The stack that you define has to reside in an area that the CPU can actually use as
stack. Most CPUs cannot use the entire memory area as stack. Most CPUs require
alignment of stack in multiples of bytes. This is automatically done, when the task
stack is defined as an array of integers.
The task stack has to be assigned to one task only. The memory used as task stack
can not be used for other purposes as long as the task exists. The stack can not be
shared with other tasks.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
50 CHAPTER 4 Tasks
Example
OS_STACKPTR int UserStack[150]; /* Stack-space */
OS_TASK UserTCB; /* Task-control-blocks */
void UserTask(void) {
while (1) {
Delay (100);
}
}
void InitTask(void) {
OS_CREATETASK(&UserTCB, "UserTask", UserTask, 100, UserStack);
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
51
4.4.3 OS_CreateTask()
Description
Creates a task.
Prototype
void OS_CreateTask ( OS_TASK * pTask,
char * pName,
unsigned char Priority,
voidRoutine * pRoutine,
void * pStack,
unsigned StackSize,
unsigned char TimeSlice );
Parameter Description
Pointer to a data structure of type OS_TASK which will be used as
pTask
the task control block (and reference) for this task.
pName Pointer to the name of the task. Can be NULL (or 0) if not used.
Priority of the task. Must be within the following range:
Priority 1 <= Priority <=255
Higher values indicate higher priorities.
pRoutine Pointer to a routine that should run as task
Pointer to an area of memory in RAM that will serve as stack area
pStack for the task. The size of this block of memory determines the size
of the stack area.
StackSize Size of the stack in bytes.
Time slice value for round-robin scheduling. Has an effect only if
other tasks are running at the same priority. TimeSlice denotes
the time in embOS timer ticks that the task will run until it sus-
pends; thus enabling another task with the same priority. This
TimeSlice
parameter has no effect on some ports of embOS for efficiency
reasons.
The timeslice value has to be in the following range:
1 <= TimeSlice <= 255.
Table 4.4: OS_CreateTask() parameter list
Additional Information
This function works the same way as OS_CREATETASK(), except that all parameters of
the task can be specified.
The task can be dynamically created because the stack size is not calculated auto-
matically as it is with the macro.
When using a debug build of embOS, setting of an illegal TimeSlice value will call the
error handler OS_Error() with error code OE_ERR_TIMSLICE.
Important
The stack that you define has to reside in an area that the CPU can actually use as
stack. Most CPUs cannot use the entire memory area as stack.
Most CPUs require alignment of stack in multiples of bytes. This is automatically
done, when the task stack is defined as an array of integers.
The task stack has to be assigned to one task only. The memory used as task stack
can not be used for other purposes as long as the task exists. The stack can not be
shared with other tasks.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
52 CHAPTER 4 Tasks
Example
/* Demo-program to illustrate the use of OS_CreateTask */
void Clock(void) {
while(1) {
/* Code to update the clock */
}
}
void Main(void) {
while (1) {
/* Your code */
}
}
void InitTask(void) {
OS_CreateTask(&TaskMain, NULL, 50, Main, StackMain, sizeof(StackMain), 2);
OS_CreateTask(&TaskClock, NULL, 100, Clock,StackClock,sizeof(StackClock),2);
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
53
4.4.4 OS_CREATETASK_EX()
Description
Creates a task and passes a parameter to the task.
Prototype
void OS_CREATETASK_EX ( OS_TASK * pTask,
char * pName,
void * pRoutine,
unsigned char Priority,
void * pStack,
void * pContext );
Parameter Description
Pointer to a data structure of type OS_TASK which will be used as
pTask
task control block (and reference) for this task.
pName Pointer to the name of the task. Can be NULL (or 0) if not used.
pRoutine Pointer to a routine that should run as a task.
Priority of the task. Must be within the following range:
Priority 1 <= Priority <=255
Higher values indicate higher priorities.
Pointer to an area of memory in RAM that will serve as stack area
pStack for the task. The size of this block of memory determines the size
of the stack area.
pContext Parameter passed to the created task function.
Table 4.5: OS_CREATETASK_EX() parameter list
Additional Information
OS_CREATETASK_EX() is a macro calling an embOS library function. It works like
OS_CREATETASK(), but allows passing a parameter to the task.
Using a void pointer as additional parameter gives the flexibility to pass any kind of
data to the task function.
Example
The following example is delivered in the Samples folder of embOS.
/*------------------------------------------------------------------
File : Main_TaskEx.c
Purpose : Sample program for embOS using OC_CREATETASK_EX
--------- END-OF-HEADER --------------------------------------------*/
#include "RTOS.h"
OS_STACKPTR int StackHP[128], StackLP[128]; /* Task stacks */
OS_TASK TCBHP, TCBLP; /* Task-control-blocks */
/********************************************************************/
static void TaskEx(void* pVoid) {
while (1) {
OS_Delay ((OS_TIME) pVoid);
}
}
/*********************************************************************
*
* main
*
*********************************************************************/
int main(void) {
OS_IncDI(); /* Initially disable interrupts */
OS_InitKern(); /* initialize OS */
OS_InitHW(); /* initialize Hardware for OS */
/* You need to create at least one task before calling OS_Start() */
OS_CREATETASK_EX(&TCBHP, "HP Task", TaskEx, 100, StackHP, (void*) 50);
OS_CREATETASK_EX(&TCBLP, "LP Task", TaskEx, 50, StackLP, (void*) 200);
OS_SendString("Start project will start multitasking !\n");
OS_Start(); /* Start multitasking */
return 0;
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
54 CHAPTER 4 Tasks
4.4.5 OS_CreateTaskEx()
Description
Creates a task and passes a parameter to the task.
Prototype
void OS_CreateTaskEx ( OS_TASK * pTask,
char * pName,
unsigned char Priority,
voidRoutine * pRoutine,
void * pStack,
unsigned StackSize,
unsigned char TimeSlice,
void * pContext );
Parameter Description
Pointer to a data structure of type OS_TASK which will be used as
pTask
the task control block (and reference) for this task.
pName Pointer to the name of the task. Can be NULL (or 0) if not used.
Priority of the task. Must be within the following range:
Priority 1 <= Priority <=255
Higher values indicate higher priorities.
pRoutine Pointer to a routine that should run as task.
Pointer to an area of memory in RAM that will serve as stack area
pStack for the task. The size of this block of memory determines the size
of the stack area.
StackSize Size of the stack in bytes.
Time slice value for round-robin scheduling. Has an effect only if
other tasks are running at the same priority.TimeSlice denotes
the time in embOS timer ticks that the task will run until it sus-
pends; thus enabling another task with the same priority. This
TimeSlice
parameter has no effect on some ports of embOS for efficiency
reasons.
The timeslice value has to be in the following range:
1 <= TimeSlice <= 255.
pContext Parameter passed to the created task.
Table 4.6: OS_Create_TaskEx() parameter list
Additional Information
This function works the same way as OS_CreateTask(), except that a parameter is
passed to the task function.
An example of parameter passing to tasks is shown under OS_CREATETASK_EX().
When using a debug build of embOS, setting of an illegal TimeSlice value will call the
error handler OS_Error() with error code OE_ERR_TIMSLICE.
Important
The stack that you define has to reside in an area that the CPU can actually use as
stack. Most CPUs cannot use the entire memory area as stack.
Most CPUs require alignment of stack in multiples of bytes. This is automatically
done, when the task stack is defined as an array of integers.
The task stack has to be assigned to one task only. The memory used as task stack
can not be used for other purposes as long as the task exists. The stack can not be
shared with other tasks.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
55
4.4.6 OS_Delay()
Description
Suspends the calling task for a specified period of time.
Prototype
void OS_Delay (OS_TIME ms);
Parameter Description
Time interval to delay. Must be within the following range:
ms 1 <= ms <= 2 15-1 = 0x7FFF = 32767 for 8/16-bit CPUs
1 <= ms <= 2 31-1 = 0x7FFFFFFF for 32-bit CPUs
Table 4.7: OS_Delay() parameter list
Additional Information
The calling task will be put into the TS_DELAY state for the period of time specified.
The task will stay in the delayed state until the specified time has expired. The
parameter ms specifies the precise interval during which the task has to be sus-
pended given in basic time intervals (usually 1/1000 seconds). The actual delay (in
basic time intervals) will be in the following range: ms - 1 <= delay <= ms, depending
on when the interrupt for the scheduler will occur.
After the expiration of a delay, the task is made ready again and activated according
to the rules of the scheduler. A delay can be ended prematurely by another task or by
an interrupt handler calling OS_WakeTask().
Example
void Hello() {
printf("Hello");
printf("The next output will occur in 5 seconds");
OS_Delay (5000);
printf("Delay is over");
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
56 CHAPTER 4 Tasks
4.4.7 OS_DelayUntil()
Description
Suspends the calling task until a specified time.
Prototype
void OS_DelayUntil (OS_TIME t);
Parameter Description
Time to delay until. Must be within the following range:
0 <= t <= 2 16 -1 = 0xFFFF = 65535 for 8/16-bit CPUs
0 <= t <= 2 32-1 = 0xFFFFFFFF for 32-bit CPUs
t and has to meet the following additional condition
1 <= ( t - OS_Time) <= 2 15-1 = 0x7FFF = 32767 for 8/16-bit
CPUs
1 <= ( t- OS_Time) <= 2 31-1 = 0x7FFFFFFF for 32-bit CPUs
Table 4.8: OS_DelayUntil() parameter list
Additional Information
The calling task will be put into the TS_DELAY state until the time specified.
The OS_DelayUntil() function delays until the value of the time-variable OS_Time
has reached a certain value. It is very useful if you have to avoid accumulating
delays.
An embOS systick timer overflow is no problem as long as parameter t is within the
above mentioned range.
Example
int sec,min;
void TaskShowTime() {
int t0;
t0 = OS_GetTime();
while (1) {
ShowTime(); /* Routine to display time */
t0 += 1000;
OS_DelayUntil (t0);
if (sec < 59) {
sec++;
} else {
sec=0;
min++;
}
}
}
In the example above, the use of OS_Delay() could lead to accumulating delays and
would cause the simple “clock” to be slow.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
57
4.4.8 OS_Delayus()
Description
Waits for the given time in microseconds.
Prototype
void OS_Delayus (OS_U16 us);
Parameter Description
Time interval to delay. Must be within the following range:
us
1 <= us <= 2 15-1 = 0x7FFF = 32767
Table 4.9: OS_Delay() parameter list
Additional Information
This function can be used for short delays.
Example
void Hello() {
printf("Hello");
printf("The next output will occur in 500 microseconds");
OS_Delayus (500);
printf("Delay is over");
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
58 CHAPTER 4 Tasks
4.4.9 OS_ExtendTaskContext()
Description
The function may be used for a variety of purposes. Typical applications include, but
are not limited to:
• global variables such as “errno” in the C-library, making the C-lib functions
thread-safe.
• additional, optional CPU / registers such as MAC / EMAC registers (multiply and
accumulate unit) if they are not saved in the task context per default.
• Co-processor registers such as registers of a VFP (floating point coprocessor).
• Data registers of an add. hardware unit such as a CRC calculation unit
This allows the user to extend the task context as required by his system. A major
advantage is that the task extension is task specific. This means that the additional
information (such as floating point registers) needs to be saved only by tasks that
actually use these registers. The advantage is that the task switching time of the
other tasks is not affected. The same thing is true for the required stack space: Add.
stack space is required only for the tasks which actually save the add. registers.
Prototype
void OS_ExtendTaskContext(const OS_EXTEND_TASK_CONTEXT * pExtendContext);
Parameter Description
Pointer to the OS_EXTEND_TASK_CONTEXT structure which contains
pExtendContext the addresses of the specific save and restore functions which
save and restore the extended task context during task switches.
Table 4.10: OS_ExtendTaskContext() parameter list
Additional Information
The OS_EXTEND_TASK_CONTEXT structure is defined as follows:
The save and restore functions have to be declared according the function type used
in the structure. The sample below shows, how the task stack has to be addressed to
save and restore the extended task context.
OS_ExtendTaskContext() is not available in the XR libraries.
Important
The task context can be extended only once per task. The function must not be called
multple times for one task.
Note that some ports of embOS use the mechanism of extending the task context for
individual tasks for CPU or compiler specific purposes like storing floating point regis-
ters or deliver a thread local storage.
In this case, the user can not extend the task context by OS_ExtendTaskContext().
Extended tasks, created by OS_CREATETASK_EX() or OS_CreateTaskEx() can still be
used.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
59
Example
The following example is delivered in the Samples folder of embOS.
/*--------------------------------------------------------------------
File : ExtendTaskContext.c
Purpose : Sample program for embOS demonstrating how to dynamically
extend the task context.
This example adds a global variable to the task context of
certain tasks.
-------- END-OF-HEADER -----------------------------------------------
*/
#include "RTOS.h"
/*********************************************************************
*
* _Restore
* _Save
*
* Function description
* This function pair saves and restores an extended task context.
* In this case, the extended task context consists of just a single
* member, which is a global variable.
*/
typedef struct {
int GlobalVar;
} CONTEXT_EXTENSION;
/********************************************************************/
/*********************************************************************
*
* HPTask
*
* Function description
* During the execution of this function, the thread-specific
* global variable has always the same value of 1.
*/
static void HPTask(void) {
OS_ExtendTaskContext(&_SaveRestore);
GlobalVar = 1;
while (1) {
OS_Delay (10);
}
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
60 CHAPTER 4 Tasks
/*********************************************************************
*
* LPTask
*
* Function description
* During the execution of this function, the thread-specific
* global variable has always the same value of 2.
*/
static void LPTask(void) {
OS_ExtendTaskContext(&_SaveRestore);
GlobalVar = 2;
while (1) {
OS_Delay (50);
}
}
/*********************************************************************
*
* main
*/
int main(void) {
OS_IncDI(); /* Initially disable interrupts */
OS_InitKern(); /* initialize OS */
OS_InitHW(); /* initialize Hardware for OS */
/* You need to create at least one task here ! */
OS_CREATETASK(&TCBHP, "HP Task", HPTask, 100, StackHP);
OS_CREATETASK(&TCBLP, "LP Task", LPTask, 50, StackLP);
OS_Start(); /* Start multitasking */
return 0;
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
61
4.4.10 OS_GetpCurrentTask()
Description
Returns a pointer to the task control block structure of the currently running task.
Prototype
OS_TASK* OS_GetpCurrentTask (void);
Return value
OS_TASK*: A pointer to the task control block structure.
Additional Information
This function may be used for determining which task is executing. This may be help-
ful if the reaction of any function depends on the currently running task.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
62 CHAPTER 4 Tasks
4.4.11 OS_GetPriority()
Description
Returns the priority of a specified task.
Prototype
unsigned char OS_GetPriority (const OS_TASK* pTask);
Parameter Description
pTask Pointer to a data structure of type OS_TASK.
Table 4.11: OS_GetPriority() parameter list
Return value
Priority of the specified task as an “unsigned character” (range 1 to 255).
Additional Information
If pTask is the NULL pointer, the function returns the priority of the currently running
task. If pTask does not specify a valid task, the debug version of embOS calls
OS_Error(). The release version of embOS cannot check the validity of pTask and
may therefore return invalid values if pTask does not specify a valid task.
Important
This function may not be called from within an interrupt handler.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
63
4.4.12 OS_GetSuspendCnt()
Description
The function returns the suspension count and thus suspension state of the specified
task. This function may be used for examining whether a task is suspended by previ-
ous calls of OS_Suspend().
Prototype
unsigned char OS_GetSuspendCnt (const OS_TASK* pTask);
Parameter Description
pTask Pointer to a data structure of type OS_TASK.
Table 4.12: OS_GetSuspendCnt() parameter list
Return value
Suspension count of the specified task as unsigned character value.
0: Task is not suspended.
>0: Task is suspended by at least one call of OS_Suspend().
Additional Information
If pTask does not specify a valid task, the debug version of embOS calls OS_Error().
The release version of embOS can not check the validity of pTask and may therefore
return invalid values if pTask does not specify a valid task. When tasks are created
and terminated dynamically, OS_IsTask() may be called prior calling
OS_GetSuspendCnt() to examine whether the task is valid. The returned value can
be used for resuming a suspended task by calling OS_Resume() as often as indicated
by the returned value.
Example
/* Demo-function to illustrate the use of OS_GetSuspendCnt() */
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
64 CHAPTER 4 Tasks
4.4.13 OS_GetTaskID()
Description
Returns a pointer to the task control block structure of the currently running task.
This pointer is unique for the task and is used as task Id.
Prototype
OS_TASK * OS_GetTaskID ( void );
Return value
A pointer to the task control block. A value of 0 (NULL) indicates that no task is exe-
cuting.
Additional Information
This function may be used for determining which task is executing. This may be help-
ful if the reaction of any function depends on the currently running task.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
65
4.4.14 OS_GetTaskName()
Description
Returns a pointer to the name of a task.
Prototype
const char* OS_GetTaskName(const OS_TASK* pTask);
Parameter Description
pTask Pointer to a data structure of type OS_TASK.
Table 4.13: OS_GetTaskName() parameter list
Return value
A pointer to the name of the task. A value of 0 (NULL) indicates that the task has no
name.
Additional Information
If pTask is the NULL pointer, the function returns the name of the currently running
task. If not called from a task with a NULL pointer as parameter, the return value is
“OS_Idle()”. If pTask does not specify a valid task, the debug version of embOS calls
OS_Error(). The release version of embOS cannot check the validity of pTask and
may therefore return invalid values if pTask does not specify a valid task.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
66 CHAPTER 4 Tasks
4.4.15 OS_GetTimeSliceRem()
Description
Returns the remaining timeslice value of a task.
Prototype
unsigned char OS_GetTimeSliceRem(const OS_TASK* pTask);
Parameter Description
pTask Pointer to a data structure of type OS_TASK.
Table 4.14: OS_GetTimeSliceRem() parameter list
Return value
The remaining timslice value of the task.
Additional Information
If pTask is the NULL pointer, the function returns the remaining timeslice of the run-
ning task. If not called from a task with a NULL pointer as parameter, or if pTask does
not specify a valid task, the debug version of embOS calls OS_Error(). The release
version of embOS cannot check the validity of pTask and may therefore return invalid
values if pTask does not specify a valid task.
The function is not available when round-robin is not supported.
The embOS eXtreme release libraries don’t support round robin.
When embOS is recompiled with OS_RR_SUPPORTED set to 0, the function will not be
available.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
67
4.4.16 OS_IsRunning()
Description
Determines whether the embOS scheduler was started by a call of OS_Start().
Prototype
unsigned char OS_IsRunning (void);
Return value
Character value:
0: Scheduler was not started.
!=0: Scheduler is running, OS_Start() has been called.
Additional Information
This function may be helpful for some functions which might be called from main() or
from running tasks.
As long as the scheduler was not started and a function is called from main(), block-
ing task switches are not allowed.
A function which may be called from a task or main(), may use OS_IsRunning() to
determine whether a blocking task switch is allowed.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
68 CHAPTER 4 Tasks
4.4.17 OS_IsTask()
Description
Determines whether a task control block actually belongs to a valid task.
Prototype
char OS_IsTask (const OS_TASK* pTask);
Parameter Description
Pointer to a data structure of type OS_TASK which is used as task
pTask
control block (and reference) for this task.
Table 4.15: OS_IsTask() parameter list
Return value
Character value:
0: TCB is not used by any task
1: TCB is used by a task
Additional Information
This function checks if the specified task is still in the internal task list. If the task
was terminated, it is removed from the internal task list. This function may be useful
to determine whether the task control block and stack for the task may be reused for
another task in applications that create and terminate tasks dynamically.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
69
4.4.18 OS_Resume()
Description
Decrements the suspend count of the specified task and resumes it, if the suspend
count reaches zero.
Prototype
void OS_Resume (OS_TASK* pTask);
Parameter Description
Pointer to a data structure of type OS_TASK which is used as task
pTask control block (and reference) for the task that should be sus-
pended.
Table 4.16: OS_Resume() parameter list
Additional Information
The specified task's suspend count is decremented. If the resulting value is 0, the
execution of the specified task is resumed.
If the task is not blocked by other task blocking mechanisms, the task will be set
back in ready state and continues operation according to the rules of the scheduler.
In debug versions of embOS, the OS_Resume() function checks the suspend count of
the specified task. If the suspend count is 0 when OS_Resume() is called, the
specified task is not currently suspended and OS_Error() is called with error
OS_ERR_RESUME_BEFORE_SUSPEND.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
70 CHAPTER 4 Tasks
4.4.19 OS_ResumeAllSuspendedTasks()
Description
Decrements the suspend count of all tasks when it is set and and resumes the task if
the suspend count reaches zero.
Prototype
void OS_ResumeAllSuspendedTasks (void);
Additional Information
This function may be helpful to synchronize or start multiple tasks at the same time.
The function resumes all tasks, no specific task has to be addressed.
The function may be used together with the functions OS_SuspendAllTasks() and
OS_SetInitialSuspendCnt().
The function may cause a task switch, when a task with higher priority than the call-
ing task is resumed.
The task switch will be executed after all suspended tasks are resumed.
As this is a non blocking function, the function may be called from all contexts, main,
ISR or timer.
The function may be called regardless any tasks are suspended. No error will be gen-
erated when tasks are not suspended.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
71
4.4.20 OS_SetInitialSuspendCnt()
Description
Sets the initial suspend count for newly created tasks. May be used to create tasks
which are initially suspended.
Prototype
void OS_SetInitialSuspendCnt (unsigned char SuspendCnt);
Parameter Description
!= 0: Tasks will be created in suspended state.
SuspendCnt
= 0: Tasks will be created normally without suspension.
Table 4.17: OS_SetInitialSuspendCnt() parameter list
Additional Information
Can be called at any time from main(), any task, ISR or software timer.
After calling this function with SuspendCnt unequal to zero, all newly created tasks
will be automatically suspended.
Therefore, this function may be used to inhibit further task switches. This may be
useful during system initailization.
Important
When this function is called from main() to initialize all tasks in suspended state, at
least one task has to be resumed before the system is started by a call of
OS_Start().
The initial suspend count should be reset to allow normal creation of tasks before the
system is started.
Example
/* Sample to demonstrate the use of OS_SetInitialSuspendCnt */
void InitTask(void) {
//
// High priority task started first after OS_Start()
//
OS_SuspendAllTasks(); // Ensure, no other existing task can run.
OS_SetInitialSuspendCnt(1); // Ensure, no newly created task will run.
//
// Perform application initialization
//
... // New tasks may be created, but can not start.
... // Even when InitTask() blocks itself by a delay, no other task will run.
OS_SetInitialSuspendCnt(0); // Reset the initial suspend count for tasks.
//
// Resume all tasks taht were blocked before or were created in suspended state.
//
OS_ResumeAllSuspendedTasks();
while (1) {
... // Do the normal work
}
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
72 CHAPTER 4 Tasks
4.4.21 OS_SetPriority()
Description
Assigns a specified priority to a specified task.
Prototype
void OS_SetPriority (OS_TASK* pTask,
unsigned char Priority);
Parameter Description
pTask Pointer to a data structure of type OS_TASK.
Priority of the task. Must be within the following range:
Priority
1 <= Priority <= 255 Higher values indicate higher priorities.
Table 4.18: OS_SetPriority() parameter list
Additional Information
Can be called at any time from any task or software timer. Calling this function might
lead to an immediate task switch.
Important
This function may not be called from within an interrupt handler.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
73
4.4.22 OS_SetTaskName()
Description
Allows modification of a task name at runtime.
Prototype
void OS_SetTaskName (OS_TASK* pTask,
const char* s);
Parameter Description
pTask Pointer to a data structure of type OS_TASK.
s Pointer to a zero terminated string which is used as task name.
Table 4.19: OS_SetTaskName() parameter list
Additional Information
Can be called at any time from any task or software timer.
When pTask is the NULL pointer, the name of the currently running task is modified.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
74 CHAPTER 4 Tasks
4.4.23 OS_SetTimeSlice()
Description
Assigns a specified timeslice value to a specified task.
Prototype
unsigned char OS_SetTimeSlice (OS_TASK* pTask,
unsigned char TimeSlice);
Parameter Description
pTask Pointer to a data structure of type OS_TASK.
New timeslice value for the task. Must be within the following
TimeSlice range:
1 <= TimeSlice <= 255.
Table 4.20: OS_SetTimeSlice() parameter list
Return value
Previous timeslice value of the task as unsigned char.
Additional Information
Can be called at any time from any task or software timer. Setting the timeslice value
only affects the tasks running in round-robin mode. This means another task with the
same priority must exist.
The new timeslice value is interpreted as reload value. It is used after the next acti-
vation of the task. It does not affect the remaining timeslice of a running task.
When using a debug build of embOS, setting of an illegal TimeSlice value will call the
error handler OS_Error() with error code OE_ERR_TIMSLICE.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
75
4.4.24 OS_Start()
Description
Starts the embOS scheduler.
Prototype
void OS_Start (void);
Additional Information
This function starts the embOS scheduler and schould be the last function called from
main().
OS_Start() marks embOS as running. The running state can be examined by a call
of the function OS_IsRunning().
OS_Start() will activate and start the task with the highest priority.
OS_Start() automatically enables interrupts.
OS_Start() does not return.
OS_Start() must not be called from a task, from an interrupt or an embOS timer, it
may be called from main() only once.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
76 CHAPTER 4 Tasks
4.4.25 OS_Suspend()
Description
Suspends the specified task.
Prototype
void OS_Suspend (OS_TASK* pTask);
Parameter Description
Pointer to a data structure of type OS_TASK which is used as task
pTask control block (and reference) for the task that should be sus-
pended.
Table 4.21: OS_Suspend() parameter list
Additional Information
If pTask is the NULL pointer, the current task suspends.
If the function succeeds, execution of the specified task is suspended and the task's
suspend count is incremented. The specified task will be suspended immediately. It
can only be restarted by a call of OS_Resume().
Every task has a suspend count with a maximum value of OS_MAX_SUSPEND_CNT. If
the suspend count is greater than zero, the task is suspended.
In debug versions of embOS, calling OS_Suspend() more often than
OS_MAX_SUSPEND_CNT times without calling OS_Resume(), the task's internal suspend
count is not incremented and OS_Error() is called with error
OS_ERR_SUSPEND_TOO_OFTEN.
Can not be called from an interrupt handler or timer as this function may cause a
task switch immediately.
The debug version of embOS will call the OS_Error() function when OS_Suspend() is
called from an interrupt handler.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
77
4.4.26 OS_SuspendAllTasks()
Description
Suspends all except the running task.
Prototype
void OS_SuspendAllTasks (void);
Additional Information
This function may be used to inhibit task switches. It may be useful during applica-
tion initialization or supervising.
The calling task will not be suspended.
After calling OS_SuspendAllTasks, the calling task may block or suspend itself. No
other task will be activated until all tasks are resumed again.
All suspended tasks can be resumed by a call of OS_ResumeAllSuspendedtasks().
Example
/* Sample to demonstrate the use of OS_SuspendAllTasks */
void InitTask(void) {
//
// High priority task started first after OS_Start()
//
OS_SuspendAllTasks(); // Ensure, no other existing task can run.
OS_SetInitialSuspendCnt(1); // Ensure, no newly created task will run.
//
// Perform application initialization
//
... // New tasks may be created, but can not start.
... // Even when InitTask() blocks itself by a delay, no other task will run.
OS_SetInitialSuspendCnt(0); // Reset the initial suspend count for tasks.
//
// Resume all tasks taht were blocked before or were created in suspended state.
//
OS_ResumeAllSuspendedTasks();
while (1) {
... // Do the normal work
}
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
78 CHAPTER 4 Tasks
4.4.27 OS_TerminateTask()
Description
Ends (terminates) a task.
Prototype
void OS_TerminateTask (OS_TASK* pTask);
Parameter Description
Pointer to a data structure of type OS_TASK which is used as task
pTask
control block (and reference) for this task.
Table 4.22: OS_Terminate() parameter list
Additional Information
If pTask is the NULL pointer, the current task terminates. The specified task will ter-
minate immediately. The memory used for stack and task control block can be reas-
signed.
Since version 3.26 of embOS, all resources which are held by the terminated task are
released. Any task may be terminated regardless of its state. This functionality is
default for any 16-bit or 32-bit CPU and may be changed by recompiling embOS
sources. On 8-bit CPUs, terminating tasks that hold any resources, like semaphores,
which may block other tasks, is prohibited.
Since embOS version 3.82u, OS_TerminateTask() replaces the former function
OS_Terminate() which may still be used.
Important
This function may not be called from within an interrupt handler.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
79
4.4.28 OS_WakeTask()
Description
Ends delay of a task immediately.
Prototype
void OS_WakeTask (OS_TASK* pTask);
Parameter Description
Pointer to a data structure of type OS_TASK which is used as task
pTask
control block (and reference) for this task.
Table 4.23: OS_WakeTask() parameter list
Additional Information
Puts the specified task, which is already suspended for a certain amount of time with
OS_Delay() or OS_DelayUntil() back to the state TS_READY (ready for execution).
The specified task will be activated immediately if it has a higher priority than the
priority of the task that had the highest priority before. If the specified task is not in
the state TS_DELAY (because it has already been activated, or the delay has already
expired, or for some other reason), this command is ignored.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
80 CHAPTER 4 Tasks
4.4.29 OS_Yield()
Description
Calls the scheduler to force a task switch.
Prototype
void OS_Yield (void);
Additional Information
If the task is running on round-robin, it will be suspended if there is an other task
with the same priority ready for execution.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
81
Chapter 5
Software timers
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
82 CHAPTER 5 Software timers
5.1 Introduction
A software timer is an object that calls a user-specified routine after a specified
delay. A basically unlimited number of software timers can be defined with the macro
OS_CREATETIMER().
Timers can be stopped, started and retriggered much like hardware timers. When
defining a timer, you specify any routine that is to be called after the expiration of
the delay. Timer routines are similar to interrupt routines; they have a priority higher
than the priority of all tasks. For that reason they should be kept short just like inter-
rupt routines.
Software timers are called by embOS with interrupts enabled, so they can be inter-
rupted by any hardware interrupt. Generally, timers run in single-shot mode, which
means they expire only once and call their callback routine only once. By calling
OS_RetriggerTimer() from within the callback routine, the timer is restarted with its
initial delay time and therefore works just as a free-running timer.
The state of timers can be checked by the functions OS_GetTimerStatus(),
OS_GetTimerValue(), and OS_GetTimerPeriod().
Maximum timeout / period
The timeout value is stored as an integer, thus a 16-bit value on 8/16-bit CPUs, a 32-
bit value on 32-bit CPUs. The comparisons are done as signed comparisons, (because
expired time-outs are permitted). This means that only 15-bits can be used on 8/16
bit CPUs, 31-bits on 32-bit CPUs. Another factor to take into account is the maximum
time spent in critical regions. During critical regions timers may expire, but because
the timer routine can not be called from a critical region (timers are “put on hold”),
the maximum time that the system spends at once in a critical region needs to be
deducted. In most systems, this is no more than a single tick. However, to be safe,
we have assumed that your system spends no more than up to 255 ticks in a row in
a critical region and defined a macro which defines the maximum timeout value. It is
normally 0x7F00 for 8/16-bit systems or 0x7FFFFF00 for 32-bit Systems and defined
in RTOS.h as OS_TIMER_MAX_TIME. If your system spends more than 255 ticks without
break in a critical section (effectively disabling the scheduler during this time. Not
recommended!), you have to make sure your application uses shorter timeouts.
Extended software timers
Sometimes it may be useful to pass a parameter to the timer callback function. This
allows usage of one callback function for different software timers.
Since version 3.32m of embOS, the extended timer structure and related extended
timer functions were implemented to allow parameter passing to the callback func-
tion.
Except the different callback function with parameter passing, extended timers
behave exactly the same as normal embOS software timers and may be used in par-
allel with normal software timers.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
83
Timer
main
Task
ISR
Routine Description
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
84 CHAPTER 5 Software timers
5.2.1 OS_CREATETIMER()
Description
Macro that creates and starts a software timer.
Prototype
void OS_CREATETIMER (OS_TIMER* pTimer,
OS_TIMERROUTINE* Callback,
OS_TIME Timeout);)
Parameter Description
Pointer to the OS_TIMER data structure which contains the data of
pTimer
the timer.
Pointer to the callback routine to be called from the RTOS after
expiration of the delay. The callback function has to be a void
Callback
function which does not take any parameter and does not return
any value.
Initial timeout in basic embOS time units (nominal ms):
The data type OS_TIME is defined as an integer, therefore valid
Timeout values are
1 <= Timeout <= 2 15-1 = 0x7FFF = 32767 for 8/16-bit CPUs
1 <= Timeout <= 2 31-1 = 0x7FFFFFFF for 32-bit CPUs
Table 5.2: OS_CREATETIMER() parameter list
Additional Information
embOS keeps track of the timers by using a linked list. Once the timeout is expired,
the callback routine will be called immediately (unless the current task is in a critical
region or has interrupts disabled).
This macro uses the functions OS_CreateTimer() and OS_StartTimer(). It is sup-
plied for backward compatibility; in newer applications these routines should be
called directly instead.
OS_TIMERROUTINE is defined in RTOS.h as follows:
typedef void OS_TIMERROUTINE(void);
#define OS_CREATETIMER(pTimer,c,d) \
OS_CreateTimer(pTimer,c,d); \
OS_StartTimer(pTimer);
Example
OS_TIMER TIMER100;
void Timer100(void) {
LED = LED ? 0 : 1; /* Toggle LED */
OS_RetriggerTimer(&TIMER100); /* Make timer periodical */
}
void InitTask(void) {
/* Create and start Timer100 */
OS_CREATETIMER(&TIMER100, Timer100, 100);
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
85
5.2.2 OS_CreateTimer()
Description
Creates a software timer (but does not start it).
Prototype
void OS_CreateTimer (OS_TIMER* pTimer,
OS_TIMERROUTINE* Callback,
OS_TIME Timeout);)
Parameter Description
Pointer to the OS_TIMER data structure which contains the data of
pTimer
the timer.
Pointer to the callback routine to be called from the RTOS after
Callback
expiration of the delay.
Initial timeout in basic embOS time units (nominal ms):
The data type OS_TIME is defined as an integer, therefore valid
Timeout values are
1 <= Timeout <= 215-1 = 0x7FFF = 32767 for 8/16-bit CPUs
1 <= Timeout <= 231-1 = 0x7FFFFFFF for 32-bit CPUs
Table 5.3: OS_CreateTimer() parameter list
Additional Information
embOS keeps track of the timers by using a linked list. Once the timeout is expired,
the callback routine will be called immediately (unless the current task is in a critical
region or has interrupts disabled). The timer is not automatically started. This has to
be done explicitly by a call of OS_StartTimer() or OS_RetriggerTimer().
OS_TIMERROUTINE is defined in RTOS.h as follows:
typedef void OS_TIMERROUTINE(void);
Example
OS_TIMER TIMER100;
void Timer100(void) {
LED = LED ? 0 : 1; /* Toggle LED */
OS_RetriggerTimer(&TIMER100); /* Make timer periodical */
}
void InitTask(void) {
/* Create Timer100, start it elsewhere */
OS_CreateTimer(&TIMER100, Timer100, 100);
OS_StartTimer(&TIMER100);
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
86 CHAPTER 5 Software timers
5.2.3 OS_StartTimer()
Description
Starts a software timer.
Prototype
void OS_StartTimer (OS_TIMER* pTimer);
Parameter Description
Pointer to the OS_TIMER data structure which contains the data of
pTimer
the timer.
Table 5.4: OS_StartTimer() parameter list
Additional Information
OS_StartTimer() is used for the following reasons:
• Start a timer which was created by OS_CreateTimer(). The timer will start with
its initial timer value.
• Restart a timer which was stopped by calling OS_StopTimer(). In this case, the
timer will continue with the remaining time value which was preserved by stop-
ping the timer.
Important
This function has no effect on running timers. It also has no effect on timers that are
not running, but have expired. Use OS_RetriggerTimer() to restart those timers.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
87
5.2.4 OS_StopTimer()
Description
Stops a software timer.
Prototype
void OS_StopTimer (OS_TIMER* pTimer);
Parameter Description
Pointer to the OS_TIMER data structure which contains the data of
pTimer
the timer.
Table 5.5: OS_StopTimer() parameter list
Additional Information
The actual value of the timer (the time until expiration) is kept until
OS_StartTimer() lets the timer continue.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
88 CHAPTER 5 Software timers
5.2.5 OS_RetriggerTimer()
Description
Restarts a software timer with its initial time value.
Prototype
void OS_RetriggerTimer (OS_TIMER* pTimer);
Parameter Description
Pointer to the OS_TIMER data structure which contains the data of
pTimer
the timer.
Table 5.6: OS_RetriggerTimer() parameter list
Additional Information
OS_RetriggerTimer() restarts the timer using the initial time value programmed at
creation of the timer or with the function OS_SetTimerPeriod().
OS_RetriggerTimer() can be called regardless the state of the timer. A running
timer will continue using the full initial time. A timer that was stopped before or had
expired will be restarted.
Example
OS_TIMER TIMERCursor;
BOOL CursorOn;
void TimerCursor(void) {
if (CursorOn) ToggleCursor(); /* Invert character at cursor-position */
OS_RetriggerTimer(&TIMERCursor); /* Make timer periodical */
}
void InitTask(void) {
/* Create and start TimerCursor */
OS_CREATETIMER(&TIMERCursor, TimerCursor, 500);
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
89
5.2.6 OS_SetTimerPeriod()
Description
Sets a new timer reload value for a software timer.
Prototype
void OS_SetTimerPeriod (OS_TIMER* pTimer,
OS_TIME Period);
Parameter Description
Pointer to the OS_TIMER data structure which contains the data of
pTimer
the timer.
Timer period in basic embOS time units (nominal ms):
The data type OS_TIME is defined as an integer, therefore valid
Period values are
1 <= Timeout <= 215-1 = 0x7FFF = 32767 for 8/16-bit CPUs
1 <= Timeout <= 231-1 = 0x7FFFFFFF for 32-bit CPUs
Table 5.7: OS_SetTimerPeriod() parameter list
Additional Information
OS_SetTimerPeriod() sets the initial time value of the specified timer. Period is the
reload value of the timer to be used as initial value when the timer is retriggered by
OS_RetriggerTimer().
Example
OS_TIMER TIMERPulse;
BOOL CursorOn;
void TimerPulse(void) {
if TogglePulseOutput(); /* Toggle output */
OS_RetriggerTimer(&TIMERCursor); /* Make timer periodical */
}
void InitTask(void) {
/* Create and start Pulse Timer with first pulse = 500ms */
OS_CREATETIMER(&TIMERPulse, TimerPulse, 500);
/* Set timer period to 200 ms for further pulses */
OS_SetTimerPeriod(&TIMERPulse, 200);
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
90 CHAPTER 5 Software timers
5.2.7 OS_DeleteTimer()
Description
Stops and deletes a software timer.
Prototype
void OS_DeleteTimer (OS_TIMER* pTimer);
Parameter Description
Pointer to the OS_TIMER data structure which contains the data of
pTimer
the timer.
Table 5.8: OS_DeleteTimer() parameter list
Additional Information
The timer is stopped and therefore removed out of the linked list of running timers.
In debug builds of embOS, the timer is also marked as invalid.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
91
5.2.8 OS_GetTimerPeriod()
Description
Returns the current reload value of a software timer.
Prototype
OS_TIME OS_GetTimerPeriod (const OS_TIMER* pTimer);
Parameter Description
Pointer to the OS_TIMER data structure which contains the data of
pTimer
the timer.
Table 5.9: OS_GetTimerPeriod() parameter list
Return value
Type OS_TIME, which is defined as an integer between
1 and 2 15-1 = 0x7FFF = 32767 for 8/16-bit CPUs and as an integer between
1 and <= 231-1 = 0x7FFFFFFF for 32-bit CPUs, which is the permitted range of timer
values.
Additional Information
The period returned is the reload value of the timer set as initial value when the
timer is retriggered by OS_RetriggerTimer().
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
92 CHAPTER 5 Software timers
5.2.9 OS_GetTimerValue()
Description
Returns the remaining timer value of a software timer.
Prototype
OS_TIME OS_GetTimerValue (const OS_TIMER* pTimer);
Parameter Description
Pointer to the OS_TIMER data structure which contains the data of
pTimer
the timer.
Table 5.10: OS_GetTimerValue() parameter list
Return value
Type OS_TIME, which is defined as an integer between
1 and 2 15-1 = 0x7FFF = 32767 for 8/16-bit CPUs and as an integer between
1 and <= 2 31 -1 = 0x7FFFFFFF for 32-bit CPUs, which is the permitted range of timer
values.
The returned time value is the remaining timer time in embOS tick units until expira-
tion of the timer.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
93
5.2.10 OS_GetTimerStatus()
Description
Returns the current timer status of a software timer.
Prototype
unsigned char OS_GetTimerStatus (const OS_TIMER* pTimer);
Parameter Description
Pointer to the OS_TIMER data structure which contains the data of
pTimer
the timer.
Table 5.11: OS_GetTimerStatus parameter list
Return value
Unsigned character, denoting whether the specified timer is running or not:
0: timer has stopped
! = 0: timer is running.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
94 CHAPTER 5 Software timers
5.2.11 OS_GetpCurrentTimer()
Description
Returns a pointer to the data structure of the timer that just expired.
Prototype
OS_TIMER* OS_GetpCurrentTimer (void);
Return value
OS_TIMER*: A pointer to the control structure of a timer.
Additional Information
The return value of OS_GetpCurrentTimer() is valid during execution of a timer call-
back function; otherwise it is undetermined. If only one callback function should be
used for multiple timers, this function can be used for examining the timer that
expired.
The example below shows one usage of OS_GetpCurrentTimer(). Since version
3.32m of embOS, the extended timer structure and functions which come with
embOS may be used to generate and use software timer with individual parameter
for the callback function. Please be aware that OS_TIMER have to be the first ele-
ment in the structure.
Example
#include "RTOS.H"
/********************************************************
*
* Types
*/
typedef struct { /* Timer object with its own user data */
OS_TIMER Timer; /* OS_TIMER have to be first element */
void* pUser;
} TIMER_EX;
/********************************************************
*
* Variables
*/
TIMER_EX Timer_User;
int a;
/********************************************************
*
* Local Functions
*/
/********************************************************
*
* main
*/
int main(void) {
OS_InitKern(); /* Initialize OS */
OS_InitHW(); /* Initialize Hardware for OS */
CreateTimer(&Timer_User, cb, 100, &a);
OS_Start(); /* Start multitasking */
return 0;
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
95
5.2.12 OS_CREATETIMER_EX()
Description
Macro that creates and starts an extended software timer.
Prototype
void OS_CREATETIMER_EX (OS_TIMER_EX* pTimerEx,
OS_TIMER_EX_ROUTINE* Callback,
OS_TIME Timeout
void* pData)
Parameter Description
Pointer to the OS_TIMER_EX data structure which contains the
pTimerEx
data of the extended software timer.
Pointer to the callback routine to be called from the RTOS after
expiration of the delay. The callback function has to be of type
Callback
OS_TIMER_EX_ROUTINE which takes a void pointer as parameter
and does not return any value.
Initial timeout in basic embOS time units (nominal ms):
The data type OS_TIME is defined as an integer, therefore valid
Timeout values are
1 <= Timeout <= 215-1 = 0x7FFF = 32767 for 8/16-bit CPUs
1 <= Timeout <= 231-1 = 0x7FFFFFFF for 32-bit CPUs
A void pointer which is used as parameter for the extended timer
pData
callback function.
Table 5.12: OS_CREATETIMER_EX() parameter list
Additional Information
embOS keeps track of the timers by using a linked list. Once the timeout is expired,
the callback routine will be called immediately (unless the current task is in a critical
region or has interrupts disabled).
This macro uses the functions OS_CreateTimerEx() and OS_StartTimerEx().
OS_TIMER_EX_ROUTINE is defined in RTOS.h as follows:
typedef void OS_TIMER_EX_ROUTINE(void* pVoid);
#define OS_CREATETIMER_EX(pTimerEx,cb,Timeout,pData) \
OS_CreateTimerEx(pTimerEx,cb,Timeout,pData); \
OS_StartTimerEx(pTimerEx)
Example
OS_TIMER_EX TIMER100;
OS_TASK TCB_HP;
void InitTask(void) {
/* Create and start Timer100 */
OS_CREATETIMER_EX(&TIMER100, Timer100, 100, (void*) &TCB_HP);
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
96 CHAPTER 5 Software timers
5.2.13 OS_CreateTimerEx()
Description
Creates an extended software timer (but does not start it).
Prototype
void OS_CreateTimerEx (OS_TIMER_EX* pTimerEx,
OS_TIMER_EX_ROUTINE* Callback,
OS_TIME Timeout,
void* pData)
Parameter Description
Pointer to the OS_TIMER_EX data structure which contains the
pTimerEx
data of the extended software timer.
Pointer to the callback routine of type OS_TIMER_EX_ROUTINE to
Callback
be called from the RTOS after expiration of the timer.
Initial timeout in basic embOS time units (nominal ms):
The data type OS_TIME is defined as an integer, therefore valid
Timeout values are
1 <= Timeout <= 2 15-1 = 0x7FFF = 32767 for 8/16-bit CPUs
1 <= Timeout <= 2 31-1 = 0x7FFFFFFF for 32-bit CPUs
A void pointer which is used as parameter for the extended timer
pData
callback function.
Table 5.13: OS_CreateTimerEx() parameter list
Additional Information
embOS keeps track of the timers by using a linked list. Once the timeout has expired,
the callback routine will be called immediately (unless the current task is in a critical
region or has interrupts disabled).
The extended software timer is not automatically started. This has to be done explic-
itly by a call of OS_StartTimerEx() or OS_RetriggerTimerEx().
Example
OS_TIMER_EX TIMER100;
OS_TASK TCB_HP;
void InitTask(void) {
/* Create Timer100, start it elsewhere later on*/
OS_CreateTimerEx(&TIMER100, Timer100, 100, (void*) & TCB_HP);
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
97
5.2.14 OS_StartTimerEx()
Description
Starts an extended software timer.
Prototype
void OS_StartTimerEx (OS_TIMER_EX* pTimerEx);
Parameter Description
Pointer to the OS_TIMER_EX data structure which contains the
pTimerEx
data of the extended software timer.
Table 5.14: OS_StartTimereEx() parameter list
Additional Information
OS_StartTimerEx() is used for the following reasons:
• Start an extended software timer which was created by OS_CreateTimerEx().
The timer will start with its initial timer value.
• Restart a timer which was stopped by calling OS_StopTimerEx(). In this case,
the timer will continue with the remaining time value which was preserved by
stopping the timer.
Important
This function has no effect on running timers. It also has no effect on timers that are
not running, but have expired. Use OS_RetriggerTimerEx() to restart those timers.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
98 CHAPTER 5 Software timers
5.2.15 OS_StopTimerEx()
Description
Stops an extended software timer.
Prototype
void OS_StopTimerEx (OS_TIMER_EX* pTimerEx);
Parameter Description
Pointer to the OS_TIMER_EX data structure which contains the
pTimerEx
data of the extended software timer.
Table 5.15: OS_StopTimerEx() parameter list
Additional Information
The actual time value of the extended software timer (the time until expiration) is
kept until OS_StartTimerEx() lets the timer continue.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
99
5.2.16 OS_RetriggerTimerEx()
Description
Restarts an extended software timer with its initial time value.
Prototype
void OS_RetriggerTimerEx (OS_TIMER_EX* pTimerEx);
Parameter Description
Pointer to the OS_TIMER_EX data structure which contains the
pTimerEx
data of the extended software timer.
Table 5.16: OS_RetriggerTimerEx() parameter list
Additional Information
OS_RetriggerTimerEx() restarts the extended software timer using the initial time
value which was programmed at creation of the timer or which was set using the
function OS_SetTimerPeriodEx().
OS_RetriggerTimerEx() can be called regardless the state of the timer. A running
timer will continue using the full initial time. A timer that was stopped before or had
expired will be restarted.
Example
OS_TIMER_EX TIMERCursor;
OS_TASK TCB_HP;
BOOL CursorOn;
void InitTask(void) {
/* Create and start TimerCursor */
OS_CREATETIMER_EX(&TIMERCursor, TimerCursor, 500, (void*)&TCB_HP);
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
100 CHAPTER 5 Software timers
5.2.17 OS_SetTimerPeriodEx()
Description
Sets a new timer reload value for an extended software timer.
Prototype
void OS_SetTimerPeriodEx (OS_TIMER_EX* pTimerEx,
OS_TIME Period);
Parameter Description
Pointer to the OS_TIMER_EX data structure which contains the
pTimerEx
data of the extended software timer.
Timer period in basic embOS time units (nominal ms):
The data type OS_TIME is defined as an integer, therefore valid
Period values are
1 <= Timeout <= 2 15-1 = 0x7FFF = 32767 for 8/16-bit CPUs
1 <= Timeout <= 2 31-1 = 0x7FFFFFFF for 32-bit CPUs
Table 5.17: OS_SetTimerPeriodEx() parameter list
Additional Information
OS_SetTimerPeriodEx() sets the initial time value of the specified extended soft-
ware timer. Period is the reload value of the timer to be used as initial value when
the timer is retriggered the next time by OS_RetriggerTimerEx().
A call of OS_SetTimerPeriodEx() does not affect the remaining time period of an
extended software timer.
Example
OS_TIMER_EX TIMERPulse;
OS_TASK TCB_HP;
void InitTask(void) {
/* Create and start Pulse Timer with first pulse == 500ms */
OS_CREATETIMER_EX(&TIMERPulse, TimerPulse, 500, (void*)&TCB_HP);
/* Set timer period to 200 ms for further pulses */
OS_SetTimerPeriodEx(&TIMERPulse, 200);
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
101
5.2.18 OS_DeleteTimerEx()
Description
Stops and deletes an extended software timer.
Prototype
void OS_DeleteTimerEx(OS_TIMER_EX* pTimerEx);
Parameter Description
Pointer to the OS_TIMER_EX data structure which contains the
pTimerEx
data of the timer.
Table 5.18: OS_DeleteTimerEx() parameter list
Additional Information
The extended software timer is stopped and therefore removed out of the linked list
of running timers. In debug builds of embOS, the timer is also marked as invalid.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
102 CHAPTER 5 Software timers
5.2.19 OS_GetTimerPeriodEx()
Description
Returns the current reload value of an extended software timer.
Prototype
OS_TIME OS_GetTimerPeriodEx (OS_TIMER_EX* pTimerEx);
Parameter Description
Pointer to the OS_TIMER_EX data structure which contains the
pTimerEx
data of the extended timer.
Table 5.19: OS_GetTimerPeriodEx() parameter list
Return value
Type OS_TIME, which is defined as an integer between
1 and 2 15-1 = 0x7FFF = 32767 for 8/16-bit CPUs and as an integer between
1 and <= 2 31 -1 = 0x7FFFFFFF for 32-bit CPUs, which is the permitted range of timer
values.
Additional Information
The period returned is the reload value of the timer which was set as initial value
when the timer was created or which was modified by a call of
OS_SetTimerPeriodEx(). This reload value will be used as time period when the
timer is retriggered by OS_RetriggerTimerEx().
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
103
5.2.20 OS_GetTimerValueEx()
Description
Returns the remaining timer value of an extended software timer.
Prototype
OS_TIME OS_GetTimerValueEx(OS_TIMER_EX* pTimerEx);
Parameter Description
Pointer to the OS_TIMER_EX data structure which contains the
pTimerEx
data of the timer.
Table 5.20: OS_GetTimerValueEx() parameter list
Return value
Type OS_TIME, which is defined as an integer between
1 and 2 15-1 = 0x7FFF = 32767 for 8/16-bit CPUs and as an integer between
1 and <= 231-1 = 0x7FFFFFFF for 32-bit CPUs, which is the permitted range of timer
values.
The returned time value is the remaining timer time in embOS tick units until expira-
tion of the extended software timer.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
104 CHAPTER 5 Software timers
5.2.21 OS_GetTimerStatusEx()
Description
Returns the current timer status of an extended software timer.
Prototype
unsigned char OS_GetTimerStatusEx (OS_TIMER_EX* pTimerEx);
Parameter Description
Pointer to the OS_TIMER_EX data structure which contains the
pTimerEx
data of the extended timer.
Table 5.21: OS_GetTimerStatusEx parameter list
Return value
Unsigned character, denoting whether the specified timer is running or not:
0: timer has stopped
! = 0: timer is running.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
105
5.2.22 OS_GetpCurrentTimerEx()
Description
Returns a pointer to the data structure of the extended timer that just expired.
Prototype
OS_TIMER_EX* OS_GetpCurrentTimerEx (void);
Return value
OS_TIMER_EX*: A pointer to the control structure of an extended software timer.
Additional Information
The return value of OS_GetpCurrentTimerEx() is valid during execution of a timer
callback function; otherwise it is undetermined. If one callback function should be
used for multiple extended timers, this function can be used for examining the timer
that expired.
Example
#include "RTOS.H"
OS_TIMER_EX MyTimerEx;
/********************************************************
*
* Local Functions
*/
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
106 CHAPTER 5 Software timers
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
107
Chapter 6
Resource semaphores
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
108 CHAPTER 6 Resource semaphores
6.1 Introduction
Resource semaphores are used for managing resources by avoiding conflicts caused
by simultaneous use of a resource. The resource managed can be of any kind: a part
of the program that is not reentrant, a piece of hardware like the display, a flash
prom that can only be written to by a single task at a time, a motor in a CNC control
that can only be controlled by one task at a time, and a lot more.
The basic procedure is as follows:
Any task that uses a resource first claims it calling the OS_Use() or OS_Request()
routines of embOS. If the resource is available, the program execution of the task
continues, but the resource is blocked for other tasks. If a second task now tries to
use the same resource while it is in use by the first task, this second task is sus-
pended until the first task releases the resource. However, if the first task that uses
the resource calls OS_Use() again for that resource, it is not suspended because the
resource is blocked only for other tasks.
The following diagram illustrates the process of using a resource:
OS_Use()
Access resource
OS_Unuse()
A resource semaphore contains a counter that keeps track of how many times the
resource has been claimed by calling OS_Request() or OS_Use() by a particular task.
It is released when that counter reaches 0, which means the OS_Unuse() routine has
to be called exactly the same number of times as OS_Use() or OS_Request(). If it is
not, the resource remains blocked for other tasks.
On the other hand, a task cannot release a resource that it does not own by calling
OS_Unuse(). In the debug version of embOS, a call of OS_Unuse() for a semaphore
that is not owned by this task will result in a call to the error handler OS_Error().
Example of using resource semaphores
Here, two tasks access an LC display completely independently from each other. The
LCD is a resource that needs to be protected with a resource semaphore. One task
may not interrupt another task which is writing to the LCD, because otherwise the
following might occur:
• Task A positions the cursor
• Task B interrupts Task A and repositions the cursor
• Task A writes to the wrong place in the LCD' s memory.
To avoid this type of situation, every time the LCD must be accessed by a task, it is
first claimed by a call to OS_Use() (and is automatically waited for if the resource is
blocked). After the LCD has been written to, it is released by a call to OS_Unuse().
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
109
/*
* demo program to illustrate the use of resource semaphores
*/
OS_STACKPTR int StackMain[100], StackClock[50];
OS_TASK TaskMain,TaskClock;
OS_RSEMA SemaLCD;
void TaskClock(void) {
char t=-1;
char s[] = "00:00";
while(1) {
while (TimeSec==t) Delay(10);
t= TimeSec;
s[4] = TimeSec%10+'0';
s[3] = TimeSec/10+'0';
s[1] = TimeMin%10+'0';
s[0] = TimeMin/10+'0';
OS_Use(&SemaLCD); /* Make sure nobody else uses LCD */
LCD_Write(10,0,s);
OS_Unuse(&SemaLCD); /* Release LCD */
}
}
void TaskMain(void) {
signed char pos ;
LCD_Write(0,0,"Software tools by Segger ! ") ;
OS_Delay(2000);
while (1) {
for ( pos=14 ; pos >=0 ; pos-- ) {
OS_Use(&SemaLCD); /* Make sure nobody else uses LCD */
LCD_Write(pos,1,"train "); /* Draw train */
OS_Unuse(&SemaLCD); /* Release LCD */
OS_Delay(500);
}
OS_Use(&SemaLCD); /* Make sure nobody else uses LCD */
LCD_Write(0,1," ") ;
OS_Unuse(&SemaLCD); /* Release LCD */
}
}
void InitTask(void) {
OS_CREATERSEMA(&SemaLCD); /* Creates resource semaphore */
OS_CREATETASK(&TaskMain, 0, Main, 50, StackMain);
OS_CREATETASK(&TaskClock, 0, Clock, 100, StackClock);
}
In most applications, the routines that access a resource should automatically call
OS_Use() and OS_Unuse() so that when using the resource you do not have to worry
about it and can use it just as you would in a single-task system. The following is an
example of how to implement a resource into the routines that actually access the
display:
/*
* Simple example when accessing single line dot matrix LCD
*/
OS_RSEMA RDisp; /* Define resource semaphore */
void DISPInit(void) {
OS_CREATERSEMA(&RDisp);
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
110 CHAPTER 6 Resource semaphores
Timer
main
Task
ISR
Routine Description
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
111
6.2.1 OS_CREATERSEMA()
Description
Macro that creates a resource semaphore.
Prototype
void OS_CREATERSEMA (OS_RSEMA* pRSema);
Parameter Description
pRSema Pointer to the data structure for a resource semaphore.
Table 6.2: OS_CREATESEMA() parameter list
Additional Information
After creation, the resource is not blocked; the value of the counter is 0.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
112 CHAPTER 6 Resource semaphores
6.2.2 OS_Use()
Description
Claims a resource and blocks it for other tasks.
Prototype
int OS_Use (OS_RSEMA* pRSema);
Parameter Description
pRSema Pointer to the data structure for a resource semaphore.
Table 6.3: OS_Use() parameter list
Return value
The counter value of the semaphore.
A value larger than 1 means the resource was already locked by the calling task.
Additional Information
The following situations are possible:
• Case A: The resource is not in use.
If the resource is not used by a task, which means the counter of the semaphore
is 0, the resource will be blocked for other tasks by incrementing the counter and
writing a unique code for the task that uses it into the semaphore.
• Case B: The resource is used by this task.
The counter of the semaphore is simply incremented. The program continues
without a break.
• Case C: The resource is being used by another task.
The execution of this task is suspended until the resource semaphore is released.
In the meantime if the task blocked by the resource semaphore has a higher pri-
ority than the task blocking the semaphore, the blocking task is assigned the pri-
ority of the task requesting the resource semaphore. This is called priority
inheritance. Priority inheritance can only temporarily increase the priority of a
task, never reduce it.
An unlimited number of tasks can wait for a resource semaphore. According to the
rules of the scheduler, of all the tasks waiting for the resource, the task with the
highest priority will get access to the resource and can continue program execution.
Important
This function may not be called from within an interrupt handler.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
113
OS_Use(...)
Increase Usage
Usage counter = 1
counter
return return
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
114 CHAPTER 6 Resource semaphores
6.2.3 OS_UseTimed()
Description
Tries to claim a resource and blocks it for other tasks if it is available within a speci-
fied time.
Prototype
int OS_UseTimed(OS_RSEMA* pRSema, OS_TIME TimeOut)
Parameter Description
pRSema Pointer to the data structure of a resource semaphore.
Maximum time until the resource semaphore should be available.
Timer period in basic embOS time units (nominal ms):
The data type OS_TIME is defined as an integer, therefore valid
TimeOut values are
1 <= Timeout <= 2 15-1 = 0x7FFF = 32767 for 8/16-bit CPUs
1 <= Timeout <= 2 31-1 = 0x7FFFFFFF for 32-bit CPUs.
Return value
Integer value:
0: Failed, semaphore not available before timeout.
>0: Success, resource semaphore was available. The counter value of the sema-
phore.
A value larger than 1 means the resource was already locked by the calling task.
Additional Information
The following situations are possible:
• Case A: The resource is not in use.
If the resource is not used by a task, which means the counter of the semaphore
is 0, the resource will be blocked for other tasks by incrementing the counter and
writing a unique code for the task that uses it into the semaphore.
• Case B: The resource is used by this task.
The counter of the semaphore is simply incremented. The program continues
without a break.
• Case C: The resource is being used by another task.
The execution of this task is suspended until the resource semaphore is released
or the timeout time expired. In the meantime if the task blocked by the resource
semaphore has a higher priority than the task blocking the semaphore, the
blocking task is assigned the priority of the task requesting the resource sema-
phore. This is called priority inheritance. Priority inheritance can only temporarily
increase the priority of a task, never reduce it.
If the resource semaphore becomes available during the timeout time, the calling
task claims the resource and the function returns with a value larger than 0, oth-
erwise, if the resource does not become available, the function returns with 0.
When the calling task is blocked by higher priority tasks for a longer period than the
timeout value, it may happen, that the resource semaphore becomes available after
the timeout time before the calling task continues. In this case, the function does not
claim the resource and returns with timeout, because the resource was not availbale
within the requested time.
An unlimited number of tasks can wait for a resource semaphore. According to the
rules of the scheduler, of all the tasks waiting for the resource, the task with the
highest priority will get access to the resource and can continue program execution.
Important
This function may not be called from within an interrupt handler.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
115
6.2.4 OS_Unuse()
Description
Releases a semaphore currently in use by a task.
Prototype
void OS_Unuse (OS_RSEMA* pRSema)
Parameter Description
pRSema Pointer to the data structure for a resource semaphore.
Table 6.5: OS_Unuse() parameter list
Additional Information
OS_Unuse() may be used on a resource semaphore only after that semaphore has
been used by calling OS_Use() or OS_Request(). OS_Unuse() decrements the usage
counter of the semaphore which must never become negative. If this counter
becomes negative, the debug version will call the embOS error handler OS_Error()
with error code OS_ERR_UNUSE_BEFORE_USE. In the debug version OS_Error() will
also be called, if OS_Unuse() is called from a task which does not own the resource.
The error code in this case is OS_ERR_RESOURCE_OWNER.
Important
This function may not be called from within an interrupt handler.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
116 CHAPTER 6 Resource semaphores
6.2.5 OS_Request()
Description
Requests a specified semaphore and blocks it for other tasks if it is available. Contin-
ues execution in any case.
Prototype
char OS_Request (OS_RSEMA* pRSema);
Parameter Description
pRSema Pointer to the data structure for a resource semaphore.
Table 6.6: OS-Request() parameter list
Return value
1: Resource was available, now in use by calling task
0: Resource was not available.
Additional Information
The following diagram illustrates how OS_Request() works:
OS_Request (RSEMA*ps)
No
Yes
return 1 return 1
Example
if (!OS_Request(&RSEMA_LCD) ) {
LED_LCDBUSY = 1; /* Indicate that task is waiting for */
/* resource */
OS_Use(&RSEMA_LCD); /* Wait for resource */
LED_LCDBUSY = 0; /* Indicate task is no longer waiting */
}
DispTime(); /* Access the resource LCD */
OS_Unuse(&RSEMA_LCD); /* Resource LCD is no longer needed */
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
117
6.2.6 OS_GetSemaValue()
Description
Returns the value of the usage counter of a specified resource semaphore.
Prototype
int OS_GetSemaValue (const OS_SEMA* pSema);
Parameter Description
pRSema Pointer to the data structure for a resource semaphore.
Table 6.7: OS_GetSemaValue() parameter list
Return value
The counter of the semaphore.
A value of 0 means the resource is available.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
118 CHAPTER 6 Resource semaphores
6.2.7 OS_GetResourceOwner()
Description
Returns a pointer to the task that is currently using (blocking) a resource.
Prototype
OS_TASK* OS_GetResourceOwner (const OS_RSEMA* pSema);
Parameter Description
pRSema Pointer to the data structure for a resource semaphore.
Table 6.8: OS_GetResourceOwner() parameter list
Return value
Pointer to the task that is blocking the resource.
A value of 0 means the resource is available.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
119
6.2.8 OS_DeleteRSema()
Description
Deletes a specified resource semaphore. The memory of that semaphore may be
reused for other purposes or may be used for creating another resources semaphore
using the same memory.
Prototype
void OS_DeleteRSema (OS_RSEMA* pRSema);
Parameter Description
pRSema Pointer to a data structure of type OS_RSEMA.
Table 6.9: OS_DeleteRSema parameter list
Additional Information
Before deleting a resource semaphore, make sure that no task is claiming the
resources semaphore. The debug version of embOS will call OS_Error(), if a
resources semaphore is deleted when it is already used. In systems with dynamic
creation of resource semaphores, it is required to delete a resource semaphore,
before re-creating it. Otherwise the semaphore handling will not work correctly.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
120 CHAPTER 6 Resource semaphores
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
121
Chapter 7
Counting Semaphores
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
122 CHAPTER 7 Counting Semaphores
7.1 Introduction
Counting semaphores are counters that are managed by embOS. They are not as
widely used as resource semaphores, events or mailboxes, but they can be very
useful sometimes. They are used in situations where a task needs to wait for
something that can be signaled one or more times. The semaphores can be accessed
from any point, any task, or any interrupt in any way.
Example of using counting semaphores
OS_STACKPTR int Stack0[96], Stack1[64]; /* Task stacks */
OS_TASK TCB0, TCB1; /* Data-area for tasks (task-control-blocks) */
OS_CSEMA SEMALCD;
void Task0(void) {
while(1) {
Disp("Task0 will wait for task 1 to signal");
OS_WaitCSema(&SEMALCD);
Disp("Task1 has signaled !!");
OS_Delay(100);
}
}
void Task1(void) {
while(1) {
OS_Delay(5000);
OS_SignalCSema(&SEMALCD);
}
}
void InitTask(void) {
OS_CREATECSEMA(&SEMALCD); /* Create Semaphore */
OS_CREATETASK(&TCB0, NULL, Task0, 100, Stack0); /* Create Task0 */
OS_CREATETASK(&TCB1, NULL, Task1, 50, Stack1); /* Create Task1 */
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
123
Timer
main
Task
ISR
Routine Description
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
124 CHAPTER 7 Counting Semaphores
7.2.1 OS_CREATECSEMA()
Description
Macro that creates a counting semaphore with an initial count value of zero.
Prototype
void OS_CREATECSEMA (OS_CSEMA* pCSema);
Parameter Description
pCSema Pointer to a data structure of type OS_CSEMA.
Table 7.2: OS_CREATECSEMA() parameter list
Additional Information
To create a counting semaphore, a data structure of the type OS_CSEMA needs to be
defined in memory and initialized using OS_CREATECSEMA(). The value of a sema-
phore created using this macro is zero. If, for any reason, you have to create a sema-
phore with an initial counting value above zero, use the function OS_CreateCSema().
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
125
7.2.2 OS_CreateCSema()
Description
Creates a counting semaphore with a specified initial count value.
Prototype
void OS_CreateCSema (OS_CSEMA* pCSema,
OS_UINT InitValue);
Parameter Description
pCSema Pointer to a data structure of type OS_CSEMA.
Initial count value of the semaphore:
InitValue 0 <= InitValue <= 216 = 0xFFFF for 8/16-bit CPUs
0 <= InitValue <= 232 = 0xFFFFFFFF for 32-bit CPUs
Table 7.3: OS_CreateCSema() parameter list
Additional Information
To create a counting semaphore, a data structure of the type OS_CSEMA needs to be
defined in memory and initialized using OS_CreateCSema(). If the value of the cre-
ated semaphore should be zero, the macro OS_CREATECSEMA() should be used.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
126 CHAPTER 7 Counting Semaphores
7.2.3 OS_SignalCSema()
Description
Increments the counter of a semaphore.
Prototype
void OS_SignalCSema (OS_CSEMA * pCSema);
Parameter Description
pCSema Pointer to a data structure of type OS_CSEMA.
Table 7.4: OS_SignalCSema() parameter list
Additional Information
OS_SignalCSema() signals an event to a semaphore by incrementing its counter. If
one or more tasks are waiting for an event to be signaled to this semaphore, the task
that has the highest priority will become the running task. The counter can have a
maximum value of 0xFFFF for 8/16-bit CPUs / 0xFFFFFFFF for 32-bit CPUs. It is the
responsibility of the application to make sure that this limit will not be exceeded. The
debug version of embOS detects an counter overflow and calls OS_Error() with error
code OS_ERR_CSEMA_OVERFLOW, if an overflow occurs.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
127
7.2.4 OS_SignalCSemaMax()
Description
Increments the counter of a semaphore up to a specified maximum value.
Prototype
void OS_SignalCSemaMax (OS_CSEMA* pCSema,
OS_UINT MaxValue );
Parameter Description
pCSema Pointer to a data structure of type OS_CSEMA.
Limit of semaphore count value.
MaxValue 1 <= MaxValue <= 216 = 0xFFFF for 8/16-bit CPUs
1 <= MaxValue <= 232 = 0xFFFFFFFF for 32-bit CPUs
Table 7.5: OS_SignalCSemaMax() parameter list
Additional Information
As long as current value of the semaphore counter is below the specified maximum
value, OS_SignalCSemaMax() signals an event to a semaphore by incrementing its
counter. If one or more tasks are waiting for an event to be signaled to this sema-
phore, the tasks are put into ready state and the task that has the highest priority
will become the running task. Calling OS_SignalCSemaMax() with a MaxValue of 1
handles a counting semaphore as a binary semaphore.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
128 CHAPTER 7 Counting Semaphores
7.2.5 OS_WaitCSema()
Description
Decrements the counter of a semaphore.
Prototype
void OS_WaitCSema (OS_CSEMA* pCSema);
Parameter Description
pCSema Pointer to a data structure of type OS_CSEMA.
Table 7.6: OS_WaitCSema() parameter list
Additional Information
If the counter of the semaphore is not 0, the counter is decremented and program
execution continues.
If the counter is 0, WaitCSema() waits until the counter is incremented by another
task, a timer or an interrupt handler via a call to OS_SignalCSema(). The counter is
then decremented and program execution continues.
An unlimited number of tasks can wait for a semaphore. According to the rules of the
scheduler, of all the tasks waiting for the semaphore, the task with the highest prior-
ity will continue program execution.
Important
This function may not be called from within an interrupt handler.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
129
7.2.6 OS_WaitCSemaTimed()
Description
Decrements a semaphore counter if the semaphore is available within a specified
time.
Prototype
int OS_WaitCSemaTimed (OS_CSEMA* pCSema,
OS_TIME TimeOut);
Parameter Description
pCSema Pointer to a data structure of type OS_CSEMA.
Maximum time until semaphore should be available
Timer period in basic embOS time units (nominal ms):
The data type OS_TIME is defined as an integer, therefore valid
TimeOut values are
1 <= Timeout <= 215-1 = 0x7FFF = 32767 for 8/16-bit CPUs
1 <= Timeout <= 231-1 = 0x7FFFFFFF for 32-bit CPUs.
Table 7.7: OS_WaitCSemaTimed parameter list
Return value
Integer value:
0: Failed, semaphore not available before timeout.
1: OK, semaphore was available and counter decremented.
Additional Information
If the counter of the semaphore is not 0, the counter is decremented and program
execution continues. If the counter is 0, WaitCSemaTimed() waits until the sema-
phore is signaled by another task, a timer, or an interrupt handler via a call to
OS_SignalCSema(). The counter is then decremented and program execution contin-
ues. If the semaphore was not signaled within the specified time, the program execu-
tion continues but returns a value of 0. An unlimited number of tasks can wait for a
semaphore. According to the rules of the scheduler, of all the tasks waiting for the
semaphore, the task with the highest priority will continue program execution.
When the calling task is blocked by higher priority tasks for a longer period than the
timeout value, it may happen, that the semaphore becomes signaled after the time-
out time before the calling task continues. In this case, the function returns with tim-
eout, because the semaphore was not availbale within the requested time. In this
case, the state of the semaphore is not modified by OS_WaitCSemaTimed().
Important
This function may not be called from within an interrupt handler.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
130 CHAPTER 7 Counting Semaphores
7.2.7 OS_CSemaRequest()
Description
Decrements the counter of a semaphore, if it is signaled.
Prototype
char OS_CSemaRequest (OS_CSEMA* pCSema);
Parameter Description
pCSema Pointer to a data structure of type OS_CSEMA.
Table 7.8: OS_CSemaRequest() parameter list
Return value
Integer value:
0: Failed, semaphore was not signaled.
1: OK, semaphore was available and counter was decremented once.
Additional Information
If the counter of the semaphore is not 0, the counter is decremented and program
execution continues.
If the counter is 0, OS_CSemaRequest() does not wait and does not modify the sema-
phore counter. The function returns with error state.
Because this function never blocks a calling task, this function may be called from an
interrupt handler.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
131
7.2.8 OS_GetCSemaValue()
Description
Returns the counter value of a specified semaphore.
Prototype
int OS_GetCSemaValue (const OS_SEMA* pCSema);
Parameter Description
pCSema Pointer to a data structure of type OS_CSEMA.
Table 7.9: OS_GetCSemaValue() parameter list
Return value
The counter value of the semaphore.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
132 CHAPTER 7 Counting Semaphores
7.2.9 OS_SetCSemaValue()
Description
Sets the counter value of a specified semaphore.
Prototype
OS_U8 OS_SetCSemaValue (OS_SEMA* pCSema,
OS_UINT Value);
Parameter Description
pCSema Pointer to a data structure of type OS_CSEMA.
Count value of the semaphore:
Value 0 <= InitValue <= 216 = 0xFFFF for 8/16-bit CPUs
0 <= InitValue <= 232 = 0xFFFFFFFF for 32-bit CPUs
Table 7.10: OS_SetCSemaValue() parameter list
Return value
0: If the value could be set.
!= 0: In case of error.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
133
7.2.10 OS_DeleteCSema()
Description
Deletes a specified semaphore.
Prototype
void OS_DeleteCSema (OS_CSEMA* pCSema);
Parameter Description
pCSema Pointer to a data structure of type OS_CSEMA.
Table 7.11: OS_DeleteCSema() parameter list
Additional Information
Before deleting a semaphore, make sure that no task is waiting for it and that no
task will signal that semaphore at a later point.
The debug version of embOS will reflect an error if a deleted semaphore is signaled.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
134 CHAPTER 7 Counting Semaphores
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
135
Chapter 8
Mailboxes
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
136 CHAPTER 8 Mailboxes
8.1 Introduction
In the preceding chapters, task synchronization by the use of semaphores was
described. Unfortunately, semaphores cannot transfer data from one task to another.
If we need to transfer data between tasks via a buffer for example, we could use a
resource semaphore every time we accessed the buffer. But doing so would make the
program less efficient. Another major disadvantage would be that we could not
access the buffer from an interrupt handler, because the interrupt handler is not
allowed to wait for the resource semaphore.
One way out would be the usage of global variables. In this case we would have to
disable interrupts every time and in every place that we accessed these variables.
This is possible, but it is a path full of pitfalls. It is also not easy for a task to wait for
a character to be placed in a buffer without polling the global variable that contains
the number of characters in the buffer. Again, there is a way out - the task could be
notified by an event signaled to the task every time a character is placed in the
buffer. That is why there is an easier way to do this with a real-time OS:
The use of mailboxes.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
137
8.2 Basics
A mailbox is a buffer that is managed by the real-time operating system. The buffer
behaves like a normal buffer; you can put something (called a message) in and
retrieve it later. Mailboxes usually work as FIFO: first in, first out. So a message that
is put in first will usually be retrieved first. “Message” might sound abstract, but very
simply just means “item of data”. It will become clearer in the typical applications
explained in the following section.
The number of mailboxes is limited only by the amount of available memory.
Message size: 1 <= x <= 127 bytes.
Number of messages: 1 <= x <= 32767.
These limitations have been placed on mailboxes to guarantee efficient coding and
also to ensure efficient management. The limitations are normally not a problem.
For handling messages larger than 127 bytes, you may use queues. For more infor-
mation, refer to the Chapter Queues on page 155.
A mailbox can have more than one producer but only one consumer. This means that
more than one task or interrupt handler is allowed to store new data in the mailbox
but only one task is allowed to get data from the mailbox.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
138 CHAPTER 8 Mailboxes
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
139
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
140 CHAPTER 8 Mailboxes
Timer
main
Task
ISR
Routine Explanation
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
141
8.5.1 OS_CreateMB()
Description
Creates a new mailbox.
Prototype
void OS_CreateMB (OS_MAILBOX* pMB,
unsigned char sizeofMsg,
unsigned int maxnofMsg,
void* pMsg);)
Parameter Description
Pointer to a data structure of type OS_MAILBOX reserved for man-
pMB
aging the mailbox.
sizeofMsg Size of a message in bytes. (1 <= sizeofMsg <= 127)
maxnoMsg Maximum number of messages. (1 <= MaxnofMsg <= 32767)
Pointer to a memory area used as buffer. The buffer has to be big
pMsg enough to hold the given number of messages of the specified
size: sizeofMsg * maxnoMsg bytes.
Table 8.2: OS_CreateMB() parameter list
Example
Mailbox used as keyboard buffer:
OS_MAILBOX MBKey;
char MBKeyBuffer[6];
void InitKeyMan(void) {
/* Create mailbox, functioning as type ahead buffer */
OS_CreateMB(&MBKey, 1, sizeof(MBKeyBuffer), &MBKeyBuffer);
}
Mailbox used for transferring complex commands from one task to another:
/*
* Example of mailbox used for transferring commands to a task
* that controls 2 motors
*/
typedef struct {
char Cmd;
int Speed[2];
int Position[2];
} MOTORCMD ;
OS_MAILBOX MBMotor;
#define MOTORCMD_SIZE 4
char BufferMotor[sizeof(MOTORCMD)*MOTORCMD_SIZE];
void MOTOR_Init(void) {
/* Create mailbox that holds commands messages */
OS_CreateMB(&MBMotor, sizeof(MOTORCMD), MOTORCMD_SIZE, BufferMotor);
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
142 CHAPTER 8 Mailboxes
Parameter Description
pMB Pointer to the mailbox.
pMail Pointer to the message to store.
Table 8.3: OS_PutMail() / OS_PutMail1() parameter list
Additional Information
If the mailbox is full, the calling task is suspended.
Because this routine might require a suspension, it must not be called from an inter-
rupt routine. Use OS_PutMailCond()/OS_PutMailCond1() instead if you have to
store data in a mailbox from within an ISR.
Important
This function may not be called from within an interrupt handler.
Example
Single-byte mailbox as keyboard buffer:
OS_MAILBOX MBKey;
char MBKeyBuffer[6];
void KEYMAN_StoreKey(char k) {
OS_PutMail1(&MBKey, &k); /* Store key, wait if no space in buffer */
}
void KEYMAN_Init(void) {
/* Create mailbox functioning as type ahead buffer */
OS_CreateMB(&MBKey, 1, sizeof(MBKeyBuffer), &MBKeyBuffer);
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
143
Parameter Description
pMB Pointer to the mailbox.
pMail Pointer to the message to store.
Table 8.4: OS_PutMailCond() / OS_PutMailCond1() overview
Return value
0: Success; message stored.
1: Message could not be stored (mailbox is full).
Additional Information
If the mailbox is full, the message is not stored.
This function never suspends the calling task. It may therefore be called from an
interrupt routine.
Example
OS_MAILBOX MBKey;
char MBKeyBuffer[6];
char KEYMAN_StoreCond(char k) {
return OS_PutMailCond1(&MBKey, &k); /* Store key if space in buffer */
}
This example can be used with the sample program shown earlier to handle a mail-
box as keyboard buffer.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
144 CHAPTER 8 Mailboxes
Parameter Description
pMB Pointer to the mailbox.
pMail Pointer to the message to store.
Table 8.5: OS_PutMailFront() / OS_PutMailFront1() parameter list
Additional Information
If the mailbox is full, the calling task is suspended. Because this routine might
require a suspension, it must not be called from an interrupt routine. Use
OS_PutMailFrontCond()/OS_PutMailFrontCond1() instead if you have to store data
in a mailbox from within an ISR.
This function is useful to store “emergency” messages into a mailbox which have to
be handled quick.
It may also be used in general instead of OS_PutMail() to change the FIFO structure
of a mailbox into a LIFO structure.
Important
This function may not be called from within an interrupt handler.
Example
Single-byte mailbox as keyboard buffer which will follow the LIFO pattern:
OS_MAILBOX MBCmd;
char MBCmdBuffer[6];
void KEYMAN_StoreCommand(char k) {
OS_PutMailFront1(&MBCmd, &k); /* Store command, wait if no space in buffer*/
}
void KEYMAN_Init(void) {
/* Create mailbox for command buffer */
OS_CreateMB(&MBCmd, 1, sizeof(MBCmdBuffer), &MBCmdBuffer);
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
145
Parameter Description
pMB Pointer to the mailbox.
pMail Pointer to the message to store.
Table 8.6: OS_PutMailFrontCond() / OS_PutMailFrontCond1() parameter list
Return value
0: Success; message stored.
1: Message could not be stored (mailbox is full).
Additional Information
If the mailbox is full, the message is not stored. This function never suspends the
calling task. It may therefore be called from an interrupt routine. This function is
useful to store “emergency” messages into a mailbox which have to be handled
quick. It may also be used in general instead of OS_PutMailCond() to change the
FIFO structure of a mailbox into a LIFO structure.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
146 CHAPTER 8 Mailboxes
Parameter Description
pMB Pointer to the mailbox.
Pointer to the memory area that the message should be stored
at. Make sure that it points to a valid memory area and that there
pDest
is sufficient space for an entire message. The message size (in
bytes) was defined when the mailbox was created.
Table 8.7: OS_GetMail() / OS_GetMail1() parameter list
Additional Information
If the mailbox is empty, the task is suspended until the mailbox receives a new mes-
sage. Because this routine might require a suspension, it may not be called from an
interrupt routine. Use OS_GetMailCond/OS_GetMailCond1 instead if you have to
retrieve data from a mailbox from within an ISR.
Important
This function may not be called from within an interrupt handler.
Example
OS_MAILBOX MBKey;
char MBKeyBuffer[6];
char WaitKey(void) {
char c;
OS_GetMail1(&MBKey, &c);
return c;
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
147
Parameter Description
pMB Pointer to the mailbox.
Pointer to the memory area that the message should be stored
at. Make sure that it points to a valid memory area and that there
pDest
is sufficient space for an entire message. The message size (in
bytes) was defined when the mailbox was created.
Table 8.8: OS_GetMailCond() / OS_GetMailCond1() parameter list
Return value
0: Success; message retrieved.
1: Message could not be retrieved (mailbox is empty); destination remains
unchanged.
Additional Information
If the mailbox is empty, no message is retrieved, but the program execution contin-
ues. This function never suspends the calling task. It may therefore also be called
from an interrupt routine.
Example
OS_MAILBOX MBKey;
/*
* If a key has been pressed, it is taken out of the mailbox and returned to caller.
* Otherwise, 0 is returned.
*/
char GetKey(void) {
char c = 0;
OS_GetMailCond1(&MBKey, &c)
return c;
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
148 CHAPTER 8 Mailboxes
8.5.8 OS_GetMailTimed()
Description
Retrieves a new message of a predefined size from a mailbox, if a message is avail-
able within a given time.
Prototype
char OS_GetMailTimed (OS_MAILBOX* pMB,
void* pDest,
OS_TIME Timeout);
Parameter Description
pMB Pointer to the mailbox.
Pointer to the memory area that the message should be stored
at. Make sure that it points to a valid memory area and that there
pDest
is sufficient space for an entire message. The message size (in
bytes) has been defined upon creation of the mailbox.
Maximum time in timer ticks until the requested mail has to be
available. The data type OS_TIME is defined as an integer, there-
Timeout fore valid values are
1 <= Timeout <= 2 15-1 = 0x7FFF = 32767 for 8/16-bit CPUs
1 <= Timeout <= 2 31-1 = 0x7FFFFFFF for 32-bit CPUs
Table 8.9: OS_GetMailTimed() parameter list
Return value
0: Success; message retrieved.
1: Message could not be retrieved (mailbox is empty); destination remains
unchanged.
Additional Information
If the mailbox is empty, no message is retrieved, the task is suspended for the given
timeout. The task continues execution, according to the rules of the scheduler, as
soon as a mail is available within the given timeout, or after the timeout value has
expired.
When the calling task is blocked by higher priority tasks for a longer period than the
timeout value, it may happen, that mail becomes available after the timeout time
before the calling task continues. In this case, the function returns with timeout,
because the mail was not availbale within the requested time. In this case, the state
of the mailbox is not modified by OS_GetMailTimed(), no mail is retrieved from the
mailbox.
Important
This function may not be called from within an interrupt handler.
Example
OS_MAILBOX MBKey;
/*
* If a key has been pressed, it is taken out of the mailbox and returned to caller.
* Otherwise, 0 is returned.
*/
char GetKey(void) {
char c =0;
OS_GetMailTimed(&MBKey, &c, 10) /* Wait for 10 timer ticks */
return c;
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
149
8.5.9 OS_WaitMail()
Description
Waits until a mail is available, but does not retrieve the message from the mailbox.
Prototype
void OS_WaitMail (OS_MAILBOX* pMB);
Parameter Description
pMB Pointer to the mailbox.
Table 8.10: OS_WaitMail() parameter list
Additional Information
If the mailbox is empty, the task is suspended until a mail is available, otherwise the
task continues. The task continues execution, according to the rules of the scheduler,
as soon as a mail is available, but the mail is not retrieved from the mailbox.
Important
This function may not be called from within an interrupt handler.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
150 CHAPTER 8 Mailboxes
8.5.10 OS_WaitMailTimed()
Description
Waits until a mail is available or the timeout has expired, but does not retrieve the
message from the mailbox.
Prototype
char OS_WaitMailTimed (OS_MAILBOX* pMB, OS_TIME Timeout)
Parameter Description
pMB Pointer to the mailbox.
Maximum time in timer ticks until the requested mail has to be
available. The data type OS_TIME is defined as an integer, there-
Timeout fore valid values are
1 <= Timeout <= 2 15-1 = 0x7FFF = 32767 for 8/16-bit CPUs
1 <= Timeout <= 2 31-1 = 0x7FFFFFFF for 32-bit CPUs
Table 8.11: OS_WaitMail() parameter list
Return value
0: Success; message available.
1: Timeout; no message available within the given timeout time.
Additional Information
If the mailbox is empty, the task is suspended for the given timeout. The task contin-
ues execution, according to the rules of the scheduler, as soon as a mail is available
within the given timeout, or after the timeout value has expired.
When the calling task is blocked by higher priority tasks for a longer period than the
timeout value, it may happen, that mail becomes available after the timeout time
before the calling task continues. In this case, the function returns with timeout,
because the mail was not availbale within the requested time.
Important
This function may not be called from within an interrupt handler.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
151
8.5.11 OS_PeekMail()
Description
Peeks a mail from a mailbox without removing the mail.
Prototype
char OS_PeekMail (OS_MAILBOX* pMB, void* pDest)
Parameter Description
pMB Pointer to the mailbox.
pDest Pointer to a buffer that should receive the mail
Table 8.12: OS_PeekMail() parameter list
Return value
0: Success; message available.
1: Message could not be retrieved (mailbox is empty).
Additional Information
This function is non blocking and never suspends the calling task. It may therefore
also be called from an interrupt routine.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
152 CHAPTER 8 Mailboxes
8.5.12 OS_ClearMB()
Description
Clears all messages in a specified mailbox.
Prototype
void OS_ClearMB (OS_MAILBOX* pMB);
Parameter Description
pMB Pointer to the mailbox.
Table 8.13: OS_ClearMB() parameter list
Example
OS_MAILBOX MBKey;
/*
* Clear keyboard type ahead buffer
*/
void ClearKeyBuffer(void) {
OS_ClearMB(&MBKey);
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
153
8.5.13 OS_GetMessageCnt()
Description
Returns the number of messages currently available in a specified mailbox.
Prototype
unsigned int OS_GetMessageCnt (OS_MAILBOX* pMB);
Parameter Description
pMB Pointer to the mailbox.
Table 8.14: OS_GetMessageCnt() parameter list
Return value
The number of messages in the mailbox.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
154 CHAPTER 8 Mailboxes
8.5.14 OS_DeleteMB()
Description
Deletes a specified mailbox.
Prototype
void OS_DeleteMB (OS_MAILBOX* pMB);
Parameter Description
pMB Pointer to the mailbox.
Table 8.15: OS_DeleteMB() parameter list
Additional Information
To keep the system fully dynamic, it is essential that mailboxes can be created
dynamically. This also means there has to be a way to delete a mailbox when it is no
longer needed. The memory that has been used by the mailbox for the control struc-
ture and the buffer can then be reused or reallocated.
It is the programmer's responsibility to:
• make sure that the program no longer uses the mailbox to be deleted
• make sure that the mailbox to be deleted actually exists (i.e. has been created
first).
Example
OS_MAILBOX MBSerIn;
void Cleanup(void) {
OS_DeleteMB(MBSerIn);
return 0;
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
155
Chapter 9
Queues
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
156 CHAPTER 9 Queues
9.1 Introduction
In the preceding chapter, intertask communication using mailboxes was described.
Mailboxes can handle small messages with fixed data size only.
Queues enable intertask communication with larger messages or with messages of
various sizes.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
157
9.2 Basics
A queue consists of a data buffer and a control structure that is managed by the real-
time operating system. The queue behaves like a normal buffer; you can put
something (called a message) in and retrieve it later. Queues work as FIFO: first in,
first out. So a message that is put in first will be retrieved first.
There are three major differences between queues and mailboxes:
1. Queues accept messages of various size. When putting a message into a queue,
the message size is passed as a parameter.
2. Retrieving a message from the queue does not copy the message, but returns a
pointer to the message and its size. This enhances performance because the data
is copied only once, when the message is written into the queue.
3. The retrieving function has to delete every message after processing it.
4. A new message can only be retrieved from the queue when the previous message
was deleted from the queue.
Both the number and size of queues is limited only by the amount of available
memory. Any data structure can be written into a queue. The message size is not
fixed.
Queues can have more than one producer but only one consumer. This means that
more than one task or interrupt handler is allowed to store new data in the queue but
only one task is allowed to get data from the queue.
The queue data buffer contains the messages as also some additional management
information bytes. Each message has a message header containing the message size.
Additionally the queue buffer will be aligned for those CPUs which needs data align-
ment. Therefore the queue data buffer size has to be larger than the sum of all mes-
sages.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
158 CHAPTER 9 Queues
Timer
main
Task
ISR
Routine Description
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
159
9.3.1 OS_Q_Create()
Description
Creates and initializes a message queue.
Prototype
void OS_Q_Create (OS_Q* pQ,
void*pData,
OS_UINT Size);
Parameter Description
Pointer to a data structure of type OS_Q reserved for the manage-
pQ
ment of the message queue.
pData Pointer to a memory area used as data buffer for the queue.
Size Size in bytes of the data buffer.
Table 9.2: OS_Q_Create() parameter list
Example
#define MEMORY_QSIZE 10000;
static OS_Q _MemoryQ;
static char _acMemQBuffer[MEMORY_QSIZE];
void MEMORY_Init(void) {
OS_Q_Create(&_MemoryQ, &_acMemQBuffer, sizeof(_acMemQBuffer));
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
160 CHAPTER 9 Queues
9.3.2 OS_Q_Put()
Description
Stores a new message of given size in a queue.
Prototype
int OS_Q_Put (OS_Q* pQ,
const void* pSrc,
OS_UINT Size);
Parameter Description
Pointer to a data structure of type OS_Q reserved for the manage-
pQ
ment of the message queue.
pSrc Pointer to the message to store
Size Size of the message to store
Table 9.3: OS_Q_Put() parameter list
Return value
0: Success; message stored.
1: Message could not be stored (queue is full).
Additional Information
If the queue is full, the function returns a value unequal to 0.
This routine never suspends the calling task. It may therefore also be called from an
interrupt routine.
Example
char MEMORY_Write(char* pData, int Len) {
return OS_Q_Put(&_MemoryQ, pData, Len);
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
161
9.3.3 OS_Q_PutBlocked()
Description
Stores a new message of given size in a queue.
Prototype
void OS_Q_PutBlocked (OS_Q* pQ,
const void* pSrc,
OS_UINT Size);
Parameter Description
Pointer to a data structure of type OS_Q reserved for the manage-
pQ
ment of the message queue.
pSrc Pointer to the message to store
Size Size of the message to store
Table 9.4: OS_Q_Put() parameter list
Additional Information
If the queue is full, the calling task is suspended. Because this routine might require
a suspension, it must not be called from an interrupt routine. Use OS_Q_Put()
instead if you have to store data in a queue from within an ISR.
Important
This function may not be called from within an interrupt handler.
Example
void StoreMessage(void)
OS_Q_PutBlocked(&_MemoryQ, pData, Len);
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
162 CHAPTER 9 Queues
9.3.4 OS_Q_GetPtr()
Description
Retrieves a message from a queue.
Prototype
int OS_Q_GetPtr (OS_Q* pQ,
void** ppData);
Parameter Description
pQ Pointer to the queue.
ppData Address of pointer to the message to be retrieved from queue.
Table 9.5: OS_Q_GetPtr() parameter list
Return value
The size of the retrieved message.
Sets the pointer ppData to the message that should be retrieved.
Additional Information
If the queue is empty, the calling task is suspended until the queue receives a new
message. Because this routine might require a suspension, it must not be called from
an interrupt routine. Use OS_GetPtrCond() instead. The retrieved message is not
removed from the queue. This has to be done by a call of OS_Q_Purge() after the
message was processed. Only one message can be processed at a time.
As long as the message is not removed from the queue, the queue is marked
“in use”.
A following call of OS_Q_GetPtr() or OS_Q_GetPtrCond() is not allowed before
OS_Q_Purge() is called as long as the queue is in use.
Consecutive calls of OS_Q_GetPtr() without calling OS_Q_Purge() will call
the embOS error handler OS_Error() in debug builds of embOS.
Example
static void MemoryTask(void) {
int Len;
char* pData;
while (1) {
Len = OS_Q_GetPtr(&_MemoryQ, &pData); /* Get message */
Memory_WritePacket(*(U32*)pData, Len); /* Process message */
OS_Q_Purge(&_MemoryQ); /* Delete message */
}
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
163
9.3.5 OS_Q_GetPtrCond()
Description
Retrieves a message from a queue, if one message is available.
Prototype
int OS_Q_GetPtrCond (OS_Q* pQ,
void** ppData);
Parameter Description
pQ Pointer to the queue.
ppData Address of pointer to the message to be retrieved from queue.
Table 9.6: OS_Q_GetPtrCond() parameter list
Return value
0: No message available in queue.
>0: Size of message that was retrieved from queue.
Sets the pointer ppData to the message that should be retrieved.
Additional Information
If the queue is empty, the function returns 0. The value of ppData is undefined. This
function never suspends the calling task. It may therefore also be called from an
interrupt routine. If a message could be retrieved, it is not removed from the queue.
This has to be done by a call of OS_Q_Purge() after the message was processed.
As long as the message is not removed from the queue, the queue is marked
“in use”.
A following call of OS_Q_GetPtrCond() or OS_Q_GetPtr() is not allowed before
OS_Q_Purge() is called as long as the queue is in use.
Consecutive calls of OS_Q_GetPtrCond() without calling OS_Q_Purge() will call
the embOS error handler OS_Error() in debug builds of embOS.
Example
static void MemoryTask(void) {
int Len;
char* pData;
while (1) {
Len = OS_Q_GetPtrCond(&_MemoryQ, &pData); /* Check message */
if (Len > 0) {
Memory_WritePacket(*(U32*)pData, Len); /* Process message */
OS_Q_Purge(&_MemoryQ); /* Delete message */
} else {
DoSomethingElse();
}
}
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
164 CHAPTER 9 Queues
9.3.6 OS_Q_GetPtrTimed()
Description
Retrieves a message from a queue within a specified time if a message is available.
Prototype
int OS_Q_GetPtrTimed (OS_Q* pQ,
void** ppData,
OS_TIME Timeout);
Parameter Description
pQ Pointer to the queue.
ppData Address of pointer to the message to be retrieved from queue.
Maximum time in timer ticks until the requested message has to
be available. The data type OS_TIME is defined as an integer,
Timeout therefore valid values are
1 <= Timeout <= 2 15-1 = 0x7FFF = 32767 for 8/16-bit CPUs
1 <= Timeout <= 2 31-1 = 0x7FFFFFFF for 32-bit CPUs
Table 9.7: OS_Q_GetPtrTimed() parameter list
Return value
0: No message available in queue.
>0: Size of message that was retrieved from queue.
Sets the pointer ppData to the message that should be retrieved.
Additional Information
If the queue is empty, no message is retrieved, the task is suspended for the given
timeout. The value of ppData is undefined. The task continues execution, according
to the rules of the scheduler, as soon as a message is available within the given tim-
eout, or after the timeout value has expired.
When the calling task is blocked by higher priority tasks for a longer period than the
timeout value, it may happen, that a message becomes available after the timeout
time before the calling task continues. In this case, the function returns with time-
out, because the message was not availbale within the requested time. In this case,
the state of the queue is not modified by OS_Q_GetPtrTimed(), a pointer to the mes-
sage is not delivered.
As long as a message was retrieved and the message is not removed from the queue,
the queue is marked “in use”.
A following call of OS_Q_GetPtrTimed() is not allowed before OS_Q_Purge() is
called as long as the queue is in use.
Consecutive calls of OS_Q_GetPtrTimed() without calling OS_Q_Purge() after
retrieving a message call the embOS error handler OS_Error() in debug
builds of embOS.
Example
static void MemoryTask(void) {
int Len;
char* pData;
while (1) {
Len = OS_Q_GetPtrTimed(&_MemoryQ, &pData, 10); /* Check message */
if (Len > 0) {
Memory_WritePacket(*(U32*)pData, Len); /* Process message */
OS_Q_Purge(&_MemoryQ); /* Delete message */
} else { /* Timeout */
DoSomethingElse();
}
}
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
165
9.3.7 OS_Q_Purge()
Description
Deletes the last retrieved message in a queue.
Prototype
void OS_Q_Purge (OS_Q* pQ);
Parameter Description
pQ Pointer to the queue.
Table 9.8: OS_Q_Purge() parameter list
Additional Information
This routine should be called by the task that retrieved the last message from the
queue, after the message is processed.
Once a message was retrieved by a call of OS_Q_GetPtr(), OS_Q_GetPtrCond()
or OS_Q_GetPtrTimed(), the message has to be removed from the queue by a
call of OS_Q_Purge() before a following message can be retrieved from the
queue. Consecutive calls of OS_Q_GetPtr(), OS_Q_GetPtrCond() or
OS_Q_GetPtrTimed() will call the embOS error handler OS_Error() in embOS
debug builds.
Consecutive calls of OS_Q_Purge() or calling OS_Q_Purge() without having
retrieved a message from the queue will also call the embOS error handler
OS_Error() in embOS debug builds.
Example
static void MemoryTask(void) {
int Len;
char* pData;
while (1) {
Len = OS_Q_GetPtr(&_MemoryQ, &pData); /* Get message */
Memory_WritePacket(*(U32*)pData, Len); /* Process message */
OS_Q_Purge(&_MemoryQ); /* Delete message */
}
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
166 CHAPTER 9 Queues
9.3.8 OS_Q_Clear()
Description
Deletes all message in a queue.
Prototype
void OS_Q_Clear (OS_Q* pQ);
Parameter Description
pQ Pointer to the queue.
Table 9.9: OS_Q_Clear() parameter list
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
167
9.3.9 OS_Q_GetMessageCnt()
Description
Returns the number of messages currently in a queue.
Prototype
int OS_Q_GetMessageCnt (const OS_Q* pQ);
Parameter Description
pQ Pointer to the queue.
Table 9.10: OS_Q_GetMessageCnt() parameter list
Return value
The number of messages in the queue.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
168 CHAPTER 9 Queues
9.3.10 OS_Q_Delete()
Description
Deletes a specific queue.
Prototype
void OS_Q_Delete (OS_Q* pQ);
Parameter Description
pQ Pointer to the queue.
Table 9.11: OS_Q_GetMessageCnt() parameter list
Additional Information
To keep the system fully dynamic, it is essential that queues can be created dynami-
cally. This also means there has to be a way to delete a queue when it is no longer
needed. The memory that has been used by the queue for the control structure and
the buffer can then be reused or reallocated.
It is the programmer's responsibility to:
• make sure that the program no longer uses the queue to be deleted
• make sure that the queue to be deleted actually exists (i.e. has been created
first).
Example
OS_Q QSerIn;
void Cleanup(void) {
OS_Q_Delete(QSerIn);
}.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
169
9.3.11 OS_Q_IsInUse()
Description
Delivers information whether the queue is actually in use.
Prototype
OS_BOOL OS_Q_IsInUse(const OS_Q* pQ)
Parameter Description
pQ Pointer to the queue.
Table 9.12: OS_Q_GetMessageCnt() parameter list
Return value
0: Queue not in use
!=0: Queue is in use and may not be deleted or cleared.
Additional Information
A queue must not be cleared or deleted when it is in use by any task or function.
In use means, any task or function actually accesses the queue and holds a pointer
to data in the queue.
OS_Q_IsInUse() can be used to examine the state of the queue before it can be
cleared or deleted, as these functions must not be performed as long as the queue is
used.
Example
void DeleteQ(OS_Q* pQ) {
OS_IncDI(); // Avoid state changes of the queue by task or interrupt
//
// Wait until queue is not used
//
while (OS_Q_IsInUse(pQ) != 0) {
OS_Delay(1);
}
OS_Q_Delete(pQ);
OS_DecRI();
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
170 CHAPTER 9 Queues
9.3.12 OS_Q_GetMessageSize()
Description
Returns the message size.
Prototype
int OS_Q_GetMessageSize (OS_Q* pQ)
Parameter Description
pQ Pointer to the queue.
Table 9.13: OS_Q_GetMessageSize() parameter list
Return value
The size of the first message or 0 when no message is available.
Additional Information
If the queue is empty OS_Q_GetMessageSize returns 0. If a message is available
OS_Q_GetMessageSize returns the size of that message. The message is not
retrieved from the queue.
Example
static void MemoryTask(void) {
int Len;
while (1) {
Len = OS_Q_GetMessageSize(&_MemoryQ); /* Get message length */
if (Len > 0) {
printf(“Message with size %d retrieved\n”, Len);
}
OS_Delay(100)
}
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
171
9.3.13 OS_Q_PeekPtr()
Description
Retrieves a message from a queue.
Prototype
int OS_Q_PeekPtr (OS_Q* pQ,
void** ppData);
Parameter Description
pQ Pointer to the queue.
ppData Address of pointer to the message to be retrieved from queue.
Table 9.14: OS_Q_GetPtr() parameter list
Return value
The size of the retrieved message or 0 when no new message is available.
Sets the pointer ppData to the message that should be retrieved.
Additional Information
If the queue is empty, 0 is returned.
The retrieved message is not removed from the queue. Use OS_GetPtr()/
OS_Q_Purge() to retrieve and remove a message from the queue.
Example
static void MemoryTask(void) {
int Len;
char* pData;
while (1) {
OS_IncDI(); // Avoid state changes of the queue by task or interrupt
Len = OS_Q_PeekPtr(&_MemoryQ, &pData); /* Get message */
if (Len > 0) {
Memory_WritePacket(*(U32*)pData, Len); /* Process message */
}
OS_RESTORE_I();
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
172 CHAPTER 9 Queues
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
173
Chapter 10
Task events
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
174 CHAPTER 10 Task events
10.1 Introduction
Task events are another way of communication between tasks. In contrast to sema-
phores and mailboxes, task events are messages to a single, specified recipient. In
other words, a task event is sent to a specified task.
The purpose of a task event is to enable a task to wait for a particular event (or for
one of several events) to occur. This task can be kept inactive until the event is sig-
naled by another task, a S/W timer or an interrupt handler. The event can consist of
anything that the software has been made aware of in any way. For example, the
change of an input signal, the expiration of a timer, a key press, the reception of a
character, or a complete command.
Every task has an individual bit-mask, which per default is 32bit wide on 32bit CPUs,
and 8bits wide on 16- and 8-bit CPUs. This means that 32 or 8 different events can
be signaled to and distinguished by every task. By calling OS_WaitEvent(), a task
waits for one of the events specified as a bitmask. As soon as one of the events
occurs, this task must be signaled by calling OS_SignalEvent(). The waiting task will
then be put in the READY state immediately. It will be activated according to the
rules of the scheduler as soon as it becomes the task with the highest priority of all
the tasks in the READY state.
By changing the definition of OS_TASK_EVENT which is defined as unsigned long on
32bit CPUs and unsigned char on 16- or 8-bit CPUs per default, the task events can
be expanded to 16 or 32 bits thus allowing more different events, or reduced to
smaller data types on 32bit CPUs.
Changing the definition of OS_TASK_EVENT can only be done when using the embOS
sources in a project, or when the libraries are rebuilt from sources with the modified
definition
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
175
Timer
main
Task
ISR
Routine Description
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
176 CHAPTER 10 Task events
10.2.1 OS_WaitEvent()
Description
Waits for one of the events specified in the bitmask and clears the event memory
after an event occurs.
Prototype
OS_TASK_EVENT OS_WaitEvent (OS_TASK_EVENT EventMask);
Parameter Description
The events that the task will be waiting for. The type
EventMask OS_TASK_EVENT is defined as unsigned long for 32bit CPUs and
unsigned char for 8- or 16-bit CPUs per default.
Table 10.2: OS_WaitEvent() parameter list
Return value
All events that have actually occurred.
Additional Information
If none of the specified events are signaled, the task is suspended. The first of the
specified events will wake the task. These events are signaled by another task, a S/W
timer or an interrupt handler. Any bit in the event mask may enable the correspond-
ing event.
When a task shall wait on multiple events, all of the specified events shall be
requested by a single call of OS_WaitEvent() and all events have to be be handled
when the function returns.
Note that all events of the task are cleared when the function returns, even those
events that were not given as parameter in the eventmask. Consecutive calls of
OS_WaitEvent() with different event masks will not work, as all events are cleared
when the function returns. Events may got lost. OS_WaitSingleEvent() may be used
for this case.
OS_TASK_EVENT is defined as unsigned long for 32bit CPUs and unsigned char for
8- or 16-bit CPUs per default. It may be modified to any other type when embOS
sources are used in a project, or when the libraries are rebuilt with a modified defini-
tion.
Example
void Task(void) {
OS_TASK_EVENT MyEvents;
while(1) {
MyEvents = OS_WaitEvent(3); /* Wait for event 1 or 2 to be signaled */
/* Handle ALL events */
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
177
10.2.2 OS_WaitSingleEvent()
Description
Waits for one or more of the events specified by the Eventmask and clears only those
events that were specified in the eventmask.
Prototype
OS_TASK_EVENT OS_WaitSingleEvent (OS_TASK_EVENT EventMask);
Parameter Description
EventMask The events that the task will be waiting for.
Table 10.3: OS_WaitSingleEvent() parameter list
Return value
All requested events that have actually occurred.
Additional Information
If none of the specified events are signaled, the task is suspended. The first of the
requested events will wake the task. These events are signaled by another task, a S/
W timer, or an interrupt handler. Any bit in the event mask may enable the corre-
sponding event. When the function returns, it delivers all of the requested events.
The requested events are cleared in the event state of the task. All other events
remain unchanged and will not be returned.
OS_WaitSingleEvent() may be used in consecutive calls with individual requests.
Only requested events will be handled, no other events can get lost.
When the function waits on multiple events, the returned value has to be evaluated,
because the function returns when at least one of the requested events was signaled.
When the function requests a single event, the returned value does not need to be
evaluated.
OS_TASK_EVENT is defined as unsigned long for 32bit CPUs and unsigned char for
8- or 16-bit CPUs per default. It may be modified to any other type when embOS
sources ar used in a project, or when the libraries are rebuilt with a modified defini-
tion.
Example
void Task(void) {
OS_TASK_EVENT MyEvents;
while(1) {
MyEvents = OS_WaitSingleEvent(3); /* Wait for event 1 or 2 to be signaled */
/* Handle ALL events */
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
178 CHAPTER 10 Task events
10.2.3 OS_WaitEvent_Timed()
Description
Waits for the specified events for a given time, and clears the event memory after
one of the requsted events occurs, or after the timeout expired.
Prototype
OS_TASK_EVENT OS_WaitEventTimed (OS_TASK_EVENT EventMask,
OS_TIME TimeOut);
Parameter Description
EventMask The events that the task will be waiting for.
Maximum time in timer ticks until the events have to be signaled.
The data type OS_TIME is defined as an integer, therefore valid
Timeout values are
1 <= Timeout <= 2 15-1 = 0x7FFF = 32767 for 8/16-bit CPUs
1 <= Timeout <= 2 31-1 = 0x7FFFFFFF for 32-bit CPUs
Table 10.4: OS_WaitEventTimed() parameter list
Return value
The events that have actually occurred within the specified time.
0 if no events were signaled in time.
Additional Information
If none of the specified events are available, the task is suspended for the given
time. The first of the requested events will wake the task if the event is signaled by
another task, a S/W timer, or an interrupt handler within the specified TimeOut time.
If none of the requested events is signaled, the task is activated after the specified
timeout and all actual events are returned and then cleared.
Note that the function returns all events that were signaled within the given timeout
time, even those which were not requested.
The calling function has to evaluate the returned value.
OS_TASK_EVENT is defined as unsigned long for 32bit CPUs and unsigned char for
8- or 16-bit CPUs per default.
It may be modified to any other type when embOS sources ar used in a project, or
when the libraries are rebuilt with a modified definition.
Example
void Task(void) {
OS_TASK_EVENT MyEvents;
while(1) {
MyEvents = OS_WaitEvent_Timed(3, 10); /* Wait for events 1+2 for 10 ms */
if ((MyEvents & 0x3) == 0) {
_HandleTimeout();
} else {
if (MyEvents & (1 << 0)) {
_HandleEvent1();
}
if (MyEvents & (1 << 1)) {
_HandleEvent2();
}
}
}
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
179
10.2.4 OS_WaitSingleEventTimed()
Description
Waits for the specified events for a given time; after an event occurs, only the
requested events are cleared.
Prototype
OS_TASK_EVENT OS_WaitSingleEventTimed (OS_TASK_EVENT EventMask,
OS_TIME TimeOut);
Parameter Description
EventMask The events that the task will be waiting for.
Maximum time in timer ticks until the events have to be signaled.
The data type OS_TIME is defined as an integer, therefore valid
Timeout values are
1 <= Timeout <= 215-1 = 0x7FFF = 32767 for 8/16-bit CPUs
1 <= Timeout <= 231-1 = 0x7FFFFFFF for 32-bit CPUs
Table 10.5: OS_WaitSingleEventTimed() parameter list
Return value
The masked events that have actually occurred within the specified time.
0 if no masked events were signaled in time.
Additional Information
If none of the specified events are available, the task is suspended for the given
time. The first of the specified events will wake the task if the event is signaled by
another task, a S/W timer or an interrupt handler within the specified TimeOut time.
If no event is signaled, the task is activated after the specified timeout and the
function returns zero. Any bit in the event mask may enable the corresponding event.
All unmasked events remain unchanged.
OS_TASK_EVENT is defined as unsigned long for 32bit CPUs and unsigned char for
8- or 16-bit CPUs per default. It may be modified to any other type when embOS
sources ar used in a project, or when the libraries are rebuilt with a modified defini-
tion.
Example
void Task(void) {
OS_TASK_EVENT MyEvents;
while(1) {
MyEvents = OS_WaitSingleEventTimed(3, 10); /* Wait for event 1 or 2 to be
signaled within 10ms */
/* Handle requested events */
if (MyEvents == 0) {
_HandleTimeout;
} else {
if (MyEvents & (1 << 0)) {
_HandleEvent1();
}
if (MyEvents & (1 << 1)) {
_HandleEvent2();
}
}
if (OS_WaitSingleEvent((1 << 2), 10) == 0) {
_HandleTimeout();
} else {
_HandleEvent3();
}
}
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
180 CHAPTER 10 Task events
10.2.5 OS_SignalEvent()
Description
Signals event(s) to a specified task.
Prototype
void OS_SignalEvent (OS_TASK_EVENT Event,
OS_TASK* pTask);
Parameter Description
The event(s) to signal:
1 means event 1
2 means event 2
4 means event 3
Event
...
128 means event 8.
Multiple events can be signaled as the sum of the single events
(for example, 6 will signal events 2 & 3).
pTask Task that the events are sent to.
Table 10.6: OS_SignalEvent() parameter list
Additional Information
If the specified task is waiting for one of these events, it will be put in the READY
state and activated according to the rules of the scheduler.
OS_TASK_EVENT is defined as unsigned long for 32bit CPUs and unsigned char for
8- or 16-bit CPUs per default. It may be modified to any other type when embOS
sources ar used in a project, or when the libraries are rebuilt with a modified defini-
tion.
Example
The task that handles the serial input and the keyboard waits for a character to be
received either via the keyboard (EVENT_KEYPRESSED) or serial interface
(EVENT_SERIN):
/*
* Just a small demo for events
*/
#define EVENT_KEYPRESSED (1)
#define EVENT_SERIN (2)
void Task0(void) {
OS_TASK_EVENT MyEvent;
while(1)
MyEvent = OS_WaitEvent(EVENT_KEYPRESSED | EVENT_SERIN)
if (MyEvent & EVENT_KEYPRESSED) {
/* handle key press */
}
if (MyEvent & EVENT_SERIN) {
/* Handle serial reception */
}
}
}
void TimerKey(void) {
/* More code to find out if key has been pressed */
OS_SignalEvent(EVENT_SERIN, &TCB0); /* Notify Task that key was pressed */
}
void InitTask(void) {
OS_CREATETASK(&TCB0, 0, Task0, 100, Stack0); /* Create Task0 */
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
181
If the task was only waiting for a key to be pressed, OS_GetMail() could simply be
called. The task would then be deactivated until a key is pressed. If the task has to
handle multiple mailboxes, as in this case, events are a good option.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
182 CHAPTER 10 Task events
10.2.6 OS_GetEventsOccurred()
Description
Returns a list of events that have occurred for a specified task.
Prototype
OS_TASK_EVENT OS_GetEventsOccurred (const OS_TASK* pTask);
Parameter Description
The task who's event mask is to be returned,
pTask
NULL means current task.
Table 10.7: OS_GetEventsOccured() parameter list
Return value
The event mask of the events that have actually occurred.
Additional Information
By calling this function, the actual events remain signaled. The event memory is not
cleared. This is one way for a task to find out which events have been signaled. The
task is not suspended if no events are signaled.
OS_TASK_EVENT is defined as unsigned long for 32bit CPUs and unsigned char for
8- or 16-bit CPUs per default. It may be modified to any other type when embOS
sources ar used in a project, or when the libraries are rebuilt with a modified defini-
tion.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
183
10.2.7 OS_ClearEvents()
Description
Returns the actual state of events and then clears the events of a specified task.
Prototype
OS_TASK_EVENT OS_ClearEvents (OS_TASK* pTask);
Parameter Description
The task who's event mask is to be returned,
pTask
NULL means current task.
Table 10.8: OS_ClearEvents() parameter list
Return value
The events that were actually signaled before clearing.
OS_TASK_EVENT is defined as unsigned long for 32bit CPUs and unsigned char for
8- or 16-bit CPUs per default. It may be modified to any other type when embOS
sources ar used in a project, or when the libraries are rebuilt with a modified defini-
tion.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
184 CHAPTER 10 Task events
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
185
Chapter 11
Event objects
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
186 CHAPTER 11 Event objects
11.1 Introduction
Event objects are another type of communication and synchronization objects. In
contrast to task-events, event objects are standalone objects which are not owned by
any task.
The purpose of an event object is to enable one or multiple tasks to wait for a partic-
ular event to occur. The tasks can be kept suspended until the event is set by another
task, a S/W timer, or an interrupt handler. The event can be anything that the soft-
ware is made aware of in any way. Examples include the change of an input signal,
the expiration of a timer, a key press, the reception of a character, or a complete
command.
Compared to a task event, the signaling function does not need to know which task is
waiting for the event to occur.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
187
Timer
main
Task
ISR
Routine Description
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
188 CHAPTER 11 Event objects
11.2.1 OS_EVENT_Create()
Description
Creates an event object and resets the event.
Prototype
void OS_EVENT_Create (OS_EVENT* pEvent)
Parameter Description
pEvent Pointer to an event object data structure.
Table 11.2: OS_EVENT_Create() parameter list
Additional Information
Before the event object can be used, it has to be created once by a call of
OS_EVENT_Create(). On creation, the event is set in non-signaled state, and the list
of waiting tasks is deleted. Therefore, OS_EVENT_Create() must not be called for an
event object which was already created before. The debug version of embOS checks
whether the specified event object was already created and calls OS_Error() with
error code OS_ERR_2USE_EVENTOBJ, if the event object was already created before the
call of OS_EVENT_Create().
Example
OS_EVENT _HW_Event;
OS_EVENT_Create(&HW_Event); /* Create and initialize event object */
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
189
11.2.2 OS_EVENT_Wait()
Description
Waits for an event and suspends the calling task as long as the event is not signaled.
Prototype
void OS_EVENT_Wait (OS_EVENT* pEvent)
Parameter Description
pEvent Pointer to the event object that the task will be waiting for.
Table 11.3: OS_EVENT_Wait() parameter list
Additional Information
If the specified event object is already set, the calling task resets the event and con-
tinues operation.
If the specified event object is not set, the calling task is suspended until the event
object becomes signaled. The event is not reset when the task resumes.
pEvent has to address an existing event object, which has to be created before the
call of OS_EVENT_Wait(). The debug version of embOS will check whether pEvent
addresses a valid event object and will call OS_Error() with error code
OS_ERR_EVENT_INVALID in case of an error.
Important
This function may not be called from within an interrupt handler or software timer.
Example
OS_EVENT_Wait(&_HW_Event); // Wait for event object
OS_EVENT_Reset(&_HW_Event); // Reset the event
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
190 CHAPTER 11 Event objects
11.2.3 OS_EVENT_WaitTimed()
Description
Waits for an event and suspends the calling task for a specified time as long as the
event is not signaled.
Prototype
char OS_EVENT_WaitTimed (OS_EVENT* pEvent,
OS_TIME Timeout)
Parameter Description
pEvent Pointer to the event object that the task will be waiting for.
Maximum time in timer ticks until the event have to be signaled.
The data type OS_TIME is defined as an integer, therefore valid
Timeout values are
1 <= Timeout <= 2 15-1 = 0x7FFF = 32767 for 8/16-bit CPUs
1 <= Timeout <= 2 31-1 = 0x7FFFFFFF for 32-bit CPUs
Table 11.4: OS_EVENT_WaitTimed() parameter list
Return value
0 success, the event was signaled within the specified time.
1 if the event was not signaled within the specified timeout time.
Additional Information
If the specified event object is already set, the calling task resets the event and con-
tinues operation.
If the specified event object is not set, the calling task is suspended until the event
object becomes signaled or the timeout time has expired.
If the event object becomes signaled within the specified timeout time, the event is
reset and the function returns without timeout result.
When the timeout expired and the event was not signaled during the specified time-
out time, OS_EVENT_WaitTimed() returns 1.
pEvent has to address an existing event object, which has to be created before the
call of OS_EVENT_WaitTimed(). The debug version of embOS will check whether
pEvent addresses a valid event object and will call OS_Error() with error code
OS_ERR_EVENT_INVALID in case of an error.
When the calling task is blocked by higher priority tasks for a longer period than the
timeout value, it may happen, that the event becomes signaled after the timeout
time before the calling task continues. In this case, the function returns with time-
out, because the event was not availbale within the requested time. In this case, the
state of the event is not modified by OS_EVENT_WaitTimed().
Important
This function may not be called from within an interrupt handler or software timer.
Example
if (OS_EVENT_WaitTimed(&_HW_Event, 10) == 0) {
/* event was signaled within timeout time, handle event */
...
} else {
/* event was not signaled within timeout time, handle timeout */
...
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
191
11.2.4 OS_EVENT_Set()
Description
Sets an event object to signaled state, or resumes tasks which are waiting at the
event object.
Prototype
void OS_EVENT_Set (OS_EVENT* pEvent)
Parameter Description
pEvent Pointer to the event object which should be set to signaled state.
Table 11.5: OS_EVENT_Set() parameter list
Additional Information
If no tasks are waiting at the event object, the event object is set to signaled state.
If at least one task is already waiting at the event object, all waiting tasks are
resumed and the event object is not set to the signaled state. pEvent has to address
an existing event object, which has to be created before by a call of
OS_EVENT_Create(). The debug version of embOS will check whether pEvent
addresses a valid event object and will call OS_Error() with error code
OS_ERR_EVENT_INVALID in case of an error.
Example
Examples on how to use the OS_EVENT_Set() function are shown in the section
“Examples”.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
192 CHAPTER 11 Event objects
11.2.5 OS_EVENT_Reset()
Description
Resets the specified event object to non-signaled state.
Prototype
void OS_EVENT_Reset (OS_EVENT* pEvent)
Parameter Description
Pointer to the event object which should be reset to non-signaled
pEvent
state.
Table 11.6: OS_EVENT_Reset() parameter list
Additional Information
pEvent has to address an existing event object, which has been created before by a
call of OS_EVENT_Create(). The debug version of embOS will check whether pEvent
addresses a valid event object and will call OS_Error() with the error code
OS_ERR_EVENT_INVALID in case of an error.
Example
OS_EVENT_Reset(&_HW_Event); /* Reset event object to non-signaled state */
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
193
11.2.6 OS_EVENT_Pulse()
Description
Signals an event object and resumes waiting tasks, then resets the event object to
non-signaled state.
Prototype
void OS_EVENT_Pulse (OS_EVENT* pEvent);
Parameter Description
pEvent Pointer to the event object which should be pulsed.
Table 11.7: OS_EVENT_Pulse() parameter list
Additional Information
If any tasks are waiting at the event object, the tasks are resumed. The event object
remains in non-signaled state.
The debug version of embOS will check whether pEvent addresses a valid event
object and will call OS_Error() with the error code OS_ERR_EVENT_INVALID in case of
an error.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
194 CHAPTER 11 Event objects
11.2.7 OS_EVENT_Get()
Description
Returns the state of an event object.
Prototype
unsigned char OS_EVENT_Get (const OS_EVENT* pEvent);
Parameter Description
pEvent Pointer to an event object who’s state should be examined.
Table 11.8: OS_EVENT_Get() parameter list
Return value
0: Event object is not set to signaled state
1: Event object is set to signaled state.
Additional Information
By calling this function, the actual state of the event object remains unchanged.
pEvent has to address an existing event object, which has been created before by a
call of OS_EVENT_Create().
The debug version of embOS will check whether pEvent addresses a valid event
object and will call OS_Error() with error code OS_ERR_EVENT_INVALID in case of an
error.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
195
11.2.8 OS_EVENT_Delete()
Description
Deletes an event object.
Prototype
void OS_EVENT_Delete (OS_EVENT* pEvent);
Parameter Description
pEvent Pointer to an event object which should be deleted.
Table 11.9: OS_EVENT_Delete() parameter list
Additional Information
To keep the system fully dynamic, it is essential that event objects can be created
dynamically. This also means there has to be a way to delete an event object when it
is no longer needed. The memory that has been used by the event object’s control
structure can then be reused or reallocated.
It is your responsibility to make sure that:
• the program no longer uses the event object to be deleted
• the event object to be deleted actually exists (has been created first)
• no tasks are waiting at the event object when it is deleted.
pEvent has to address an existing event object, which has been created before by a
call of OS_EVENT_Create().
The debug version of embOS will check whether pEvent addresses a valid event
object and will call OS_Error() with error code OS_ERR_EVENT_INVALID in case of an
error.
If any task is waiting at the event object which is deleted, the debug version of
embOS calls OS_Error() with error code OS_ERR_EVENT_DELETE.
To avoid any problems, an event object should not be deleted in a normal application.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
196 CHAPTER 11 Event objects
/************************************************************
*
* _ISRhandler
*/
static void _ISRhandler(void) {
//
// Perform some simple & fast processing in ISR //
//
...
//
// Wake up task to do the rest of the work
//
OS_EVENT_Set(&_Event);
}
/************************************************************
*
* _Task
*/
static void _Task(void) {
while (1) {
OS_EVENT_Wait(&_Event);
OS_EVENT_Reset(&_Event);
//
// Do the rest of the work (which has not been done in the ISR)
//
}
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
197
/********************************************************************
* SEGGER MICROCONTROLLER SYSTEME GmbH
* Solutions for real time microcontroller applications
*********************************************************************
File : Main_EVENT.c
Purpose : Sample program for embOS using EVENT object
--------- END-OF-HEADER --------------------------------------------*/
#include "RTOS.h"
/********************************************************************/
void HW_Wait(void);
void HW_Free(void);
void HW_Init(void);
/********************************************************************/
void HW_Free(void) {
OS_EVENT_Set(&_HW_Event);
}
void HW_Init(void) {
OS_CREATETASK(&_TCBHW, "HWTask", _HWTask, 25, _StackHW);
OS_EVENT_Create(&_HW_Event);
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
198 CHAPTER 11 Event objects
/********************************************************************/
/*********************************************************************
*
* main
*
**********************************************************************/
int main(void) {
OS_IncDI(); /* Initially disable interrupts */
OS_InitKern(); /* Initialize OS */
OS_InitHW(); /* Initialize Hardware for OS */
HW_Init(); /* Initialize HW module */
/* You need to create at least one task before calling OS_Start() */
OS_CREATETASK(&TCBHP, "HP Task", HPTask, 100, StackHP);
OS_CREATETASK(&TCBLP, "LP Task", LPTask, 50, StackLP);
OS_SendString("Start project will start multitasking !\n");
OS_Start(); /* Start multitasking */
return 0;
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
199
Chapter 12
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
200 CHAPTER 12 Heap type memory management
12.1 Introduction
ANSI C offers some basic dynamic memory management functions. These are mal-
loc, free, and realloc.
Unfortunately, these routines are not thread-safe, unless a special thread-safe imple-
mentation exists in the compiler specific runtime libraries; they can only be used
from one task or by multiple tasks if they are called sequentially. Therefore, embOS
offer task-safe variants of these routines. These variants have the same names as
their ANSI counterparts, but are prefixed OS_; they are called OS_malloc(),
OS_free(), OS_realloc(). The thread-safe variants that embOS offers use the stan-
dard ANSI routines, but they guarantee that the calls are serialized using a resource
semaphore.
If heap memory management is not supported by the standard C-libraries for a spe-
cific CPU, embOS heap memory management is not implemented.
Heap type memory management is part of the embOS libraries. It does not use any
resources if it is not referenced by the application (that is, if the application does not
use any memory management API function).
Note that another aspect of these routines may still be a problem: the memory used
for the functions (known as heap) may fragment. This can lead to a situation where
the total amount of memory is sufficient, but there is not enough memory available
in a single block to satisfy an allocation request.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
201
Timer
main
Task
ISR
API routine Description
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
202 CHAPTER 12 Heap type memory management
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
203
Chapter 13
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
204 CHAPTER 13 Fixed block size memory pools
13.1 Introduction
Fixed block size memory pools contain a specific number of fixed-size blocks of mem-
ory. The location in memory of the pool, the size of each block, and the number of
blocks are set at runtime by the application via a call to the OS_MEMF_CREATE() func-
tion. The advantage of fixed memory pools is that a block of memory can be allo-
cated from within any task in a very short, determined period of time.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
205
Timer
main
Task
ISR
API routine Description
Create / Delete
OS_MEMF_Create Creates fixed block memory pool. X X
OS_MEMF_Delete Deletes fixed block memory pool. X X
Allocation
Allocates memory block from a given mem-
OS_MEMF_Alloc ory pool. Wait indefinitely if no block is X X
available.
Allocates memory block from a given mem-
OS_MEMF_AllocTimed ory pool. Wait no longer than given time X X
limit if no block is available.
Allocates block from a given memory pool,
OS_MEMF_Request X X X X
if available. Non-blocking.
Release
Releases memory block from a given mem-
OS_MEMF_Release X X X X
ory pool.
OS_MEMF_FreeBlock Releases memory block from any pool. X X X X
Info
Returns the number of available blocks in a
OS_MEMF_GetNumFreeBlocks X X X X
pool.
OS_MEMF_IsInPool Returns !=0 if block is in memory pool. X X X X
Returns the maximum number of blocks in a
OS_MEMF_GetMaxUsed X X X X
pool which have been used at a time.
OS_MEMF_GetNumBlocks Returns the number of blocks in a pool. X X X X
Returns the size of one block of a given
OS_MEMF_GetBlockSize X X X X
pool.
Table 13.1: Memory pools API functions
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
206 CHAPTER 13 Fixed block size memory pools
13.2.1 OS_MEMF_Create()
Description
Creates and initializes a fixed block size memory pool.
Prototype
void OS_MEMF_Create (OS_MEMF* pMEMF,
void* pPool,
OS_UINT NumBlocks,
OS_UINT BlockSize);
Parameter Description
pMEMF Pointer to the control data structure of memory pool.
Pointer to memory to be used for the memory pool. Required size
pPool
is: NumBlocks * (BlockSize + OS_MEMF_SIZEOF_BLOCKCONTROL).
NumBlocks Number of blocks in the pool.
BlockSize Size in bytes of one block.
Table 13.2: OS_MEMF_Create() parameter list
Additional Information
OS_MEMF_SIZEOF_BLOCKCONTROL gives the number of bytes used for control and
debug purposes. It is guaranteed to be 0 in release or stack check builds. Before
using any memory pool, it has to be created. The debug version of libraries keeps
track of created and deleted memory pools. The release and stack check versions do
not.
The maximum number of blocks and the maximum block size is for 16Bit CPUs 32768
and for 32Bit CPUs 2147483648.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
207
13.2.2 OS_MEMF_Delete()
Description
Deletes a fixed block size memory pool. After deletion, the memory pool and memory
blocks inside this pool can no longer be used.
Prototype
void OS_MEMF_Delete (OS_MEMF* pMEMF);
Parameter Description
pMEMF Pointer to the control data structure of memory pool.
Table 13.3: OS_MEMF_Delete() parameter list
Additional Information
This routine is provided for completeness. It is not used in the majority of
applications because there is no need to dynamically create/delete memory pools.
For most applications it is preferred to have a static memory pool design; memory
pools are created at startup (before calling OS_Start()) and will never be deleted.
The debug version of libraries mark the memory pool as deleted.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
208 CHAPTER 13 Fixed block size memory pools
13.2.3 OS_MEMF_Alloc()
Description
Requests allocation of a memory block. Waits until a block of memory is available.
Prototype
void* OS_MEMF_Alloc (OS_MEMF* pMEMF,
int Purpose);
Parameter Description
pMEMF Pointer to the control data structure of memory pool.
This is a parameter which is used for debugging purpose only. Its
value has no effect on program execution, but may be remem-
Purpose
bered in debug builds to allow runtime analysis of memory allo-
cation problems.
Table 13.4: OS_MEMF_Alloc() parameter list
Return value
Pointer to the allocated block.
Additional Information
If there is no free memory block in the pool, the calling task is suspended until a
memory block becomes available. The retrieved pointer must be delivered to
OS_MEMF_Release() as a parameter to free the memory block. The pointer must not
be modified.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
209
13.2.4 OS_MEMF_AllocTimed()
Description
Requests allocation of a memory block. Waits until a block of memory is available or
the timeout has expired.
Prototype
void* OS_MEMF_AllocTimed (OS_MEMF* pMEMF,
OS_TIME Timeout,
int Purpose);
Parameter Description
pMEMF Pointer to the control data structure of memory pool.
Time limit before timeout, given in ticks. 0 or negative values are
permitted.
Timeout in basic embOS time units (nominal ms):
Timeout The data type OS_TIME is defined as an integer, therefore valid
values are
1 <= Timeout <= 215-1 = 0x7FFF = 32767 for 8/16-bit CPUs
1 <= Timeout <= 231-1 = 0x7FFFFFFF for 32-bit CPUs
This is a parameter which is used for debugging purpose only. Its
value has no effect on program execution, but may be remem-
Purpose
bered in debug builds to allow runtime analysis of memory allo-
cation problems.
Table 13.5: OS_MEMF_AllocTimed()
Return value
!=NULL pointer to the allocated block
NULL if no block could be allocated allocated within the specified time.
Additional Information
If there is no free memory block in the pool, the calling task is suspended until a
memory block becomes available or the timeout has expired. The retrieved pointer
must be delivered to OS_MEMF_Release() as parameter to free the memory block.
The pointer must not be modified.
When the calling task is blocked by higher priority tasks for a longer period than the
timeout value, it may happen, that the memory block becomes available after the
timeout time before the calling task continues. In this case, the function returns with
timeout, because the memory block was not availbale within the requested time.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
210 CHAPTER 13 Fixed block size memory pools
13.2.5 OS_MEMF_Request()
Description
Requests allocation of a memory block. Continues execution in any case.
Prototype
void* OS_MEMF_Request (OS_MEMF* pMEMF,
int Purpose);
Parameter Description
pMEMF Pointer to the control data structure of memory pool.
This is a parameter which is used for debugging purpose only. Its
value has no effect on program execution, but may be remem-
Purpose
bered in debug builds to allow runtime analysis of memory allo-
cation problems.
Table 13.6: OS_MEMF_Request() parameter list
Return value
!=NULL pointer to the allocated block
NULL if no block has been allocated.
Additional Information
The calling task is never suspended by calling OS_MEMF_Request(). The retrieved
pointer must be delivered to OS_MEMF_Release() as parameter to free the memory
block. The pointer must not be modified.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
211
13.2.6 OS_MEMF_Release()
Description
Releases a memory block that was previously allocated.
Prototype
void OS_MEMF_Release (OS_MEMF* pMEMF,
void* pMemBlock);
Parameter Description
pMEMF Pointer to the control data structure of memory pool.
pMemBlock Pointer to the memory block to free.
Table 13.7: OS_MEMF_Release() parameter list
Additional Information
The pMemBlock pointer has to be the one that was delivered from any retrieval func-
tion described above. The pointer must not be modified between allocation and
release. The memory block becomes available for other tasks waiting for a memory
block from the pool. If any task is waiting for a fixed memory block, it is activated
according to the rules of the scheduler.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
212 CHAPTER 13 Fixed block size memory pools
13.2.7 OS_MEMF_FreeBlock()
Description
Releases a memory block that was previously allocated. The memory pool does not
need to be denoted.
Prototype
void OS_MEMF_FreeBlock (void* pMemBlock);
Parameter Description
pMemBlock Pointer to the memory block to free.
Table 13.8: OS_MEMF_FreeBlock() parameter list
Additional Information
The pMemBlock pointer has to be the one that was delivered form any retrieval func-
tion described above. The pointer must not be modified between allocation and
release. This function may be used instead of OS_MEMF_Release(). It has the advan-
tage that only one parameter is needed. embOS itself will find the associated mem-
ory pool. The memory block becomes available for other tasks waiting for a memory
block from the pool. If any task is waiting for a fixed memory block, it is activated
according to the rules of the scheduler.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
213
13.2.8 OS_MEMF_GetNumBlocks()
Description
Information routine to examine the total number of available memory blocks in the
pool.
Prototype
int OS_MEMF_GetNumBlocks (const OS_MEMF* pMEMF);
Parameter Description
pMEMF Pointer to the control data structure of memory pool.
Table 13.9: OS_MEMF_GetNumBlocks() parameter list
Return value
Returns the number of blocks in the specified memory pool. This is the value that
was given as parameter during creation of the memory pool.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
214 CHAPTER 13 Fixed block size memory pools
13.2.9 OS_MEMF_GetBlockSize()
Description
Information routine to examine the size of one memory block in the pool.
Prototype
int OS_MEMF_GetBlockSize (const OS_MEMF* pMEMF);
Parameter Description
pMEMF Pointer to the control data structure of memory pool.
Table 13.10: OS_MEMF_GetBlockSize() parameter list
Return value
Size in bytes of one memory block in the specified memory pool. This is the value of
the parameter when the memory pool was created.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
215
13.2.10 OS_MEMF_GetNumFreeBlocks()
Description
Information routine to examine the number of free memory blocks in the pool.
Prototype
int OS_MEMF_GetNumFreeBlocks (OS_MEMF* pMEMF);
Parameter Description
pMEMF Pointer to the control data structure of memory pool.
Table 13.11: OS_MEMF_GetNumFreeBlocks() parameter list
Return value
The number of free blocks actually available in the specified memory pool.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
216 CHAPTER 13 Fixed block size memory pools
13.2.11 OS_MEMF_GetMaxUsed()
Description
Information routine to examine the amount of memory blocks in the pool that were
used concurrently since creation of the pool.
Prototype
int OS_MEMF_GetMaxUsed (const OS_MEMF* pMEMF);
Parameter Description
pMEMF Pointer to the control data structure of memory pool.
Table 13.12: OS_MEMF_GetMaxUsed() parameter list
Return value
Maximum number of blocks in the specified memory pool that were used concurrently
since the pool was created.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
217
13.2.12 OS_MEMF_IsInPool()
Description
Information routine to examine whether a memory block reference pointer belongs to
the specified memory pool.
Prototype
char OS_MEMF_IsInPool (const OS_MEMF* pMEMF,
const void* pMemBlock);
Parameter Description
pMEMF Pointer to the control data structure of memory pool.
pMemBlock Pointer to a memory block that should be checked
Table 13.13: OS_MEMF_IsInPool() parameter list
Return value
0: Pointer does not belong to memory pool.
1: Pointer belongs to the pool.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
218 CHAPTER 13 Fixed block size memory pools
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
219
Chapter 14
Stacks
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
220 CHAPTER 14 Stacks
14.1 Introduction
The stack is the memory area used for storing the return address of function calls,
parameters, and local variables, as well as for temporary storage. Interrupt routines
also use the stack to save the return address and flag registers, except in cases
where the CPU has a separate stack for interrupt functions. Refer to the CPU &
Compiler Specifics manual of embOS documentation for details on your processor's
stack. A “normal” single-task program needs exactly one stack. In a multitasking
system, every task has to have its own stack.
The stack needs to have a minimum size which is determined by the sum of the stack
usage of the routines in the worst-case nesting. If the stack is too small, a section of
the memory that is not reserved for the stack will be overwritten, and a serious pro-
gram failure is most likely to occur. embOS monitors the stack size (and, if available,
also interrupt stack size in the debug version), and calls the failure routine
OS_Error() if it detects a stack overflow. However, embOS cannot reliably detect a
stack overflow.
A stack that has been defined larger than necessary does not hurt; it is only a waste
of memory. To detect a stack overflow, the debug and stack check builds of embOS
fill the stack with control characters when it is created and check these characters
every time the task is deactivated. If an overflow is detected, OS_Error() is called.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
221
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
222 CHAPTER 14 Stacks
Timer
main
Task
ISR
Routine Description
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
223
14.2.1 OS_GetStackBase()
Description
Returns a pointer to the base of a task stack.
Prototype
void* OS_GetStackBase (OS_TASK* pTask);
Parameter Description
The task who's stack base has to be returned.
pTask
NULL means current task.
Table 14.2: OS_GetStackBase() parameter list
Return value
The pointer to the base address of the task stack.
Additional Information
This function is only available in the debug and stack check builds of embOS, because
only these builds initialize the stack space used for the tasks.
Example
void CheckStackBase(void) {
printf("Addr Stack[0] %x", OS_GetStackBase(&TCB[0]);
OS_Delay(1000);
printf("Addr Stack[1] %x", OS_GetStackBase(&TCB[1]);
OS_Delay(1000);
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
224 CHAPTER 14 Stacks
14.2.2 OS_GetStackSize()
Description
Returns the size of a task stack.
Prototype
unsigned int OS_GetStackSize (OS_TASK* pTask);
Parameter Description
The task who's stack size should be checked.
pTask
NULL means current task.
Table 14.3: OS_GetStackSize() parameter list
Return value
The size of the task stack in bytes.
Additional Information
This function is only available in the debug and stack check builds of embOS, because
only these builds initialize the stack space used for the tasks.
Example
void CheckStackSize(void) {
printf("Size Stack[0] %d", OS_GetStackSize(&TCB[0]);
OS_Delay(1000);
printf("Size Stack[1] %d", OS_GetStackSize(&TCB[1]);
OS_Delay(1000);
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
225
14.2.3 OS_GetStackSpace()
Description
Returns the unused portion of a task stack.
Prototype
unsigned int OS_GetStackSpace (OS_TASK* pTask);
Parameter Description
The task who's stack space has to be checked.
pTask
NULL means current task.
Table 14.4: OS_GetStackSpace() parameter list
Return value
The unused portion of the task stack in bytes.
Additional Information
In most cases, the stack size required by a task cannot be easily calculated, because
it takes quite some time to calculate the worst-case nesting and the calculation itself
is difficult.
However, the required stack size can be calculated using the function
OS_GetStackSpace(), which returns the number of unused bytes on the stack. If
there is a lot of space left, you can reduce the size of this stack and vice versa.
This function is only available in the debug and stack check builds of embOS, because
only these builds initialize the stack space used for the tasks.
Important
This routine does not reliably detect the amount of stack space left, because it can
only detect modified bytes on the stack. Unfortunately, space used for register stor-
age or local variables is not always modified. In most cases, this routine will detect
the correct amount of stack bytes, but in case of doubt, be generous with your stack
space or use other means to verify that the allocated stack space is sufficient.
Example
void CheckStackSpace(void) {
printf("Unused Stack[0] %d", OS_GetStackSpace(&TCB[0]);
OS_Delay(1000);
printf("Unused Stack[1] %d", OS_GetStackSpace(&TCB[1]);
OS_Delay(1000);
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
226 CHAPTER 14 Stacks
14.2.4 OS_GetStackUsed()
Description
Returns the used portion of a task stack.
Prototype
unsigned int OS_GetStackUsed (OS_TASK* pTask);
Parameter Description
The task who's stack usage has to be checked.
pTask
NULL means current task.
Table 14.5: OS_GetStackUsed() parameter list
Return value
The used portion of the task stack in bytes.
Additional Information
In most cases, the stack size required by a task cannot be easily calculated, because
it takes quite some time to calculate the worst-case nesting and the calculation itself
is difficult.
However, the required stack size can be calculated using the function
OS_GetStackUsed(), which returns the number of used bytes on the stack. If there is
a lot of space left, you can reduce the size of this stack and vice versa.
This function is only available in the debug and stack check builds of embOS, because
only these builds initialize the stack space used for the tasks.
Important
This routine does not reliably detect the amount of stack space used, because it can
only detect modified bytes on the stack. Unfortunately, space used for register stor-
age or local variables is not always modified. In most cases, this routine will detect
the correct amount of stack bytes, but in case of doubt, be generous with your stack
space or use other means to verify that the allocated stack space is sufficient.
Example
void CheckStackUsed(void) {
printf("Used Stack[0] %d", OS_GetStackUsed(&TCB[0]);
OS_Delay(1000);
printf("Used Stack[1] %d", OS_GetStackUsed(&TCB[1]);
OS_Delay(1000);
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
227
14.2.5 OS_GetSysStackBase()
Description
Returns a pointer to the base of the system stack.
Prototype
void* OS_GetSysStackBase (void);
Return value
The pointer to the base address of the system stack.
Example
void CheckSysStackBase(void) {
printf("Addr System Stack %x", OS_GetSysStackBase());
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
228 CHAPTER 14 Stacks
14.2.6 OS_GetSysStackSize()
Description
Returns the size of the system stack.
Prototype
unsigned int OS_GetSysStackSize (void);
Return value
The size of the system stack in bytes.
Example
void CheckSysStackSize(void) {
printf("Size System Stack %d", OS_GetSysStackSize());
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
229
14.2.7 OS_GetSysStackSpace()
Description
Returns the unused portion of the system stack.
Prototype
unsigned int OS_GetSysStackSpace (void);
Return value
The unused portion of the system stack in bytes.
Additional Information
This function is only available in the debug and stack check builds of embOS.
Important
This routine does not reliably detect the amount of stack space left, because it can
only detect modified bytes on the stack. Unfortunately, space used for register stor-
age or local variables is not always modified. In most cases, this routine will detect
the correct amount of stack bytes, but in case of doubt, be generous with your stack
space or use other means to verify that the allocated stack space is sufficient.
Example
void CheckSysStackSpace(void) {
printf("Unused System Stack %d", OS_GetSysStackSpace());
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
230 CHAPTER 14 Stacks
14.2.8 OS_GetSysStackUsed()
Description
Returns the used portion of the system stack.
Prototype
unsigned int OS_GetSysStackUsed (void);
Return value
The used portion of the system stack in bytes.
Additional Information
This function is only available in the debug and stack check builds of embOS.
Important
This routine does not reliably detect the amount of stack space used, because it can
only detect modified bytes on the stack. Unfortunately, space used for register stor-
age or local variables is not always modified. In most cases, this routine will detect
the correct amount of stack bytes, but in case of doubt, be generous with your stack
space or use other means to verify that the allocated stack space is sufficient.
Example
void CheckSysStackUsed(void) {
printf("Used System Stack %d", OS_GetSysStackUsed());
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
231
14.2.9 OS_GetIntStackBase()
Description
Returns a pointer to the base of the interrupt stack.
Prototype
void* OS_GetIntStackBase (void);
Return value
The pointer to the base address of the interrupt stack.
Additional Information
This function is only available when an interrupt stack exists.
Example
void CheckIntStackBase(void) {
printf("Addr Interrupt Stack %x", OS_GetIntStackBase());
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
232 CHAPTER 14 Stacks
14.2.10 OS_GetIntStackSize()
Description
Returns the size of the interrupt stack.
Prototype
unsigned int OS_GetIntStackSize (void);
Return value
The size of the interrupt stack in bytes.
Additional Information
This function is only available when an interrupt stack exists.
Example
void CheckIntStackSize(void) {
printf("Size Interrupt Stack %d", OS_GetIntStackSize());
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
233
14.2.11 OS_GetIntStackSpace()
Description
Returns the unused portion of the interrupt stack.
Prototype
unsigned int OS_GetIntStackSpace (void);
Return value
The unused portion of the interrupt stack in bytes.
Additional Information
This function is only available in the debug and stack check builds and when an inter-
rupt stack exists.
Important
This routine does not reliably detect the amount of stack space left, because it can
only detect modified bytes on the stack. Unfortunately, space used for register stor-
age or local variables is not always modified. In most cases, this routine will detect
the correct amount of stack bytes, but in case of doubt, be generous with your stack
space or use other means to verify that the allocated stack space is sufficient.
Example
void CheckIntStackSpace(void) {
printf("Unused Interrupt Stack %d", OS_GetIntStackSpace());
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
234 CHAPTER 14 Stacks
14.2.12 OS_GetIntStackUsed()
Description
Returns the used portion of the interrupt stack.
Prototype
unsigned int OS_GetIntStackUsed (void);
Return value
The used portion of the interrupt stack in bytes.
Additional Information
This function is only available in the debug and stack check builds and when an inter-
rupt stack exists.
Important
This routine does not reliably detect the amount of stack space used, because it can
only detect modified bytes on the stack. Unfortunately, space used for register stor-
age or local variables is not always modified. In most cases, this routine will detect
the correct amount of stack bytes, but in case of doubt, be generous with your stack
space or use other means to verify that the allocated stack space is sufficient.
Example
void CheckIntStackUsed(void) {
printf("Used Interrupt Stack %d", OS_GetIntStackUsed());
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
235
Chapter 15
Interrupts
This chapter explains how to use interrupt service routines (ISRs) in cooperation with
embOS. Specific details for your CPU and compiler can be found in the CPU & Com-
piler Specifics manual of the embOS documentation.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
236 CHAPTER 15 Interrupts
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
237
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
238 CHAPTER 15 Interrupts
interrupt latencies for all interrupts, some (like embOS) disable only low-priority
interrupts and do thereby not affect the latency of high priority interrupts.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
239
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
240 CHAPTER 15 Interrupts
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
241
Task1 is interrupted
by a high priority interrupt
The task 1 is interrupted by a high priority interrupt. This high priority interrupt is
not allowed to call an embOS API function directly. Therefore the high priority inter-
rupt triggers a low priority interrupt, which is allowed to call embOS API functions.
The low priority interrupt calls an embOS API function to resume task 2.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
242 CHAPTER 15 Interrupts
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
243
Timer
main
Task
ISR
Routine Description
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
244 CHAPTER 15 Interrupts
15.6.1 OS_CallISR()
Description
Entry function for use in an embOS interrupt handler. Nestable interrupts disabled.
Prototype
void OS_CallISR (void (*pRoutine)(void));
Parameter Description
pRoutine Pointer to a routine that should run on interrupt.
Table 15.2: OS_CallISR() parameter list
Additional Information
OS_CallISR() can be used as entry function in an embOS interrupt handler, when
the corresponding interrupt should not be interrupted by another embOS interrupt.
OS_CallISR() sets the interrupt priority of the CPU to the user definable ’fast’ inter-
rupt priority level, thus locking any other embOS interrupt.
Fast interrupts are not disabled.
Note: For some specific CPUs OS_CallISR() has to be used to call an interrupt
handler because OS_EnterInterrupt() / OS_LeaveInterrupt() may not be avail-
able.
Refer to the CPU specific manual.
Example
#pragma interrupt void OS_ISR_Tick(void) {
OS_CallISR(_IsrTickHandler);
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
245
15.6.2 OS_CallNestableISR()
Description
Entry function for use in an embOS interrupt handler. Nestable interrupts enabled.
Prototype
void OS_CallNestableISR (void (*pRoutine)(void));
Parameter Description
pRoutine Pointer to a routine that should run on interrupt.
Table 15.3: OS_CallNestableISR() parameter list
Additional Information
OS_CallNestableISR() can be used as entry function in an embOS interrupt handler,
when interruption by higher prioritized embOS interrupts should be allowed.
OS_CallNestableISR() does not alter the interrupt priority of the CPU, thus keeping
all interrupts with higher priority enabled.
Note: For some specific CPUs OS_CallNestableISR() has to be used to call an
interrupt handler because OS_EnterNestableInterrupt() /
OS_LeaveNestableInterrupt() may not be available.
Refer to the CPU specific manual.
Example
#pragma interrupt void OS_ISR_Tick(void) {
OS_CallNestableISR(_IsrTickHandler);
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
246 CHAPTER 15 Interrupts
15.6.3 OS_EnterInterrupt()
Note: This function may not be available in all ports.
Description
Informs embOS that interrupt code is executing.
Prototype
void OS_EnterInterrupt (void);
Additional Information
If OS_EnterInterrupt() is used, it should be the first function to be called in the
interrupt handler. It must be used with OS_LeaveInterrupt() as the last function
called. The use of this function has the following effects, it:
• disables task switches
• keeps interrupts in internal routines disabled.
An example is shown in the the description of OS_LeaveInterrupt().
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
247
15.6.4 OS_LeaveInterrupt()
Note: This function may not be available in all ports.
Description
Informs embOS that the end of the interrupt routine has been reached; executes
task switching within ISR.
Prototype
void OS_LeaveInterrupt (void);
Additional Information
If OS_LeaveInterrupt() is used, it should be the last function to be called in the
interrupt handler. If the interrupt has caused a task switch, it will be executed
(unless the program which was interrupted was in a critical region).
Example using OS_EnterInterrupt()/OS_LeaveInterrupt()
_interrupt void ISR_Timer(void) {
OS_EnterInterrupt();
OS_SignalEvent(1,&Task);/* Any functionality could be here */
OS_LeaveInterrupt();
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
248 CHAPTER 15 Interrupts
The problem with disabling and re-enabling interrupts is that functions that disable/
enable the interrupt cannot be nested.
Your C compiler offers two intrinsic functions for enabling and disabling interrupts.
These functions can still be used, but it is recommended to use the functions that
embOS offers (to be precise, they only look like functions, but are macros in reality).
If you do not use these recommended embOS functions, you may run into a problem
if routines which require a portion of the code to run with disabled interrupts are
nested or call an OS routine.
We recommend disabling interrupts only for short periods of time, if possible. Also,
you should not call routines when interrupts are disabled, because this could lead to
long interrupt latency times (the longer interrupts are disabled, the higher the inter-
rupt latency). As long as you only call embOS functions with interrupts enabled, you
may also safely use the compiler-provided intrinsics to disable interrupts.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
249
OS_IncDI() increments the interrupt disable counter which is used for the entire OS
and is therefore consistent with the rest of the program in that any routine can be
called and the interrupts will not be switched on before the matching OS_DecRI() has
been executed.
If you need to disable interrupts for a short moment only where no routine is called,
as in the example above, you could also use the pair OS_DI() and OS_RestoreI().
These are a bit more efficient because the interrupt disable counter OS_DICnt is not
modified twice, but only checked once. They have the disadvantage that they do not
work with routines because the status of OS_DICnt is not actually changed, and they
should therefore be used with great care. In case of doubt, use OS_IncDI() and
OS_DecRI().
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
250 CHAPTER 15 Interrupts
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
251
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
252 CHAPTER 15 Interrupts
Interrupt 1
Interrupt 2
Interrupt 3
Time
For applications requiring short interrupt latency, you may re-enable interrupts inside
an ISR by using OS_EnterNestableInterrupt() and OS_LeaveNestableInterrupt()
within the interrupt handler.
Nested interrupts can lead to problems that are difficult to track; therefore it is not
really recommended to enable interrupts within an interrupt handler. As it is impor-
tant that embOS keeps track of the status of the interrupt enable/disable flag, the
enabling and disabling of interrupts from within an ISR has to be done using the
functions that embOS offers for this purpose.
The routine OS_EnterNestableInterrupt() enables interrupts within an ISR and
prevents further task switches; OS_LeaveNestableInterrupt() disables interrupts
right before ending the interrupt routine again, thus restores the default condition.
Re-enabling interrupts will make it possible for an embOS scheduler interrupt to
shortly interrupt this ISR. In this case, embOS needs to know that another ISR is still
running and that it may not perform a task switch.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
253
15.9.1 OS_EnterNestableInterrupt()
Note: This function may not be available in all ports.
Description
Re-enables interrupts and increments the embOS internal critical region counter,
thus disabling further task switches.
Prototype
void OS_EnterNestableInterrupt (void);
Additional Information
This function should be the first call inside an interrupt handler when nested inter-
rupts are required. The function OS_EnterNestableInterrupt() is implemented as a
macro and offers the same functionality as OS_EnterInterrupt() in combination
with OS_DecRI(), but is more efficient, resulting in smaller and faster code.
Example
Refer to the example for OS_LeaveNestableInterrupt().
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
254 CHAPTER 15 Interrupts
15.9.2 OS_LeaveNestableInterrupt()
Note: This function may not be available in all ports.
Description
Disables further interrupts, then decrements the embOS internal critical region
count, thus re-enabling task switches if the counter has reached zero again.
Prototype
void OS_LeaveNestableInterrupt (void);
Additional Information
This function is the counterpart of OS_EnterNestableInterrupt(), and has to be the
last function call inside an interrupt handler when nested interrupts have earlier been
enabled by OS_EnterNestableInterrupt().
The function OS_LeaveNestableInterrupt() is implemented as a macro and offers
the same functionality as OS_LeaveInterrupt() in combination with OS_IncDI(),
but is more efficient, resulting in smaller and faster code.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
255
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
256 CHAPTER 15 Interrupts
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
257
Chapter 16
Critical Regions
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
258 CHAPTER 16 Critical Regions
16.1 Introduction
Critical regions are program sections during which the scheduler is switched off,
meaning that no task switch and no execution of software timers are allowed except
in situations where the running task has to wait. Effectively, preemptions are
switched off.
A typical example for a critical region would be the execution of a program section
that handles a time-critical hardware access (for example writing multiple bytes into
an EEPROM where the bytes have to be written in a certain amount of time), or a
section that writes data into global variables used by a different task and therefore
needs to make sure the data is consistent.
A critical region can be defined anywhere during the execution of a task. Critical
regions can be nested; the scheduler will be switched on again after the outermost
loop is left. Interrupts are still legal in a critical region. Software timers and inter-
rupts are executed as critical regions anyhow, so it does not hurt but does not do any
good either to declare them as such. If a task switch becomes due during the execu-
tion of a critical region, it will be performed right after the region is left.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
259
Timer
main
Task
ISR
Routine Description
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
260 CHAPTER 16 Critical Regions
16.2.1 OS_EnterRegion()
Description
Indicates to the OS the beginning of a critical region.
Prototype
void OS_EnterRegion (void);
Additional Information
OS_EnterRegion() is not actually a function but a macro. However, it behaves very
much like a function but is much more efficient. Using the macro indicates to embOS
the beginning of a critical region. A critical region counter (OS_RegionCnt), which is 0
by default, is incremented so that the routine can be nested. The counter will be dec-
remented by a call to the routine OS_LeaveRegion(). If this counter reaches 0 again,
the critical region ends.
Interrupts are not disabled using OS_EnterRegion(); however, preemptive task
switches are disabled in a critical region.
If any interrupt triggers a task switch, the task switch is delayed and kept pending
until the final call of OS_LeaveRegion(). When the OS_RegionCnt reaches 0 again, a
pending task switch is executed.
Cooperative task switches are not affected and will be executed in critical regions.
When the is running in a critical region and then calls any blocking embOS function,
the task will be suspended.
When the task is resumed again, the task specific OS_RegionCnt is restored, the task
continues to run in a critical region until OS_LeaveRegion() is called.
Example
void SubRoutine(void) {
OS_EnterRegion();
/* The following code will not be interrupted by the OS */
/* Preemptive task switches are blocked until the call of OS_leaveRegion() */
OS_LeaveRegion();
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
261
16.2.2 OS_LeaveRegion()
Description
Indicates to the OS the end of a critical region.
Prototype
void OS_LeaveRegion (void);
Additional Information
OS_LeaveRegion() is not actually a function but a macro. However, it behaves very
much like a function but is much more efficient. Usage of the macro indicates to
embOS the end of a critical region. A critical region counter (OS_RegionCnt), which is
0 by default, is decremented. If this counter reaches 0 again, the critical region ends.
A task switch which became pending during a critical region will be executed in
OS_Enterregion() when the OS_RegionCnt reaches 0 again.
Example
Refer to the example for OS_EnterRegion().
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
262 CHAPTER 16 Critical Regions
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
263
Chapter 17
Time measurement
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
264 CHAPTER 17 Time measurement
17.1 Introduction
embOS supports two basic types of run-time measurement which may be used for
calculating the execution time of any section of user code. Low-resolution measure-
ments use a time base of ticks, while high-resolution measurements are based on a
time unit called a cycle. The length of a cycle depends on the timer clock frequency.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
265
Code to be timed
0 ms 1 ms 2 ms 3 ms 4 ms 5 ms 6 ms
For many applications, low-resolution measurement may be fully sufficient for your
needs. In some cases, it may be more desirable than high-resolution measurement
due to its ease of use and faster computation time.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
266 CHAPTER 17 Time measurement
Timer
main
Task
ISR
Routine Description
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
267
17.2.1.1 OS_GetTime()
Description
Returns the current system time in ticks.
Prototype
int OS_GetTime (void);
Return value
The system variable OS_Time as a 16- or 32-bit integer value.
Additional Information
This function returns the system time as a 16-bit value on 8/16-bit CPUs, and as a
32-bit value on 32-bit CPUs. The OS_Time variable is a 32-bit value. Therefore, if the
return value is 32-bit, it is simply the entire contents of the OS_Time variable. If the
return value is 16-bit, it is the lower 16 bits of the OS_Time variable.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
268 CHAPTER 17 Time measurement
17.2.1.2 OS_GetTime32()
Description
Returns the current system time in ticks as a 32-bit value.
Prototype
int OS_GetTime32 (void);
Return value
The system variable OS_Time as a 32-bit integer value.
Additional Information
This function always returns the system time as a 32-bit value. Because the OS_Time
variable is also a 32-bit value, the return value is simply the entire contents of the
OS_Time variable.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
269
Code to be timed
0 ms 1 ms 2 ms 3 ms 4 ms 5 ms 6 ms
The call to OS_Timing_Start() calculates the starting value at 5,000 cycles, while
the call to OS_Timing_End() calculates the ending value at 52,000 cycles (both val-
ues are kept track of internally). The measured execution time of the code in this
example would therefore be (52,000 - 5,000) = 47,000 cycles, which corresponds to
4.7 ms.
Although the function OS_Timing_GetCycles() may be used for returning the execu-
tion time in cycles as above, it is typically more common to use the function
OS_Timing_Getus(), which returns the value in microseconds (µs). In the above
example, the return value would be 4,700 µs.
Data structure
All high-resolution routines take as parameter a pointer to a data structure of type
OS_TIMING, defined as follows:
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
270 CHAPTER 17 Time measurement
Timer
main
Task
ISR
Routine Description
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
271
17.3.1.1 OS_Timing_Start()
Description
Marks the beginning of a section of code to be timed.
Prototype
void OS_Timing_Start (OS_TIMING* pCycle);
Parameter Description
pCycle Pointer to a data structure of type OS_TIMING.
Table 17.3: OS_TimingStart() parameter list
Additional Information
This function must be used with OS_Timing_End().
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
272 CHAPTER 17 Time measurement
17.3.1.2 OS_Timing_End()
Description
Marks the end of a section of code to be timed.
Prototype
void OS_Timing_End (OS_TIMING* pCycle);
Parameter Description
pCycle Pointer to a data structure of type OS_TIMING.
Table 17.4: OS_TimingEnd() parameter list
Additional Information
This function must be used with OS_Timing_Start().
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
273
17.3.1.3 OS_Timing_Getus()
Description
Returns the execution time of the code between OS_Timing_Start() and
OS_Timing_End() in microseconds.
Prototype
OS_U32 OS_Timing_Getus (const OS_TIMING* pCycle);
Parameter Description
pCycle Pointer to a data structure of type OS_TIMING.
Table 17.5: OS_Timing_Getus() parameter list
Additional Information
The execution time in microseconds (µs) as a 32-bit integer value.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
274 CHAPTER 17 Time measurement
17.3.1.4 OS_Timing_GetCycles()
Description
Returns the execution time of the code between OS_Timing_Start() and
OS_Timing_End() in cycles.
Prototype
OS_U32 OS_Timing_GetCycles (OS_TIMING* pCycle);
Parameter Description
pCycle Pointer to a data structure of type OS_TIMING.
Table 17.6: OS_Timing_GetCycles() parameter list
Return value
The execution time in cycles as a 32-bit integer.
Additional Information
Cycle length depends on the timer clock frequency.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
275
17.4 Example
The following sample demonstrates the use of low-resolution and high-resolution
measurement to return the execution time of a section of code:
/**********************************************************
* SEGGER MICROCONTROLLER SYSTEME GmbH
* Solutions for real time microcontroller applications
***********************************************************
File : SampleHiRes.c
Purpose : Demonstration of embOS Hires Timer
--------------END-OF-HEADER------------------------------*/
#include "RTOS.H"
#include <stdio.h>
/*
* Measure the execution time with low resolution and return it in ms (ticks)
*/
int BenchmarkLoRes(void) {
int t;
t = OS_GetTime();
UserCode(); /* Execute the user code to be benchmarked */
t = OS_GetTime() - t;
return t;
}
/*
* Measure the execution time with hi resolution and return it in us
*/
OS_U32 BenchmarkHiRes(void) {
OS_U32 t;
OS_Timing_Start(&t);
UserCode(); /* Execute the user code to be benchmarked */
OS_Timing_End(&t);
return OS_Timing_Getus(&t);
}
void Task(void) {
int tLo;
OS_U32 tHi;
char ac[80];
while (1) {
tLo = BenchmarkLoRes();
tHi = BenchmarkHiRes();
sprintf(ac, "LoRes: %d ms\n", tLo);
OS_SendString(ac);
sprintf(ac, "HiRes: %d us\n", tHi);
OS_SendString(ac);
}
}
/**********************************************************
*
* main
*
**********************************************************/
void main(void) {
OS_InitKern(); /* Initialize OS */
OS_InitHW(); /* Initialize Hardware for OS */
/* You need to create at least one task here ! */
OS_CREATETASK(&TCB, "HP Task", Task, 100, Stack);
OS_Start(); /* Start multitasking */
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
276 CHAPTER 17 Time measurement
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
277
Chapter 18
System variables
The system variables are described here for a deeper understanding of how the OS
works and to make debugging easier.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
278 CHAPTER 18 System variables
18.1 Introduction
Note: Do not change the value of any system variables.
These variables are accessible and are not declared constant, but they should only be
altered by functions of embOS. However, some of these variables can be very useful,
especially the time variables.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
279
18.2.2 OS_Time
Description
This is the time variable which contains the current system time in ticks (usually
equivalent to ms).
Additional Information
The time variable has a resolution of one time unit, which is normally 1/1000 sec
(1 ms) and is normally the time between two successive calls to the embOS timer
interrupt handler. Instead of accessing this variable directly, use OS_GetTime() or
OS_GetTime32() as explained in the Chapter Time measurement on page 263.
18.2.3 OS_TimeDex
Basically, for internal use only. Contains the time at which the next task switch or
timer activation is due. If ((int)(OS_Time - OS_TimeDex)) >= 0, the task list and
timer list will be checked for a task or timer to activate. After activation, OS_TimeDex
will be assigned the time stamp of the next task or timer to be activated.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
280 CHAPTER 18 System variables
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
281
Chapter 19
System tick
This chapter explains the concept of the system tick, generated by a hardware timer
and all options available for it.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
282 CHAPTER 19 System tick
19.1 Introduction
Typically a hardware timer generates periodic interrupts used as a time base for the
OS. The interrupt service routine then calls one of the tick handlers of the OS.
embOS offers tick handlers with different functionality as well as a way to call a hook
function from within the system tick handler.
Generating timer interrupts
The hardware timer is normally initialized in the OS_InitHW() function which is deliv-
ered with the BSP. The BSP also includes the interrupt handler which is called by the
hardware timer interrupt. This interrupt handler has to call one of the embOS system
tick handler functions which are explained in this chapter.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
283
Timer
main
Task
ISR
Routine Description
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
284 CHAPTER 19 System tick
19.2.1.1 OS_TICK_Handle()
Description
The default embOS timer tick handler which is typically called by the hardware timer
interrupt handler.
Prototype
void OS_TICK_Handle ( void );
Additional Information
The embOS tick handler must not be called by the application, it has to be called
from an interrupt handler.
OS_EnterInterrupt(), or OS_EnterNestableInterrupt() has to be called, before
calling the embOS tick handler
Example
/* Example of a timer interrupt handler */
/*********************************************************************
*
* OS_ISR_Tick
*/
__interrupt void OS_ISR_Tick(void) {
OS_EnterNestableInterrupt();
OS_TICK_Handle();
OS_LeaveNestableInterrupt();
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
285
19.2.1.2 OS_TICK_HandleEx()
Description
An alternate tick handler which may be used instead of the standard tick handler. It
can be used in situations where the basic timer-interrupt interval (tick) is a multiple
of 1 ms and the time values used as parameter for delays still should use 1 ms as the
time base.
Prototype
void OS_TICK_HandleEx ( void );
Additional Information
The embOS tick handler must not be called by the application, it has to be called
from an interrupt handler. OS_EnterInterrupt(), or OS_EnterNestableInterrupt()
has to be called, before calling the embOS tick handler. Refer to OS_TICK_Config()
on page 287 about how to configure OS_TICK_HandleEx().
Example
/* Example of a timer interrupt handler using OS_HandleTickEx */
/*********************************************************************
*
* OS_ISR_Tick
*/
__interrupt void OS_ISR_Tick(void) {
OS_EnterNestableInterrupt();
OS_TICK_HandleEx();
OS_LeaveNestableInterrupt();
}
Assuming the hardware timer runs at a frequency of 500Hz, thus interrupting the
system every 2ms, the embOS tick handler configuration function OS_TICK_Config()
should be called as demonstrated in the Example section of OS_TICK_Config(). This
should be done during OS_InitHW(), before the embOS timer is started.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
286 CHAPTER 19 System tick
19.2.1.3 OS_TICK_HandleNoHook()
Description
The alternate speed optimized embOS timer tick handler without hook function which
is typically called by the hardware timer interrupt handler.
Prototype
void OS_TICK_HandleNoHook ( void );
Additional Information
The embOS tick handler must not be called by the application, it has to be called
from an interrupt handler.
OS_EnterInterrupt(), or OS_EnterNestableInterrupt() has to be called, before
calling the embOS tick handler
Example
/* Example of a timer interrupt handler */
/*********************************************************************
*
* OS_ISR_Tick
*/
__interrupt void OS_ISR_Tick(void) {
OS_EnterNestableInterrupt();
OS_TICK_HandleNoHook();
OS_LeaveNestableInterrupt();
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
287
19.2.1.4 OS_TICK_Config()
Description
Configures the tick to interrupt ratio. The “normal” tick handler OS_TICK_Handle()
assumes a 1:1 ratio, meaning one interrupt increments the tick count (OS_Time) by
one. For other ratios, OS_TICK_HandleEx() needs to be used; the ratio is defined by
calling the OS_TICK_Config().
Prototype
void OS_TICK_Config ( unsigned FractPerInt, unsigned FractPerTick );
Parameter Description
FractPerInt Number of Fractions per interrupt
FractPerTick Number of Fractions per tick
Table 19.2: OS_TICK_Config() parameter list
Additional Information
Note that fractional values are supported, such as tick is 1 ms, where an interrupt is
generated every 1.6ms. This means that FractPerInt and FractPerTick are:
FractPerInt = 16;
FractPerTick = 10;
or
FractPerInt = 8;
FractPerTick = 5;
Examples:
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
288 CHAPTER 19 System tick
Timer
main
Task
ISR
Routine Description
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
289
19.3.1.1 OS_TICK_AddHook()
Description
Adds a tick hook handler.
Prototype
void OS_TICK_AddHook ( OS_TICK_HOOK * pHook,
OS_TICK_HOOK_ROUTINE * pfUser );
Parameter Description
pHook Pointer to a structure of OS_TICK_HOOK.
pfUser Pointer to an OS_TICK_HOOK_ROUTINE function.
Table 19.4: OS_TICK_AddHook() parameter list
Additional Information
The hook function is called directly from the interrupt handler.
The function therefore should execute as fast as possible.
The function called by the tick hook must not re-enable interrupts.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
290 CHAPTER 19 System tick
19.3.1.2 OS_TICK_RemoveHook()
Description
Removes a tick hook handler.
Prototype
void OS_TICK_RemoveHook ( const OS_TICK_HOOK * pHook );
Parameter Description
pHook Pointer to a structure of OS_TICK_HOOK.
Table 19.5: OS_TICK_RemoveHook() parameter list
Additional Information
The function may be called to dynamically remove a tick hook function which was
installed by a call of OS_TICK_AddHook().
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
291
Chapter 20
This chapter explains the target system specific parts of embOS, also called BSP
(board support package).
If the system is up and running on your target system, there is no need to read this
chapter.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
292 CHAPTER 20 Configuration of target system (BSP)
20.1 Introduction
You do not have to configure anything to get started with embOS. The start project
supplied will execute on your system. Small changes in the configuration will be nec-
essary at a later point for system frequency or for the UART used for communication
with the optional embOSView.
The file RTOSInit.c is provided in source code and can be modified to match your
target hardware needs. It is compiled and linked with your application program.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
293
Timer
main
Task
ISR
Routine Description
20.2.1 OS_Idle()
The embOS function OS_Idle() is called when no task is ready for execution.
The function OS_Idle() is part of the target CPU specific RTOSInit.c file delivered
with embOS.
Normally it is programmed as an endless loop without any functionality.
In most embOS ports, it activates a power saving sleep mode of the target CPU.
The embOS OS_Idle() function is not a task, it has no task context and does not
have its own stack.
The OS_Idle() function runs on the normal CSTACK which is also used for the kernel.
Exceptions and interrupts which occur during OS_Idle() are no problem as long as
they don't trigger a task switch.
They return into OS_Idle() and the code is continued where it was interrupted.
When a task switch occurs during the execution of OS_Idle(), the OS_Idle() func-
tion is interrupted and does not continue execution when it is activated again.
When OS_Idle() is activated, it always starts from the beginning. Interrupted code
is not continued.
You might create your own idle task running as endless loop with the lowest task pri-
ority in the system.
When you don't call any blocking or suspending function in this idle task, you will
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
294 CHAPTER 20 Configuration of target system (BSP)
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
295
Define Description
System frequency (in Hz).
OS_FSYS
Example: 20000000 for 20MHz.
Selection of UART to be used with embOSView
OS_UART
(-1 will disable communication),
OS_BAUDRATE Selection of baudrate for communication with embOSView.
Table 20.2: Configuration defines overview
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
296 CHAPTER 20 Configuration of target system (BSP)
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
297
time, the basic time unit can be made 1 ms by using the function OS_TICK_Config().
The basic time unit does not have to be 1 ms; it might just as well be 100 µs or 10
ms or any other value. For most applications, 1 ms is an appropriate value.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
298 CHAPTER 20 Configuration of target system (BSP)
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
299
Chapter 21
Profiling
This chapter explains the profiling functions that can be used by an application.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
300 CHAPTER 21 Profiling
Timer
main
Task
ISR
Routine Description
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
301
21.0.1.1 OS_STAT_Sample()
Description
OS_STAT_Sample() starts profiling and calculates the absolute task run time since
the last call to OS_STAT_Sample().
Prototype
void OS_STAT_Sample ( void );
Additional Information
OS_STAT_Sample() starts the profiling for 5 seconds, the next call to
OS_STAT_Sample() must be within this 5 seconds. Please use the embOS function
OS_STAT_GetLoad() to get the task specific cpu load in 1/10 percent.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
302 CHAPTER 21 Profiling
21.0.1.2 OS_STAT_GetLoad()
Description
OS_STAT_GetLoad() calculates the current task cpu load in 1/10 percent.
Prototype
int OS_STAT_GetLoad(OS_TASK * pTask);
Parameter Description
pTask Pointer to task control block
Table 21.2: OS_STAT_GetLoad() parameter list
Return value
OS_STAT_GetLoad returns the current task cpu load in 1/10 percent.
Additional Information
OS_STAT_GetLoad() requires that OS_STAT_Sample() is called periodically.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
303
int main(void) {
OS_IncDI(); /* Initially disable interrupts */
OS_InitKern(); /* Initialize OS */
OS_InitHW(); /* Initialize Hardware for OS */
/* You need to create at least one task before calling OS_Start() */
OS_CREATETASK(&TCBHP, "HP Task", HPTask, 100, StackHP);
OS_CREATETASK(&TCBMP, "MP Task", MPTask, 50, StackMP);
OS_CREATETASK(&TCBLP, "LP Task", LPTask, 50, StackLP);
OS_Start(); /* Start multitasking */
return 0;
}
Output:
500
499
501
500
500
...
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
304 CHAPTER 21 Profiling
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
305
Chapter 22
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
306 CHAPTER 22 embOSView: Profiling and analyzing
22.1 Overview
embOSView displays the state of a running application using embOS. A serial
interface (UART) is normally used for communication with the target. The hardware-
dependent routines and defines available for communication with embOSView are
located in RTOSInit.c. This file has to be configured properly. For details on how to
configure this file, refer the CPU & Compiler Specifics manual of embOS documenta-
tion. The embOSView utility is shipped as embOSView.exe with embOS and runs
under Windows 9x / NT / 2000 / Vista and Windows 7. The latest version is available
on our website at www.segger.com
embOSView is a very helpful tool for analysis of the running target application.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
307
Context
Number of activations since reset. SP, DP, DT
Switches
Table 22.1: Task list window overview
The Task list window is helpful in analysis of stack usage and CPU load for every
running task.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
308 CHAPTER 22 embOSView: Profiling and analyzing
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
309
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
310 CHAPTER 22 embOSView: Profiling and analyzing
Timer
main
Task
ISR
Routine Description
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
311
22.5.1 OS_SendString()
Description
Sends a string over SIO to the Terminal window.
Prototype
void OS_SendString (const char* s);
Parameter Description
Pointer to a zero-terminated string that should be sent to the
s
Terminal window.
Table 22.4: OS_SendString() parameter list
Additional Information
This function uses OS_COM_Send1() which is defined in RTOSInit.c.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
312 CHAPTER 22 embOSView: Profiling and analyzing
22.5.2 OS_SetRxCallback()
Description
Sets a callback hook to a routine for receiving one character.
Prototype
typedef void OS_RX_CALLBACK (OS_U8 Data)
OS_RX_CALLBACK* OS_SetRxCallback (OS_RX_CALLBACK* cb);
Parameter Description
Pointer to the application routine that should be called when one
cb
character is received over the serial interface.
Table 22.5: OS_SetRxCallback() parameter list
Return value
OS_RX_CALLBACK* as described above. This is the pointer to the callback function that
was hooked before the call.
Additional Information
The user function is called from embOS. The received character is passed as parame-
ter. See the example below.
Example
void GUI_X_OnRx(OS_U8 Data); /* Callback ... called from Rx-interrupt */
void GUI_X_Init(void) {
OS_SetRxCallback( &GUI_X_OnRx);
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
313
Every entry in the Trace list is recorded with the actual system time. In case of calls
or events from tasks, the task ID (TaskId) and task name (TaskName) (limited to
15 characters) are also recorded. Parameters of API calls are recorded if possible,
and are shown as part of the APIName column. In the example above, this can be
seen with OS_Delay(3). Once the trace buffer is full, trace is automatically stopped.
The Trace list and buffer can be cleared from embOSView.
Setting up trace from embOSView
Three different kinds of trace filters are defined for tracing. These filters can be set
up from embOSView via the menu Options/Setup/Trace.
Filter 0 is not task-specific and records all specified events regardless of the task. As
the Idle loop is not a task, calls from within the idle loop are not traced.
Filter 1 is specific for interrupt service routines, software timers and all calls that
occur outside a running task. These calls may come from the idle loop or during star-
tup when no task is running.
Filters 2 to 4 allow trace of API calls from named tasks.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
314 CHAPTER 22 embOSView: Profiling and analyzing
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
315
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
316 CHAPTER 22 embOSView: Profiling and analyzing
Timer
main
Task
ISR
Routine Description
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
317
22.8.1 OS_TraceEnable()
Description
Enables tracing of filtered API calls.
Prototype
void OS_TraceEnable (void);
Additional Information
The trace filter conditions should have been set up before calling this function. This
functionality is available in trace builds only. In non-trace builds, the API call is
removed by the preprocessor.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
318 CHAPTER 22 embOSView: Profiling and analyzing
22.8.2 OS_TraceDisable()
Description
Disables tracing of API and user function calls.
Prototype
void OS_TraceDisable (void);
Additional Information
This functionality is available in trace builds only. In non-trace builds, the API call is
removed by the preprocessor.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
319
22.8.3 OS_TraceEnableAll()
Description
Sets up Filter 0 (any task), enables tracing of all API calls and then enables the trace
function.
Prototype
void OS_TraceEnableAll (void);
Additional Information
The trace filter conditions of all the other trace filters are not affected.
This functionality is available in trace builds only. In non-trace builds, the API call is
removed by the preprocessor.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
320 CHAPTER 22 embOSView: Profiling and analyzing
22.8.4 OS_TraceDisableAll()
Description
Sets up Filter 0 (any task), disables tracing of all API calls and also disables trace.
Prototype
void OS_TraceDisableAll (void);
Additional Information
The trace filter conditions of all the other trace filters are not affected, but tracing is
stopped.
This functionality is available in trace builds only. In non-trace builds, the API call is
removed by the preprocessor.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
321
22.8.5 OS_TraceEnableId()
Description
Sets the specified ID value in Filter 0 (any task), thus enabling trace of the specified
function, but does not start trace.
Prototype
void OS_TraceEnableId (OS_U8 Id);
Parameter Description
ID value of API call that should be enabled for trace:
Id 0 <= Id <= 127
Values from 0 to 99 are reserved for embOS.
Table 22.7: OS_TraceEnableId() parameter list
Additional Information
To enable trace of a specific embOS API function, you must use the correct Id value.
These values are defined as symbolic constants in RTOS.h.
This function may also enable trace of your own functions.
This functionality is available in trace builds only. In non-trace builds, the API call is
removed by the preprocessor.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
322 CHAPTER 22 embOSView: Profiling and analyzing
22.8.6 OS_TraceDisableId()
Description
Resets the specified ID value in Filter 0 (any task), thus disabling trace of the speci-
fied function, but does not stop trace.
Prototype
void OS_TraceDisableId (OS_U8 Id);
Parameter Description
ID value of API call that should be enabled for trace:
Id 0 <= Id <= 127
Values from 0 to 99 are reserved for embOS.
Table 22.8: OS_TraceDisabledId() parameter list
Additional Information
To disable trace of a specific embOS API function, you must use the correct Id value.
These values are defined as symbolic constants in RTOS.h.
This function may also be used for disabling trace of your own functions.
This functionality is available in trace builds only. In non-trace builds, the API call is
removed by the preprocessor.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
323
22.8.7 OS_TraceEnableFilterId()
Description
Sets the specified ID value in the specified trace filter, thus enabling trace of the
specified function, but does not start trace.
Prototype
void OS_TraceEnableFilterId (OS_U8 FilterIndex,
OS_U8 Id)
Parameter Description
Index of the filter that should be affected:
FilterIndex 0 <= FilterIndex <= 4
0 affects Filter 0 (any task) and so on.
ID value of API call that should be enabled for trace:
Id 0 <= Id <= 127
Values from 0 to 99 are reserved for embOS.
Table 22.9: OS_TraceEnabledFilterId() parameter list
Additional Information
To enable trace of a specific embOS API function, you must use the correct Id value.
These values are defined as symbolic constants in RTOS.h.
This function may also be used for enabling trace of your own functions.
This functionality is available in trace builds only. In non-trace builds, the API call is
removed by the preprocessor.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
324 CHAPTER 22 embOSView: Profiling and analyzing
22.8.8 OS_TraceDisableFilterId()
Description
Resets the specified ID value in the specified trace filter, thus disabling trace of the
specified function, but does not stop trace.
Prototype
void OS_TraceDisableFilterId (OS_U8 FilterIndex,
OS_U8 Id)
Parameter Description
Index of the filter that should be affected:
FilterIndex 0 <= FilterIndex <= 4
0 affects Filter 0 (any task) and so on.
ID value of API call that should be enabled for trace:
Id 0 <= Id <= 127
Values from 0 to 99 are reserved for embOS.
Table 22.10: OS_TraceDisableFilterId() parameter list
Additional Information
To disable trace of a specific embOS API function, you must use the correct Id value.
These values are defined as symbolic constants in RTOS.h.
This function may also be used for disabling trace of your own functions.
This functionality is available in trace builds only. In non-trace builds, the API call is
removed by the preprocessor.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
325
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
326 CHAPTER 22 embOSView: Profiling and analyzing
Timer
main
Task
ISR
Routine Description
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
327
22.10.1 OS_TraceVoid()
Description
Writes an entry identified only by its ID into the trace buffer.
Prototype
void OS_TraceVoid (OS_U8 Id);
Parameter Description
ID value of API call that should be enabled for trace:
Id 0 <= Id <= 127
Values from 0 to 99 are reserved for embOS.
Table 22.12: OS_TraceVoid() parameter list
Additional Information
This functionality is available in trace builds only, and the API call is not removed by
the preprocessor.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
328 CHAPTER 22 embOSView: Profiling and analyzing
22.10.2 OS_TracePtr()
Description
Writes an entry with ID and a pointer as parameter into the trace buffer.
Prototype
void OS_TracePtr (OS_U8 Id,
void* p);
Parameter Description
ID value of API call that should be enabled for trace:
Id 0 <= Id <= 127
Values from 0 to 99 are reserved for embOS.
p Any void pointer that should be recorded as parameter.
Table 22.13: OS_TracePtr() parameter list
Additional Information
The pointer passed as parameter will be displayed in the trace list window of
embOSView. This functionality is available in trace builds only. In non-trace builds,
the API call is removed by the preprocessor.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
329
22.10.3 OS_TraceData()
Description
Writes an entry with ID and an integer as parameter into the trace buffer.
Prototype
void OS_TraceData (OS_U8 Id,
int v);
Parameter Description
ID value of API call that should be enabled for trace:
Id 0 <= Id <= 127
Values from 0 to 99 are reserved for embOS.
v Any integer value that should be recorded as parameter.
Table 22.14: OS_TraceData() parameter list
Additional Information
The value passed as parameter will be displayed in the trace list window of
embOSView.This functionality is available in trace builds only. In non-trace builds,
the API call is removed by the preprocessor.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
330 CHAPTER 22 embOSView: Profiling and analyzing
22.10.4 OS_TraceDataPtr()
Description
Writes an entry with ID, an integer, and a pointer as parameter into the trace buffer.
Prototype
void OS_TraceDataPtr (OS_U8 Id,
int v,
void* p);
Parameter Description
ID value of API call that should be enabled for trace:
Id 0 <= Id <= 127
Values from 0 to 99 are reserved for embOS.
v Any integer value that should be recorded as parameter.
p Any void pointer that should be recorded as parameter.
Table 22.15: OS_TraceDataPtr() parameter list
Additional Information
The values passed as parameters will be displayed in the trace list window of embOS-
View. This functionality is available in trace builds only. In non-trace builds, the API
call is removed by the preprocessor.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
331
22.10.5 OS_TraceU32Ptr()
Description
Writes an entry with ID, a 32-bit unsigned integer, and a pointer as parameter into
the trace buffer.
Prototype
void OS_TraceU32Ptr (OS_U8 Id,
OS_U32 p0,
void* p1);
Parameter Description
ID value of API call that should be enabled for trace:
Id 0 <= Id <= 127
Values from 0 to 99 are reserved for embOS.
p0 Any unsigned 32-bit value that should be recorded as parameter.
p1 Any void pointer that should be recorded as parameter.
Table 22.16: OS_TraceU32Ptr() parameter list
Additional Information
This function may be used for recording two pointers. The values passed as parame-
ters will be displayed in the trace list window of embOSView. This functionality is
available in trace builds only. In non-trace builds, the API call is removed by the pre-
processor.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
332 CHAPTER 22 embOSView: Profiling and analyzing
#ifndef OS_TRACE_FROM_START
#define OS_TRACE_FROM_START 1
#endif
char MainState;
/* Sample main routine, that enables and setup API and function call trace
from start */
void main(void) {
OS_InitKern();
OS_InitHW();
#if (OS_TRACE && OS_TRACE_FROM_START)
/* OS_TRACE is defined in trace builds of the library */
OS_TraceDisableAll(); /* Disable all API trace calls */
OS_TraceEnableId(APP_TRACE_ID_SETSTATE); /* User trace */
OS_TraceEnableFilterId(APP_TRACE_ID_SETSTATE); /* User trace */
OS_TraceEnable();
#endif
By default, embOSView lists all user function traces in the trace list window as Rou-
tine, followed by the specified ID and two parameters as hexadecimal values. The
example above would result in the following:
Routine100(0xabcd, 0x01)
where 0xabcd is the pointer address and 0x01 is the parameter recorded from
OS_TraceDataPtr().
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
333
#
# Define add. API functions.
# Syntax: API( <Index>, <Routinename> [parameters])
# Index: Integer, between 100 and 127
# Routinename: Identifier for the routine. Should be no more than 32 characters
# parameters: Optional paramters. A max. of 2 parameters can be specified.
# Valid parameters are:
# int
# ptr
# Every parameter has to be placed after a colon.
#
API( 100, "Routine100")
API( 101, "Routine101", int)
API( 102, "Routine102", int, ptr)
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
334 CHAPTER 22 embOSView: Profiling and analyzing
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
335
Chapter 23
This chapter covers the performance and resource usage of embOS. It explains how
to benchmark embOS and contains information about the memory requirements in
typical systems which can be used to obtain sufficient estimates for most target sys-
tems.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
336 CHAPTER 23 Performance and resource usage
23.1 Introduction
High performance combined with low resource usage has always been a major design
consideration. embOS runs on 8/16/32-bit CPUs. Depending on which features are
being used, even single-chip systems with less than 2 Kbytes ROM and 1 Kbyte RAM
can be supported by embOS. The actual performance and resource usage depends on
many factors (CPU, compiler, memory model, optimization, configuration, etc.).
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
337
* These values are typical values for a 32 bit cpu and depends on CPU, compiler, and
library model used.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
338 CHAPTER 23 Performance and resource usage
23.3 Performance
The following section shows how to benchmark embOS with the supplied example
programs.
23.4 Benchmarking
embOS is designed to perform fast context switches. This section describes two dif-
ferent methods to calculate the execution time of a context switch from a task with
lower priority to a task with a higher priority.
The first method uses port pins and requires an oscilloscope. The second method
uses the high-resolution measurement functions. Example programs for both meth-
ods are supplied in the \Sample directory of your embOS shipment.
Segger uses these programs to benchmark the embOS performance. You can use
these examples to evaluate the benchmark results. Note, that the actual perfor-
mance depends on many factors (CPU, clock speed, toolchain, memory model, opti-
mization, configuration, etc.).
Please be aware that the amount of cycles are not equal to the amount of instruc-
tions. Many instructions on ARM7 need two or three cycles even at zero waitstates,
e.g. LDR needs 3 cycles.
The following table gives an overview about the variations of the context switch time
depending on the memory type and the CPU mode:
All named example performance values in the following section are determined with
the following system configuration:
All sources are compiled with IAR Embedded Workbench version 5.40 using thumb or
arm mode, XR library and high optimization level. embOS version 3.82 has been
used; values may differ for different builds.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
339
#include "RTOS.h"
#include "LED.h"
/*********************************************************************
*
* HPTask
*/
static void HPTask(void) {
while (1) {
OS_Suspend(NULL); // Suspend high priority task
LED_ClrLED0(); // Stop measurement
}
}
/*********************************************************************
*
* LPTask
*/
static void LPTask(void) {
while (1) {
OS_Delay(100); // Synchronize to tick to avoid jitter
//
// Display measurement overhead
//
LED_SetLED0();
LED_ClrLED0();
//
// Perform measurement
//
LED_SetLED0(); // Start measurement
OS_Resume(&TCBHP); // Resume high priority task to force task switch
}
}
/*********************************************************************
*
* main
*/
int main(void) {
OS_IncDI(); // Initially disable interrupts
OS_InitKern(); // Initialize OS
OS_InitHW(); // Initialize Hardware for OS
LED_Init(); // Initialize LED ports
OS_CREATETASK(&TCBHP, "HP Task", HPTask, 100, StackHP);
OS_CREATETASK(&TCBLP, "LP Task", LPTask, 99, StackLP);
OS_Start(); // Start multitasking
return 0;
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
340 CHAPTER 23 Performance and resource usage
A B C D
tAB tCD
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
341
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
342 CHAPTER 23 Performance and resource usage
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
343
#include "RTOS.h"
#include "stdio.h"
/*********************************************************************
*
* HPTask
*/
static void HPTask(void) {
while (1) {
OS_Suspend(NULL); // Suspend high priority task
OS_Timing_End(&_Time); // Stop measurement
}
}
/*********************************************************************
*
* LPTask
*/
static void LPTask(void) {
char acBuffer[100]; // Output buffer
OS_U32 MeasureOverhead; // Time for Measure Overhead
OS_U32 v;
//
// Measure Overhead for time measurement so we can take
// this into account by subtracting it
//
OS_Timing_Start(&MeasureOverhead);
OS_Timing_End(&MeasureOverhead);
//
// Perform measurements in endless loop
//
while (1) {
OS_Delay(100); // Sync. to tick to avoid jitter
OS_Timing_Start(&_Time); // Start measurement
OS_Resume(&TCBHP); // Resume high priority task to force task switch
v = OS_Timing_GetCycles(&_Time) - OS_Timing_GetCycles(&MeasureOverhead);
v = OS_ConvertCycles2us(1000 * v); // Convert cycles to nano-seconds
sprintf(acBuffer, "Context switch time: %u.%.3u usec\r", v / 1000, v % 1000);
OS_SendString(acBuffer);
}
}
The example program calculates and subtracts the measurement overhead itself, so
there is no need to do this. The results will be transmitted to embOSView, so the
example runs on every target that supports UART communication to embOSView.
The example program MeasureCST_HRTimer_Printf.c is equal to the example pro-
gram MeasureCST_HRTimer_embOSView.c but displays the results with the printf()
function for those debuggers which support terminal output emulation.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
344 CHAPTER 23 Performance and resource usage
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
345
Chapter 24
Debugging
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
346 CHAPTER 24 Debugging
This routine is shipped as source code as part of the module OS_Error.c. It simply
disables further task switches and then, after re-enabling interrupts, loops forever as
follows:
Example
/*
Run time error reaction
*/
void OS_Error(int ErrCode) {
OS_EnterRegion(); /* Avoid further task switches */
OS_DICnt =0; /* Allow interrupts so we can communicate */
OS_EI();
OS_Status = ErrCode;
while (OS_Status);
}
If you are using embOSView, you can see the value and meaning of OS_Status in the
system variable window.
When using an emulator, you should set a breakpoint at the beginning of this routine
or simply stop the program after a failure. The error code is passed to the function as
parameter.
You can modify the routine to accommodate your own hardware; this could mean
that your target hardware sets an error-indicating LED or shows a little message on
the display.
Note: When modifying the OS_Error() routine, the first statement needs
to be the disabling of scheduler via OS_EnterRegion(); the last statement
needs to be the infinite loop.
If you look at the OS_Error() routine, you will see that it is more complicated than
necessary. The actual error code is assigned to the global variable OS_Status. The
program then waits for this variable to be reset. Simply reset this variable to 0 using
your in circuit-emulator, and you can easily step back to the program sequence caus-
ing the problem. Most of the time, looking at this part of the program will make the
problem clear.
24.1.1 OS_DEBUG_LEVEL
The define OS_DEBUG_LEVEL defines the embOS debug level. The default value is 1.
With higher debug level more debug code is included. The debug level 2 checks if
OS_RegionCnt overflows.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
347
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
348 CHAPTER 24 Debugging
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
349
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
350 CHAPTER 24 Debugging
The latest version of the defined error table is part of the comment just before the
OS_Error() function declaration in the source file OS_Error.c.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
351
void UserAppFunc(void) {
int r;
r = DoSomething()
if (r == 0) {
OS_Error(OS_ERR_APPL)
}
}
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
352 CHAPTER 24 Debugging
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
353
Chapter 25
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
354 CHAPTER 25 Supported development tools
25.1 Overview
embOS has been developed with and for a specific C compiler version for the selected
target processor. Check the file RELEASE.HTML for details. It works with the specified
C compiler only, because other compilers may use different calling conventions
(incompatible object file formats) and therefore might be incompatible. However, if
you prefer to use a different C compiler, contact us and we will do our best to satisfy
your needs in the shortest possible time.
Reentrance
All routines that can be used from different tasks at the same time have to be fully
reentrant. A routine is in use from the moment it is called until it returns or the task
that has called it is terminated.
All routines supplied with your real-time operating system are fully reentrant. If for
some reason you need to have non-reentrant routines in your program that can be
used from more than one task, it is recommended to use a resource semaphore to
avoid this kind of problem.
C routines and reentrance
Normally, the C compiler generates code that is fully reentrant. However, the com-
piler may have options that force it to generate non-reentrant code. It is recom-
mended not to use these options, although it is possible to do so under certain
circumstances.
Assembly routines and reentrance
As long as assembly functions access local variables and parameters only, they are
fully reentrant. Everything else has to be thought about carefully.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
355
Chapter 26
Limitations
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
356 CHAPTER 26 Limitations
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
357
Chapter 27
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
358 CHAPTER 27 Source code of kernel and library
27.1 Introduction
embOS is available in two versions:
1. Object version: Object code + hardware initialization source.
2. Full source version: Complete source code.
Because this document describes the object version, the internal data structures are
not explained in detail. The object version offers the full functionality of embOS
including all supported memory models of the compiler, the debug libraries as
described and the source code for idle task and hardware initialization. However, the
object version does not allow source-level debugging of the library routines and the
kernel.
The full source version gives you the ultimate options: embOS can be recompiled for
different data sizes; different compile options give you full control of the generated
code, making it possible to optimize the system for versatility or minimum memory
requirements. You can debug the entire system and even modify it for new memory
models or other CPUs.
The source code distribution of embOS contains the following additional files:
• The CPU folder contains all CPU and compiler specific source code and header
files used for building the embOS libraries. It also contains the sample start
project, workspace, and source files for the embOS demo project delivered in the
Start folder. Normally, you should not modify any of the files in the CPU folder.
• The GenOSSrc folder contains all embOS sources and a batch file used for compil-
ing all of them in batch mode as described in the following section.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
359
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
360 CHAPTER 27 Source code of kernel and library
27.3.1 OS_RR_SUPPORTED
This switch defines whether round robin scheduling algorithm is supported. All
embOS versions enable round robin scheduling by default. If you never use round
robin scheduling and all of your tasks run on different individual priorities, you may
disable round robin scheduling by defining this switch to 0. This will save RAM and
ROM and will also speed up the task-switching process. Ensure that none of your
tasks ever run on the same priority when you disable round robin scheduling. This
compile time switch must not be modified in RTOS.h. It has to be modified in
OS_RAW.h before embOS libraries are rebuilt.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
361
Chapter 28
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
362 CHAPTER 28 FAQ (frequently asked questions)
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
363
Chapter 29
Support
This chapter should help if any problem occurs. This could be a problem with the tool
chain, with the hardware or the use of the embOS functions and it describes how to
contact the embOS support.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
364 CHAPTER 29 Support
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
365
Chapter 30
Glossary
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
366 CHAPTER 30 Glossary
Cooperative multi- A scheduling system in which each task is allowed to run until
tasking it gives up the CPU; an ISR can make a higher priority task
ready, but the interrupted task will be returned to and finished
first.
Mailbox A data buffer managed by the RTOS, used for sending mes-
sages to a task or interrupt handler.
Preemptive multi- A scheduling system in which the highest priority task that is
tasking ready will always be executed. If an ISR makes a higher prior-
ity task ready, that task will be executed before the inter-
rupted task is returned to.
Process Processes are tasks with their own memory layout. 2 pro-
cesses can not normally access the same memory locations.
Different processes typically have different access rights and
(in case of MMUs) different translation tables.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
367
Queue Like a mailbox, but used for sending larger messages, or mes-
sages of individual size, to a task or an interrupt handler.
Running task Only one task can execute at any given time. The task that is
currently executing is called the running task.
Scheduler The program section of an RTOS that selects the active task,
based on which tasks are ready to run, their relative priorities,
and the scheduling system being used.
Thread Threads are tasks which share the same memory layout. 2
threads can access the same memory locations. If virtual
memory is used, the same virtual to physical translation and
access rights are used
(-> Thread, Process)
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
368 CHAPTER 30 Glossary
Timeslice The time (number of ticks) for which a task will be executed
until a round-robin task change may occur.
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
369
Index
B Interrupts ..................................235–255
Baudrate for embOSView .................... 296 enabling/disabling ............................248
interrupt handler .............................242
ISR ..................................................235
C
C startup ............................................37
Compiler .......................................... 354 L
Configuration defines ......................... 295 Libraries, building ..............................359
Configuration, of embOS .......281, 291–299 Limitations, of embOS ........................355
Counting Semaphores ........................ 121
Critical regions ......................30, 257–261 M
Mailboxes ............................. 33, 135–154
D basics ............................................137
Debug version, of embOS .....................38 single-byte .....................................139
Debugging ................................. 345–350 Measurement ....................................265
error codes ..............................347, 351 high-resolution ................................269
runtime errors ................................ 346 low-resolution .................................265
Development tools ............................. 353 Memory management
fixed block size ................................203
heap memory ..................................199
E Memory pools .............................203–217
embOS Multitasking systems ........................... 27
building libraries of .......................... 359 cooperative multitasking .................... 29
different builds of ..............................38 preemptives multitasking ................... 28
features of .......................................21
embOS features ..................................21
embOS profiling ..................................38 N
embOSView ............................... 305–333 Nesting interrupts ..............................252
API trace ........................................ 313 Non-maskable interrupts .....................255
overview ........................................ 306
SIO ............................................... 309 O
system variables window .................. 308 OS_AddOnTerminateHook .................... 48
task list window .............................. 307 OS_BAUDRATE ..................................295
trace filter setup functions ................ 315 OS_CallISR() .....................................244
trace record functions ...................... 325 OS_CallNestableISR() .........................245
Error codes ................................347, 351 OS_ClearEvents() ..............................183
Events ................... 33, 173–183, 185–198 OS_ClearMB() ...................................152
OS_COM_Init() ..................................293
I OS_COM_Send1() ..............................293
Internal data-structures ...................... 280 OS_ConvertCycles2us() ......................293
Interrupt control macros ..................... 251 OS_CREATECSEMA() ..........................124
Interrupt level .....................................25 OS_CreateCSema() ............................125
Interrupt service routines ..............25, 235 OS_CREATEMB() ................................141
OS_CREATERSEMA() ..........................111
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
370 Index
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
Index 371
P
Preemptive multitasking .......................28
Priority ...............................................30
Priority inheritance ...............................31
priority inversion .................................31
Profiling ..............................................38
Q
Queues ................................33, 155–169
R
Reentrance ....................................... 354
Release version, of embOS ....................38
Resource semaphores ........................ 107
Round-robin ........................................30
RTOSInit.c configuration ..................... 292
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
372 Index
UM01001 User & Reference Guide for embOS © 1995- 2013 SEGGER Microcontroller GmbH & Co. KG
1.XX.01 EMBOS SOL ASIA 1.XX.02 EMBOS ADDITIONAL 1.XX.04 EMBOS SSL ASIA
SEAT ASIA