MQX RTOS For Kinetis SDK User's Guide
MQX RTOS For Kinetis SDK User's Guide
Chapter 1
Before You Begin
1.1 About MQX™ RTOS..................................................................................................................................................... 15
1.3 Conventions.................................................................................................................................................................... 16
1.3.1 Tips.....................................................................................................................................................................16
1.3.2 Notes.................................................................................................................................................................. 16
1.3.3 Cautions............................................................................................................................................................. 17
Chapter 2
MQX RTOS at a Glance
2.1 Organization of MQX RTOS..........................................................................................................................................19
2.2 Initialization.................................................................................................................................................................... 21
2.4 Scheduling.......................................................................................................................................................................22
2.11 Events..............................................................................................................................................................................24
2.13 Semaphores..................................................................................................................................................................... 25
2.14 Mutexes...........................................................................................................................................................................25
2.16 Messages......................................................................................................................................................................... 26
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 3
Section number Title Page
2.20 Timers............................................................................................................................................................................. 27
2.21 Watchdogs.......................................................................................................................................................................27
2.24 Logs.................................................................................................................................................................................28
Chapter 3
Using MQX RTOS
3.1 Before You Begin........................................................................................................................................................... 31
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
4 Freescale Semiconductor, Inc.
Section number Title Page
3.4.2.1 Preemption......................................................................................................................................... 43
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 5
Section number Title Page
3.6.1 Events.................................................................................................................................................................54
3.6.3.1 Strictness............................................................................................................................................ 61
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
6 Freescale Semiconductor, Inc.
Section number Title Page
3.6.5 Semaphores........................................................................................................................................................ 68
3.6.5.8.2 Task Templates for the Task Synchronization and Mutual Exclusion Example............ 72
3.6.6 Mutexes.............................................................................................................................................................. 75
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 7
Section number Title Page
3.6.7 Messages............................................................................................................................................................ 80
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
8 Freescale Semiconductor, Inc.
Section number Title Page
3.7 Timing.............................................................................................................................................................................94
3.7.3.7.1 DATE_STRUCT.............................................................................................................98
3.7.3.7.2 TM STRUCT.................................................................................................................. 98
3.7.3.8 Timeouts.............................................................................................................................................98
3.7.4 Timers................................................................................................................................................................ 99
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 9
Section number Title Page
3.7.6 Watchdogs..........................................................................................................................................................104
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
10 Freescale Semiconductor, Inc.
Section number Title Page
3.9.1 Logs....................................................................................................................................................................118
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 11
Section number Title Page
3.10 Utilities............................................................................................................................................................................129
3.10.1 Queues................................................................................................................................................................129
Chapter 4
Rebuilding MQX RTOS
4.1 Why Rebuild MQX RTOS?............................................................................................................................................151
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
12 Freescale Semiconductor, Inc.
Section number Title Page
Chapter 5
Configuring MQX RTOS
5.1 Configuration Options.................................................................................................................................................... 157
Chapter 6
FAQs
6.1 General............................................................................................................................................................................161
6.2 Events..............................................................................................................................................................................161
6.6 Memory...........................................................................................................................................................................163
6.8 Mutexes...........................................................................................................................................................................164
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 13
Section number Title Page
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
14 Freescale Semiconductor, Inc.
Chapter 1
Before You Begin
MQX RTOS provides a run-time library of functions that programs use to become real-
time multitasking applications. The main features of MQX RTOS are scalable size,
component-oriented architecture, and ease of use.
MQX RTOS supports multiprocessor applications and can be used with flexible
embedded I/O products for networking, data communications, and file management.
Throughout this book, we use MQX RTOS as the abbreviation for Message Queue
Executive Real Time Operating System.
These paths are relevant for the MQX RTOS for Kinetis SDK (KSDK):
Table 1-2. Relative paths
<KSDK_DIR> Directory where the Kinetis SDK package is installed on your hardware.
<MQX_DIR> Directory where MQX RTOS is located within KSDK. Specifically, <KSDK_DIR>\rtos\mqx.
<board> Replaces board name (for example, TWR-K64F120M).
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 15
About This Book
1.3 Conventions
The following tips, notes, and cautions represent the conventions used in MQX RTOS
documentation.
1.3.1 Tips
Tips point out useful information.
Table 1-4. Generic Tip Format
Tip The most efficient way to allocate a message from an ISR is to use _msg_alloc().
1.3.2 Notes
Notes point out important information.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
16 Freescale Semiconductor, Inc.
Chapter 1 Before You Begin
1.3.3 Cautions
Cautions tell you about commands or procedures that could have unexpected or
undesirable side effects or could be dangerous to your files or your hardware.
Table 1-6. Generic Cautions Format
Caution If you modify MQX RTOS data types, some MQX RTOS Host Tools might not operate properly.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 17
Conventions
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
18 Freescale Semiconductor, Inc.
Chapter 2
MQX RTOS at a Glance
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 19
Organization of MQX RTOS
Core Components
A minimal image is Name
configured based only
Queues services Interrupts
on functions called by
the MQX RTOS or the
applications.
Partitions
OPTIONAL Messages
Utilities Events
Watchdogs Initialization
Task errors
Semaphores
Lightweight Core memory
Timers CORE services
semaphores
The following table summarizes core and optional components, each of which is briefly
described in subsequent sections of the chapter.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
20 Freescale Semiconductor, Inc.
Chapter 2 MQX RTOS at a Glance
2.2 Initialization
Initialization is a core component. The application starts when _mqx() runs. The function
initializes the hardware and starts MQX RTOS. When MQX RTOS starts, it creates tasks
that the application defines as autostart tasks.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 21
Scheduling
• An exit function, which MQX RTOS calls when it terminates the task.
• An exception handler, which MQX RTOS calls if an exception occurs while the task
is active.
2.4 Scheduling
Scheduling complies with POSIX.4 (real-time extensions) and supports these policies:
• FIFO (also called priority-based preemptive) scheduling is a core component - the
active task is the highest-priority task that has been ready the longest.
• Round robin (also called time slice) scheduling is a core component - the active task
is the highest-priority task that has been ready the longest without consuming its time
slice.
• Explicit scheduling (using task queues) is an optional component - you can use task
queues to explicitly schedule tasks or to create more complex synchronization
mechanisms. Because task queues provide minimal functionality, they are fast. An
application can specify a FIFO or round robin scheduling policy when it creates the
task queue.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
22 Freescale Semiconductor, Inc.
Chapter 2 MQX RTOS at a Glance
For systems, which have only a few kilobytes of RAM, it is advised to use the LWMEM
allocator. It has a lower initial RAM footprint and its linear time complexity is not a
problem if the number of free blocks in the free list cannot grow much - the RAM is
small and there is a minimum size for an allocated block. However for all other
applications, it is advised to switch to the new TLSF allocators.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 23
Controlling an MMU
2.11 Events
Events are an optional component. They support the dynamic management of objects that
are formatted as bit fields. Tasks and interrupt service routines can use events to
synchronize and convey simple information in the form of bit-state changes. There are
named and fast-event groups. Event groups can have autoclearing event bits, whereby
MQX RTOS clears the bits immediately after they are set. An application can set event
bits in an event group that is on a remote processor.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
24 Freescale Semiconductor, Inc.
Chapter 2 MQX RTOS at a Glance
2.13 Semaphores
Semaphores are an optional component. They are counting semaphores. You can use
semaphores to synchronize tasks. You can use a semaphore to guard access to a shared
resource, or to implement a producer/consumer-signalling mechanism. Semaphores
provide FIFO queuing, priority queuing, and priority inheritance. Semaphores can be
strict or non-strict. There are named and fast semaphores.
2.14 Mutexes
Mutexes are an optional component. A mutex provides mutual exclusion among tasks,
when they access a shared resource. Mutexes provide polling, FIFO queuing, priority
queuing, spin-only and limited-spin queuing, priority inheritance, and priority protection.
Mutexes are strict; that is, a task cannot unlock a mutex, unless it had first locked the
mutex.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 25
Messages
2.16 Messages
Messages are an optional component. Tasks can communicate with each other by sending
messages to message queues that are opened by other tasks. Each task opens its own
input-message queues. A message queue is uniquely identified by its queue ID, which
MQX RTOS assigns when the queue is created. Only the task that opens a message queue
can receive messages from the queue. Any task can send to any previously opened
message queue, if it knows the queue ID of the opened queue.
Tasks allocate messages from message pools. There are system-message pools and
private-message pools. Any task can allocate a message (system message) from system-
message pools. Any task with the pool ID can allocate a message (private message) from
a private-message pool.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
26 Freescale Semiconductor, Inc.
Chapter 2 MQX RTOS at a Glance
2.20 Timers
Timers are an optional component. They provide periodic execution of an application
function. MQX RTOS supports one-shot timers (they expire once) and periodic timers
(they expire repeatedly at a given interval). You can set timers to start at a specified time
or after a specified duration.
When you set a timer, you specify the notification function that timer task calls when the
timer expires. The notification function can be used to synchronize tasks by sending
messages, setting events, or using one of the other MQX RTOS synchronization
mechanisms.
2.21 Watchdogs
Watchdogs are option components that let the user detect task starvation and deadlock
conditions at the task level.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 27
Logs
2.24 Logs
Logs are an optional component that lets you store and retrieve application-specific
information. Each log entry has a timestamp and sequence number. You can use the
information to test, debug, verify, and analyze performance.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
28 Freescale Semiconductor, Inc.
Chapter 2 MQX RTOS at a Glance
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 29
Queue Manipulation
• queues (application-defined)
• semaphores and lightweight semaphores
• task queues
• timers and lightweight timers
• watchdogs
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
30 Freescale Semiconductor, Inc.
Chapter 3
Using MQX RTOS
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 31
Initializing and Starting MQX RTOS
typedef struct mqx_initialization_struct
{
_mqx_uint PROCESSOR_NUMBER;
void * START_OF_KERNEL_MEMORY;
void * END_OF_KERNEL_MEMORY;
_mqx_uint INTERRUPT_STACK_SIZE;
TASK_TEMPLATE_STRUCT_PTR TASK_TEMPLATE_LIST;
_mqx_uint MQX_HARDWARE_INTERRUPT_LEVEL_MAX;
_mqx_uint MAX_MSGPOOLS;
_mqx_uint MAX_MSGQS;
char * IO_CHANNEL;
char * IO_OPEN_MODE;
void *INTERRUPT_STACK_LOCATION;
void *START_OF_HEAP;
void *END_OF_HEAP;
} MQX_INITIALIZATION_STRUCT, * MQX_INITIALIZATION_STRUCT_PTR;
For a description of each field, see Freescale MQX™ RTOS Reference Manual.
At initialization, MQX RTOS creates one instance of each task, whose template defines it
as an autostart task. In addition, while an application is running, it can create other tasks
using a task template that either the task template list defines or the application defines
dynamically. The end of the task template list is a zero-filled task template.
typedef struct task_template_struct
{
_mqx_uint TASK_TEMPLATE_INDEX;
TASK_FPTR TASK_ADDRESS;
_mem_size TASK_STACKSIZE;
_mqx_uint TASK_PRIORITY;
char * TASK_NAME;
_mqx_uint TASK_ATTRIBUTES;
uint32_t CREATION_PARAMETER;
_mqx_uint DEFAULT_TIME_SLICE;
} TASK_TEMPLATE_STRUCT, * TASK_TEMPLATE_STRUCT_PTR;
For a description of each field, see the Freescale MQX™ RTOS Reference Manual.
When you assign task priorities in the task template list, note that:
• MQX RTOS creates one ready queue for each priority up to the lowest priority
(highest number).
• While an application is running, it cannot create a task that has a lower priority (a
higher number) than the lowest-priority task in the task template list.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 33
Initializing and Starting MQX RTOS
world_task
The world_task is an autostart task. So, at initialization, MQX RTOS creates one instance
of the task with a creation parameter of zero. The application defines the task template
index (MAIN_TASK). The task is of priority five. The function world_task() is the
code-entry point for the task. The stack size is 0x2000 single-addressable units.
hello_task
The hello_task task is a time-slice task with a time slice of 100, in milliseconds, if the
default compile-time configuration options are used. For information about these options,
see page Configuring MQX RTOS at Compile Time.
Float_task
The Float_task task is both a floating-point task and an autostart task.
#include <stdio.h>
/* Task IDs */
#define HELLO_TASK 5
extern void hello_task(uint32_t);
const TASK_TEMPLATE_STRUCT MQX_template_list[] =
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
34 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
{
/* Task Index, Function, Stack, Priority, Name, Attributes, Param, Time
Slice */
{ HELLO_TASK, hello_task, 1500, 8, "hello", MQX_AUTO_START_TASK, 0, 0 },
{ 0 }
};
void hello_task(uint32_t initial_data)
{
printf("\n Hello World \n");
_mqx_exit(0);
}
Note See Getting Started with Freescale MQX™ RTOS for Kinetis SDK (document MQXKSDKGSUG)
for more details about supported tool chains.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 35
Managing Tasks
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
36 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
higher priority than the creator, the child becomes the active task because it is the
highest-priority ready task. If the creator is of higher or equal priority, it remains the
active task. The same can be achieved by calling the create_task() function.
The function _task_create_blocked() creates a task that is blocked. The task is not ready
to run until another task calls the _task_ready() function. The same can be achieved by
calling the create_task() function by special attribute
MQX_TASK_CREATE_BLOCKED.
The function _task_create_at() creates a task with the stack location specified, i.e., task
stack is not dynamically allocated but has to be allocated before the _task_create_at()
function is issued. The same can be achieved by calling the create_task() function.
Some MQX RTOS configurations support creating tasks in the main() function manually.
The only function that enables creating this task is the the create_task() function.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 37
Managing Tasks
If an MQX RTOS function detects an error and the application ignores the error,
additional errors might still occur. Usually the first error best indicates the problem;
subsequent errors might be misleading. To provide a reliable opportunity to diagnose
problems after MQX RTOS sets the task error code to a value other than MQX_OK,
MQX RTOS does not further change the task error code until the task explicitly resets it
to MQX_OK.
A task can get its task error code from:
• _task_get_error()
• _task_errno
A task resets its task error code by calling _task_set_error() with MQX_OK. The
function returns the previous task error code and sets the task error code to MQX_OK.
Using _task_set_error(), a task can attempt to set its task error code to a value other than
MQX_OK. However, only if the current task error code is MQX_OK, does MQX RTOS
change the task error code to the new value.
If MQX_CHECK_ERRORS is set to 0 (see MQX RTOS Compile-Time Configuration
Options), then not all error codes listed for a particular function are returned.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
38 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
Note The user is responsible for destroying all lightweight objects (lightweight semaphores, lightweight events,
lightweight timers, etc.) before terminating a task as this is not done by the MQX RTOS task termination
functions!
An application can terminate a task immediately (after MQX RTOS frees the task's
resources) with _task_destroy() or gracefully with _task_abort(). While
_task_destroy() causes the task destroy to happen from the context of the caller and is
performed immediately, _task_abort() causes the victim task to be removed from any
queues it is blocked on, its PC is effectively set to the task exit handler and then the
victim task is added to the ready to run queue. Normal task scheduling and priority rules
apply, so the actual task destruction may be deferred indefinitely (or for a long time). The
implication is that there is no guarantee that the victim task is destroyed upon return from
_task_abort().
When the to-be-terminated task becomes active, an application-defined task exit handler
runs. The exit handler could clean up resources that MQX RTOS does not manage.
The task exit handler is set with _task_set_exit_handler(), and obtained with
_task_get_exit_handler().
MQX RTOS also calls the task exit handler if the task returns from its task body.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 39
Managing Tasks
If you change the priority of world_task to be of the same priority as hello_task, the
output is World Hello only. The world_task runs before hello_task, because world_task
has the same priority and does not relinquish control with a blocking function. When the
world_task becomes blocked, the hello_task becomes active.
/* hello2.c */
#include <mqx.h>
#include <stdio.h>
/* Task IDs */
#define HELLO_TASK 5
#define WORLD_TASK 6
extern void hello_task(uint32_t);
extern void world_task(uint32_t);
const TASK_TEMPLATE_STRUCT MQX_template_list[] =
{
/* Task Index, Function, Stack, Priority, Name, Attributes, Param, Time
Slice */
{ WORLD_TASK, world_task, 1000, 9, "world", MQX_AUTO_START_TASK, 0, 0 },
{ HELLO_TASK, hello_task, 1000, 8, "hello", 0, 0, 0 },
{ 0 }
};
/*TASK*-----------------------------------------------------
*
* Task Name : world_task
* Comments :
* This task creates hello_task and then prints "World".
*
*END*-----------------------------------------------------*/
void world_task(uint32_t initial_data)
{
_task_id hello_task_id;
hello_task_id = _task_create(0, HELLO_TASK, 0);
if (hello_task_id == MQX_NULL_TASK_ID) {
printf("\n Could not create hello_task\n");
} else {
printf(" World \n");
}
_task_block();
}
/*TASK*-----------------------------------------------------
*
* Task Name : hello_task
* Comments :
* This task prints "Hello".
*
*END*-----------------------------------------------------*/
void hello_task(uint32_t initial_data)
{
printf(" Hello \n");
_task_block();
}
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
40 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
World
Note See Getting Started with Freescale MQX™ RTOS for Kinetis SDK (document MQXKSDKGSUG)
for more details about supported tool chains.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 41
Scheduling Tasks
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
42 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
3.4.2.1 Preemption
The active task can be preemptied. Preemption occurs, when a higher-priority task
becomes ready, and thus becomes the active task. The previously active task is still ready,
but is no longer the active task. Preemption occurs, when an interrupt handler causes a
higher-priority task to become ready, or the active task makes a higher-priority task
ready.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 43
Managing Memory with Variable-Size Blocks
A memory block can be a private memory block (a resource owned by the task that
allocates it) or a system memory block (not owned by any task). When a task is
terminated, MQX RTOS returns the task's private memory blocks to memory.
When MQX RTOS allocates a memory block, it allocates a block of at least the requested
size (the block might be larger).
A task can transfer ownership of a memory block to another task (_mem_transfer()).
Table 3-5. Summary: Managing Memory with Variable-Size Blocks
_mem_alloc Allocates a private memory block from the default memory pool.
_mem_alloc_from Allocates a private memory block from the specified memory pool.
_mem_alloc_zero Allocates a zero-filled private memory block from the default memory
pool.
_mem_alloc_zero_from Allocates a zero-filled private memory block from the specified memory
pool.
_mem_alloc_system Allocates a system memory block from the default memory.
_mem_alloc_system_from Allocates a system memory block from the specified memory pool.
_mem_alloc_system_zero Allocates a zero-filled system memory block from the default memory
pool.
_mem_alloc_system_zero_from Allocates a zero-filled system memory block from the specified memory
pool.
_mem_alloc_align Allocates an aligned private memory block from the default memory pool.
_mem_alloc_align_from Allocates an aligned private memory block from the specified memory
pool.
_mem_alloc_system_align Allocates an aligned system memory block from the default memory pool.
_mem_alloc_system_align_from Allocates an aligned system memory block from the specified memory
pool.
_mem_alloc_at Allocates a private memory block at the defined start address.
_mem_copy Copies data from one memory location to another.
_mem_create_pool Creates a memory pool outside the default memory pool.
_mem_extend Adds additional memory to the default memory pool; the additional
memory must by outside the current default memory pool, but need not
be contiguous with it.
_mem_extend_pool Adds additional memory to a memory pool that is outside the default
memory pool; the additional memory must be outside the memory pool,
but it needs not to be contiguous with the pool.
_mem_free Frees a memory block that is inside or outside the default memory pool.
_mem_free_part Frees part of a memory block (used if the memory block is larger than
requested, or if it is larger than needed).
_mem_get_error Gets a pointer to the memory block that caused _mem_test() to indicate
an error.
_mem_get_error_pool Gets a pointer to the last memory block that caused _mem_test_pool()
to indicate an error.
_mem_get_highwater Gets the highest memory address that has been allocated in the default
memory pool (it might have since been freed).
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
44 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 45
Managing Memory with Variable-Size Blocks
Table 3-6. Summary: Managing Lightweight Memory with Variable-Size Blocks (continued)
_lwmem_alloc_system_zero_from Allocates a zero-filled system memory block from the
specified lightweight-memory pool.
_lwmem_alloc_align Allocates an aligned private lightweight-memory block from
the default lightweight-memory pool.
_lwmem_alloc_align_from Allocates an aligned private lightweight-memory block from
the specified lightweight-memory pool.
_lwmem_alloc_system_align Allocates an aligned system lightweight-memory block from
the default lightweight-memory pool.
_lwmem_alloc_system_align_from Allocates an aligned system lightweight memory block from
the specified lightweight memory pool.
_lwmem_alloc_at Allocates a private lightweight-memory block at the defined
start address.
_lwmem_create_pool Creates a lightweight-memory pool.
_lwmem_free Frees a lightweight-memory block.
_lwmem_get_size Gets the size of a lightweight-memory block; the size might
be larger than the requested size.
_lwmem_set_default_pool Sets the pool to be used for the default lightweight-memory
pool.
_lwmem_test Tests all lightweight memory pools.
_lwmem_transfer Transfers ownership of a lightweight-memory block to
another task.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
46 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
If you create a static partition, you must ensure that the memory does not overlap code or
data space that your application uses.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 47
Managing Memory with Variable-Size Blocks
memory
core
memory static partition
data
code
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
48 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
Table 3-9. Summary: Managing Memory with Fixed-Sixe Blocks (Partitions) (continued)
_partition_get_total_blocks Gets the number of partition blocks in a partition.
_partition_get_total_size Gets the size of a partition, including extensions.
_partition_test Tests the partition component.
_partition_transfer Transfers ownership of a partition block to another task (including the
system); only the new owner can free the partition block.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 49
Managing Memory with Variable-Size Blocks
Note The flushing and invalidating functions always operate with whole cache lines. In case the data entity is not
aligned to the cache line size, these operations affect data that precedes and follows data area currently being
flushed/invalidated.
The MQX RTOS memory allocators align data entity to the cache line size by default. Once an entity is declared
statically the alignment to the cache line size is not guaranteed (unless align pragma is used).
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
50 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
virtual address
physical addr
With the virtual memory component, an application can manage virtual memory, which
maps to physical addresses.
An application can use the virtual memory component to create a virtual context for a
task. Virtual context provides memory that is private to a task, and is visible only while
the task is the active task.
The functions are called when the BSP is initialized.
Table 3-12. Summary: Managing Virtual Memory
_mmu_add_vcontext Adds a memory region to a virtual context.
_mmu_add_vregion Adds a memory region to the MMU page tables that all tasks and MQX
RTOS can use.
_mmu_create_vcontext Creates a virtual context for a task.
_mmu_create_vtask Creates a task with an initialized virtual context.
_mmu_destroy_vcontext Destroys a virtual context for a task.
_mmu_get_vmem_attributes Gets the virtual memory attributes of an MMU page.
_mmu_get_vpage_size Gets the size of an MMU page.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 51
Managing Memory with Variable-Size Blocks
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
52 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
result = _mmu_create_vcontext(MQX_NULL_TASK_ID);
if (result != MQX_OK) {
}
result = _mmu_add_vcontext(MQX_NULL_TASK_ID,
virtual_mem_ptr, size, 0);
if (result != MQX_OK) {
}
...
• Message passing - lets tasks transfer data between themselves. A task fills a message
with data and sends it to a particular message queue. Another task waits for messages
to arrive at the message queue (receives messages).
• Lightweight Message Queue - simpler implementation of Messages.
• Task queues - let an application suspend and resume tasks.
3.6.1 Events
Events can be used to synchronize a task with another task or with an ISR.
The event component consists of event groups, which are groupings of event bits. The
number of event bits in an event group is the number of bits in _mqx_uint.
Any task can wait for event bits in an event group. If the event bits are not set, the task
blocks. Any other task or ISR can set the event bits. When the event bits are set, MQX
RTOS puts all waiting tasks, whose waiting condition is met, into the task's ready queue.
If the event group has autoclearing event bits, MQX RTOS clears the event bits as soon
as they are set, and makes one task ready.
Note To optimize code and data memory requirements on some target platforms, the event component
is not compiled in the MQX RTOS kernel by default. To test this feature, you need to enable it
first in the MQX RTOS user configuration file, and recompile the MQX RTOS PSP, BSP, and
other core components. See Rebuilding Freescale MQX RTOS for more details.
There can be named event groups, which are identified by a unique string name, and fast
event groups, which are identified by a unique number.
An application can open an event group on a remote processor by specifying the
processor number in the string that it uses to open the event group. After opening the
remote-processor event group, an application can set any event bit in the event group. An
application cannot wait for event bits in a remote event group.
Table 3-13. Summary: Using the Event Component
Event1 Description
_event_clear Clears the specified event bits in an event group.
_event_close Closes a connection to an event group.
_event_create Creates a named event group.
_event_create_auto_clear Creates a named event group with autoclearing event bits.
_event_create_component Creates the event component.
_event_create_fast Creates a fast event group.
_event_create_fast_auto_clear Creates a fast event group with autoclearing event bits.
_event_destroy Destroys a named event group.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
54 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
1. Events use certain structures and constants, which are defined in event.h.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 55
Synchronizing Tasks
If an event group is created with autoclearing event bits, MQX RTOS clears the bits as
soon as they are set. This action makes ready any tasks that are waiting for the bits,
without the tasks having to clear the bits.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
56 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
#include <stdio.h>
#include <event.h>
/* Task IDs */
#define SERVICE_TASK 5
#define ISR_TASK 6
/* Function Prototypes */
extern void simulated_ISR_task(uint32_t);
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 57
Synchronizing Tasks
extern void service_task(uint32_t);
const TASK_TEMPLATE_STRUCT MQX_template_list[] =
{
/* Task Index, Function, Stack,Prio, Name, Attributes, Param,
TS */
{ SERVICE_TASK, service_task, 2000, 8, "service", MQX_AUTO_START_TASK, 0, 0},
{ ISR_TASK, simulated_ISR_task, 2000, 8, "simulated_ISR", 0, 0, 0},
{ 0 }
};
/*TASK*-----------------------------------------------------
*
* Task Name : simulated_ISR_task
* Comments :
* This task opens a connection to the event. After
*END*-----------------------------------------------------*/
void * event_ptr;
_task_block();
while (TRUE) {
_time_delay(200);
_task_block();
}
}
}
/*TASK*-----------------------------------------------------
*
* Task Name : service_task
* Comments :
* This task creates an event and the simulated_ISR_task
* task. It opens a connection to the event and waits.
* After all bits have been set "Tick" is printed and
* the event is cleared.
*END*-----------------------------------------------------*/
void service_task(uint32_t initial_data)
{
void * event_ptr;
_task_id second_task_id;
/* setup event */
if (_event_create("global") != MQX_OK) {
printf("\nMake event failed");
_mqx_exit(0);
}
if (_event_open("global", &event_ptr) != MQX_OK) {
printf("\nOpen event failed");
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
58 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
_task_block();
}
/* create task */
second_task_id = _task_create(0, ISR_TASK, 0);
if (second_task_id == MQX_NULL_TASK_ID) {
printf("Could not create simulated_ISR_task \n");
_task_block();
}
while (TRUE) {
if (_event_wait_all(event_ptr, 0x01, 0) != MQX_OK) {
printf("\nEvent Wait failed");
_task_block();
}
if (_event_clear(event_ptr, 0x01) != MQX_OK) {
printf("\nEvent Clear Failed");
_task_block();
}
printf(" Tick \n");
}
}
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 59
Synchronizing Tasks
Lightweight event groups are created from static-data structures and are not multi-
processor.
Table 3-17. Summary: Using the Lightweight Event Component
Event1 Description
_lwevent_clear Clears the specified event bits in a lightweight event group.
_lwevent_create Creates a lightweight event group, indicating whether it has autoclearing event bits.
_lwevent_destroy Destroys a lightweight event group.
_lwevent_set Sets the specified event bits in a lightweight event group.
_lwevent_test Tests the lightweight event component.
_lwevent_wait_for Waits for all or any of the specified event bits in a lightweight event group for a
specified tick-time period.
_lwevent_wait_ticks Waits for all or any of the specified event bits in a lightweight event group for a
specified number of ticks.
_lwevent_wait_until Waits for all or any of the specified event bits in a lightweight event group until a
specified tick time.
1. Lightweight events use certain structures and constants, which are defined in lwevent.h.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
60 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
3.6.3.1 Strictness
If a semaphore-type object is strict, a task must first wait for and get the object, before it
can release the object. If the object is non-strict, a task does not need to get the object
before it releases the object.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 61
Synchronizing Tasks
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
62 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 63
Synchronizing Tasks
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
64 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 65
Synchronizing Tasks
LWSEM_STRUCT WRITE_SEM;
uchar DATA;
} SW_FIFO, _PTR_ SW_FIFO_PTR;
/* Function prototypes */
extern void write_task(uint32_t initial_data);
extern void read_task(uint32_t initial_data);
extern SW_FIFO fifo;
_task_block();
}
fifo.DATA = (uchar)initial_data;
_lwsem_post(&fifo.READ_SEM);
}
}
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
66 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
* on the read_sem and finally outputs the
* "data" variable.
*END*--------------------------------------------------------*/
void read_task(uint32_t initial_data)
{
_task_id task_id;
_mqx_uint result;
_mqx_uint i;
/* Create the lightweight semaphores */
result = _lwsem_create(&fifo.READ_SEM, 0);
if (result != MQX_OK) {
printf("\nCreating read_sem failed: 0x%X", result);
_task_block();
}
result = _lwsem_create(&fifo.WRITE_SEM, 1);
if (result != MQX_OK) {
printf("\nCreating write_sem failed: 0x%X", result);
_task_block();
}
/* Create write tasks */
for (i = 0; i < NUM_WRITERS; i++) {
task_id = _task_create(0, WRITE_TASK, (uint32_t)('A' + i));
printf("\nwrite_task created, id 0x%lX", task_id);
}
while (TRUE) {
result = _lwsem_wait(&fifo.READ_SEM);
if (result != MQX_OK) {
printf("\n_lwsem_wait failed: 0x%X", result);
_task_block();
}
putchar('\n');
putchar(fifo.DATA);
_lwsem_post(&fifo.WRITE_SEM);
}
}
<MQX_DIR>
mqx\examples\lwsem
2. See the Getting Started with Freescale MQX™ RTOS for Kinetis SDK (document
MQXKSDKGSUG) for instructions on how to build and run the application.
The following appears on the output device:
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 67
Synchronizing Tasks
...
Note See Getting Started with Freescale MQX™ RTOS for Kinetis SDK (document MQXKSDKGSUG)
for more details about supported tool chains.
3.6.5 Semaphores
Semaphores can be used for task synchronization and mutual exclusion. The main
operations that a task performs on a semaphore, are to wait for the semaphore and to post
the semaphore.
Note To optimize code and data memory requirements on some target platforms, the Semaphore
component is not compiled in the MQX RTOS kernel by default. To test this feature, you need to
enable it first in the MQX RTOS user configuration file and recompile the MQX RTOS PSP, BSP,
and other core components. See Rebuilding Freescale MQX RTOS for more details.
1. Semaphores use certain structures and constants, which are defined in sem.h.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
68 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
70 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
As well, the task can specify, whether to force destruction. If destruction is forced, MQX
RTOS readies tasks that are waiting for the semaphore, and destroys the semaphore after
all the tasks that have the semaphore post the semaphore.
If destruction is not forced, MQX RTOS destroys the semaphore after the last waiting
task gets and posts the semaphore. (This is always the action if the semaphore is strict).
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 71
Synchronizing Tasks
** Contains a DATA array that simulates a FIFO. READ_INDEX
** and WRITE_INDEX mark the location in the array that the read
** and write tasks are accessing. All data is protected by
** semaphores.
*/
typedef struct
{
_task_id DATA[ARRAY_SIZE];
uint32_t READ_INDEX;
uint32_t WRITE_INDEX;
} SW_FIFO, * SW_FIFO_PTR;
/* Function prototypes */
extern void main_task(uint32_t initial_data);
extern void write_task(uint32_t initial_data);
extern void read_task(uint32_t initial_data);
extern SW_FIFO fifo;
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
72 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
_block_task();
}
if (_sem_create("write", ARRAY_SIZE, 0) != MQX_OK) {
printf("\nCreating write semaphore failed");
_block_task();
}
if (_sem_create("read", 0, 0) != MQX_OK) {
printf("\nCreating read semaphore failed");
_block_task();
}
if (_sem_create("index", 1, 0) != MQX_OK) {
printf("\nCreating index semaphore failed");
_block_task();
}
/* Create tasks: */
for (i = 0; i < NUM_WRITERS; i++) {
task_id = _task_create(0, WRITE_TASK, i);
printf("\nwrite_task created, id 0x%lx", task_id);
}
task_id = _task_create(0, READ_TASK, 0);
printf("\nread_task created, id 0x%lx", task_id);
}
_task_block();
}
if (_sem_open("index", &index_sem) != MQX_OK) {
printf("\nOpening index semaphore failed");
_task_block();
}
if (_sem_open("read", &read_sem) != MQX_OK) {
printf("\nOpening read semaphore failed");
_task_block();
}
while (TRUE) {
/* Wait for the semaphores: */
if (_sem_wait(read_sem, 0) != MQX_OK) {
printf("\nWaiting for read semaphore failed");
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 73
Synchronizing Tasks
_task_block();
}
if (_sem_wait(index_sem, 0) != MQX_OK) {
printf("\nWaiting for index semaphore failed");
_task_block();
}
printf("\n 0x%lx", fifo.DATA[fifo.READ_INDEX++]);
if (fifo.READ_INDEX >=ARRAY_SIZE) {
fifo.READ_INDEX = 0;
}
/* Post the semaphores: */
_sem_post(index_sem);
_sem_post(write_sem);
}
}
_task_block();
}
if (_sem_open("index", &index_sem) != MQX_OK) {
printf("\nOpening index semaphore failed");
_task_block();
}
if (_sem_open("read", &read_sem) != MQX_OK) {
printf("\nOpening read semaphore failed");
_task_block();
}
while (TRUE) {
/* Wait for the semaphores: */
if (_sem_wait(write_sem, 0) != MQX_OK) {
printf("\nWaiting for write semaphore failed");
_task_block();
}
if (_sem_wait(index_sem, 0) != MQX_OK) {
printf("\nWaiting for index semaphore failed");
_task_block();
}
fifo.DATA[fifo.WRITE_INDEX++] = _task_get_id();
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
74 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
if (fifo.WRITE_INDEX >=ARRAY_SIZE) {
fifo.WRITE_INDEX = 0;
}
/* Post the semaphores: */
_sem_post(index_sem);
_sem_post(read_sem);
}
}
3.6.6 Mutexes
Mutexes are used for mutual exclusion, so that only one task at a time uses a shared
resource such as data or a device. To access the shared resource, a task locks the mutex
associated with the resource. The task owns the mutex, until it unlocks the mutex.
Note To optimize code and data memory requirements on some target platforms, the Mutex
component is not compiled in the MQX RTOS kernel by default. To test this feature, you need to
enable it first in the MQX RTOS user configuration file, and recompile the MQX RTOS PSP, BSP,
and other core components. See Rebuilding Freescale MQX RTOS for more details.
Mutexes provide priority inheritance and priority protection to prevent priority inversion.
Table 3-27. Summary: Using Mutexes
Mutex1 Description
_mutex_create_component Creates the mutex component.
_mutex_destroy Destroys a mutex.
_mutex_get_priority_ceiling Gets the priority of a mutex.
_mutex_get_wait_count Gets the number of tasks that are waiting for a mutex.
_mutex_init Initializes a mutex.
_mutex_lock Locks a mutex.
_mutex_set_priority_ceiling Sets the priority of a mutex.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 75
Synchronizing Tasks
1. Mutexes use certain structures and constants, which are defined in mutex.h.
Spin-only protocol functions properly, only if the tasks that share the mutex are either:
• time-slice tasks
• the same priority
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
76 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 77
Synchronizing Tasks
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
78 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
_task_block();
}
_task_block();
}
/* Create the print tasks */
_task_create(0, PRINT_TASK, (uint32_t)string1);
_task_create(0, PRINT_TASK, (uint32_t)string2);
}
/*TASK*--------------------------------------------------------
*
* Task Name : print_task
* Comments : This task prints a message. It uses a mutex to
* ensure I/O is not interleaved.
*END*--------------------------------------------------------*/
void print_task(uint32_t initial_data)
{
while(TRUE) {
if (_mutex_lock(&print_mutex) != MQX_OK) {
printf("Mutex lock failed.\n");
_task_block();
}
puts((char *) initial_data);
_mutex_unlock(&print_mutex);
}
}
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 79
Synchronizing Tasks
3.6.7 Messages
Tasks can communicate with each other by exchanging messages. Tasks allocate
messages from message pools. Tasks send messages to message queues, and receive
messages from message queues. Messages can be assigned a priority or marked urgent.
Tasks can send broadcast messages.
Note To optimize code and data memory requirements on some target platforms, the Message
component is not compiled in the MQX RTOS kernel by default. To test this feature, you need to
enable it first in the MQX RTOS user configuration file, and recompile the MQX RTOS PSP, BSP,
and other core components. See Rebuilding Freescale MQX RTOS for more details.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
80 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 81
Synchronizing Tasks
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
82 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
uchar RESERVED[3];
#else
uchar RESERVED;
#endif
} MESSAGE_HEADER_STRUCT, * MESSAGE_HEADER_STRUCT_PTR;
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 83
Synchronizing Tasks
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
84 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 85
Synchronizing Tasks
extern void client_task(uint32_t initial_data);
extern _pool_id message_pool;
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
86 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
#include "server.h"
/*TASK*--------------------------------------------------------
*
* Task Name : client_task
* Comments This task creates a message queue and allocates
a message in the message pool. It sends the message to the
server_task and waits for a reply. It then frees the message.
*END*--------------------------------------------------------*/
void client_task(uint32_t index)
{
SERVER_MESSAGE_PTR msg_ptr;
_queue_id client_qid;
client_qid = _msgq_open((_queue_number)(CLIENT_QUEUE_BASE +
index), 0);
while (TRUE) {
/* Allocate a message: */
msg_ptr = (SERVER_MESSAGE_PTR) _msg_alloc(message_pool);
if(msg_ptr == NULL){
printf("\nCould not allocate a message\n");
_task_block();
}/* if */
msg_ptr->HEADER.SOURCE_QID = client_qid;
msg_ptr->HEADER.TARGET_QID = _msgq_get_id(0, SERVER_QUEUE);
msg_ptr->HEADER.SIZE = sizeof(MESSAGE_HEADER_STRUCT) +
strlen((char *)msg_ptr->DATA) + 1;
msg_ptr->DATA[0] = ('A'+ index);
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 87
Synchronizing Tasks
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
88 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 89
Synchronizing Tasks
while (TRUE) {
_lwmsgq_receive((void *)server_queue, msg, LWMSGQ_RECEIVE_BLOCK_ON_EMPTY, 0, 0);
printf(" %c \n", msg[0]);
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
90 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
while (TRUE) {
msg[0] = ('A'+ index);
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 91
Synchronizing Tasks
#include <stdio.h>
/* Task IDs */
#define SERVICE_TASK 5
#define ISR_TASK 6
extern void simulated_ISR_task(uint32_t);
extern void service_task(uint32_t);
const TASK_TEMPLATE_STRUCT MQX_template_list[] =
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
92 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
{
/* Task Index, Function, Stack,Prio,Name, Attributes, Param, TS
*/
{ SERVICE_TASK,service_task, 2000, 8, "service", MQX_AUTO_START_TASK,0, 0},
{ ISR_TASK, simulated_ISR_task,2000, 8, "simulated_ISR",0, 0, 0},
{ 0 }
};
void * my_task_queue;
/*TASK*-----------------------------------------------------
*
* Task Name : simulated_ISR_task
* Comments :
* This task pauses and then resumes the task queue.
*END*-----------------------------------------------------*/
void simulated_ISR_task(uint32_t initial_data)
{
while (TRUE) {
_time_delay(200);
_taskq_resume(my_task_queue, FALSE);
}
}
/*TASK*-----------------------------------------------------
*
* Task Name : service_task
* Comments :
* This task creates a task queue and the simulated_ISR_task
* task. Then it enters an infinite loop, printing "Tick" and
* suspending the task queue.
*END*-----------------------------------------------------*/
void service_task(uint32_t initial_data)
{
_task_id second_task_id;
/* Create a task queue: */
my_task_queue = _taskq_create(MQX_TASK_QUEUE_FIFO);
if (my_task_queue == NULL) {
_task_block();
}
/* Create the task: */
second_task_id = _task_create(0, ISR_TASK, 0);
if (second_task_id == MQX_NULL_TASK_ID) {
printf("\n Could not create simulated_ISR_task\n");
_task_block();
}
while (TRUE) {
printf(" Tick \n");
_taskq_suspend(my_task_queue);
}
}
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 93
Timing
3.7 Timing
MQX RTOS provides the core-time component, which can be extended with optional
timer and watchdog components.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
94 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 95
Timing
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
96 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 97
Timing
3.7.3.7.1 DATE_STRUCT
typedef struct date_struct
{
int16_t YEAR;
int16_t MONTH;
int16_t DAY;
int16_t HOUR;
int16_t MINUTE;
int16_t SECOND;
int16_t MILLISEC;
int16_t WDAY;
int16_t YDAY;
} DATE_STRUCT, * DATE_STRUCT_PTR;
3.7.3.7.2 TM STRUCT
struct tm {
int32_t tm_sec;
int32_t tm_min;
int32_t tm_hour;
int32_t tm_mday;
int32_t tm_mon;
int32_t tm_year;
int32_t tm_wday;
int32_t tm_yday;
int32_t tm_isdst;
};
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
98 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
3.7.3.8 Timeouts
A task can supply the time as a timeout parameter to several MQX RTOS components,
for example, functions in the _msgq_receive, _lwmsgq_receive, _sem_wait,
_lwsem_wait, _event_wait and _lwevent_wait families. Note, that the resolution of all
time functions is always one tick.
_time_delay(), _event_wait_all(), _event_wait_any(), _sem_wait(), msgq_receive()
and _sched_set_rr_interval() functions wait at least the specified time in milliseconds.
This time is usually bigger than the requested time, depending on the tick length, on other
scheduled events and their priorities.
_time_delay_ticks() function waits at least the requested number of tick interrupts.
_time_delay_ticks(1) waits at least to the first tick interrupt.
_time_delay(0) and _time_delay_tick(0) cause shed_yield() function calling. For ticks
higher than zero, the actual waiting time is typically shorter than ticks multiplied by tick
time in milliseconds.
A task can also explicitly suspend itself by calling a function from the _time_delay
family. When the time expires, MQX RTOS puts the task in the task's ready queue.
3.7.4 Timers
Timers are an optional component that extends the core-time component. An application
can use timers:
• To cause a notification function to run at a specific time - when MQX RTOS creates
the timer component, it starts Timer task, which maintains timers and their
application-defined notification functions. When a timer expires, Timer Task calls
the appropriate notification function.
• To communicate that a time period has expired.
Note To optimize code and data memory requirements on some target platforms, the Timer
component is not compiled in the MQX kernel by default. To test this feature, you need to enable
it first in the MQX user configuration file and recompile the MQX PSP, BSP, and other core
components. See Rebuilding Freescale MQX RTOS for more details.
A task can start a timer at a specific time or at some specific time after the current time.
Timers can use elapsed time or absolute time.
There are two types of timers:
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 99
Timing
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
100 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
• _timer_start_oneshot_at(), _timer_start_oneshot_at_ticks()
• _timer_start_periodic_at(), _timer_start_periodic_at_ticks()
• _timer_start_periodic_every(), _timer_start_periodic_every_ticks()
When a task calls one of these functions, MQX RTOS inserts a timer request into the
queue of outstanding timers. When the timer expires, the notification function runs.
Note The stack space for Timer task should include the stack space that the notification function needs.
#include <stdio.h>
#include <timer.h>
#define TIMER_TASK_PRIORITY 2
#define TIMER_STACK_SIZE 1000
#define MAIN_TASK 10
extern void main_task(uint32_t);
const TASK_TEMPLATE_STRUCT MQX_template_list[] =
{
/* Task Index, Function, Stack, Priority, Name, Attributes, Param, Time Slice
*/
{ MAIN_TASK, main_task, 2000, 8, "Main", MQX_AUTO_START_TASK, 0, 0},
{ 0 }
};
/*FUNCTION*------------------------------------------------------
*
* Function Name : LED_on
* Returned Value : none
* Comments :
* This timer function prints "ON"
*END*-----------------------------------------------------------*/
void LED_on
(
_timer_id id,
void * data_ptr,
MQX_TICK_STRUCT_PTR tick_ptr
)
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 101
Timing
{
printf("ON\n");
}
/*FUNCTION*------------------------------------------------------
*
* Function Name : LED_off
* Returned Value : none
* Comments :
* This timer function prints "OFF"
*END*-----------------------------------------------------------*/
void LED_off
(
_timer_id id,
void * data_ptr,
MQX_TICK_STRUCT_PTR tick_ptr
)
{
printf("OFF\n");
}
/*TASK*----------------------------------------------------------
*
* Task Name : main_task
* Comments :
* This task creates two timers, each of a period of 2 seconds,
* the second timer offset by 1 second from the first.
*END*-----------------------------------------------------------*/
void main_task
(
uint32_t initial_data
)
{
MQX_TICK_STRUCT ticks;
MQX_TICK_STRUCT dticks;
_timer_id on_timer;
_timer_id off_timer;
/*
** Create the timer component with more stack than the default
** in order to handle printf() requirements:
*/
_timer_create_component(TIMER_DEFAULT_TASK_PRIORITY, 1024);
_time_init_ticks(&dticks, 0);
_time_add_sec_to_ticks(&dticks, 2);
_time_get_ticks(&ticks);
_time_add_sec_to_ticks(&ticks, 1);
on_timer = _timer_start_periodic_at_ticks(LED_on, 0,
TIMER_ELAPSED_TIME_MODE, &ticks, &dticks);
_time_add_sec_to_ticks(&ticks, 1);
off_timer = _timer_start_periodic_at_ticks(LED_off, 0,
TIMER_ELAPSED_TIME_MODE, &ticks, &dticks);
_time_delay_ticks(600);
printf("\nThe task is finished!");
_timer_cancel(on_timer);
_timer_cancel(off_timer);
_task_block();
}
Note
Note Because the notification function runs in the context of the kernel timer ISR, it is subject to the same
restrictions as the ISR (see page Restrictions on ISRs).
The MQX RTOS interrupt stack size should include the stack space that the notification function needs.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 103
Timing
3.7.6 Watchdogs
Most embedded systems have a hardware watchdog timer. If the application does not
reset the timer within a certain time (perhaps because of deadlock or some other error
condition), the hardware generates a reset operation. As such, a hardware watchdog timer
monitors the entire application on a processor; it does not monitor individual tasks.
Note To optimize code and data memory requirements on some target platforms, the Watchdog
component is not compiled in the MQX RTOS kernel by default. To test this feature, you need to
enable it first in the MQX RTOS user configuration file and recompile the MQX RTOS PSP, BSP,
and other core components. See Rebuilding Freescale MQX RTOS for more details.
The MQX RTOS watchdog component provides a software watchdog for each task. If a
single task starves or runs beyond certain timing constraints, the watchdog provides a
way to detect the problem. Initially, the task starts its watchdog with a specific time
value, and if the task fails to stop or restart the watchdog before that time expires, MQX
RTOS calls a processor-unique, application-supplied expiry function that can initiate
error recovery.
Table 3-41. Summary: Using Watchdogs
Watchdogs use certain structures and constants, Watchdogs use certain structures and constants, which are defined in
which are defined in watchdog.h. watchdog.h.
_watchdog_create_component Creates the watchdog component.
_watchdog_start Starts or restarts the watchdog (time is specified in milliseconds).
_watchdog_start_ticks Starts or restarts the watchdog (time is specified in ticks).
_watchdog_stop Stops the watchdog.
_watchdog_test Tests the watchdog component.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 105
Timing
*END*-----------------------------------------------------------*/
_mqx_uint waste_time
(
_mqx_uint n
)
{
_mqx_uint i;
volatile _mqx_uint result;
result = 0;
for (i = 0; i < n; i++) {
result += 1;
}
return result*10;
}
/*TASK*----------------------------------------------------------
*
* Task Name : main_task
* Comments :
* This task creates a watchdog, then loops, performing
* work for longer and longer periods until the watchdog fires.
*END*-----------------------------------------------------------*/
void main_task
(
uint32_t initial_data
)
{
MQX_TICK_STRUCT ticks;
_mqx_uint result;
_mqx_uint n;
_time_init_ticks(&ticks, 10);
result = _watchdog_create_component(BSP_TIMER_INTERRUPT_VECTOR,
handle_watchdog_expiry);
if (result != MQX_OK) {
printf("\nError creating watchdog component");
_task_block();
}
n = 100;
while (TRUE) {
result = _watchdog_start_ticks(&ticks);
n = waste_time(n);
_watchdog_stop();
printf("\n %d", n);
}
}
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
106 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
The ISR might run with some interrupts disabled, depending on the priority of the
interrupt being serviced. Therefore, it is important that the ISR performs a minimal
number of functions. The ISR usually causes a task to become ready. It is the priority of
this task that then determines, how quickly the information gathered from the interrupting
device can be processed. The ISR can ready a task in a number of ways: through
lightweight events, events, lightweight semaphores, semaphores, messages, lightweight
message queues or task queues.
MQX RTOS provides a kernel ISR, which is written in assembly language. The kernel
ISR runs before any other ISR, and does the following:
• It saves the context of the active task.
• It switches to the interrupt stack.
• It calls the appropriate ISR.
• After the ISR has returned, it restores the context of the highest-priority ready task.
When MQX RTOS starts, it installs the default kernel ISR (_int_kernel_isr()) for all
possible interrupts.
When the ISR returns to the kernel ISR, the kernel ISR performs a task dispatch
operation if the ISR readied a task that is of higher priority, than the one that was active
at the time of the interrupt. This means that the context of the previously active task is
saved, and the higher-priority task becomes the active task.
The following diagram shows, how MQX RTOS handles interrupts.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 107
Handling Interrupts and Exceptions
device task
task
device kernel
ISR
task
device
task
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
108 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
• dequeuing a task from a task queue, which puts the task in the task's ready queue.
Task queues let you implement signaling methods that are customized for your
application (_taskq_resume()).
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 109
Handling Interrupts and Exceptions
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
110 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
• _msgq_receive family
• _mutatr_set_wait_protocol()
• _mutex_lock()
• _partition_create_component()
• _task_block()
• _task_create() and _task_create_blocked()
• _task_destroy()
• _time_delay family
• _timer_start family
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 111
Handling Interrupts and Exceptions
On Cortex®-M4® and Cortex®-A5® core based platforms, the MQX RTOS interrupt
processing is designed this way. Kinetis K family MCUs support 16 hardware interrupt
priority levels. Internally MQX RTOS maps even levels (0, 2, 4, .., 14) for MQX RTOS
applications while odd levels (1, 3, .., 15) are used internally. MQX RTOS application
interrupt levels are 0 to 7, the mapping from MQX RTOS application levels 0 to 7 to
hardware priority levels (0, 2 to 14) is implemented in the _bsp_int_init() function.
To install an MQX RTOS application defined ISR on Kinetis K, use the following code:
_int_install_isr(vector, isr_ptr, isr_data);
_bsp_int_init(vector, priority, subpriority, enable);
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
112 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
To install a kernel ISR on Kinetis K (to bypass MQX RTOS), use the following code:
_int_install_kernel_isr(Vector, isr_ptr); /* works only for vector table located in the RAM
*/
_bsp_int_init(vector, priority, subpriority, enable);
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 113
Handling Interrupts and Exceptions
ARM Cortex-A5 interrupt priority mask register (GICC_PMR – GIC register) values for
different task priorities and different values of
MQX_HARDWARE_INTERRUPT_LEVEL_MAX are shown in the following table.
Note the most significant nibble is used to set-up the priority. Refer to the ARM Generic
Interrupt Controller Architecture Specification for GICC_PMR register description.
Table 3-46. SR Register Values for Different Task Priorities and Different
Values of MQX_HARDWARE_INTERRUPT_LEVEL_MAX valid
for ARM® Cortex®-A5 core based platforms
For Freescale PowerPC® devices and ARM® Cortex®-M0+ devices, there is no support
for automatic switching of interrupt levels based on priority of running task and all
peripheral interrupts are always disabled by _int_disable regardless of
MQX_HARDWARE_INTERRUPT_LEVEL_MAX setting.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
114 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 115
Handling Interrupts and Exceptions
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
116 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
isr_ptr->TICK_COUNT++;
/* Chain to previous notifier */
(*isr_ptr->OLD_ISR)(isr_ptr->OLD_ISR_DATA);
}
/*TASK*----------------------------------------------------------
*
* Task Name : main_task
* Comments :
* This task installs a new ISR to replace the timer ISR.
* It then waits for some time, finally printing out the
* number of times the ISR ran.
*END*-----------------------------------------------------------*/
void main_task
(
uint32_t initial_data
)
{
MY_ISR_STRUCT_PTR isr_ptr;
isr_ptr = _mem_alloc_zero(sizeof(MY_ISR_STRUCT));
isr_ptr->TICK_COUNT = 0;
isr_ptr->OLD_ISR_DATA =
int_get_isr_data(BSP_TIMER_INTERRUPT_VECTOR);
isr_ptr->OLD_ISR =
int_get_isr(BSP_TIMER_INTERRUPT_VECTOR);
_int_install_isr(BSP_TIMER_INTERRUPT_VECTOR, new_tick_isr,
isr_ptr);
_time_delay_ticks(200);
printf("\nTick count = %d\n", isr_ptr->TICK_COUNT);
_mqx_exit(0);
}
3.9 Instrumentation
Instrumentation includes the following components:
• logs
• lightweight logs
• kernel log
• stack usage utilities
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 117
Instrumentation
3.9.1 Logs
Many real-time applications need to record information about significant conditions, such
as events, state transitions, or function entry and exit information. If the application
records the information as it occurs, you can analyze the sequence to determine whether
the application processed conditions correctly. If each piece of information has a
timestamp (in absolute time), you can determine, where the application spends processing
time, and therefore, which code should be optimized.
Note To optimize code and data memory requirements on some target platforms, the Log component
is not compiled in the MQX RTOS kernel by default. To test this feature, you need to enable it
first in the MQX RTOS user configuration file and recompile the MQX RTOS PSP, BSP, and
other core components. See Rebuilding Freescale MQX RTOS for more details.
With the log component, you can store data into and retrieve it from a maximum of 16
logs. Each log has a predetermined number of entries. Each entry contains a timestamp
(in absolute time), a sequence number, and application-defined data.
Table 3-50. Summary: Using Logs
Logs use certain structures and Logs use certain structures and constants, which are defined in log.h.
constants, which are defined in log.h.
_log_create Creates a log.
_log_create_component Creates the log component.
_log_destroy Destroys a log.
_log_disable Disables logging.
_log_enable Enables logging.
_log_read Reads from a log.
_log_reset Resets the contents of a log.
_log_test Tests the log component.
_log_write Writes to a log.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
118 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 119
Instrumentation
_task_block();
}
/* Create a log */
result = _log_create(MY_LOG,
10 * (sizeof(ENTRY_STRUCT)/sizeof(_mqx_uint)), 0);
if (result != MQX_OK) {
printf("Main task - _log_create failed!");
_task_block();
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
120 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
}
/* Write data into the log */
printf("Please type in 10 characters:\n");
for (i = 0; i < 10; i++) {
c = getchar();
result = _log_write(MY_LOG, 2, (_mqx_uint)c, i);
if (result != MQX_OK) {
printf("Main task - _log_write failed!");
}
}
/* Read data from the log */
printf("\nLog contains:\n");
while (_log_read(MY_LOG, LOG_READ_OLDEST_AND_DELETE, 2,
(LOG_ENTRY_STRUCT_PTR)&entry) == MQX_OK)
{
printf("Time: %ld.%03d%03d, c=%c, i=%d\n",
entry.HEADER.SECONDS,
(_mqx_uint)entry.HEADER.MILLISECONDS,
(_mqx_uint)entry.HEADER.MICROSECONDS,
(uchar)entry.C & 0xff,
entry.I);
}
/* Delete the log */
_log_destroy(MY_LOG);
_task_block();
}
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 121
Instrumentation
Note To optimize code and data memory requirements on some target platforms, the LWLog
component is not compiled in the MQX RTOS kernel by default. To test this feature, you need to
enable it first in the MQX RTOS user configuration file and recompile the MQX RTOS PSP, BSP,
and other core components. See Rebuilding Freescale MQX RTOS for more details.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
122 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
_task_block();
}
/* Create a log */
result = _lwlog_create(MY_LOG, 10, 0);
if (result != MQX_OK) {
printf("Main task: _lwlog_create failed.");
_task_block();
}
/* Write data to the log */
printf("Enter 10 characters:\n");
for (i = 0; i < 10; i++) {
c = getchar();
result = _lwlog_write(MY_LOG, (_mqx_max_type)c,
(_mqx_max_type)i, 0, 0, 0, 0, 0);
if (result != MQX_OK) {
printf("Main task: _lwlog_write failed.");
}
}
/* Read data from the log */
printf("\nLog contains:\n");
while (_lwlog_read(MY_LOG, LOG_READ_OLDEST_AND_DELETE,
&entry) == MQX_OK)
{
printf("Time: ");
#if MQX_LWLOG_TIME_STAMP_IN_TICKS
_psp_print_ticks((PSP_TICK_STRUCT_PTR)&entry.TIMESTAMP);
#else
printf("%ld.%03ld%03ld", entry.SECONDS, entry.MILLISECONDS,
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
124 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
entry.MICROSECONDS);
#endif
printf(, c=%c, I=%d\n", (uchar)entry.DATA[0] & 0xff,
(_mqx_uint)entry.DATA[1]);
}
_task_block();
}
Performance tool uses kernel log data to analyze, how an application operates and how it
uses resources. For more information, see Getting Started with Performance Tool for
Freescale MQX™ RTOS (MQXGSPERFTOOL) document.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 125
Instrumentation
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
126 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 127
Instrumentation
printf("Main task - _klog_create failed!");
_task_block();
}
/* Enable kernel log */
_klog_control(KLOG_ENABLED | KLOG_CONTEXT_ENABLED |
KLOG_INTERRUPTS_ENABLED| KLOG_SYSTEM_CLOCK_INT_ENABLED |
KLOG_FUNCTIONS_ENABLED | KLOG_TIME_FUNCTIONS |
KLOG_INTERRUPT_FUNCTIONS, TRUE);
/* Write data into kernel log */
for (i = 0; i < 10; i++) {
_time_delay_ticks(5 * i);
}
/* Disable kernel log */
_klog_control(0xFFFFFFFF, FALSE);
/* Read data from kernel log */
printf("\nKernel log contains:\n");
while (_klog_display()){
}
_task_block();
}
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
128 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
3.10 Utilities
Utilities include:
• queues
• name component
• run-time testing
• additional utilities
3.10.1 Queues
The queue component lets you manage doubly linked lists of elements.
Note To optimize code and data memory requirements on some target platforms, the Queue
component is not compiled in the MQX RTOS kernel by default. To test this feature, you need to
enable it first in the MQX RTOS user configuration file and recompile the MQX RTOS PSP, BSP,
and other core components. See Rebuilding Freescale MQX RTOS for more details.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 129
Utilities
• QUEUE_STRUCT- keeps track of the size of the queue, and pointers to the start
and end of the queue. MQX RTOS initializes the structure, when a task creates the
queue.
• QUEUE_ELEMENT_STRUCT- defines the structure of a queue element. The
structure is the header structure of an application-defined object that the task wants to
queue.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
130 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 131
Utilities
#include <stdio.h>
#include <event.h>
#include <log.h>
#include <lwevent.h>
#include <lwlog.h>
#include <lwmem.h>
#include <lwtimer.h>
#include <message.h>
#include <mutex.h>
#include <name.h>
#include <part.h>
#include <sem.h>
#include <timer.h>
#include <watchdog.h>
extern void background_test_task(uint32_t);
const TASK_TEMPLATE_STRUCT MQX_template_list[] =
{
/* Task Index,Function, Stack,Prio,Name, Attributes, Param,Time Slice */
{ 10 , background_test_task,2000, 8, "Main",MQX_AUTO_START_TASK,0, 0},
{ 0 }
};
/*TASK*----------------------------------------------------------
*
* Task Name : background_test_task
* Comments :
* This task is meant to run in the background testing for
* integrity of MQX RTOS component data structures.
*END*-----------------------------------------------------------*/
void background_test_task
(
uint32_t parameter
)
{
_partition_id partition;
_lwmem_pool_id lwmem_pool_id;
void * error_ptr;
void * error2_ptr;
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
132 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
_mqx_uint error;
_mqx_uint result;
while (TRUE) {
result = _event_test(&error_ptr);
if (result != MQX_OK){
printf("\nFailed _event_test: 0x%X.", result);
_task_block();
}
result = _log_test(&error);
if (result != MQX_OK){
printf("\nFailed _log_test: 0x%X.", result);
_task_block();
}
result = _lwevent_test(&error_ptr, &error2_ptr);
if (result != MQX_OK){
printf("\nFailed _lwevent_test: 0x%X.", result);
_task_block();
}
result = _lwlog_test(&error);
if (result != MQX_OK){
printf("\nFailed _lwlog_test: 0x%X.", result);
_task_block();
}
result = _lwsem_test(&error_ptr, &error2_ptr);
if (result != MQX_OK){
printf("\nFailed _lwsem_test: 0x%X.", result);
_task_block();
}
result = _lwmem_test(&lwmem_pool_id, &error_ptr);
if (result != MQX_OK){
printf("\nFailed _lwmem_test: 0x%X.", result);
_task_block();
}
result = _lwtimer_test(&error_ptr, &error2_ptr);
if (result != MQX_OK){
printf("\nFailed _lwtimer_test: 0x%X.", result);
_task_block();
}
result = _mem_test_all(&error_ptr);
if (result != MQX_OK){
printf("\nFailed _mem_test_all,");
printf("\nError = 0x%X, pool = 0x%X.", result,
(_mqx_uint)error_ptr);
_task_block();
}
/*
** Create the message component.
** Verify the integrity of message pools and message queues.
*/
if (_msg_create_component() != MQX_OK){
printf("\nError creating the message component.");
_task_block();
}
if (_msgpool_test(&error_ptr, &error2_ptr) != MQX_OK){
printf("\nFailed _msgpool_test.");
_task_block();
}
if (_msgq_test(&error_ptr, &error2_ptr) != MQX_OK){
printf("\nFailed _msgq_test.");
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 133
Utilities
_task_block();
}
if (_mutex_test(&error_ptr) != MQX_OK){
printf("\nFailed _mutex_test.");
_task_block();
}
if (_name_test(&error_ptr, &error2_ptr) != MQX_OK){
printf("\nFailed _name_test.");
_task_block();
}
if (_partition_test(&partition, &error_ptr, &error2_ptr)
!= MQX_OK)
{
printf("\nFailed _partition_test.");
_task_block();
}
if (_sem_test(&error_ptr) != MQX_OK){
printf("\nFailed _sem_test.");
_task_block();
}
if (_taskq_test(&error_ptr, &error2_ptr) != MQX_OK){
printf("\nFailed _takq_test.");
_task_block();
}
if (_timer_test(&error_ptr) != MQX_OK){
printf("\nFailed _timer_test.");
_task_block();
}
if (_watchdog_test(&error_ptr, &error2_ptr) != MQX_OK){
printf("\nFailed _watchlog_test.");
_task_block();
}
printf("All tests passed.");
_task_block();
}
}
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
134 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 135
User Mode Tasks and Memory Protection
First introduced in MQX RTOS 3.8 for Kinetis K60 device, the MPU and User-mode
tasks are supported through extended MQX RTOS API. When User-mode support is
enabled in the MQX RTOS configuration header file, the BSP startup code enables the
MPU and sets up read-only mode for key RAM areas. The protection covers the kernel-
owned variables, default memory allocation pool and all other data structures which are
necessary for proper operation of MQX RTOS scheduler.
The user is able to declare tasks in Task Template List as "User Tasks". Such a User Task
runs in a restricted CPU mode and all MPU protections are active. The task has no
chance to corrupt the kernel memory or affect tasks running in privileged mode. It still
can affect other User-mode tasks. In case the User task tries to violate the protection, an
exception is generated and handled as configured in the system.
The MQX RTOS API which may be used from the User tasks is limited. In general only
the lightweight synchronization objects, lightweight memory management and limited
task creation is supported for User-mode tasks.
More details about User-mode support can be found in the following sections. The
reference of all API functions can be found in the MQX RTOS Reference Manual.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
136 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 137
User Mode Tasks and Memory Protection
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
138 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
An access to variables which are not explicitly declared (default .data and .bss segments)
is determined by the MQX_DEFAULT_USER_ACCESS_RW configuration option.
When it is not defined or is defined as 0, the global variables are declared read-only for
User-mode tasks. When the configuration option is set non-zero, the read-write access is
granted to the global variables.
3.11.5 API
This section gives an overview of the API subset which is also available to User-mode
tasks. The API can be identified easily by the _usr_ prefix. Beware that the API function
prototypes are only declared when User-mode is enabled in the MQX RTOS
configuration.
Table 3-60. User Mode API Overview
USERMODE function PRIVILEGE original
_usr_lwsem_poll _lwsem_poll
_usr_lwsem_post _lwsem_post
_usr_lwsem_wait _lwsem_wait
_usr_lwsem_create _lwsem_create
_usr_lwsem_wait_for _lwsem_wait_for
_usr_lwsem_wait_ticks _lwsem_wait_ticks
_usr_lwsem_wait_until _lwsem_wait_until
_usr_lwsem_destroy _lwsem_destroy
_usr_lwevent_clear _lwevent_clear
_usr_lwevent_set _lwevent_set
_usr_lwevent_set_auto_clear _lwevent_set_auto_clear
_usr_lwevent_wait_for _lwevent_wait_for
_usr_lwevent_wait_ticks _lwevent_wait_ticks
_usr_lwevent_wait_until _lwevent_wait_until
_usr_lwevent_get_signalled _lwevent_get_signalled
_usr_lwevent_create _lwevent_create
_usr_lwevent_destroy _lwevent_destroy
_usr_task_create _task_create
_usr_task_destroy _task_destroy
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 139
Embedded Debugging
_usr_lwmem_alloc _lwmem_alloc
_usr_lwmem_alloc_from _lwmem_alloc_from
_usr_lwmem_free _lwmem_free
_usr_lwmem_create_pool _lwmem_create_pool
_mem_set_pool_access n/a
_usr_time_delay_ticks _time_delay_ticks
_usr_time_get_elapsed_ticks _time_get_elapsed_ticks
_usr_lwmsgq_init _lwmsgq_init
_usr_lwmsgq_receive _lwmsgq_receive
_usr_lwmsgq_send _lwmsgq_send
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
140 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
tasks. It also helps to examine the internal MQX RTOS data strucutres in a user-
friendly way.
MQX_CHECK_ERRORS
Default is one.
One: MQX RTOS components perform error checking on all their parameters.
Zero: MQX RTOS components do not perform parameters checking. Not all error codes
listed for a particular function are returned.
MQX_CHECK_MEMORY_ALLOCATION_ERRORS
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 141
Configuring MQX RTOS at Compile Time
Default is one.
One: MQX RTOS components check all memory allocations for errors and verify that the
allocations are successful.
MQX_CHECK_VALIDITY
Default is one.
One: MQX RTOS checks the VALID field of all structures when it accesses them.
MQX_COMPONENT_DESTRUCTION
Default is one.
One: MQX RTOS includes the functions that allow MQX RTOS components (such as
the semaphore component or event component) to be destroyed. MQX RTOS reclaims all
the resources that the component allocated.
MQX_DEFAULT_TIME_SLICE_IN_TICKS
Default is one.
One: Default time slice in the task template structure is in units of ticks.
Zero: Default time slice in the task template structure is in milliseconds.
The value also affects the time-slice field in the task template, because the value is used
to set a task's default time slice.
MQX_EXIT_ENABLED
Default is one.
One: MQX RTOS includes code to allow the application to return from the _mqx() call.
MQX_HAS_TIME_SLICE
Default is one.
One: MQX RTOS includes code to allow time-slice scheduling of tasks at the same
priority.
MQX_HAS_DYNAMIC_PRIORITIES
Default is one.
One: MQX RTOS includes code to change task priorities dynamically by
_task_set_priority() call or by priority inheritance or priority boosting.
MQX_HAS_EXCEPTION_HANDLER
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
142 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
Default is one.
One MQX RTOS includes code to handle exceptions (see psp/<psp>/int_xcpt.c) and to
set/get task exception handler routine by using the _task_set_exception_handler and
_task_get_exception_handler calls.
MQX_HAS_EXIT_HANDLER
Default is one.
One: MQX RTOS includes code to execute task exit handler before the task exits. Also
the _task_set_exit_handler and _task_get_exit_handler calls are included.
MQX_HAS_HW_TICKS
Default is one.
One: MQX RTOS includes support for hardware ticks and associated calls:
_time_get_hwticks, _time_get_hwticks_per_tick and _psp_usecs_to_ticks. Note that
hardware ticks also need to be supported by the BSP.
MQX_HAS_TASK_ENVIRONMENT
Default is one.
One: MQX RTOS includes code to set and get task environment data
pointer:_task_set_environment and _task_get_environment.
MQX_HAS_TICK
Default is one. It is recommended to leave this option enabled.
One: MQX RTOS includes support for tick time and all related functionality of delaying
tasks, waiting for synchronization objects with timeout etc.
MQX_KD_HAS_COUNTER
Default is one.
One: The MQX RTOS kernel maintains the counter value, which is automatically
increamented any time the value is queried by the _mqx_get_counter call.
MQX_TD_HAS_PARENT
Default is one.
One: The MQX RTOS task descriptors maintain the task's creator ID, which is available
through _task_get_creator call.
MQX_TD_HAS_TEMPLATE_INDEX
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 143
Configuring MQX RTOS at Compile Time
Default is one.
One: The MQX RTOS task descriptors maintain the original index value coming from
the TASK_TEMPLATE_ STRUCT array. This value is maintained for backward
compatiblity only and is not used by MQX RTOS kernel.
MQX_TD_HAS_TASK_TEMPLATE_PTR
Default is one.
One: The MQX RTOS task descriptors maintain the pointer to original
TASK_TEMPLATE_STRUCT structure used for task creation. This pointer is used by
task restart call _task_restart() and by several lookup functions like
_task_get_id_from_name().
MQX_TD_HAS_ERROR_CODE
Default is one.
One: The MQX RTOS task descriptors maintain the error code which is accessible with
_task_set_error and _task_get_error calls.
MQX_TD_HAS_STACK_LIMIT
Default is one.
One: The MQX RTOS task descriptors maintain the task limit value which is needed by
various stack overflow checking calls like _task_check_stack.
MQX_INCLUDE_FLOATING_POINT_IO
Default is zero.
One: _io_printf() and _io_scanf() include floating point I/O code.
MQX_IS_MULTI_PROCESSOR
Default is one.
One: MQX RTOS includes code to support multiprocessor MQX RTOS applications.
MQX_KERNEL_LOGGING
Default is one.
One: Certain functions in each component write to kernel log, when they are entered and
as they exit. The setting reduces performance, only if you enable logging for the
component. You can control, which component is logged with _klog_control().
MQX_LWLOG_TIME_STAMP_IN_TICKS
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
144 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
Default is one.
One: Timestamp in lightweight logs is in ticks.
Zero: Timestamp is in seconds, milliseconds, and microseconds.
MQX_MEMORY_FREE_LIST_SORTED
Default is one.
One: MQX RTOS sorts the freelist of memory blocks by address. This reduces memory
fragmentation, but increases the time MQX RTOS takes to free memory.
MQX_MONITOR_STACK
Default is one.
One: MQX RTOS initializes all task and interrupt stacks to a known value, so that MQX
RTOS components and debuggers can calculate how much stack is used. The setting
reduces performance, only when MQX RTOS creates a task.
You must set the option to one in order to make use of:
• _klog_get_interrupt_stack_usage()
• _klog_get_task_stack_usage()
• _klog_show_stack_usage()
MQX_MUTEX_HAS_POLLING
Default is one.
One: MQX RTOS includes code to support the mutex options MUTEX_SPIN_ONLY
and MUTEX_LIMITED_SPIN.
MQX_PROFILING_ENABLE
Default is zero.
One: Code to support an external profiling tool is compiled into MQX RTOS. Profiling
adds to the size of the compiled image, and MQX RTOS runs slower. You can use
profiling, only if the toolset that you are using supports profiling.
MQX_RUN_TIME_ERR_CHECK_ENABLE
Default is zero.
One: Code to support an external run-time error-checking tool is compiled into MQX
RTOS. This adds to the size of the compiled image, and MQX RTOS runs slower. You
can use run-time error checking, only if the toolset that you are using supports it.
MQX_ROM_VECTORS
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 145
Configuring MQX RTOS at Compile Time
Default is zero.
One: The interrupt vector table is not copied into RAM. The ROM-based table is set up
correctly to handle all interrupts by the default MQX RTOS interrupt dispatcher. The
application is still able to install interrupt service routine by using the _int_install_isr
call. However, the _int_install_kernel_isr call cannot be used to install the low-level
interrupt service routines directly in the vector table.
MQX_SPARSE_ISR_TABLE
Default is zero.
One: The MQX RTOS interrupt service routine table is allocated as an "array of linked
lists" instead of linear array. This option is independent on the MQX_ROM_VECTORS
as it deals with the "logical" table managed by the interrupt dispatcher in MQX RTOS.
With the sparse ISR table, only the ISRs installed by the _int_install_isr call consume
RAM memory. Interrupt latency increases as MQX RTOS needs to walk the list to find
user ISR to be invoked.
MQX_SPARSE_ISR_SHIFT
Default is 3.
When MQX_SPARSE_ISR_TABLE is defined as 1, this MQX_SPARSE_ISR_SHIFT
option determines the number of bits the vector number is shifted to get index of ISR
linked list root. For example, with 256 potential interrupt sources and with shift value of
3, it makes 256>>3=32 lists each with maximum depth of eight ISR entries. Shift value
of 8 would yield one big linked list of all ISR entries.
MQX_TASK_CREATION_BLOCKS
Default is one. The option applies to multiprocessor applications only.
One: A task blocks, when it calls _task_create() to create a task on another processor.
The creating task blocks, until the new task is created and an error code is returned.
MQX_TASK_DESTRUCTION
Default is one.
One: MQX RTOS allows tasks to be terminated. As a result, MQX RTOS includes code
that frees all the MQX RTOS-managed resources that terminated tasks own.
MQX_TIMER_USES_TICKS_ONLY
Default is zero.
One: Timer task processes periodic-timer and one-shot timer requests using tick time for
timeout reporting, rather than second/millisecond time.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
146 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
MQX_USE_32BIT_MESSAGE_QIDS
Default is zero.
Zero: Message-component data types (_queue_number and _queue_id) are uint16_t.
One: Message-component data types (_queue_number and _queue_id) are uint32_t.
This allows for more than 256 message queues on a processor and more than 256
processors in a multiprocessor network.
MQX_USE_IDLE_TASK
Default is one.
One: the kernel creates the idle task which executes when no other tasks are ready,
otherwise, the processor stops when there are no tasks to run.
MQX_USE_INLINE_MACROS
Default is one.
One: Some internal functions that MQX RTOS calls are changed from function calls to
in-line code. The setting optimizes MQX RTOS for speed.
Zero: MQX RTOS is optimized for code size.
MQX_USE_LWMEM_ALLOCATOR
Default is zero.
One: Calls to the _mem family of functions are replaced with calls to the corresponding
function in the _lwmem family.
MQXCFG_ENABLE_FP
Default value depends on the MQXCFG_MEM_COPY_NEON. If
MQXCFG_MEM_COPY_NEON is set, default value is 1. Otherwise, default value is
0.
If it is set, enables FPU support in MQX RTOS. Scheduler stores and restores the FPU
context and provides API for float point support in tasks and interrupts.
MQX_SAVE_FP_ALWAYS
Default value depends on the MQXCFG_MEM_COPY_NEON. If
MQXCFG_MEM_COPY_NEON is set, default value is 1. Otherwise, default value is
0.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 147
Configuring MQX RTOS at Compile Time
MQXCFG_MEM_COPY_NEON
Default value is 0.
If it is set, MQX RTOS uses special memory copy implementation with NEON
instructions. This feature requires FPU to be supported in MQX RTOS. The options
MQXCFG_ENABLE_FP, MQX_SAVE_FP_ALWAYS are set to 1.
The following table shows common settings you can use as you develop your application.
Table 3-61. Compile-time Configuration Setting
Option Default Debug Speed Size
MQX_ALLOW_TYPED_MEMORY 1 1 0 0,1
MQX_CHECK_ERRORS 1 1 0 0
MQX_CHECK_MEMORY_ALLOCATION_ ERRORS 1 1 0 0
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
148 Freescale Semiconductor, Inc.
Chapter 3 Using MQX RTOS
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 149
Configuring MQX RTOS at Compile Time
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
150 Freescale Semiconductor, Inc.
Chapter 4
Rebuilding MQX RTOS
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 151
Freescale MQX RTOS Directory Structure
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
152 Freescale Semiconductor, Inc.
Chapter 4 Rebuilding MQX RTOS
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 153
Freescale MQX RTOS Build Projects
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
154 Freescale Semiconductor, Inc.
Chapter 4 Rebuilding MQX RTOS
PSP project does not contain any board-specific code. Despite this, both projects refer to
the board name in their file names, and both also generate the binary output file into the
same board-specific directory lib\<board>.<compiler>.
The board-independent PSP library is also compiled to board-specific output directory
because the compile-time configuration file is taken from board-specific directory config
\<board>. In other words, even if the PSP source code itself does not depend on the
board features, the user may want to build a different PSP for different boards.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 155
Rebuilding Freescale MQX RTOS
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
156 Freescale Semiconductor, Inc.
Chapter 5
Configuring MQX RTOS
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 157
MQX RTOS Lite creating tasks methodology
• TLSF (experimental)
• (no allocators) - defined when MQX_USE_ALLOCATOR is set to 0.
MQX RTOS must be started correctly when implementing its own main() function. This
is a code example to create the, so-called, "autostart" task taskA:
};
int main(void)
_mqx_init();
create_task(taskA);
_mqx_start();
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
158 Freescale Semiconductor, Inc.
Chapter 5 Configuring MQX RTOS
TASK_TEMPLATE_STRUCT ttl[1] = {
};
int main(void)
_mqx();
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 159
BSP layer removal
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
160 Freescale Semiconductor, Inc.
Chapter 6
FAQs
6.1 General
My application stopped. How do I tell if MQX RTOS is still running?
If the time is being updated, MQX RTOS is processing the periodic timer interrupt. If
Idle task is running, MQX RTOS is running.
6.2 Events
Two tasks use an event group. The connection works for one task, but not for the
other. Why?
The tasks are probably sharing the same global connection, rather than having their own
local, individual connection. Each task should call _event_open() or _event_open_fast()
to get its own connection.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 161
Interrupts
If Idle task blocks, System task, which is really a system task descriptor that has no code,
becomes the active task. System task descriptor sets up the interrupt stack, then re-
enables interrupts. As a result, the application can continue to run.
6.5 Interrupts
An interrupt comes at periodic intervals that my application must respond to very
quickly - quicker than MQX RTOS allows. What can I do?
Call _int_install_kernel_isr() to replace the kernel ISR (_int_kernel_isr()). Your
replacement ISR must:
• Save all registers on entry, and restore them on exit.
• It must not call any MQX RTOS functions.
• Pass information to other tasks (if required) by an application-implemented
mechanism (usually ring buffers with head and tail pointers and total size fields).
My application consists of several tasks that should run only when a certain signal
comes in by an interrupt. How can my ISR that handles the interrupt communicate
to the appropriate tasks?
If the target hardware allows it, set the priority of the interrupt to be higher than what
MQX RTOS uses, when it disables interrupts (see the
MQX_HARDWARE_INTERRUPT_LEVEL_MAX field in the
MQX_INITIALIZATION_STRUCT). If you do so, the interrupt is able to interrupt an
MQX RTOS-critical section. For example, on an ARCtangent processor, MQX RTOS
can be configured to never disable level-2 interrupts and to use only level-1 interrupts to
disable/enable in critical sections.
If the target hardware does not allow you to set the priority of the interrupt as described
in the preceding paragraph, use the event component to send a signal from the ISR to
several tasks. The tasks open connections to an event group, and one of the tasks gives
the ISR the connection. Each task calls _event_wait_any() or _event_wait_all() and
blocks. The ISR calls _event_set() to unblock the tasks.
When I save, and then restore an ISR for a specific interrupt, how do I get the value
of the data pointer that was associated with the original ISR?
Call _int_get_isr_data() before you install the temporary ISR. This function returns a
pointer to the data of the specific vector that you pass to it.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
162 Freescale Semiconductor, Inc.
Chapter 6 FAQs
6.6 Memory
How does a task transfer a memory block that it does not own?
Although the task that owns the memory is the one that usually transfers it, a non-owner
can do so with _mem_transfer().
My task allocates a 10-byte memory block, but it always gets more. Why?
When MQX RTOS allocates a memory block, it aligns the block to the appropriate
memory boundary and associates an internal header with the block. It also enforces a
minimum size.
Can a task allocate a memory block for another task?
No. Tasks allocate their own memory. However, a task can subsequently transfer the
memory to another task.
If _partition_test() detects a problem, does it try to repair the problem?
No. This indicates that memory is corrupted. Debug the application to determine the
cause.
When I extend the default memory pool, must the additional memory be contiguous
with the existing end of the pool?
No. The additional memory can be anywhere.
What does _mem_get_highwater() return, if I extend the default-memory pool with
non-contiguous memory?
The highwater mark is the highest memory location, from which MQX RTOS has
allocated a memory block.
I have tasks on several processors that need to share memory. How can I provide
mutual exclusion to the memory?
Depending on your hardware, you might be able to use a spin mutex to protect the shared
memory. Spin mutexes call _mem_test_and_set(), which is multiprocessor safe, when
the hardware supports locking shared memory.
Create one task that uses the names database to associate each message queue number
with a name. Each task then gets the queue number by specifying the name.
Can I send messages between a PC and my target hardware?
Yes. Create a program to run on your PC that sends and receives data packets to/from the
application either serially, over PCI, or over ethernet. As long as the packets are
formatted correctly, MQX RTOS passes on any that it receives.
My task successfully calls _msgq_send() several times with a newly allocated
message each time. Eventually _msgq_send() fails.
You have probably run out of messages. Each time you allocate a new message to send,
check whether the return is NULL. If it is, the receiving task is probably not freeing the
messages, or is not getting an opportunity to run.
6.8 Mutexes
What happens, when the task that owns a mutex data structure is destroyed? Do
tasks that are waiting to lock the mutex wait forever?
No. All components have cleanup functions. When a task is terminated, the cleanup
function determines what resources the task is using and frees them. If a task has a mutex
locked, MQX RTOS unlocks the mutex when it terminates the task. A task should not
own the mutex structure memory; it should create the structure as a global variable or
allocate it from a system memory block.
6.9 Semaphores
What happens if I "force destroy" a strict semaphore?
If the force destroy flag is set when you destroy a strict semaphore, MQX RTOS does not
destroy the semaphore, until all the waiting tasks get and post the semaphore. (If the
semaphore is non-strict, MQX RTOS immediately readies all the tasks that are waiting
for the semaphore.)
Two tasks use a semaphore. The connection works for one task, but not for the
other. Why?
The tasks are probably sharing the same global connection, rather than having their own
local, individual connection. Each task should call _sem_open() or _sem_open_fast() to
get its own connection.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
164 Freescale Semiconductor, Inc.
Chapter 6 FAQs
6.12 Tasks
Do I always need at least one autostart task?
Yes. In an application, at least one autostart application task is required in order to start
the application. If no application task is created on a processor, Idle task runs.
One autostart task creates all my other tasks and initializes global memory. Can I
terminate it without affecting the child tasks?
Yes. When MQX RTOS terminates the creator, it frees the creator's resources (memory,
partitions, queues, and so on) and stack space. The resources of the child tasks are
independent of the creator and are not affected.
Does the creator task own its child task?
No. The only relationship between the two is that the child can get the task ID of its
creator. The child has its own stack space and automatic variables.
What are tasks, and how are they created?
Tasks share the same code space, if they execute the same root function. A task always
starts executing at the entry point of the root function even if the function is its creator's
root function. This is not the same behavior as fork() in UNIX.
Can I move a created task to another processor?
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 165
Time Slices
No.
6.14 Timers
My application is on more than one processor. I have a master processor that sends
a synchronization message to the other processors that causes them to reset their
time. How can I make sure that the reset messages don't interfere with the timers
that the application uses?
So that timers are not affected by changes to absolute time (_time_set()), start timers
with relative time (TIMER_ELAPSED_TIME), rather than absolute time
(TIMER_KERNEL_TIME_MODE).
What happens if _timer_start_oneshot_at() is given an expiry time that is in the
past?
MQX RTOS puts the element in the timer queue. When the next periodic timer interrupt
occurs, MQX RTOS determines that the current time is greater than, or equal to the
expiry time, so the timer triggers and MQX RTOS calls the notification function.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
166 Freescale Semiconductor, Inc.
Appendix A
Revision History
The following table contains a history of changes made to this block guide.
To provide the most up-to-date information, the revision of our documents on
freescale.com are the most current. Your printed copy may be an earlier revision. To
verify you have the latest information available, see www.freescale.com/mqx.
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
Freescale Semiconductor, Inc. 167
Freescale MQX™ RTOS for Kinetis SDK User's Guide, Rev. 2, 04/2015
168 Freescale Semiconductor, Inc.
How to Reach Us: Information in this document is provided solely to enable system and
Home Page: software implementers to use Freescale products. There are no express
freescale.com or implied copyright licenses granted hereunder to design or fabricate
Web Support: any integrated circuits based on the information in this document.
freescale.com/support
Freescale reserves the right to make changes without further notice to
any products herein. Freescale makes no warranty, representation, or
guarantee regarding the suitability of its products for any particular
purpose, nor does Freescale assume any liability arising out of the
application or use of any product or circuit, and specifically disclaims
any and all liability, including without limitation consequential or
incidental damages. “Typical” parameters that may be provided in
Freescale data sheets and/or specifications can and do vary in different
applications, and actual performance may vary over time. All operating
parameters, including “typicals,” must be validated for each customer
application by customer's technical experts. Freescale does not convey
any license under its patent rights nor the rights of others. Freescale
sells products pursuant to standard terms and conditions of sale, which
can be found at the following address: freescale.com/
SalesTermsandConditions.