W 5.0
VDK (Kernel) User’s Guide(including the ADSP-BFxxx, ADSP-21xxx, ADSP-TSxxx)

Revision 3.5, January 2011
Part Number
82-000420-07

Analog Devices, Inc.
One Technology Way
Norwood, Mass. 02062-9106aCopyright Information© 2011 Analog Devices, Inc., ALL RIGHTS RESERVED. This document may not be reproduced in any form without prior, express writtenconsent from Analog Devices, Inc.
Printed in the USA.

Disclaimer
Analog Devices, Inc. reserves the right to change this product without
prior notice. Information furnished by Analog Devices is believed to beaccurate and reliable. However, no responsibility is assumed by Analog
Devices for its use; nor for any infringement of patents or other rights ofthird parties which may result from its use. No license is granted by implication or otherwise under the patent rights of Analog Devices, Inc.

Trademark and Service Mark Notice
The Analog Devices logo, Blackfin, EZ-KIT Lite, SHARC, TigerSHARC,
and VisualDSP++ are registered trademarks of Analog Devices, Inc.
All other brand and product names are trademarks or service marks of
their respective owners.

CONTENTS

PREFACE
Purpose of This Manual ................................................................ xix
Intended Audience ......................................................................... xix
Manual Contents ............................................................................ xx
What’s New in This Manual ............................................................ xx
Technical or Customer Support ..................................................... xxii
Supported Processors ................................................................... xxiii
Product Information ................................................................... xxiii
Analog Devices Web Site ....................................................... xxiii
VisualDSP++ Online Documentation .................................... xxiv
Technical Library CD .............................................................. xxv
EngineerZone .......................................................................... xxv
Social Networking Web Sites .................................................. xxvi
Notation Conventions .................................................................. xxvi

INTRODUCTION TO VDK
Rapid Application Development .............................................. 1-2
Debugged Control Structures .................................................. 1-2
Code Reuse ............................................................................. 1-3

VisualDSP++ 5.0 Kernel (VDK) User’s Guideiii

Contents

Hardware Abstraction ............................................................. 1-4
Partitioning an Application ........................................................... 1-4
Scheduling ................................................................................... 1-5
Priorities ................................................................................. 1-6
Preemption ............................................................................. 1-7
Protected Regions ......................................................................... 1-7
Disabling Scheduling .............................................................. 1-8
Disabling Interrupts ................................................................ 1-8
Thread and Hardware Interaction ................................................. 1-9
Thread Domain With Software Scheduling ............................ 1-10
Interrupt Domain With Hardware Scheduling ....................... 1-10
Device Drivers ...................................................................... 1-10

CONFIGURATION AND DEBUGGING OF VDKPROJECTS
Configuring VDK Projects ............................................................ 2-1
Linker Description File ........................................................... 2-2
Thread-Safe Libraries .............................................................. 2-2
Header Files for the VDK API ................................................. 2-2
Debugging VDK Projects .............................................................. 2-2
Instrumented Build Information .............................................. 2-3
VDK State History Window .................................................... 2-3
Target Load Graph Window .................................................... 2-4
VDK Status Window .............................................................. 2-4
General Debugging Tips ......................................................... 2-5

iv

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Contents

KernelPanic ............................................................................. 2-5

USING VDK
Threads ........................................................................................ 3-2
Thread Types .......................................................................... 3-3
Thread Parameters .............................................................. 3-3
Stack Size ........................................................................ 3-3
Priority ........................................................................... 3-4
Required Thread Functionality ............................................ 3-4
Run Function ................................................................. 3-4
Error Function ................................................................ 3-5
Create Function .............................................................. 3-5
InitFunction/Constructor ................................................ 3-6
Destructor ...................................................................... 3-6
Writing Threads in Different Languages .............................. 3-7
C++ Threads ................................................................... 3-7
C and Assembly Threads ................................................. 3-8
Thread Parameterization ..................................................... 3-8
CreateThreadEx2() ............................................................. 3-9
User-Defined Thread Stacks .............................................. 3-10
Global Variables ................................................................ 3-11
Error Handling Facilities ................................................... 3-11
Scheduling ................................................................................. 3-12
Ready Queue ......................................................................... 3-12
Scheduling Methodologies ..................................................... 3-13

VisualDSP++ 5.0 Kernel (VDK) User’s Guidev

Contents

Cooperative Scheduling .................................................... 3-14
Round-Robin Scheduling ................................................. 3-14
Preemptive Scheduling ...................................................... 3-14
Disabling Scheduling ............................................................ 3-15
Entering the Scheduler From API Calls .................................. 3-16
Entering the Scheduler From Interrupts ................................. 3-16
Idle Thread ........................................................................... 3-18
Signals ........................................................................................ 3-18
Semaphores ........................................................................... 3-19
Behavior of Semaphores .................................................... 3-19
Thread’s Interaction With Semaphores .............................. 3-20
Pending on a Semaphore ............................................... 3-21
Posting a Semaphore ..................................................... 3-22
Periodic Semaphores ..................................................... 3-25
Mutexes ................................................................................ 3-26
Behavior of Mutexes ......................................................... 3-26
Thread Interaction With Mutexes ..................................... 3-27
Acquiring a Mutex ........................................................ 3-28
Releasing a Mutex ......................................................... 3-28
Messages ............................................................................... 3-32
Behavior of Messages ........................................................ 3-32
Thread’s Interaction With Messages .................................. 3-34
Pending on a Message ................................................... 3-34
Posting a Message ......................................................... 3-35

viVisualDSP++ 5.0 Kernel (VDK) User’s Guide

Contents

Multiprocessor Messaging ...................................................... 3-37
Routing Threads (RThreads) ............................................. 3-38
Data Transfer (Payload Marshalling) .................................. 3-43
Device Drivers for Messaging ............................................ 3-46
Routing Topology ............................................................. 3-47
Events and Event Bits ............................................................ 3-48
Behavior of Events ............................................................ 3-48
Global State of Event Bits .............................................. 3-49
Event Calculation .......................................................... 3-49
Effect of Unscheduled Regions on Event Calculation ..... 3-51
Thread’s Interaction With Events ...................................... 3-51
Pending on an Event ..................................................... 3-52
Setting or Clearing of Event Bits .................................... 3-53
Loading New Event Data into an Event ......................... 3-55
Device Flags .......................................................................... 3-55
Behavior of Device Flags ................................................... 3-55
Thread’s Interaction With Device Flags ............................. 3-56
Interrupt Service Routines ........................................................... 3-56
Enabling and Disabling Interrupts ......................................... 3-56
Interrupt Architecture ............................................................ 3-57
Assembly Interrupts .......................................................... 3-57
C/C++ Interrupts .............................................................. 3-58
Vector Table ...................................................................... 3-58
Global Data ...................................................................... 3-59

VisualDSP++ 5.0 Kernel (VDK) User’s Guidevii

Contents

Communication With Thread Domain ............................. 3-59
Timer ISR ............................................................................. 3-61
Reschedule ISR ..................................................................... 3-62
I/O Interface .............................................................................. 3-62
I/O Templates ....................................................................... 3-62
Device Drivers ...................................................................... 3-63
Execution ......................................................................... 3-63
Parallel Scheduling Domains ............................................. 3-64
Using Device Drivers ........................................................ 3-66
Dispatch Function ........................................................ 3-68
Device Driver Parameterization ..................................... 3-76
Device Flags ..................................................................... 3-76
Pending on a Device Flag .............................................. 3-76
Posting a Device Flag .................................................... 3-78
General Notes .................................................................. 3-79
Variables ....................................................................... 3-79
Critical/Unscheduled Regions ....................................... 3-79
Memory Pools ............................................................................ 3-80
Memory Pool Functionality ................................................... 3-80
Multiple Heaps ........................................................................... 3-81
Thread Local Storage .................................................................. 3-82
Custom VDK History Logging ................................................... 3-83
Replacing History Logging Mechanism .................................. 3-83
UserHistoryLog() .................................................................. 3-85

viiiVisualDSP++ 5.0 Kernel (VDK) User’s Guide

Contents

VDK File Attributes .................................................................... 3-86

VDK DATA TYPES
Data Type Summary ..................................................................... 4-1
Data Type Descriptions ................................................................. 4-3
Bitfield .................................................................................... 4-3
DeviceDescriptor ..................................................................... 4-4
DeviceFlagID .......................................................................... 4-5
DeviceInfoBlock ...................................................................... 4-6
DispatchID ............................................................................. 4-7
DispatchUnion ........................................................................ 4-8
DSP_Family .......................................................................... 4-10
DSP_Product ........................................................................ 4-11
EventBitID ............................................................................ 4-17
EventID ................................................................................ 4-18
EventData ............................................................................. 4-19
HeapID ................................................................................. 4-20
HistoryEnum ........................................................................ 4-21
HistoryEvent ......................................................................... 4-25
IMASKStruct ........................................................................ 4-28
IOID .................................................................................... 4-29
IOTemplateID ...................................................................... 4-30
MarshallingCode ................................................................... 4-31
MarshallingEntry .................................................................. 4-33
MessageDetails ...................................................................... 4-34

VisualDSP++ 5.0 Kernel (VDK) User’s Guideix

Contents

MessageID ............................................................................ 4-35
MsgChannel ......................................................................... 4-36
MsgWireFormat .................................................................... 4-38
MutexID .............................................................................. 4-40
PanicCode ............................................................................ 4-41
PayloadDetails ...................................................................... 4-44
PFMarshaller ........................................................................ 4-45
PoolID ................................................................................. 4-47
Priority ................................................................................. 4-48
RoutingDirection .................................................................. 4-49
SemaphoreID ........................................................................ 4-50
SystemError .......................................................................... 4-51
TCBBitfield .......................................................................... 4-57
ThreadCreationBlock ............................................................ 4-58
ThreadID ............................................................................. 4-61
ThreadStatus ......................................................................... 4-62
ThreadType .......................................................................... 4-63
Ticks .................................................................................... 4-64
VersionStruct ........................................................................ 4-65

VDK API REFERENCE
Calling Library Functions ............................................................. 5-2
Linking Library Functions ............................................................ 5-2
Working With VDK Library Header ............................................. 5-2
Passing Function Parameters ......................................................... 5-3xVisualDSP++ 5.0 Kernel (VDK) User’s Guide

Contents

Library Naming Conventions ........................................................ 5-3
API Summary ............................................................................... 5-5
VDK Error Codes and Error Values ............................................. 5-11
VDK API Validity ....................................................................... 5-19
AcquireMutex() ........................................................................... 5-26
AllocateThreadSlot() ................................................................... 5-28
AllocateThreadSlotEx() ............................................................... 5-30
ClearEventBit() ........................................................................... 5-32
ClearInterruptMaskBits() ............................................................ 5-34
ClearInterruptMaskBitsEx() ........................................................ 5-35
ClearThreadError() ..................................................................... 5-37
CloseDevice() ............................................................................. 5-38
CreateDeviceFlag() ...................................................................... 5-40
CreateMessage() .......................................................................... 5-41
CreateMutex() ............................................................................ 5-43
CreatePool() ............................................................................... 5-45
CreatePoolEx() ............................................................................ 5-47
CreateSemaphore() ...................................................................... 5-49
CreateThread() ........................................................................... 5-51
CreateThreadEx() ....................................................................... 5-53
CreateThreadEx2() ..................................................................... 5-55
DestroyDeviceFlag() .................................................................... 5-58
DestroyMessage() ........................................................................ 5-59
DestroyMessageAndFreePayload() ................................................ 5-61

VisualDSP++ 5.0 Kernel (VDK) User’s Guidexi

Contents

DestroyMutex() .......................................................................... 5-63
DestroyPool() ............................................................................. 5-65
DestroySemaphore() ................................................................... 5-67
DestroyThread() ......................................................................... 5-69
DeviceIOCtl() ............................................................................ 5-71
DispatchThreadError() ............................................................... 5-73
ForwardMessage() ....................................................................... 5-75
FreeBlock() ................................................................................. 5-78
FreeDestroyedThreads() .............................................................. 5-80
FreeMessagePayload() ................................................................. 5-81
FreeThreadSlot() ........................................................................ 5-83
GetAllDeviceFlags() .................................................................... 5-85
GetAllMemoryPools() ................................................................. 5-87
GetAllMessages() ........................................................................ 5-89
GetAllSemaphores() .................................................................... 5-91
GetAllThreads() ......................................................................... 5-93
GetBlockSize() ........................................................................... 5-95
GetClockFrequency() .................................................................. 5-96
GetContextRecordSize() ............................................................. 5-97
GetCurrentHistoryEventNum() .................................................. 5-99
GetDevFlagPendingThreads() ................................................... 5-100
GetEventBitValue() ................................................................... 5-102
GetEventData() ........................................................................ 5-103
GetEventPendingThreads() ....................................................... 5-104

xii

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Contents

GetEventValue() ....................................................................... 5-106
GetHeapIndex() ........................................................................ 5-107
GetHistoryBufferSize() .............................................................. 5-108
GetHistoryEvent() .................................................................... 5-109
GetInterruptMask() .................................................................. 5-111
GetInterruptMaskEx() ............................................................... 5-113
GetLastThreadError() ............................................................... 5-115
GetLastThreadErrorValue() ....................................................... 5-116
GetMessageDetails() ................................................................. 5-117
GetMessagePayload() ................................................................ 5-119
GetMessageReceiveInfo() .......................................................... 5-121
GetMessageStatusInfo() ............................................................. 5-123
GetNumAllocatedBlocks() ......................................................... 5-125
GetNumFreeBlocks() ................................................................ 5-126
GetNumTimesRun() ................................................................. 5-127
GetPoolDetails() ....................................................................... 5-129
GetPriority() ............................................................................. 5-131
GetSemaphoreDetails() ............................................................. 5-132
GetSemaphorePendingThreads() ............................................... 5-134
GetSemaphoreValue() ............................................................... 5-136
GetSharcThreadCycleData() ...................................................... 5-138
GetThreadBlockingID() ............................................................ 5-140
GetThreadCycleData() .............................................................. 5-142
GetThreadHandle() .................................................................. 5-144

VisualDSP++ 5.0 Kernel (VDK) User’s Guidexiii

Contents

GetThreadID() ......................................................................... 5-145
GetThreadSlotValue() ............................................................... 5-146
GetThreadStackDetails() ........................................................... 5-147
GetThreadStack2Details() ......................................................... 5-149
GetThreadStackUsage() ............................................................ 5-151
GetThreadStack2Usage() .......................................................... 5-153
GetThreadStatus() .................................................................... 5-155
GetThreadTemplateName() ...................................................... 5-156
GetThreadTickData() ............................................................... 5-158
GetTickPeriod() ....................................................................... 5-160
GetUptime() ............................................................................ 5-161
GetVersion() ............................................................................. 5-162
InstallMessageControlSemaphore() ........................................... 5-163
InstrumentStack() ..................................................................... 5-165
LoadEvent() ............................................................................. 5-167
LocateAndFreeBlock() .............................................................. 5-169
LogHistoryEvent() .................................................................... 5-170
MakePeriodic() ......................................................................... 5-171
MallocBlock() ........................................................................... 5-173
MessageAvailable() .................................................................... 5-175
OpenDevice() ........................................................................... 5-177
PendDeviceFlag() ..................................................................... 5-179
PendEvent() ............................................................................. 5-181
PendMessage() .......................................................................... 5-184

xivVisualDSP++ 5.0 Kernel (VDK) User’s Guide

Contents

PendSemaphore() ...................................................................... 5-187
PopCriticalRegion() .................................................................. 5-190
PopNestedCriticalRegions() ....................................................... 5-192
PopNestedUnscheduledRegions() .............................................. 5-194
PopUnscheduledRegion() .......................................................... 5-195
PostDeviceFlag() ....................................................................... 5-197
PostMessage() ........................................................................... 5-198
PostSemaphore() ....................................................................... 5-201
PushCriticalRegion() ................................................................. 5-203
PushUnscheduledRegion() ......................................................... 5-204
ReleaseMutex() ......................................................................... 5-205
RemovePeriodic() ...................................................................... 5-207
ReplaceHistorySubroutine() ...................................................... 5-209
ResetPriority() .......................................................................... 5-211
SetClockFrequency() ................................................................. 5-213
SetEventBit() ............................................................................ 5-214
SetInterruptMaskBits() .............................................................. 5-216
SetInterruptMaskBitsEx() .......................................................... 5-218
SetMessagePayload() ................................................................. 5-220
SetPriority() .............................................................................. 5-222
SetThreadError() ...................................................................... 5-224
SetThreadSlotValue() ................................................................ 5-225
SetTickPeriod() ......................................................................... 5-226
Sleep() ...................................................................................... 5-227

VisualDSP++ 5.0 Kernel (VDK) User’s Guidexv

Contents

SyncRead() ............................................................................... 5-229
SyncWrite() .............................................................................. 5-231
Yield() ...................................................................................... 5-233
VDK_ISR_ACTIVATE_DEVICE_() ........................................ 5-237
VDK_ISR_CLEAR_EVENTBIT_() ......................................... 5-238
VDK_ISR_LOG_HISTORY_() ................................................ 5-239
VDK_ISR_POST_SEMAPHORE_() ........................................ 5-240
VDK_ISR_SET_EVENTBIT_() ............................................... 5-241
C_ISR_ActivateDevice() ........................................................... 5-242
C_ISR_ClearEventBit() ............................................................ 5-244
C_ISR_PostSemaphore() .......................................................... 5-246
C_ISR_SetEventBit() ................................................................ 5-248

PROCESSOR-SPECIFIC NOTESVDK for Blackfin Processors ......................................................... A-1
User and Supervisor Modes ..................................................... A-1
Thread, Kernel, and Interrupt Execution Levels ....................... A-2
Exceptions .............................................................................. A-3
ISR API Assembly Macros ....................................................... A-3
Interrupts ............................................................................... A-4
Timer ..................................................................................... A-5
Idle Thread ............................................................................. A-6
Blackfin Processor Memory ..................................................... A-6
Thread Stack ........................................................................... A-7
Interrupt Nesting .................................................................... A-7

xvi

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Contents

System Stack .......................................................................... A-7
Thread Stack Usage by Interrupts ........................................... A-8
Interrupt Latency ................................................................... A-9
Multiprocessor Messaging ....................................................... A-9
Stack Overflow ..................................................................... A-10
VDK for SHARC Processors ...................................................... A-11
Thread, Kernel and Interrupt Execution Levels ...................... A-12
VDK Interrupts and Run-Time Library Interrupt Dispatchers A-12
Interrupt Latency ................................................................. A-13
Interrupt Nesting ................................................................. A-14
Interrupts on ADSP-2106x Processors ................................... A-14
Interrupts on ADSP-2116x, ADSP-2126x, ADSP-213xx, and
ADSP-214xx Processors ..................................................... A-15
Timer ................................................................................... A-16
Idle Thread .......................................................................... A-16
Memory ............................................................................... A-17
Register Usage ...................................................................... A-18
40-bit Register Usage ............................................................ A-19
System Stack ........................................................................ A-20
Multiprocessor Messaging ..................................................... A-21
VDK ISR Macros ................................................................. A-22
Stack Overflow ..................................................................... A-23
VDK for TigerSHARC Processors .............................................. A-23
Thread, Kernel, and Interrupt Execution Levels ..................... A-24
Exceptions ............................................................................ A-24
VisualDSP++ 5.0 Kernel (VDK) User’s Guide

xvii

Contents

Interrupts ............................................................................. A-25
Timer ................................................................................... A-26
Idle Thread ........................................................................... A-26
Memory ................................................................................ A-26
System Stack ......................................................................... A-27
Interrupt Nesting .................................................................. A-28
Interrupt Latency .................................................................. A-28
Multiprocessor Messaging ..................................................... A-29

INDEX

xviii

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

PREFACE

Thank you for purchasing Analog Devices, Inc. development software for
Analog Devices embedded processors.

Purpose of This Manual
The VisualDSP++ 5.0 Kernel (VDK) User’s Guide contains information
about the VisualDSP++® kernel, a real-time operating system that can run
on an Analog Devices processor and is integrated into the processor via the
VisualDSP++ 5.0 development tools. VDK incorporates scheduling andresource allocation techniques tailored specially for the memory and timing constraints of embedded programming and facilitates the developmentof structured applications using frameworks of template files. VDK isdesigned for effective operations on Analog Devices processor
architectures.
This manual is designed so that users can quickly learn about the kernelinternal structure and operation.

Intended Audience
The primary audience for this manual is a programmer who is familiar
with Analog Devices processors. The manual assumes the audience has aworking knowledge of the appropriate processor architecture and instruction set. Programmers who are unfamiliar with Analog Devices processors
can use this manual, but should supplement it with other texts, such as

VisualDSP++ 5.0 Kernel (VDK) User’s Guidexix

Manual Contents

hardware reference and programming reference manuals, that describe
their target architecture.

Manual Contents
The manual contains:• Chapter 1, “Introduction to VDK”, concentrates on concepts,
motivation, and general architectural principles of the operating
system kernel.
• Chapter 2, “Configuration and Debugging of VDK Projects”, concentrates on configuration and debugging of VDK- enabled
projects.
• Chapter 3, “Using VDK”, describes how VDK implements thegeneral concepts described in Chapter 1.
• Chapter 4, “VDK Data Types”, describes the current set of predefined data types.
• Chapter 5, “VDK API Reference”, describes the current set of the
Application Programming Interface (API) library.
• Appendix A, “Processor-Specific Notes”, provides processor-specific information.

What’s New in This ManualThis revision of the VisualDSP++ 5.0 Kernel (VDK) User’s Guide documents VDK functionality that is new to VisualDSP++ 5.0, including:• Recursive mutexes• APIs to access the data displayed in the VDK Status windowxx

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Preface• File attributes to increase control over the partitioning of VDK
code and data across the available memory hierarchy• New timeout value kDoNotWait for the PendEvent(), PendMessage(), and PendSemaphore() APIs. The value allows a thread topend on a signal and not to block if the signal is unavailable
In VisualDSP++ 5.0 update 4, VDK has introduced the kSSLInitFailure
value in the SystemError data type
In VisualDSP++ 5.0 update 8, VDK has introduced the kUnhandledExceptionError field to the SystemError data type.
In VisualDSP++ 5.0 update 9, VDK has introduced theCreateThreadEx2() API as an extension to the existing CreateThreadEx().
The ThreadCreationBlock data type has a new data field passed as anargument to the new thread creation function. The new TCBBitfield enumeration provides names for different bits that can be set in a thread. In
update 9, VDK also has introduced the GetContextRecordSize() API,
which returns the size of memory required to store the thread information
during a context switch.
This revision incudes modifications and corrections based on errata
reports against the previous revision of the manual have been made.
The manual documents VisualDSP++ kernel version 5.0.00.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

xxi

Technical or Customer Support

Technical or Customer Support
You can reach Analog Devices, Inc. Customer Support in the following
ways:• Visit the Embedded Processing and DSP products Web site at
http://www.analog.com/processors/technical_support• E-mail tools questions toprocessor.tools.support@analog.com• E-mail processor questions toprocessor.support@analog.com (World wide support)
processor.europe@analog.com (Europe support)
processor.china@analog.com (China support)• Phone questions to 1-800-ANALOGD• Contact your Analog Devices, Inc. local sales office or authorized
distributor• Send questions by mail to:
Analog Devices, Inc.
One Technology Way
P.O. Box 9106
Norwood, MA 02062-9106
USA

xxii

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Preface

Supported Processors
VDK of VisualDSP++ 5.0 supports the following Analog Devices, Inc.
processors.
• Blackfin® (ADSP-BFxxx)• SHARC® (ADSP-21xxx)• TigerSHARC® (ADSP-TSxxx)
The majority of the information in this manual applies to all processors.
Information applicable to a particular target processor, or to a particular
processor family, is provided in Appendix A, “Processor-Specific Notes”
on page A-1.
For a complete list of processors supported by VisualDSP++ 5.0, refer tothe online Help.

Product Information
Product information can be obtained from the Analog Devices Web site,
VisualDSP++ online Help system, and a technical library CD.

Analog Devices Web Site
The Analog Devices Web site, www.analog.com, provides information
about a broad range of products—analog integrated circuits, amplifiers,
converters, and digital signal processors.
To access a complete technical library for each processor family, go to
http://www.analog.com/processors/technical_library. The manuals
selection opens a list of current manuals related to the product as well as alink to the previous revisions of the manuals. When locating your manual

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

xxiii

Product Information

title, note a possible errata check mark next to the title that leads to thecurrent correction report against the manual.
Also note, MyAnalog.com is a free feature of the Analog Devices Web sitethat allows customization of a Web page to display only the latest information about products you are interested in. You can choose to receive
weekly e-mail notifications containing updates to the Web pages that meetyour interests, including documentation errata against all manuals.
MyAnalog.com provides access to books, application notes, data sheets,code examples, and more.
Visit MyAnalog.com to sign up. If you are a registered user, just log on.
Your user name is your e-mail address.

VisualDSP++ Online Documentation
Online documentation comprises the VisualDSP++ Help system, softwaretools manuals, hardware tools manuals, processor manuals, Dinkum
Abridged C++ library, and FLEXnet License Tools software documentation. You can search easily across the entire VisualDSP++ documentation
set for any topic of interest.
For easy printing, supplementary Portable Documentation Format (.pdf)
files for all manuals are provided on the VisualDSP++ installation CD.
Each documentation file type is described as follows.

xxiv

File

Description.chmHelp system files and manuals in Microsoft help format.htm or.html

Dinkum Abridged C++ library and FLEXnet License Tools software documentation. Viewing and printing the .html files requires a browser, such as Internet
Explorer 6.0 (or higher).

.pdf

VisualDSP++ and processor manuals in PDF format. Viewing and printing the.pdf files requires a PDF reader, such as Adobe Acrobat Reader (4.0 or higher).

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Preface

Technical Library CD
The technical library CD contains seminar materials, product highlights, aselection guide, and documentation files of processor manuals, VisualDSP++ software manuals, and hardware tools manuals for the following
processor families: Blackfin, SHARC, TigerSHARC, ADSP-218x, and
ADSP-219x.
To order the technical library CD, go to http://www.analog.com/processors/technical_library, navigate to the manuals page for yourprocessor, click the request CD check mark, and fill out the order form.
Data sheets, which can be downloaded from the Analog Devices Web site,change rapidly, and therefore are not included on the technical library
CD. Technical manuals change periodically. Check the Web site for thelatest manual revisions and associated documentation errata.

EngineerZone
EngineerZone is a technical support forum from Analog Devices. It allows
you direct access to ADI technical support engineers. You can search
FAQs and technical information to get quick answers to your embedded
processing and DSP design questions.
Use EngineerZone to connect with other DSP developers who face similar
design challenges. You can also use this open forum to share knowledge
and collaborate with the ADI support team and your peers. Visit
http://ez.analog.com to sign up.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

xxv

Notation Conventions

Social Networking Web Sites
You can now follow Analog Devices processor development on Twitterand LinkedIn. To access:• Twitter: http://twitter.com/ADIsharc andhttp://twitter.com/blackfin• LinkedIn: Network with the LinkedIn group, Analog Devices
SHARC or Analog Devices Blackfin: http://www.linkedin.com

Notation Conventions
Text conventions used in this manual are identified and described as follows. Additional conventions, which apply only to specific chapters, may
appear throughout this document.

xxvi

ExampleDescription

Close command(File menu)

Titles in reference sections indicate the location of an item within the
VisualDSP++ environment’s menu system (for example, the Close command appears on the File menu).

{this | that}

Alternative required items in syntax descriptions appear within curly
brackets and separated by vertical bars; read the example as this or that.
One or the other is required.

[this | that]

Optional items in syntax descriptions appear within brackets and separated by vertical bars; read the example as an optional this or that.

[this,…]

Optional item lists in syntax descriptions appear within brackets delimited by commas and terminated with an ellipse; read the example as an
optional comma-separated list of this.

.SECTION

Commands, directives, keywords, and feature names are in text with letter gothic font.

filename

Non-keyword placeholders appear in text with italic style format.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Preface

ExampleLa[

Description
Note: For correct operation, ...
A Note provides supplementary information on a related topic. In the
online version of this book, the word Note appears instead of this symbol.
Caution: Incorrect device operation may result if ...
Caution: Device damage may result if ...
A Caution identifies conditions or inappropriate usage of the product that
could lead to undesirable results or product damage. In the online versionof this book, the word Caution appears instead of this symbol.
Warning: Injury to device users may result if ...
A Warning identifies conditions or inappropriate usage of the productthat could lead to conditions that are potentially hazardous for the devices
users. In the online version of this book, the word Warning appears
instead of this symbol.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

xxvii

Notation Conventions

xxviii

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

1 INTRODUCTION TO VDKThis chapter concentrates on concepts, motivation, and general architectural principles of the operating system kernel. It also provides
information on how to partition a VDK application into independent,
reusable functional units that are easy to maintain and debug.
The following sections provide information about the operating systemkernel concepts.
• “Motivation” on page 1-2• “Partitioning an Application” on page 1-4• “Scheduling” on page 1-5• “Protected Regions” on page 1-7• “Thread and Hardware Interaction” on page 1-9

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

1-1

Motivation
All applications require control code as support for the algorithms that areoften thought of as the “real” program. The algorithms require data to be
moved to and/or from peripherals, and many algorithms consist of morethan one functional block. For some systems, this control code may be as
simple as a “superloop” blindly processing data that arrives at a constantrate. However, as processors become more powerful, considerably moresophisticated control may be needed to realize the processor’s potential, toallow the processor to absorb the required functionality of previously supported chips, and to allow a single processor to do the work of many. The
following sections provide an overview of some of the benefits of using akernel on a processor.

Rapid Application Development
The tight integration between the VisualDSP++ environment and VDK
allows rapid development of applications compared to creating all of thecontrol code required by hand. The use of automatic code generation andfile templates, as well as a standard programming interface to device drivers, allows you to concentrate on the algorithms and the desired control
flow rather than on the implementation details. VDK supports the use ofC, C++, and assembly language. You are encouraged to develop code thatis highly readable and maintainable, yet retaining the option of hand optimizing if necessary.

Debugged Control Structures
Debugging a traditional DSP application can be laborious because development tools (compiler, assembler, and linker among others) are notaware of the architecture of the target application and the flow of control
that results. Debugging complex applications is much easier when instantaneous snapshots of the system state and statistical runtime data areclearly presented by the tools. To help offset the difficulties in debugging

1-2

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Introduction to VDK

software, VisualDSP++ includes three versions of the VDK libraries containing full instrumentation (including error checking), only error
checking, and neither instrumentation nor error checking.
In the instrumented mode, the kernel maintains statistical informationand logging of all significant events into a history buffer. When the execution is paused, the debugger can traverse this buffer and present agraphical trace of the program’s execution including context switches,
pending and posting of signals, changes in a thread’s status, and more.
Statistics are presented for each thread in a tabular view and show the total
amount of time the thread has executed, the number of times it has beenrun, the signal it is currently blocked on, and other data. For more information, see “Debugging VDK Projects” on page 2-2 and the online Help.

Code Reuse
Many programmers begin a new project by writing the infrastructure portions that transfers data to, from, and between algorithms. This necessarycontrol logic usually is created from scratch by each design team and infrequently reused on subsequent projects. VDK provides much of thisfunctionality in a standard, portable and reusable library. Furthermore,
the kernel and its tight integration with the VisualDSP++ environment aredesigned to promote good coding practice and organization by partitioning large applications into maintainable and comprehensible blocks. By
isolating the functionality of subsystems, the kernel helps to prevent themorass all too commonly found in systems programming.
The kernel is designed specifically to take advantage of commonality inuser applications and to encourage code reuse. Each thread of execution iscreated from a user-defined template, either at boot time or dynamicallyby another thread. Multiple threads can be created from the same template, but the state associated with each created instance of the thread
remains unique. Each thread template represents a complete encapsulation

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

1-3

Partitioning an Applicationof an algorithm that is unaware of other threads in the system unless it has
a direct dependency.

Hardware Abstraction
In addition to a structured model for algorithms, VDK provides a hardware abstraction layer. Presented programming interfaces allow you towrite most of the application in a platform independent, high-level language (C or C++). The VDK Application Programming Interface (API) is
identical for all Analog Devices processors, allowing code to be easily
ported to a different processor core.
When porting an application to a new platform, programmers must
address the two areas necessarily specific to a particular processor—Interrupt Service Routines (ISR) and device drivers. The VDK architecture
identifies a crisp boundary around these subsystems and supports the traditionally difficult development with a clear programming framework andcode generation. Both interrupts and device drivers are declared with agraphical user interface in the VisualDSP++ Integrated Debugging andDevelopment Environment (IDDE), which generates well-commented
code that can be compiled without further effort.

Partitioning an ApplicationA VDK thread is an encapsulation of an algorithm and its associated data.
When beginning a new project, use this notion of a thread to leverage thekernel architecture and to reduce the complexity of your system. Sincemany algorithms may be thought of as being composed of “subalgorithm”
building blocks, an application can be partitioned into smaller functional
units that can be individually coded and tested. These building blocks
then become reusable components in more robust and scalable systems.
You define the behavior of VDK threads by creating thread types. Types
are templates that define the behavior and data associated with all threads

1-4

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Introduction to VDKof that type. Like data types in C or C++, thread types are not useddirectly until an instance of the type is created. Many threads of the same
thread type can be created, but for each thread type, only one copy of thecode is linked into the executable code. Each thread has its own private setof variables defined for the thread type, its own stack, and its own
C runtime context.
When partitioning an application into threads, identify portions of yourdesign in which a similar algorithm is applied to multiple sets of data.
These are, in general, good candidates for thread types. When data is present in the system in sequential blocks, only one instance of the thread typeis required. If the same operation is performed on separate sets of data
simultaneously, multiple threads of the same type can coexist and bescheduled for prioritized execution (based on when the results areneeded).

Scheduling
VDK is a preemptive multitasking kernel. Each thread begins execution atits entry point. Then, it either runs to completion or performs its primaryfunction repeatedly in an infinite loop. It is the role of the scheduler topreempt execution of a thread and to resume its execution when appropri-

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

1-5

Schedulingate. Each thread is given a priority to assist the scheduler in determining
precedence of threads (see Figure 1-1).
All ISRs serviced & noscheduling state has changed
Interrupt

Executing

ISR

Push/pop
nestedinterrupts

DoneRequest or
free
resources

Highest priority
thread isthread last
executedContext Switch

All ISRs serviced &no scheduling state
has changed

Highest priority
thread haschangedResources Reallocation& Priorities Assessment

Figure 1-1. VDK State Diagram
The scheduler gives processor time to the thread with the highest prioritythat is in the ready state (see Figure 3-2 on page 3-17). A thread is in theready state when it is not waiting for any system resources it has requested.
A reference to each ready thread is stored in a structure that is internal to
the kernel and known as the ready queue. For more information, see“Scheduling” on page 3-12.

Priorities
Each thread is assigned a dynamically modifiable priority based on thedefault for its thread type declared in the IDDE’s Project window. An
application is limited to thirty priority levels. However, the number of
threads at each priority is limited, in practice, only by system memory.
Priority level one is the highest priority, and priority thirty is the lowest.

1-6

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Introduction to VDK

The system maintains an Idle thread that is set to a priority lower thanthat of the lowest user thread.
Assigning priorities is one of the most difficult tasks of designing a realtime preemptive system. Although there has been research in the area ofrigorous algorithms for assigning priorities based on deadlines (for example, rate monotonic scheduling), most systems are designed by considering
the interrupts and signals triggering the execution, while balancing thedeadlines imposed by the system’s input and output streams. For more
information, see “Thread Parameters” on page 3-3.

Preemption
A running thread continues execution unless it requests a system resource
using a kernel API. When a thread requests a signal (semaphore, event,device flag, or message) and the signal is available, the thread resumes execution. If the signal is not available, the thread is removed from the readyqueue—the thread is blocked (see Figure 3-2 on page 3-17). The kernel
does not perform a context switch as long as the running thread maintains
the highest priority in the ready queue, even if the thread frees a resourceand enables other threads to move to the ready queue at the same or lower
priority. A thread can also be interrupted. When an interrupt occurs, thekernel yields to the hardware interrupt controller. When the ISR completes, the highest priority thread resumes execution.
For more information, see “Preemptive Scheduling” on page 3-14.

Protected Regions
Frequently, system resources must be accessed atomically. The kernel provides two levels of protection for code that needs to execute sequentially—
unscheduled regions and critical regions.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

1-7

Protected Regions

Unscheduled and critical regions can be intertwined. You can enter critical regions from within unscheduled regions, or enter unscheduled regions
from within critical regions. For example, if you are in an unscheduled
region and call a function that pushes and pops a critical region, the system is still in an unscheduled region when the function returns.

Disabling Scheduling
The VDK scheduler can be disabled by entering an unscheduled region.
The ability to disable scheduling is necessary when you need to free multiple system resources without being switched out, or access global variables
that are modified by other threads without preventing interrupts frombeing serviced. While in an unscheduled region, interrupts are still
enabled and ISRs execute. However, the kernel does not perform a thread
context switch even if a higher priority thread becomes ready. Unscheduled regions are implemented using a stack style interface. This enables
you to begin and end an unscheduled region within a function without
concern for whether or not the calling code is already in an unscheduled
region.

Disabling Interrupts
On occasions, disabling the scheduler does not provide enough protection
to keep a block of thread code reentrant. A critical region disables bothscheduling and interrupts. Critical regions are necessary when a thread ismodifying global variables that may also be modified by an ISR. Similar tounscheduled regions, critical regions are implemented as a stack. Developers can enter and exit critical regions in a function without being
concerned about the critical region state of the calling code. Care should
be taken to keep critical regions as short as possible as they may increaseinterrupt latency.

1-8

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Introduction to VDKThread and Hardware Interaction
Threads should have minimal knowledge of hardware; rather, they should
use device drivers for hardware control. A thread can control and interact
with a device in a portable and hardware abstracted manner through astandard set of APIs.
The VDK Interrupt Service Routine framework encourages you to remove
specific knowledge of hardware from the algorithms encapsulated inthreads (see Figure 1-2). Interrupts relay information to threads throughsignals to device drivers or directly to threads. Using signals to connect
hardware to the algorithms allows the kernel to schedule threads based on
asynchronous events.
KernelFunction at Boot Timeinit()

Application Algorithm (Thread)APIs: OpenDevice()
CloseDevice()
SyncRead()
SyncWrite()
DeviceIOCtl()

Communication Manager
Device Driver
MyDevice::: DispatchFunction()
Dispatch IDs: kIO_Init
kIO_Activate
kIO_OpenkIO_Close
kIO_SyncRead
kIO_SyncWrite
kIO_IOCtl

Interrupt Service Routine
VDK_ISR_ACTIVATE_DEVICE_ ()MacroFigure 1-2. Device Drivers Entry Points

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

1-9

Thread and Hardware Interaction

The VDK runtime environment can be thought of as a bridge between
two domains, the thread domain and the interrupt domain. The interrupt
domain services the hardware with minimal knowledge of the algorithms,
and the thread domain is abstracted from the details of the hardware.
Device drivers and signals bridge the two domains. For more information,
see “Threads” on page 3-2.

Thread Domain With Software Scheduling
The thread domain runs under a C/C++ runtime model. The prioritized
execution is maintained by a software scheduler with full context switching. Threads should have little or no direct knowledge of the hardware;rather, threads should request resources and then wait for them to become
available. Threads are granted processor time based on their priority andrequested resources. Threads should minimize time spent in critical andunscheduled regions to avoid short-circuiting the scheduler and interrupt
controller.

Interrupt Domain With Hardware Scheduling
The interrupt domain runs outside the C/C++ runtime model. The prioritized execution is maintained by the hardware interrupt controller. ISRs
should be as small as possible. They should only do as much work as isnecessary to acknowledge asynchronous external events and to allow
peripherals to continue operations in parallel with the processor. ISRs
should only signal that more processing can occur and leave the processing
to threads. For more information, see “Interrupt Service Routines” onpage 3-56.

Device Drivers
ISRs can communicate with threads directly using signals. Alternatively,
an interrupt service routine and a thread can use a device driver to provide
more complex device-specific functionality that is abstracted from the

1-10

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Introduction to VDK

algorithm. A device driver is a single function with multiple entry conditions and domains of execution. For more information, see “Device
Drivers” on page 3-63.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

1-11

Thread and Hardware Interaction

1-12

VisualDSP++ 5.0 Kernel (VDK) User’s Guide2 CONFIGURATION AND
DEBUGGING OF VDKPROJECTSThis chapter contains information about configuration and debugging of
VDK- enabled projects.
If you are new to VisualDSP++ application development software, we recommend that you start with the VisualDSP++ 5.0 Getting Started Guide.
The information included in this chapter is split into two areas:• “Configuring VDK Projects” on page 2-1• “Debugging VDK Projects” on page 2-2

Configuring VDK Projects
VisualDSP++ is extended to manage all of the VDK components. You
start developing a VDK-based application by creating a set of source files.
The IDDE automatically generates a source code framework for each user
requested kernel object. Use the interface to supply the required information for these objects.
For specific procedures on how to set up VDK system parameters or how
to create, modify, or delete a VDK component, refer to the VisualDSP++
online Help. Following the online procedures ensures your VDK projects
build consistently and accurately with minimal project management. The
process reduces development time and allows you to concentrate on algorithm development.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

2-1

Debugging VDK Projects

Linker Description File
When a new project makes use of the kernel, a reference to a VDK-specificdefault Linker Description File (.ldf) is added to the project. This file iscopied to your project directory to allow modifications to be made to suit
your individual hardware configurations.

Thread-Safe Libraries
Just as user threads must be reentrant, special “thread-safe” versions of thestandard C and C++ libraries are included for use with VDK. The default.ldf file included in VDK projects links with these libraries. If you modify the Linker Description File, ensure that the file links with the threadsafe libraries. Your project’s .ldf file resides in the Linker Files folder andis accessible via the Project tab of the Project window in VisualDSP++.

Header Files for the VDK API
When a VDK project is created in the development environment, one of
the automatically generated files in the project directory is VDK.h. This
header file contains enumerations for every user-defined object in thedevelopment environment and all VDK API declarations. Your source
files must include VDK.h to access any VDK services.

Debugging VDK Projects
Debugging embedded software is a difficult task. To help offset the initialdifficulties present in debugging VDK-enabled projects, the kernel offers
special instrumented builds.

2-2VisualDSP++ 5.0 Kernel (VDK) User’s GuideConfiguration and Debugging of VDK Projects

Instrumented Build Information
When building a VDK project, you have an option to include instrumentation in your executable by choosing Full Instrumentation as the
instrumentation level in the Kernel tab of the Project window. An instrumented build differs from a non-instrumented build because the build
includes extra code for thread statistic logging. In addition, an instrumented build creates a circular buffer of system events. The extra logging
introduces slight overhead in thread switches and certain API calls but
helps you to trace system activities.

VDK State History Window
VDK logs user-defined events and system state changes in a circular buffer. An event is logged in the history buffer with a call to
LogHistoryEvent(). The call to LogHistoryEvent() logs four data values:
the ThreadID of the calling thread, the tick when the call happened, theenumeration, and a value that is specific to the enumeration. Enumerations less than zero are reserved for use by VDK. For more information
about the history enumeration type, see HistoryEnum.
APIs are provided to obtain the majority of the data displayed in the VDKStatus window at run time. The details of these APIs are included in
Chapter 5,“VDK API Reference” on page 5-1.
Using the history log, the IDDE displays a graph of running threads andsystem state changes in the State History window. Note that the data displayed in this window is only updated at halt. The State History window,
the Thread Status and Thread Event legends are described in detail in the
online Help.
It is possible either to replace the VDK history logging subroutines or to
add a user-supplied history logging function to the existing history logging
mechanism (see “Custom VDK History Logging” on page 3-83).

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

2-3

Debugging VDK Projects

Target Load Graph Window
Instrumented VDK builds allow you to analyze the average load of theprocessor over a period of time. The calculated load is displayed in theTarget Load graph window. Although this calculation is not precise, thegraph helps to estimate the utilization level of the processor. Note that the
information is updated at halt. For a more precise calculation refer to the
LoadMeasurement example in the VisualDSP++ installation.
The Target Load graph shows the percent of time the target spent in the
Idle thread. A load of 0% means VDK spent all of its time in the Idle
thread. A load of 100% means the target did not spend any time in the
Idle thread. Load data is processed using a moving window average. The
load percentage is calculated for every clock tick, and all the ticks are averaged. The following formula is used to calculate the percentage ofutilization for every clock tick.
Load = 1 – (# of times idle thread ran this tick) / (# of threads
run this tick)

For more information about the Target Load graph, refer to the online
Help.

VDK Status Window
Besides history and processor load information, an instrumented build
collects statistics for relevant VDK components, such as when a thread
was created, last run, the number of times run, and so on. This data is displayed in the Status window and is updated at halt.
APIs are provided to obtain the majority of the data displayed in the VDKStatus window at runtime. The details of these APIs can be found in
Chapter 5, “VDK API Reference” on page 5-1.
For more information about the VDK Status window, refer to the online
Help.

2-4

VisualDSP++ 5.0 Kernel (VDK) User’s GuideConfiguration and Debugging of VDK Projects

General Debugging Tips
Even with the data collection features built into VDK, debugging threadcode is a difficult task. Due to the fact that multiple threads in a system
are interacting asynchronously with device drivers, interrupts, and the Idle
thread, it can become difficult to track down the source of an error.
Unfortunately, one of the oldest and easiest debugging methods—inserting breakpoints—can have uncommon side effects in VDK projects. Since
multiple threads (either multiple instantiations of the same thread type or
different threads of different thread types) can execute the same function
with completely different contexts, the utilization of non-thread-aware
breakpoints is diminished. One possible workaround involves insertingsome “thread-specific” breakpoints:
if (VDK_GetThreadID() == <thread_with_error>){<some statement>;/* Insert breakpoint}*/

KernelPanicVDK calls an internal function named KernelPanic() under certain circumstances to indicate an error from which the system cannot recover. By
default, the function loops indefinitely so that users can determine that aproblem has occurred and provide information to facilitate debugging.
The KernelPanic() function disables interrupts on entry to ensure that
execution loops in the intended location. You can override KernelPanic()
in order to handle these types of errors differently; for example, you canreset the hardware when a KernelPanic occurs.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

2-5

Debugging VDK Projects

The circumstances under which KernelPanic() is called include thefollowing.
• Errors in the creation of a VDK boot item during startup• Runtime errors that are not handled by a C/C++ Thread’s error
handler• VDK internal errors
See PanicCode for a complete list of the reasons for calling KernelPanic().
To allow users to determine the cause of the “panic”, VDK sets up the following variables.
VDK::PanicCode

VDK::g_KernelPanicCode

VDK::SystemError

VDK::g_KernelPanicError

int

VDK::g_KernelPanicValue

int

VDK::g_KernelPanicPC

where:•

g_KernelPanicCode indicates the reason why VDK has raised a

KernelPanic. For more information on the possible values of thisvariable, see PanicCode.
•2-6

g_KernelPanicError indicates the cause of the error in more detail.
For example, if g_KernelPanicCode indicates a boot error,
g_KernelPanicError specifies if the boot problem is in a semaphore, device flag, and so on. For more information, see
SystemError.

VisualDSP++ 5.0 Kernel (VDK) User’s GuideConfiguration and Debugging of VDK Projects•

g_KernelPanicValue is a value whose meaning is determined by theerror enumeration. For example, if the problem is creating the bootthread with ID of 4, g_KernelPanicValue is 4. For more information about the values, refer to “VDK Error Codes and Error
Values” on page 5-11.
•

g_KernelPanicPC provides the address that produced the

KernelPanic.
It is possible to provide your own version of KernelPanic() if required.
However, VDK does not expect a program to recover once KernelPanic()
has been called.
is no support for systems that continue running after a KerL There
nelPanic has been reached, and the call should not be ignored in auser version of KernelPanic().
The function prototype for KernelPanic() is as follows.
C++ Prototype
extern “C” void KernelPanic(
VDK::PanicCode, VDK::SystemError, const int );C Prototype
void KernelPanic( VDK_PanicCode, VDK_SystemError, const int );These prototypes are defined in VDK include files; and so when VDK.h isincluded in a source file, the correct prototype is used.
In the VDK-supplied KernelPanic(), the variables g_KernelPanicCode,g_KernelPanicError, and g_KernelPanicValue are set to the parametersof the function before going into an infinite loop.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

2-7

Debugging VDK Projects

2-8

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3 USING VDKThis chapter describes how VDK implements the general concepts
described in Chapter 1, “Introduction to VDK”. For information about
the kernel library, see Chapter 5, “VDK API Reference”.
The following sections provide information about the operating systemkernel components.
• “VDK and main()” on page 3-2• “Threads” on page 3-2• “Scheduling” on page 3-12
• “Signals” on page 3-18
• “Interrupt Service Routines” on page 3-56
• “I/O Interface” on page 3-62
• “Memory Pools” on page 3-80
• “Multiple Heaps” on page 3-81
• “Thread Local Storage” on page 3-82
• “Custom VDK History Logging” on page 3-83
• “VDK File Attributes” on page 3-86

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-1

Threads

VDK and main()
Unlike other real-time operating systems, VDK defines its own internalmain() function to initialize and start VDK.
The main() definition within the VDK libraries is:
int main(void) {VDK::Initialize();
VDK::Run();}where the prototypes for the Initialize() and Run() functions are as
follows.
C++ Prototypes:
void VDK::Initialize(void);void VDK::Run(void);

C Prototypes:
void VDK_Initialize(void);void VDK_Run(void);

You can replace the VDK’s internally defined main(), provided that theuser-defined main() calls Initialize() and Run().
The
L can
be used before

ReplaceHistorySubroutine() API is the only VDK API that

VDK::Initialize(), and no APIs that can trigger a context switch should be used before VDK::Run().

Threads
When designing an application, partition the application into threads,
where each thread is responsible for a piece of the work. Each thread operates independently of the others. A thread performs its duty as if it has its
own processor but can communicate with other threads.

3-2

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDKThread Types
You do not directly define threads; instead, you define thread types. A
thread is an instance of a thread type and is similar to any other user
defined type.
You can create multiple instantiations of the same thread type. Eachinstantiation of the thread type has its own stack, state, priority, and otherlocal variables. You can distinguish between different instances of thesame thread type. See “Thread Parameterization” on page 3-8 for further
information. Each thread is individually identified by its ThreadID, a handle that can be used to reference that thread in kernel API calls. A thread
can gain access to its ThreadID by calling GetThreadID(). A ThreadID isvalid for the life of the thread—once a thread is destroyed, the ThreadID
becomes invalid.
Old ThreadIDs are eventually reused, but there is significant time between
a thread’s destruction and the ThreadID reuse—other threads have to recognize that the original thread is destroyed.
Thread Parameters
When a thread is created, the system allocates space in the heap to store adata structure that holds the thread-specific parameters. The data structure contains internal information required by the kernel and the thread
type specifications provided by the user.
Stack Size

Each thread has its own stack, which is allocated from a heap specified by
the user in the VDK Kernel tab or in the CreateThreadEx() and
CreateThreadEx2() APIs. The full C/C++ run-time model, as specified in
the corresponding VisualDSP++ 5.0 C/C++ Compiler and Library Manual,is maintained on a per thread basis. It is your responsibility to ensure thateach thread has enough room on its stack for the return addresses andpassed parameters of all function calls appropriate to the particular

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-3

Threads

run-time model, user code structure, use of libraries, and so on. Stackoverflows do not generate an exception, so an undersized stack has thepotential to cause difficulties when reproducing errors in your system.
fully instrumented builds, when a thread is destroyed either by
L Inreaching
the end of its
function or by an explicit call to
Run()

DestroyThread(), an event of type kMaxStackUsed is logged in the

VDK History window. The value of the event indicates the amountof stack used by the thread.
Priority

Each thread type specifies a default priority. Threads may change theirown (or another thread’s) priority dynamically using the SetPriority()
or ResetPriority() functions. Priorities are predefined by the kernel asan enumeration of type Priority with a value of kPriority1 being thehighest priority (or the first to be scheduled) in the system. The priority
enumeration, such as kPriority1 > kPriority2 >..., is set up. The number of priorities is limited to the processor’s word size minus two.
Required Thread Functionality
Each thread type requires five particular functions to be declared andimplemented. Default null implementations of all five functions are provided in the templates generated by the VisualDSP++ development
environment. The thread’s run function is the entry point for the thread.
For many thread types, the thread’s run and error functions are the only
ones in the template you need to modify. The other functions allocate andfree system resources at appropriate times during the creation and destruction of a thread.
Run Function

The run function—called Run() in C++ and RunFunction() in C/assembly
implemented threads—is the entry point for a fully constructed thread;
Run() is roughly equivalent to main() in a C program. When a thread’s

3-4VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDKrun function returns, the thread is moved to the queue of threads waiting
to free their resources. If the run function never returns, the thread
remains running until destroyed.
Error Function

The thread’s error function is called by the kernel when an error occurs inan API call made by the thread. The error function passes a description of
the error in the form of an enumeration (see SystemError). It can also passan additional piece of information whose exact definition depends on theerror enumeration. A thread’s default error-handling behavior makes
VDK go into a KernelPanic function. See “Error Handling Facilities” onpage 3-11 for more information about error handling in VDK.
Create Function

The create function is similar to the C++ constructor. The function provides an abstraction used by the kernel APIs (CreateThread(),CreateThreadEx(), and CreateThreadEx2()) to enable dynamic thread
creation. The create function is the first function called in the process ofconstructing a thread; it is also responsible for calling the thread’s InitFunction()/constructor. Similar to the constructor, the create function
executes in the context of the thread that is spawning a new thread by calling CreateThread(), CreateThreadEx(), or CreateThreadEx2(). The
thread being constructed does not have a run-time context fully established until after these functions complete.
A create function calls the constructor for the thread and ensures that allof the allocations that the thread type required have taken place correctly.
If any of the allocations failed, the create function deletes the partially created thread instantiation and returns a null pointer. If the thread has been
constructed successfully, the create function returns the pointer to thethread. A create function should not call DispatchThreadError() because
CreateThread(), CreateThreadEx(), and CreateThreadEx2() handle error
reporting to the calling thread when the create function returns a nullpointer.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-5

Threads

The create function is exposed completely in C++ source templates. For C
or assembly threads, the create function appears only in the thread’s
header file. If the thread allocates data in InitFunction(), you need tomodify the create function in the thread’s header to verify that the allocations are successful and delete the thread if not.
A thread of a certain thread type can be created at boot time by specifying
a boot thread of the given thread type in the development environment.
Additionally, if the number of threads in the system is known at build
time, all the threads can be boot threads.
InitFunction/Constructor

The InitFunction() (in C/assembly) and the constructor (in C++) provide a place for a thread to allocate system resources during the dynamic
thread creation. A thread uses malloc (or new) when allocating the thread’s
local variables. The VDK APIs that a thread’s InitFunction()/constructor
is allowed to call is limited because the API is called during VDK initialization (for boot threads) or from within a different thread’s context (fordynamically created threads). See Table 5-24 on page 5-19 for API validity levels.
Destructor

The destructor is called by the system when the thread is destroyed. A
thread can do this explicitly with a call to DestroyThread(). The thread is
destroyed also if it runs to completion by reaching the end of its run function and falling out of scope. In all cases, you are responsible for freeing
the memory and other system resources that the thread has claimed. Any
memory allocated with malloc or new in the constructor should be released
with a corresponding call to free or delete in the destructor.
A thread is not necessarily destroyed immediately when DestroyThread()is called. DestroyThread() takes a parameter that provides a choice of priority as to when the thread’s destructor is called. If the second parameter,
inDestroyNow, is FALSE, the thread is placed in a queue of threads to be

3-6

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDKcleaned up by the Idle Thread, and the destructor is called at a priority
lower than that of any user threads. While this scheme has many advantages, it works, in essence, as the background garbage collector. This is notdeterministic and presents no guarantees of when the freed resources areavailable to other threads. The threads queued to be cleaned up by the Idle
Thread can also be cleaned with a call to the FreeDestroyedThreads()
API.
If the inDestroyNow argument is passed to DestroyThread() with a valueof TRUE, the destructor is called immediately. This assures the resources are
freed when the function returns, but the destructor is effectively called at
the priority of the currently running thread even if a lower priority thread
is being destroyed.
Writing Threads in Different Languages
The code to implement different thread types may be written in C, C++,or assembly. The choice of language is transparent to the kernel. The
development environment generates well commented skeleton code for all
three choices.
One of the key properties of threads is that they are separate instances of
the thread type templates—each with a unique local state. The mechanism
for allocating, managing, and freeing thread local variables varies fromlanguage to language.
C++ Threads

C++ threads have the simplest template code of the three supported languages. User threads are derived classes of the abstract base class
VDK::Thread. C++ threads have slightly different function names andinclude a Create() function as well as a constructor.
Since user thread types are derived classes of the abstract base class
VDK::Thread, member variables may be added to user thread classes in theheader as with any other C++ class. The normal C++ rules for object scope

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-7

Threads

apply so that threads may make use of public, private, and static members. All member variables are thread-specific (or instantiation-specific).
Additionally, calls to VDK APIs in C++ are different from C and assembly
calls. All VDK APIs are in the VDK namespace. For example, a call to
CreateThread() in C++ is VDK::CreateThread(). Do not expose the entire
VDK namespace in your C++ threads with the using keyword.
C and Assembly Threads

Threads written in C rely on a C++ wrapper in their generated header file
but are otherwise ordinary C functions. C thread function implementations are compiled without the C++ compiler extensions.
In C and assembly programming, the state local to the thread is accessed
through a handle (a pointer to a pointer) that is passed as an argument toeach of the four user thread functions. When more than a single word ofstate is needed, a block of memory is allocated with malloc() in the thread
type’s InitFunction(), and the handle is set to point to the new structure.
Each instance of the thread type allocates a unique block of memory, andwhen a thread of that type is executing, the handle references the correct
memory reference. Note that, in addition to being available as an argument to all functions of the thread type, the handle can be obtained at any
time for the currently running thread using the API GetThreadHandle().
The InitFunction() and DestroyFunction() implementations for a
thread should not call GetThreadHandle() but should instead use theparameter passed to these functions, as they do not execute in the context
of the thread being initialized or destroyed.
Thread Parameterization
To distinguish between different instances of boot threads of the same
thread type, users can provide a signed integer value. The value is enteredin the Initializer field in the VDK Kernel tab and is passed to the thread
constructor (thread’s InitFunction function if a C thread) via the

3-8

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDK

user_data_ptr field of the ThreadCreationBlock argument.

The DiningPhilosophers example provided with the VisualDSP++ installation shows how the Initializer field can be used in C threads.
To distinguish between different instances of dynamically created threadsof the same thread type, users can call the CreateThreadEx() orCreateThreadEx2() API and provide a field of type void* via theuser_data_ptr field of the ThreadCreationBlock argument. The pointerthen can be accessed in the thread constructor (thread’s InitFunction
function if a C thread).
Because the user_data_ptr is a generic field and a pointer, the initializer
is passed by address. The initializer can be extracted with:
int initializer = *((int*)t.user_data_ptr);

in a C++ thread constructor, or:int initializer;
initializer = *((int *)pTCB->user_data_ptr);

in a C thread InitFunction().
The initializer value typically is stored in a member variable of the threaditself. In a C thread, the thread handle (which is passed also into the InitFunction) can be used for this purpose, but this is more easily achieved in
C++.
Note also that for dynamically-created threads, the user_data_ptr can beused in the same way (i.e. as a pointer to a unique integer) or as a completely general pointer to thread-specific data. This requires
CreateThreadEx() or CreateThreadEx2(), which takes a ThreadCreationBlock as its argument, to create threads rather than CreateThread().
CreateThreadEx2()
The CreateThreadEx2() API takes a ThreadCreationBlock (TCB) and an
unsigned integer as its input arguments, inOutTCB and inFieldsRequired,

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-9

Threads

respectively. inOutTCB contains thread configuration information, while
inFieldsRequired specifies which fields from inOutTCB are used when creating the thread and which fields are ignored.
Each field in inOutTCB is represented by a corresponding bit in inFieldsRequired. If a bit in inFieldsRequired is set (1), the contents of thematching field in inOutTCB is used to create the thread. If a bit ininFieldsRequired is clear (0), the matching field in the inOutTCB isignored, and the default setting is used.
The TCBBitfield enumeration provides names for different bits that canbe set in the inFieldsRequired argument. The flags provided by TCBBitfield can be ORed together.
For more information about parameter configuration via
CreateThreadEx2(), see the ThreadCreationBlock data type description.
User-Defined Thread Stacks
Typically, VDK allocates a thread stack automatically during a thread creation, but it is also possible to allocate a thread stack manually and thencreate a thread that uses this stack. To do so, first allocate an area of memory for the thread stack. The size of the allocated memory must match thestack size specified for that thread. Then the allocated memory is passed to
the CreateThreadEx2() API via the stack_pointer field of the ThreadCreationBlock argument, and the kSetThreadStackPointer flag is set in theinFieldsRequired argument.
On Blackfin processors, VDK uses the thread stack to store the thread’s
context information, so you must ensure that the allocated memory islarge enough to store this information. The memory size allocated for the
stack must be ‘the stack size + the context area size’. An API function GetContextRecordSize() is provided to query the size of the context area.

3-10

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDKGlobal Variables
VDK applications can use global variables as normal variables. In C or
C++, a variable defined in exactly one source file is declared as extern inother files in which that variable is used. In assembly, the .GLOBAL declaration exposes a variable outside a source file, and the .EXTERN declaration
resolves a reference to a symbol at link time.
Plan carefully how you use global variables in a multithreaded system.
Limit access to a single thread (a single instantiation of a thread type)whenever possible to avoid reentrancy problems. Critical and/or unscheduled regions should be used to protect operations on global entities thatcan potentially leave the system in an undefined state if not completed
atomically.
Error Handling Facilities
VDK includes an error-handling mechanism that allows you to define
behavior independently for each thread type. Each function call in Chapter 5, “VDK API Reference” lists the possible error codes. For thecomplete list of all error codes, refer to “SystemError” on page 4-51.
The assumption underlying the error-handling mechanism in VDK is that
all function calls normally succeed and, therefore, do not require an
explicit error code to be returned and verified by the calling code. VDK’s
method differs from common C programming convention in which thereturn value of every function call must be checked to assure that the callhas succeeded without an error. While that model is widely used in conventional systems programming, real-time embedded system function calls
rarely, if ever, fail. When an error does occur, the system calls theuser-implemented ErrorFunction().
You can call GetLastThreadError() to obtain the running thread’s mostrecent error. You also can call GetLastThreadErrorValue() to obtain an
additional descriptive value whose definition depends on the specificerror. For more information, see Table 5-23 on page 5-18. The thread’s

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-11

Scheduling

ErrorFunction() should check if the value returned by GetLastThreadError() is one that can be handled intelligently and can perform theappropriate operations. Any errors that the thread cannot handle must be
passed to the default thread error function, which then raises KernelPanic. For instructions on how to pass an error to the error function, seecomments included in the generated thread code.

Scheduling
The scheduler’s role is to ensure that the highest priority ready thread isallowed to run at the earliest possible time. The scheduler is never invokeddirectly by a thread but is executed whenever a kernel API—called fromeither a thread or an Interrupt Service Routine (ISR) —changes the highest priority thread. The scheduler is not invoked during critical orunscheduled regions, but can be invoked immediately at the close of either
type of protected region.

Ready Queue
The scheduler relies on an internal data structure known as the readyqueue. The queue holds references to all threads that are not blocked or
sleeping. All threads in the ready queue have every resource needed to run;they are only waiting for processor time. The exception is the currently
running thread, which remains in the ready queue during execution.
The ready queue is called a queue because it is arranged as a prioritizedFirst-In First-Out (FIFO) buffer. That is, when a thread is moved to theready queue, it is added as the last entry at its priority. For example, there
are four threads in the ready queue at priorities kPriority3, kPriority5,

3-12

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDK

and kPriority7, and an additional thread is made ready with a priority ofkPriority5 (see Figure 3-1).
Ready Queue(ordered by priority, then FIFO )Priority List
(List of Pointers)

Reserved

kPriority0

HighestkPriority1
kPriority2

Running Thread

kPriority3

Thread 1

Thread 4

kPriority4
kPriority5

Thread 1

kPriority3

Thread 4

kPriority3

Thread 2

kPriority5

Thread 3

kPriority7

IDLE

kPriorityN

Thread 2

kPriority6

Lowest, where
n is data word
size - 2

kPriority7

Thread 3

kPriorityN

IDLE

Thread 5(priority kPriority5)
New Threadof Ready Status

Figure 3-1. Ready Queue
The additional thread is inserted after the old thread with the priority ofkPriority5 but before the thread with the priority of kPriority7.
Threads are added to and removed from the ready queue in a fixed number of cycles regardless of the size of the queue.

Scheduling Methodologies
VDK always operates as a preemptive kernel. However, you can takeadvantage of a number of modes to expand the options for simpler ormore complex scheduling in your applications.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-13

Scheduling

Cooperative SchedulingMultiple threads may be created at the same priority level. In the simplest
scheduling scheme, all threads in the system are given the same priority,and each thread has access to the processor until it manually yields control. This arrangement is called cooperative multithreading.
When a thread is ready to defer to the next thread at the same priority
level, the thread can do so by calling the Yield() function, placing thecurrently running thread at the end of the list. In addition, any system callthat causes the currently running thread to block would have a similar
result. For example, if a thread pends on a signal that is not currently
available, the next thread in the queue at that priority starts running.
Round-Robin SchedulingRound-robin scheduling, also called time slicing, allows multiple threads
with the same priority to be given processor time automatically in fixed
duration allotments. In VDK, priority levels may be designated asround-robin mode at build time and their period specified in system ticks.
Threads at that priority are run for that duration, as measured by the
number of VDK Ticks. If the thread is preempted by a higher priority
thread for a significant amount of time, the time is not subtracted fromthe time slice. When a thread’s round-robin period completes, it is moved
to the end of the list of threads at its priority in the ready queue. Note thatthe round-robin period is subject to jitter when threads at that priority are
preempted.
Preemptive Scheduling
Full preemptive scheduling, in which a thread gets processor time as soon as
it is placed in the ready queue if it has a higher priority than the running
thread, provides more power and flexibility than pure cooperative orround-robin scheduling.

3-14

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDKVDK allows the use of all three paradigms without any modal configuration. For example, multiple non-time-critical threads can be set to a low
priority in the round-robin mode, ensuring that each thread gets processor
time without interfering with time critical threads. Furthermore, a thread
can yield the processor at any time, allowing another thread to run. A
thread does not need to wait for a timer event to swap the thread out when
it has completed the assigned task.

Disabling Scheduling
Sometimes it is necessary to disable the scheduler when manipulating
global entities. For example, when a thread tries to change the state ofmore than one signal at a time, the thread can enter an unscheduled
region to ensure that all updates occur atomically. Unscheduled regions
are sections of code that execute without being preempted by a higher priority thread. Note that interrupts are serviced in an unscheduled region,
but the same thread runs on return to the thread domain. Unscheduled
regions are entered through a call to PushUnscheduledRegion(). To exit anunscheduled region, a thread calls PopUnscheduledRegion().
Unscheduled regions (in the same way as critical regions, covered in“Enabling and Disabling Interrupts” on page 3-56), are implemented witha stack. Using nested critical and unscheduled regions allows you to write
code that activates a region without being concerned about the region
context when a function is called. For example:
void My_UnscheduledFunction(){
VDK_PushUnscheduledRegion();/* In at least one unscheduled region, but
this function can be used from any numberof unscheduled or critical regions *//* ... */VDK_PopUnscheduledRegion();}void MyOtherFunction()

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-15

Scheduling{
VDK_PushUnscheduledRegion();/* ... *//* This call adds and removes one unscheduled region */My_UnscheduledFunction();/* The unscheduled regions are restored here *//* ... */VDK_PopUnscheduledRegion();}An additional function for controlling unscheduled regions is
PopNestedUnscheduledRegions(). This function completely pops thestack of all unscheduled regions. Although VDK includes
PopNestedUnscheduledRegions(), applications should use the function
infrequently and balance regions correctly.

Entering the Scheduler From API Calls
Since the highest priority ready thread is the running thread, the scheduler
is called only when a higher priority thread becomes ready. Because athread interacts with the system through a series of API calls, the points at
which the highest priority ready thread may change are well defined.
Therefore, a thread invokes the scheduler only at these times, or wheneverit leaves an unscheduled region.

Entering the Scheduler From Interrupts
ISRs communicate with the thread domain through a set of APIs that do
not assume any context. Depending on the system state, an ISR API callmay require the scheduler to be executed. VDK reserves the lowest priority software interrupt to handle the reschedule process.
If an ISR API call affects the system state, the API raises the lowest priority software interrupt. When the lowest priority software interrupt isscheduled to run by the hardware interrupt dispatcher, the interrupt
reduces to subroutine and enters the scheduler. If the interrupted thread is

3-16

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDK

not in an unscheduled region and a higher priority thread has become
ready, the scheduler swaps out the interrupted thread and swaps in the
new highest priority ready thread. The lowest priority software interrupt
respects any unscheduled regions the running thread is in. However, interrupts can still service device drivers, post semaphores, and so on. On
leaving the unscheduled region, the scheduler is run again, and the highest
priority ready thread becomes the running thread (see Figure 3-2).
CreateThread()

READY

Thread is InstantiatedReturn from Interrupt(no longer Highest
Priority Ready Thread)* PostSemaphore()* PostDeviceFlag()* PostMessage()* Sleep() ends
* Thread pends on theevent that becomes
TRUE* Round-robin period
startsHighest Priority
Ready Thread

DestroyThread()

BLOCKED
Thread is Destroyed* PendSemaphore()* PendDeviceFlag()* PendEvent()* PendMessage()* Sleep()* Round-robin period ends

INTERRUPTEDRUNNING

Interrupt

Nested Interrupts

Return from Interrupt(remains Highest Priority Ready Thread)

Figure 3-2. Thread State Diagram

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-17

Signals

Idle Thread
The Idle thread is a predefined, automatically-created thread with theThreadID set at zero and a priority lower than that of any user threads.
Thus, when there are no user threads in the ready queue, the Idle threadruns. The only substantial work performed by the Idle thread is the freeing of resources of threads that have been destroyed. In other words, theIdle thread handles destruction of threads that were passed to
DestroyThread() with a value of FALSE for inDestroyNow. Depending on
the platform, it may be possible to customize certain properties of the Idle
thread, such as its stack size and the heap from which all its memory
requirements (including the Idle thread stack) are allocated. (See online
Help for further details.) There may be processor-specific requirementsfor particular Idle thread properties (See Appendix A, “Processor-SpecificNotes”, for further details.)
The time spent in threads other than the Idle thread is shown plotted as apercentage over time on the Target Load tab of the State History window
in VisualDSP++. See “VDK State History Window” on page 2-3 andonline Help for more information about the State History window.

Signals
Threads have five different methods for communication andsynchronization:• “Semaphores” on page 3-19
• “Mutexes” on page 3-26
• “Messages” on page 3-32
• “Events and Event Bits” on page 3-48
• “Device Flags” on page 3-55

3-18

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDKEach communication method has a different behavior and use. A threadpends on any of the five types of signals, and if a signal is unavailable, thethread blocks until the signal becomes available or (optionally) a timeout
is reached.

Semaphores
Semaphores are protocol mechanisms offered by most operating systems.
Semaphores are used to:• Control access to a shared resource• Signal a certain system occurrence• Allow threads to synchronize• Schedule periodic execution of threads
The maximum number of active semaphores and initial state of the semaphores enabled at boot time are set up when your project is built.
Behavior of Semaphores
A semaphore is a token that a thread acquires so that the thread can continue execution. If the thread pends on the semaphore and the semaphoreis available (the count value associated with the semaphore is greater thanzero), the semaphore is acquired, its count value is decremented by one,and the thread continues normal execution. If the semaphore is not available (its count is zero), the thread trying to acquire (pend on) the
semaphore blocks until the semaphore is available, or the specified timeout occurs. If the semaphore does not become available in the time
specified, the thread continues execution in its error function.
Semaphores are global resources accessible to all threads in the system.
Threads of different types and priorities can pend on a semaphore. Whenthe semaphore is posted, the thread with the highest priority that has been
waiting the longest is moved to the ready queue. If there are no threads
VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-19

Signalspending on the semaphore, its count value is incremented by one. The
count value is limited by the maximum value specified at the time of thesemaphore creation. Additionally, unlike many operating systems, VDK
semaphores are not owned. In other words, any thread is allowed to post a
semaphore (make it available). If a thread has requested (pended on) andacquired a semaphore and the thread is subsequently destroyed, the semaphore is not automatically posted by the kernel.
Besides operating as a flag between threads, a semaphore can be set up tobe periodic. A periodic semaphore is posted by the kernel every n ticks,
where n is the period of the semaphore. Periodic semaphores can be used
to ensure that a thread is run at regular intervals.
Thread’s Interaction With Semaphores
Threads interact with semaphores through the set of semaphore APIs.
These functions allow a thread to create a semaphore, destroy a semaphore, pend on a semaphore, post a semaphore, get a semaphore’s value,
and add or remove a semaphore from the periodic queue.

3-20

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDKPending on a Semaphore

Figure 3-3 illustrates the process of pending on a semaphore.
Thread 1 continues execution

Thread 1
No

Yes

Is
there atimeout before Yes
semaphore became
available?

Is
No
kNoTimeoutError
set?

PendSemaphore()Is
Semaphoreavailable?
(count>0)

Yes

Decrease
semaphore's
count

No

Is
the timeout
kDoNotWait?

Yes

Set
return value to
FALSE

No

Semaphore's Listof Pending Threads

Thread 1 adds itself toOrder by priority,then FIFO

Thread 1's
ErrorFunction()is called

Figure 3-3. Pending on a Semaphore

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-21

SignalsThreads can pend on a semaphore with a call to PendSemaphore(). When athread calls PendSemaphore(), it performs one of the following.
• Acquires the semaphore, decrements its count by one, and continues execution• Blocks until the semaphore is available or the specified timeout
occurs• If the timeout is set to kDoNotWait1 and the semaphore is not available, the API returns FALSE and the thread continues execution
If the semaphore becomes available before the timeout occurs or a timeout
occurs and the kNoTimeoutError2 bit has been specified in the timeout
parameter, the thread continues execution; otherwise, the thread’s error
function is called and the thread continues execution. You should not call
PendSemaphore() within an unscheduled or critical region because if thesemaphore is not available, then the thread will block. However, with thescheduler disabled, execution cannot be switched to another thread. Pending with a timeout of zero on a semaphore pends without timeout.
Posting a Semaphore

Semaphores can be posted from two different scheduling domains: thethread domain and the interrupt domain. If there are threads pending on
the semaphore, posting it moves the highest priority thread from thesemaphore’s list of pending threads to the ready queue. All other threads
are left blocked on the semaphore until their timeout occurs, or the semaphore becomes available for them. If there are no threads pending on thesemaphore, posting it increments the count value by one. If the maximum
count (which is specified when the semaphore is created) is reached, posting the semaphore has no effect.

1
2

3-22

VDK::kDoNotWait in C++ and VDK_kDoNotWait in C.
VDK::kNoTimeoutError in C++ and VDK_kNoTimeoutError in C.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDKPosting from the Thread Domain:
Figure 3-4 and Figure 3-5 illustrate the process of posting semaphores
from the thread domain.
A thread can post a semaphore with a call to the PostSemaphore() API. If
a thread calls PostSemaphore() from within a scheduled region (seeFigure 3-4), and a higher priority thread is moved to the ready queue, thethread calling PostSemaphore() is context switched out.
1). Invoke Scheduler
2). Switch out the current thread3). Switch in the highest priority pending thread

PostSemaphore()Thread 1

Is
Semaphoreavailable(count>0)?

No

Semaphore's Listof PendingThreads
Order threads
by priority,then FIFO

No
Ready Queue
Order threads
by priority,then FIFOIs
Thread 1of the highest
priority?

Next Thread
Yes
Yes
Is
Semaphore's
count < itsmaximum
count?

Yes

Increase Semaphore's
count

No

Thread 1 runs

Figure 3-4. Thread Domain/Scheduled Region: Posting a Semaphore
If a thread calls PostSemaphore() from within an unscheduled region
where the scheduler is disabled, the highest priority thread pending on the

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-23

Signals

semaphore is moved to the ready queue, but no context switch occurs (asshown in Figure 3-4).

Is
PostSemaphore()
Semaphoreavailable
Thread 1(count>0)?

Semaphore's Listof Pending Threads
No

Ready Queue

Order threads
Order threads
by priority,
by priority,then FIFO
then FIFO
Next Thread

YesIs
Semaphore's
count <
its maximum
count?

Yes
Increase Semaphore's
count

No
Thread 1 runs

Figure 3-5. Thread Domain/Unscheduled Region: Posting a Semaphore

3-24

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDKPosting from the Interrupt Domain:
Interrupt subroutines can also post semaphores. Figure 3-6 illustrates theprocess of posting a semaphore from the interrupt domain.
Are
Yes
there threads
pending?

2). RTI
3). The low priority ISR runs

Increase Semaphore's
count4). Kernel runs

VDK_ISR_POST_SEMAPHORE ()5). Decrease Semaphore‘s count

No
ISR 1

1). Set the low priority
ISR

ISR 2
ISR 3

Is
Semaphore's
count < itsmaximum
count?

Yes

Semaphore's List
Ready Queueof Pending Threads
Order threads
Order threads
by priority,
by priority,then FIFO
then FIFO
Next Thread

Increase Semaphore's
count

No
Is
the interrupted threadof the highest
priority?

No2). Switch into the highest
priority pending thread1). Switch out theinterrupted threadYes
The interrupted thread runs

Figure 3-6. Interrupt Domain: Posting a Semaphore
An ISR posts a semaphore by calling the VDK_ISR_POST_SEMAPHORE_()
macro. The macro moves the highest priority thread pending on the semaphore to the ready queue and latches the low priority software interrupt if
a call to the scheduler is required. When the ISR completes execution andthe low priority software interrupt is run, the scheduler is run. If the interrupted thread is in a scheduled region and a higher priority thread
becomes ready, the interrupted thread is switched out and the new thread
is switched in.
Periodic Semaphores

Semaphores can also be used to schedule periodic threads. The semaphoreis posted every n ticks (where n is the semaphore’s period). A thread can

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-25

Signalsthen pend on the semaphore and be scheduled to run every time the semaphore is posted. A periodic semaphore does not guarantee that the thread
pending on the semaphore is the highest priority scheduled to run, or thatscheduling is enabled. All that is guaranteed is that the semaphore isposted, and the highest priority thread pending on that semaphore moves
to the ready queue.
Periodic semaphores are posted by the kernel during the timer interrupt at
system tick boundaries. Periodic semaphores can also be posted at any
time with a call to PostSemaphore() or VDK_ISR_POST_SEMAPHORE_(). Calls
to these functions do not affect the periodic posting of the semaphore.

Mutexes
Many operating systems offer a synchronization mechanism know as
mutexes. Mutexes allow threads to synchronize access to a shared resource.
• VDK mutexes are purely dynamic entities. This means that there
are no boot mutexes, and that the maximum number of mutexes in
an application is limited only by memory restrictions—not set upon the Kernel tab.
• VDK mutexes are owned—only the owner of a mutex can release
the mutex.
• VDK mutexes are recursive—the current owner can acquire amutex more than once, in a nested manner.
Behavior of Mutexes
A mutex is a token that a thread acquires to continue execution. If thethread attempts to acquire the mutex, and the mutex is available (themutex either has no owner or the owner is the current thread), then the
mutex is acquired. When the mutex is acquired, its internal count value isincremented, and the thread continues execution. If the mutex is not

3-26

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDKavailable (the mutex is owned by a different thread), then the thread trying to acquire the mutex blocks until the mutex becomes available.
Mutexes are global resources accessible to all threads in the system.
Threads of different types and priorities can acquire a mutex. When the
mutex is released, the thread with the highest priority that has been waiting for the mutex the longest is moved to the ready queue. VDK mutexes
are owned; the only thread allowed to release a mutex is the mutex owner.
In the case of instrumented or error-checking libraries, if a thread is
destroyed while owning a mutex, then the next time a thread tries toacquire the mutex, VDK dispatches an error and the mutex is released by
the kernel.
Thread Interaction With Mutexes
Threads interact with mutexes through the set of mutex APIs. The APIs
allow a thread to create, acquire, release, or destroy a mutex.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-27

SignalsAcquiring a Mutex

Figure 3-7 illustrates the process of acquiring a mutex. Threads canacquire a mutex with a call to AcquireMutex(), which performs one of thefollowing actions.
Thread 1 continues execution
Thread 1
AcquireMutex()

Is Mutex
owned byany thread?

No

Yes

Is
Thread 1
the Mutex
owner?

No

1). Thread 1 blocks
2). Thread 1 is added
to the list of threads
waiting for Mutex(ordered by priority,then FIFO)

Mutex becomes
available for
Thread 1

Make Thread 1
Mutex's owner

Increase Mutex's
internal countYes

Figure 3-7. Acquiring a Mutex• Makes the thread the mutex’s owner and continues execution• Increments the mutex's internal count and continues execution• Blocks until the mutex is available, then acquires the mutex
Do not call AcquireMutex() within an unscheduled (or critical) region. If
the mutex is not available, then the thread attempts to block, which is illegal within an unscheduled region.
Releasing a Mutex

A mutex can be released only by the thread that owns the mutex. If a
thread has acquired the mutex multiple times, then releasing the mutex
decreases the mutex’s internal count, and the thread remains the mutex’s

3-28

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDKowner. The mutex ownership is released only when ReleaseMutex() has
been called once for each time that the mutex was acquired, at which
point the internal count reaches zero, and the mutex becomes available toall threads. If there are threads blocked on the mutex, then making themutex available moves the highest priority thread (only) from the mutex’s
list of pending threads to the ready queue. If there are no threads pendingon the mutex when the mutex is made available, then the mutex remains
in the available state. No thread can release a mutex that it does not currently own.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-29

Signals

Figure 3-8 and Figure 3-9 illustrate the process of releasing mutexes innormal execution (a scheduled region) and in an unscheduled region.
Thread 1 continues execution
Thread 1
ReleaseMutex()

Is Mutex
owned byThread 1?

No

Thread 1‘s Error
Function() is called1). Invoke Scheduler
2). Switch out current thread3). Switch in the highest
priority pending thread

YesIs
Mutex internalcount greaterthan 1?

Yes

Decrease Mutex's
internal count

No

Yes

Is
Thread 1
highestpriority?

No
No
Make Mutex
available to all threads(set its owner to None)Is
any thread
waiting on
Mutex?

Ready QueueYes

Add highest
priority thread in
Mutex's list ofpending thread

Figure 3-8. Releasing a Mutex in a Scheduled Region

3-30

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDKThread 1 continues execution
Thread 1
ReleaseMutex()

Is Mutex
owned byThread 1?

No

Thread 1‘s Error
Function() is called

YesIs
Mutex internalcount greaterthan 1?

Yes

Decrease Mutex's
internal countNo

No
Make Mutex
available to all threads(set its owner to None)Is
any thread
waiting on
Mutex?

Ready QueueYes

Add highest
priority thread in
Mutex's list ofpending thread

Figure 3-9. Releasing a Mutex in an Unscheduled/Critical Region• If a thread calls ReleaseMutex() in normal execution (seeFigure 3-8), and a higher priority thread is moved to the readyqueue, then the thread calling ReleaseMutex() is context-switchedout.
• If a thread calls ReleaseMutex() from an unscheduled region (seeFigure 3-9) where the scheduler is disabled, then the highest priority thread waiting on the mutex is moved to the ready queue, but
no context switch occurs.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-31

Signals

Messages
Many operating systems offer an inter-thread communication mechanism
known as messages. Messages can be used to:• Communicate information between two threads• Control access to a shared resource• Signal a certain occurrence and communicate information about
the occurrence• Allow two threads to synchronize
The maximum number of messages supported in the system is set up when
the project is built. When the maximum number of messages is non-zero,a system-owned memory pool is created to support messaging. The properties of this memory pool should not be altered. Further information on
memory pools is given in “Memory Pools” on page 3-80.
Each thread type can specify whether or not it is “message-enabled”.
There is a space saving if a thread type is not message-enabled because aninternal structure is not required. A thread type that is not message-enabled can still send messages; however, it cannot receive messages.
Behavior of Messages
Messages allow two threads to communicate over logically separate channels. A message is sent on one of 15 possible channels, kMsgChannel1 to
kMsgChannel15. Messages are retrieved from these channels in priority
order: kMsgChannel1, kMsgChannel2, ... kMsgChannel15k, and messages
are received from each channel in FIFO order. Each message can pass areference to a data buffer, in the form of a message payload, from thesending thread to the receiving thread.
A thread creates a message (optionally associating a payload) and thenposts (sends) the message to another thread. The posting thread continues

3-32

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDK

normal execution unless the posting of the message activates a higher priority thread which is pending on (waiting to receive) the message.
A thread can pend on the receipt of a message on one or more of its channels. If a message is already queued for the thread, it receives the message
and continues normal execution. If no suitable message is already queued,
the thread blocks until a suitable message is posted to the thread, or until
the specified timeout occurs. If a suitable message is not posted to thethread in the time specified, the thread continues execution in its error
function. It is also possible to use a polling model, rather than a blocking
model, when waiting for the receipt of messages. The MessageAvailable()
API is provided to support the polling model.
Unlike semaphores, each message always has a defined owner at any given
time, and only the owning thread can perform operations on the message.
When a thread creates a message, it owns the message until it posts themessage to another thread. The message ownership changes to the receiving thread following the post, when it is queued on one of the receiving
message’s channels. The receiving thread is now the owner of the message.
The only operation that can be performed on the message at this time ispending on the message, making the message and its contents available to
the receiving thread.
A message can only be destroyed by its owner; therefore, a thread thatreceives a message is responsible for either destroying or reusing a message.
Ownership of the associated payload also belongs to the thread that owns
the message. The owner of the message is responsible for the control ofany memory allocation associated with the payload.
Each thread is responsible for destroying any messages it owns before it
destroys itself. If there are any messages left queued on a thread’s receiving
channels when it is destroyed, then the system destroys the queued messages. As the system has no knowledge of the contents of the payload, thesystem does not free any resources used by the payload.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-33

SignalsThread’s Interaction With Messages
Threads interact with messages through the set of message APIs. The
functions allow a thread to create a message, pend on a message, post amessage, get and set information associated with a message, and destroy amessage.
Pending on a Message

Figure 3-10 illustrates the process of pending on a message.
Thread 1 continues execution
Yes
PendMessage()
Thread 1

Is
Messageavailable?

Thread 1‘s Error
Function() is called
No

No

Is
the timeout
kDoNotWait?

Yes

Yes

No
Ready Queue
Thread is removed
from Ready QueueIs
there atimeout before Yes
Message became
available?

Is
No
kNoTimeoutError
set?

Figure 3-10. Pending on a Message

3-34

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDKThreads can pend on a message with a call to PendMessage(), specifying
one or more channels that a message is to be received on. When a threadcalls PendMessage(), it does one of the following.
• Receives a message and continues execution• Blocks until a message is available on the specified channel(s) or
the specified timeout occurs• Continues execution if the timeout is set to kDoNotWait1 and themessage is not available
If messages are queued on the specified channels before the timeout
occurs, or if a timeout occurs and the kNoTimeoutError2 bit is specified in
the timeout parameter, the thread continues normal execution; otherwise,
the thread continues execution in its error function.
Once a message has been received, you can obtain the identity of the sending thread and the channel the message was received on by calling
GetMessageReceiveInfo(). You can also obtain information about the
payload by calling GetMessagePayload(), which returns the type andlength of the payload in addition to its location. Do not call PendMessage() within an unscheduled or critical region because if a message is notavailable, then the thread blocks, but with the scheduler disabled, execution cannot be switched to another thread. Pending with a timeout of zeroon a message pends without timeout.
Posting a Message

Posting a message sends the specified message and its payload reference tothe specified thread and transfers ownership of the message to the receiving thread. The details of the message payload can be specified by a call on
the SetMessagePayload() function, which allows the thread to specify the
payload type, length, and location before posting the message. A thread
1
2

VDK::kDoNotWait in C++ and VDK_kDoNotWait in C.
VDK::kNoTimeoutError in C++ and VDK_kNoTimeoutError in C.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-35

Signals

can send a message it currently owns with a call to PostMessage(), specifying the destination thread and the channel the message is to be sent on.
Figure 3-11 illustrates the process of posting a message from a scheduled
region.
Thread 1 continues execution
YesIsthe destiPostMessage()nation thread
Thread 1
unblocked by thisMessage?

Yes

Is
Thread 1of the highest
priority?

Destination thread
is moved to
Ready Queue

No
No

Invoke Scheduler

Figure 3-11. Posting a Message From a Scheduled Region
If a thread calls PostMessage() from within a scheduled region, and ahigher priority thread is moved to the ready queue on receiving the message, then the thread calling PostMessage() is context switched out.
Figure 3-12 illustrates the process of posting a message from an unscheduled region.
Thread 1 continues execution
No

Thread 1

PostMessage()Isthe destination thread
unblocked by thisMessage?

Yes

Destination thread
is moved to
Ready Queue

Figure 3-12. Posting a Message From an Unscheduled Region

3-36

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDKIf a thread calls PostMessage() from within an unscheduled region, even if
a higher priority thread is moved to the ready queue to receive the message, the thread that calls PostMessage() continues to execute.

Multiprocessor Messaging
VDK messaging functionality was extended in VisualDSP++ 3.5 to allow
messages to be passed between the processors in a multiprocessor configuration. The APIs and corresponding behaviors are, as much as possible,
the same as for intra-processor messaging but with extensions.
Each processor in a multiprocessor configuration is referred to as a nodeand must have its own VisualDSP++ project. This means that each node
runs its own instance of the VDK kernel and all VDK entities (such as
semaphores, event bits, events, and so on, but excepting threads) are private to that node. Each node has a unique numeric node ID, which is set
in the project’s Kernel tab.
Threads are uniquely identified across the multiprocessor system byembedding the node ID as a 5-bit field within the ThreadID. The size of
this field limits the maximum number of nodes in the system to 32.
Threads are permanently located on the node where they are created—
there is no “migration” of threads between nodes.
In order for threads to be referenced on other nodes, each project in a
multiprocessor system uses the Kernel tab’s Import list to import the project files for all the other nodes in the system. This makes the bootThreadIDs for all the projects visible and usable across the system. Threads
located on other nodes may then be used as destinations for the
VDK::PostMessage() and VDK::ForwardMessage() functions, though not
for any other thread-related API function.
Boot threads serve as “anchor points” for node-to-node communications,as their identities are known at build time. In order to communicate withdynamically-created threads on other nodes, it is necessary to pass theThreadIDs as data between the nodes (that is, in a message payload). A

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-37

Signals

reply to an incoming message can always be sent, regardless of the identityof the sending thread, as the sender’s ID is carried in the message itself.
Boot threads can therefore be used to provide information about dynamically-created threads, but such arrangements are application-specific andmust form part of the system design.
Routing Threads (RThreads)
When a message is posted by a thread, the destination node ID (embeddedin the destination ThreadID) is examined. If it matches the node ID of thenode on which the thread is running, then the message is placed directly
into the message queue of the destination thread, exactly as in single-processor messaging. If the node IDs do not match, then the message ispassed to one of the routing threads (RThreads), which is responsible forthe next stage in the process of moving the message to its destination.
Each RThread takes one of two roles, incoming or outgoing, which isfixed at the time of its creation.
Each RThread employs a device driver, which manages the physical detailsof moving messages between nodes. An outgoing RThread has its device
open for writing, while an incoming RThread has its device open forreading.
Outgoing RThreads are referenced via a routing table, which is constructed by VisualDSP++ at build time. When a message must be sent to adifferent node, the destination node ID is used as an index into this table
to select which outgoing RThread will handle transmission of the message.
Each node must contain at least one incoming and one outgoing RThread,
together with their corresponding device drivers. More RThreads may be
included, depending on the number of physical connections to othernodes. However, the number of outgoing RThreads may be less than thenumber of nodes in the system, so that more than one entry in the routing
table may map to the same RThread. This means that the topology of the

3-38

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDKmultiprocessor system may require that a message make more than one“hop” to reach its final destination.
An outgoing RThread, when idle, waits for messages to be placed on any
channel of its message queue, and then transmits that message (as a message packet) by making one or more SyncWrite() calls to its associateddevice driver. These SyncWrite() calls may block waiting I/O completion.
An incoming RThread, when idle, blocks in a SyncRead() call to its device
driver awaiting reception of a message packet. Once the packet has been
received and expanded into a message object, the RThread forwards it to
its destination. This may involve passing the message to an outgoing
RThread if the current node is not the message’s final destination.
The actual message objects, as referenced by particular MessageID, are each
local to a particular node. When a message is transmitted between two
nodes, only the message contents are passed over (as a message packet).
The message object itself is destroyed on the sending side and recreated on
the receiving side with the following consequences.
• The message usually has a different ID on the receiving side than it
does on the sending.
• Message objects that are passed to an outgoing RThread aredestroyed after transmission and, hence, returned to the pool offree messages.
• When a message packet is received by an incoming RThread, amessage object must be created from the pool of free messages.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-39

Signals

Figure 3-13 shows the path taken by a message being sent between two
threads on different nodes (A and B), where a direct connection exists
between the two nodes.

Sending
ThreadNODE ANODE B
CreateMessage()

PostMessage()Transfer
SyncWrite()
Outgoing
Rthread

SyncRead()
DEVICEDRIVER

DEVICEDRIVER

Incoming
RThread

PostMessage()
DestroyMessage()
Physical Connection(Link Port, Cluster Bus,Internal Memory DMA)

Receving
ThreadFigure 3-13. Sending Messages Between Adjacent Nodes
Figure 3-14 shows a scenario where node Y is an intermediate “hop” on
the way to a third node, Z. The message is posted by Y’s incoming

3-40

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDKRThread, directly into the message queue of the routing thread for theoutgoing connection.
Node XCreateMessage()

SyncRead()
DEVICEDRIVER

Incoming
RThreadNode Y
PostMessage()

Node Z

SyncWrite()
Physical Connection(Link Port, Cluster Bus)

Outgoing
RThread

DEVICEDRIVER

DestroyMessage()
Physical Connection(Link Port, Cluster Bus)

Figure 3-14. Sending Messages Between Non-Adjacent Nodes via an
Intermediate NodeIf the message allocation by the incoming RThread fails, then a systemerror is raised and execution stops on that node. This is necessary because
the alternative of “dropping” the message is unacceptable (message
delivery is defined as being reliable in VDK).

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-41

Signals

There are a number of ways of avoiding this problem.
1. Provide a careful design of the message flow in the application, andcareful choice of priorities for the RThreads. The use of loopback(that is, returning messages to sender rather than destroying them)
may assist with this.
2. Preallocate all messages during initialization and use loopback sothat they never need to be explicitly destroyed. The maximum messages setting (on the Kernel tab) for each node must be set equal to
the total number of messages in the overall system. This ensuresthat there is no failure even if all messages are sent to the same nodeat once.
3. A counting semaphore may be installed to regulate the message
flow into the node, using the VDK::InstallMessageControlSemaphore() API. The initial count of this semaphore should be set toless than or equal to the number of free messages which arereserved for use by the RThreads. This semaphore is pended onprior to each message allocation by an incoming RThread, andposted after each deallocation by an outgoing RThread. Provided
that the semaphore’s count is never less than the number of freemessages on the node, then the allocations never fail. However,message flow into the node may stall if the semaphore count falls tozero.
Option 1 requires a thorough understanding of application behavior.
Option 2 carries a memory space overhead, as more space may be reserved
for messages than is actually needed at runtime, but is the simplest solution if this is no problem. Option 3 carries a performance overhead due tothe semaphore pend and post operations. Additionally, if message flow
stalls, which may occur with Option 3, it may have other consequences forthe system.

3-42

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDKData Transfer (Payload Marshalling)
Very simple messages can be sent between nodes without interpretation;that is, if the message information is entirely conveyed by the two wordsof message data (internal payload). However, if the message actually has
an in-memory (external) payload, then the address of this payload may not
be meaningful once the message arrives on another node. In these cases,
the payload must be transferred along with the message. This is done via
payload marshalling.
Any message type that has the MSB (sign bit) set (that is, a negative value)
is considered to be a marshalled type, meaning that the system expects toallocate, deallocate, and transfer the payload automatically from node to
node.
Since the organization of the payload for a particular message type isentirely the choice of the application designer (it might be a linked list ora tree, rather than a plain memory block), the allocation, deallocation, andtransfer of the payload is the responsibility of a marshalling function.
Pointers to these functions are held in a static marshalling table, which isindexed using the low-order bits of the message type.
The marshalling function implements (at least) the following operations:• Allocate and receive• Transmit and release
Note that it is not compulsory for the marshalling function to transfer the
payload via the device driver. It may, for example, only be necessary for it
to translate the payload address from a local value to a cluster bus address(on those processors that have cluster bus functionality), so as to permit
in-place access to the payload from another processor. When the payloads
for a particular message type are always stored in a memory (for example,
SDRAM) which is visible to all nodes and mapped to the same address
range on each, then no marshalling is needed. The message type can begiven a non-marshalled value (that is, the sign bit is zero).

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-43

Signals

Since the most common form of marshalled payload is likely to be a plain
memory block allocated either from a heap or from a VDK memory pool,
VDK provides built-in standard marshalling functions to handle thesecases. See Appendix A, “Processor-Specific Notes” on page A-1 for detailsof other standard marshalling functions that may be available only for certain processor families. The more complex cases (linked data structures,
shared memory, and so on) require user-written custom marshalling
functions.
Marshalling functions are called from the routing threads and are passed
these arguments:• Marshalling code—indicates which operation is to be performed• A pointer to the formatted message packet, which includes payload
type, size, and address— for input and output• Device descriptor—identifies the VDK device driver for theconnection• Heap index or PoolID—used by standard marshalling• I/O timeout duration—usually set to zero, for indefinite wait)
For transmission, the marshalling function is also responsible for firsttransmitting the message packet. This allows the marshalling function tomodify the payload attributes prior to transmission if required. For example, if the payload is to be accessed in-place across the cluster bus (onprocessors with cluster bus functionality), then node-specific addresses
must be translated to the global address space and back.
The marshalling functions execute in the context of the Routing Threads.
The SyncRead() or SyncWrite() calls made by the marshalling functions
will (or may) cause the threads to block awaiting I/O completion; however, the original sending thread(s) is are not blocked. In this way, theRouting Threads act as a buffer between user threads and the interprocessor message transfer mechanism.

3-44

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDKNote that it is not strictly necessary for the marshalling function to actually transfer the data. In certain circumstances, it may be sufficient for it
merely to perform the allocations and deallocations. An example of where
this may be useful is the message loopback. The message may be returnedto the sender after changing its payload type to one whose marshalling
function simply frees the payload when the message is transmitted andallocates a payload when the message is received. This avoids the overheadof transferring data that is no longer of interest but allows the payload tostill be automatically managed by the system.
The only added complexity is the need for two marshalled types instead ofone, and for the user threads to change the payload type between the two,according to whether the message is “full” or “empty”. The Empty Pooland Empty Heap standard marshalling functions are provided for thispurpose.
When defining a marshalled payload type in the Kernel tab, the user canselect either standard or custom marshalling. For standard marshalling,
the choice must be made between (at least) heap or pool marshalling,according to whether the payloads are allocated from a C/C++ heap (using
the VisualDSP++ multiple heap API extensions) or a VDK memory pool.
The HeapID or PoolID must also be specified. For custom marshalling, thename of the marshalling function must be supplied, and a source module
containing a skeleton of the marshalling function is automatically created.
It is then the user’s task to add the code that allocates and deallocates, andreads and writes, the actual payload.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-45

Signals

Device Drivers for Messaging
Device drivers employed in message transfer must provide certain properties assumed in the design of the routing threads:• Synchronous operation—once a write call returns, the caller knowsthat the data has been sent.
• Flow control—no data is lost if a Write (by the sender) is initiatedbefore the corresponding read (by the receiver).
• Reliable delivery—all data sent (written) will be received (Read) at
the other side.
As mentioned above, the contents of messages are written to and readfrom the device driver as message packets. These packets are 16 bytes(128 bits) in size and are always read and written by a single operation ofthat size. Device drivers can, therefore, be optimized for these transfers, as
they are the most frequent case, although, other sizes must still besupported.
As well as the message packets, the device driver must also transfer themessage payloads which are written and read by the marshalling functions.
It is the responsibility of the application designer to ensure that the marshalling functions and the device drivers operate together correctly, that is,any transfer size or alignment restrictions imposed by the drivers are metby the payloads. This is also true of marshalled payload types using standard marshalling—the sizes and alignments of the heap or memory poolblocks must be acceptable to the messaging device drivers.
Where a bidirectional hardware device (such as a link port on
TigerSHARC or certain SHARC processors) is managed by a single device
driver instance on each of the two nodes that it connects, then it is necessary for the device driver to permit itself to be opened by both anincoming and an outgoing routing thread. A generalized multiple-open
capability is not required. The ability to be simultaneously open once forreading and once for writing (sometimes known as a split open) is suffi-

3-46

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDKcient. Alternatively, for some devices it may be preferable to create two
device driver instances on each node, so that the hardware appears as two
unidirectional connections.
Routing Topology
Application designers must choose the routing structure for a particularapplication. This choice is closely linked to the organization of the target
hardware.
At one extreme, the ideal situation is to have a direct connection between
each node. In such a configuration, no through-routing is required: thatis, each message post requires only one “hop”. This can be achieved for asmall numbers of nodes (between two and five). However, the number ofconnections quickly becomes prohibitive as the number of nodes
increases.
At the other extreme, the minimum number of connections required is
one incoming and one outgoing per node. This is sufficient to allow thenodes to be connected in a simple “ring” configuration. However, a message post may require many “hops” if the sender and receiver are widely
separated on the ring. If the connections are bidirectional (for example,
link ports) and each node has two, then a bidirectional ring—with messages circulating in both directions—is possible.
Between these two extremes many configurations are possible, including
grids, cubes, and hypercubes (if sufficient links are available per node).
Where a host system forms part of the design and is participating in messaging, then it must also be included in the routing topology.
The design of the routing network is best begun “on paper”, as a Directed
Graph of bubbles (nodes) and arrowhead lines (connections). Designers
should consider how to assign threads to nodes so that as much message
communication as possible is over direct connections. Once the topology
has been established within the constraints of the available hardware, thena system can be described in terms of node IDs, device drivers, and rout-

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-47

Signals

ing threads. This information can then be entered into the Kernel tab of
the per-node projects for the application.
Example projects are supplied with VisualDSP++ for certain EZ-KIT Liteboards that have more than one processor core (for example, the
ADSP-BF561 processor), or that have connections specifically designed
for connecting processors (for example, link ports on TigerSHARC andcertain SHARC processors). These examples have appropriate device drivers and Routing Threads already in place (for fully-connected topologies,
since the numbers of nodes will be small) and may be used as a starting
point for new applications.

Events and Event Bits
Events and event bits are signals used to regulate thread execution based on
the state of the system. An event bit is used to signal that a certain systemelement is in a specified state. An event is a Boolean operation performedon the state of all event bits. When the Boolean combination of event bits
is such that the event evaluates to TRUE, all threads that are pending on theevent are moved to the ready queue and the event remains TRUE. Any
thread that pends on an event that evaluates as TRUE does not block, butwhen event bits have changed causing the event to evaluate as FALSE, any
thread that pends on that event blocks.
The number of events and event bits is limited to a processor’s word size
minus one. Therefore, on Blackfin, SHARC and TigerSHARC processors
there can be 31 events and event bits.
Behavior of Events
Each event maintains the VDK_EventData data structure that encapsulates
all the information used to calculate an event’s value:
typedef struct
{
bool

3-48

matchAll;

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDK

unsigned int
unsigned int} VDK_EventData;

values;mask;

When setting up an event, configure a flag describing how to treat a mask
and target value:•

matchAll: TRUE when an event must have an exact match on all of

the masked bits. FALSE if a match on any of the masked bits resultsin the event recalculating to TRUE.
•

values: The target values for the event bits masked with the mask

field of the VDK_EventData structure.
•mask: The event bits that the event calculation is based on.

Unlike semaphores, events are TRUE whenever their conditions are TRUE,
and all threads pending on the event are moved to the ready queue. If a
thread pends on an event that is already TRUE, the thread continues to run,and the scheduler is not called. Like a semaphore, a thread pending on an
event that is not TRUE blocks until the event becomes true, or the thread’stimeout is reached. Pending with a timeout of zero on an event pends
without timeout.
Global State of Event Bits

The state of all the event bits is stored in a global variable. When a user
sets or clears an event bit, the corresponding bit number in the global
word is changed. If toggling the event bit affects any events, that event isrecalculated. This happens either during the call to SetEventBit() or
ClearEventBit() (if called within a scheduled region), or the next time
the scheduler is enabled with a call to PopUnscheduledRegion().
Event Calculation

To understand how events use event bits, see the following examples.
Example 1: Calculation for an All Event

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-49

Signals

4

3

2

1

0

event bit number

0

1

0

1

0

<—

bit value

0

1

1

0

1

<—

mask

0

1

1

0

0

<—

target value

Event is FALSE because the global event bit 2 is not the target value.
Example 2: Calculation for an All Event
4

3

2

1

0

event bit number

0

1

1

1

0

<—

bit value

0

1

1

0

1

<—

mask

0

1

1

0

0

<—

target value

Event is TRUE.
Example 3: Calculation for an Any Event
4

3

2

1

0

event bit number

0

1

0

1

0

<—

bit value

0

1

1

0

1

<—

mask

0

1

1

0

0

<—

target value

Event is TRUE since bits 0 and 3 of the target and global match.
Example 4: Calculation for an Any Event
4

3

2

1

0

event bit number

0

1

0

1

1

<—

bit value

0

1

1

0

1

<—

mask

0

0

1

0

0

<—

target value

Event is FALSE since bits 0, 2, and 3 do not match.

3-50

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDK

Effect of Unscheduled Regions on Event Calculation

Each time an event bit is set or cleared, the scheduler is entered to recalculate all dependent event values. By entering an unscheduled region, you
can toggle multiple event bits without triggering spurious event calculations that could result in erroneous system conditions. Consider thefollowing code.
/* Code that accidentally triggers Event1 trying to set up
Event2. Assume the prior event bit state = 0x00. */VDK_EventData data1 = { true, 0x1, 0x3 };VDK_EventData data2 = { true, 0x3, 0x3 };VDK_LoadEvent(kEvent1, data1);
VDK_LoadEvent(kEvent2, data2);
VDK_SetEventBit(kEventBit1); /* will trigger Event1 by accident*/
VDK_SetEventBit(kEventBit2); /* Event1 is FALSE, Event2 is TRUE*/

Whenever you toggle multiple event bits, enter an unscheduled region to
avoid the above loopholes. For example, to fix the accidental triggering of
Event1 in the above code, use the following code:
VDK_PushUnscheduledRegion();VDK_SetEventBit(kEventBit1);/* Event1 has not been triggered*/

VDK_SetEventBit(kEventBit2);/* Event1 is FALSE, Event2 is TRUE */VDK_PopUnscheduledRegion();Thread’s Interaction With Events
Threads interact with events by pending on events, setting or clearing
event bits, and by loading a new VDK_EventData into a given event.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-51

SignalsPending on an Event

Like semaphores, threads can pend on an event’s condition becoming TRUE
with a timeout. Figure 3-15 illustrates the process of pending on an event.
Thread 1 continues execution
Yes

Yes
Ready QueueIs
Thread 1 of
the highest
priority?

Order threads
by priority,then
All pending threads
FIFO

PendEvent()
Does
Event evaluateas TRUE?

Thread 1

Thread 1's
error function
is called

NoNo1). Invoke Scheduler
2). Switch out Thread 1

Is the timeout
kDoNotWait?

Yes

No
Yes

No
Thread 1 blocks
until Event is TRUE

Is
there a timeout before theEvent became
available?

Yes

No

Is
kNoTimeoutError
set?

Figure 3-15. Pending on an Event
A thread calls PendEvent() and specifies the timeout. If the event becomes
TRUE before the timeout is reached, the thread (and all other threads pending on the event) is moved to the ready queue. Calling PendEvent() with atimeout of zero means that the thread is willing to wait indefinitely. Calling PendEvent() with a timeout of kDoNotWait1 means that the thread willcontinue execution even if the event is not available.

1

3-52

VDK::kDoNotWait in C++ and VDK_kDoNotWait in C.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDK

Setting or Clearing of Event Bits

Changing the status of the event bits can be accomplished in both theinterrupt domain and the thread domain. Each domain results in slightly
different results.
From the Thread Domain:
Figure 3-16 illustrates the process of setting or clearing an event bit fromthe thread domain.
Thread Domain/Scheduled Region

Thread 1 continues execution
SetEventBit()
ClearEventBit()

Yes1). Invoke Scheduler

Thread 12). Recalculate dependent bits

Is
Thread 1of the highest
priority?
No
Switch out Thread 1

Figure 3-16. Setting or Clearing an Event Bit from Thread Domain
A thread can set an event bit by calling SetEventBit() and clear it by calling ClearEventBit(). Calling either from within a scheduled region
recalculates all events that depend on the event bit and can result in ahigher priority thread being context switched in.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-53

Signals

From the Interrupt Domain:
Figure 3-17 illustrates the process of setting or clearing of an event bitfrom the interrupt domain.

Interrupt Domain/Scheduled Region
Switch out theinterrupted thread
No

VDK_ISR_SET_EVENTBIT_()VDK_ISR_CLEAR_EVENTBIT_()
1). Set Reschedule ISR
ISR 1
ISR 2

2). Invoke Scheduler

Recalculate dependent
bits

ISR 3

Thread DomainIsthe interrupted threadof the highest
priority?
Yes

RTI returns to the interrupted thread

Figure 3-17. Setting or Clearing an Event Bit from Interrupt Domain
An ISR can call VDK_ISR_SET_EVENTBIT_() and
VDK_ISR_CLEAR_EVENTBIT_() to change an event bit value and, possibly,

free a new thread to run. Calling these macros does not result in a recalculation of the events; however, the low priority software interrupt is set andthe scheduler entered. If the interrupted thread is in a scheduled region,an event recalculation takes place and can cause a higher priority thread tobe context switched in. If an ISR sets or clears multiple event bits, the calls
do not need to be protected with an unscheduled region (since there is no
thread scheduling in the interrupt domain). For example,/* The following two ISR calls do not need to be protected: */VDK_ISR_SET_EVENTBIT_(kEventBit1);
VDK_ISR_SET_EVENTBIT_(kEventBit2);

3-54

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDK

Loading New Event Data into an Event

From the thread scheduling domain, a thread can get the VDK_EventData
associated with an event with the GetEventData() API. Additionally, a
thread can change the VDK_EventData with the LoadEvent() API. A call to
LoadEvent() causes a recalculation of the event’s value. If a higher priority
thread becomes ready because of the call, it starts running if the scheduler
is enabled.

Device Flags
Because of the special nature of device drivers, most require synchronization methods that are similar to those provided by events and semaphores,
but with different operation. Device flags are created to satisfy the specificcircumstances device drivers might require. Much of their behavior cannot
be fully explained without an introduction to device drivers, which arecovered extensively in “Device Drivers” on page 3-63.
Behavior of Device Flags
Like events and semaphores, a thread can pend on a device flag, but unlike
semaphores and events, a device flag is always FALSE. A thread pending on
a device flag immediately blocks. When a device flag is posted, all threads
pending on it are moved to the ready queue.
Device flags are used to communicate to any number of threads that adevice has entered a particular state. For example, assume that multiple
threads are waiting for a new data buffer to become available from an A/D
converter device. While neither a semaphore nor an event can correctly
represent this state, a device flag’s behavior can encapsulate this system
state.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-55

Interrupt Service Routines

Thread’s Interaction With Device Flags
A thread accesses a device flag through two APIs: PendDeviceFlag() and
PostDeviceFlag(). Unlike most APIs that can cause a thread to block,
PendDeviceFlag() must be called from within a critical region.
PendDeviceFlag() is set up this way because of the nature of device drivers. See “Device Drivers” on page 3-63 for a more information about
device flags and device drivers.

Interrupt Service Routines
Starting with VisualDSP++ 4.0, VDK ISRs can be written assembly, C, or
C++. All previous releases of VDK restricted users to using assembly forwriting ISRs. While the new support provides increased flexibility, it
should be noted that there are performance considerations and certain
restrictions associated with writing your ISRs in C/C++, as described
below.
The original VDK philosophy related to the writing of ISRs still holds
true. ISRs should be short routines that perform essential tasks and thenpost semaphores, change event bit values, activate device drivers, and soon, in order to switch execution to the relevant thread or device driver.
The bulk of any associated calculations should be performed at threadlevel. This approach reduces the number of context saves/restores
required, decreases interrupt latency, and still keeps as much code as possible in a high-level language.
VDK’s interrupt architecture does not support the signal.h strategy forhandling interrupts.

Enabling and Disabling Interrupts
Each processor architecture has a slightly different mechanism for masking
and unmasking interrupts. Some architectures require that the state of the

3-56

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDKinterrupt mask be saved to memory before servicing an interrupt or an
exception, and the mask be manually restored before returning. Since thekernel installs interrupts (and exception handlers on some architectures),directly writing to the interrupt mask register may produce unintended
results. Therefore, VDK provides a simple and platform-independent API
to simplify access to the interrupt mask.
A call to GetInterruptMask() returns the actual value of the interrupt
mask, even if it has been saved temporarily by the kernel in private storage. Likewise, SetInterruptMaskBits() and ClearInterruptMaskBits()
set and clear bits in the interrupt mask in a robust and safe manner. Interrupt levels with their corresponding bits set in the interrupt mask areenabled when interrupts are globally enabled. See the Hardware Reference
manual for your target processor for more information about the interrupt
mask.
VDK also presents a standard way of turning interrupts on and off globally. Like unscheduled regions (in which the scheduler is disabled), VDK
supports critical regions where interrupts are disabled. A call to PushCriticalRegion() disables interrupts, and a call to PopCriticalRegion()re-enables interrupts. These API calls implement a stack-style interface, as
described in “Protected Regions” on page 1-7. Users are discouraged fromturning interrupts off for long sections of code since this increases interrupt latency.

Interrupt Architecture
VDK ISRs can be written in assembly or C/C++. The following sections
explain the advantages and disadvantages of each approach.
Assembly Interrupts
ISRs written in assembly are the most efficient way of servicing interrupts.
The overhead of saving and restoring processor state is eliminated, alongwith need to set up a C run-time environment. ISRs written in assembly

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-57

Interrupt Service Routinesmust save and restore only the registers that they use. The lightweightnature of assembly ISRs also encourages the use of interrupt nesting tofurther reduce latency. (VDK enables interrupt nesting by default on processors that support it.)
C/C++ Interrupts
ISRs written in C/C++ may simplify the coding of the routines, but there
are inherent overheads with implementing ISRs in a high-level language.
A C/C++ run-time must be established on entry to the ISR, incurring adelay before any actual ISR code is executed. Also, the necessary processor
state must be saved on entry to the ISR and restored on exit. If a C/C++
ISR calls any functions that are not present in the same module, then theentire processor state will be saved and restored, unless theregs_clobbered pragma is used to specify the registers modified by thefunction. (Refer to your processor’s C/C++ Compiler and Library Manualfor details.) An additional point of note is that the majority of the
run-time library is not interrupt-safe, and so can not be used in ISRs.
(Refer to your processor’s C/C++ Compiler and Library Manual for
details.) Thus, there are certain limits imposed as to what can be done in a
C/C++ ISR.
Vector Table
The method VDK uses to install interrupt handlers depends on the processor family used, and the underlying run-time library support. Refer tothe generated skeleton ISR code for further details on any restrictions,requirements, or options associated with adding your own code to ISRs.
By default, VDK reserves at least two interrupts: the timer interrupt andthe lowest priority software interrupt. For a discussion about the timer
interrupt, see “Timer ISR” on page 3-61. For information about the lowest priority software interrupt, see “Reschedule ISR” on page 3-62. For
information on any additional interrupts reserved by VDK for particular
processors, see Appendix A, “Processor-Specific Notes” on page A-1.

3-58

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDKGlobal Data
Often ISRs need to communicate data back and forth to the thread
domain besides semaphores, event bits, and device driver activations. ISRs
can use global variables to get data to the thread domain, but you must
remember to wrap any access to or from that global data in a criticalregion and to declare the variable as volatile (in C/C++). For example,
consider the following,/* MY_ISR.asm */.EXTERN _my_global_integer;<REG> = data;
DM(_my_global_integer) = <REG>;/* finish up the ISR, enable interrupts, and RTI. */and in the thread domain:/* My_C_Thread.c */volatile int my_global_integer;/* Access the global ISR data */VDK_PushCriticalRegion();if (my_global_integer == 2)
my_global_integer = 3;
VDK_PopCriticalRegion();Communication With Thread Domain
VDK supplies a set of assembly macros and APIs callable from C/C++
ISRs that can be used to communicate system state to the thread domain.
See “Assembly Macros and C/C++ ISR APIs” on page 5-235 for more
information.
The assembly macros are called from the interrupt domain; therefore, they
make no assumptions about processor state, available registers, or parameters. In other words, the assembly macros can be called without

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-59

Interrupt Service Routines

consideration of saving state or having processor state trampled during a
call.
Take for example, the following three equivalent
VDK_ISR_POST_SEMAPHORE_() calls:.VAR/DATA

semaphore_id;/* Pass the value directly */VDK_ISR_POST_SEMAPHORE_(kSemaphore1);/* Pass the value in a register */<REG> = kSemaphore1;
VDK_ISR_POST_SEMAPHORE_(<REG>);/* <REG> was not trampled *//* Post the semaphore one last time using a DM */DM(semaphore_id) = <REG>;VDK_ISR_POST_SEMAPHORE_(DM(semaphore_id));

Additionally, no condition codes are affected by the assembly macros, noassumptions are made about having space on any hardware stacks (forexample, PC or status), and all VDK internal data structures aremaintained.
The C/C++ ISR APIs provide equivalent functionality for use in ISRs
written in C/C++.
The assembly macros and APIs callable from C/C++ ISRs raise the low
priority software interrupt if thread domain scheduling is required after allother interrupts are serviced. For a discussion of the low priority softwareinterrupt, see “Reschedule ISR” on page 3-62. Refer to Appendix A, “Processor-Specific Notes” on page A-1, for additional information about ISR
APIs.
Within the interrupt domain, every effort should be made to enable interrupt nesting. Nesting may be disabled when an ISR begins. However,

3-60

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDKleaving it disabled is analogous to staying in an unscheduled region in thethread domain; other ISRs are prevented from executing, even if they havehigher priority. Allowing nested interrupts potentially lowers interrupt
latency for high-priority interrupts.

Timer ISR
By default, VDK reserves a timer interrupt. The timer is used to calculate
round-robin times, sleeping thread time to keep sleeping, and periodic
semaphores. One VDK tick is defined as the time between timer interrupts. It is the finest resolution measure of time in the kernel. The timer
interrupt can cause a low priority software interrupt (see “Reschedule ISR”
on page 3-62). It is possible to change the interrupt used for the VDKtimer interrupt from the default, leaving the default interrupt level free forcustomer use. (Refer to “Specifying System Parameters” in online Help for
details.) Additionally, it is possible to specify “None” for the VDK timer
interrupt if VDK timing services are not required.
For the default configuration, VDK sets the appropriate timer registers to
produce a repeating interrupt at a set period. The values for these registers
are calculated from the information specified for the Clock Frequency andTick Period fields in the System section of the Kernel tab.
If a different interrupt is chosen, VDK will install the VDK timer ISR tothat interrupt level, and unmask that level after start-up. Once changed, itis the user’s responsibility to configure and generate a repeating interrupt
for that interrupt level. Without a repeating interrupt, the timing services
for VDK will not work.
the VDK timer ISR is reassigned to another interrupt or “None”
L Ifis specified
as the interrupt, do not use theand
SetTickPeriod()

SetClockFrequency() APIs as they modify the timer registers.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-61

I/O Interface

Reschedule ISR
VDK designates the lowest priority interrupt that is not tied to a hardware
device as the reschedule ISR. This ISR handles housekeeping when aninterrupt causes a system state change that can result in a new high priority thread becoming ready. If a new thread is ready and the system is in ascheduled region, the software ISR saves off the context of the current
thread and switches to the new thread. If an interrupt has activated a
device driver, the low priority software interrupt calls the dispatch function for the device driver. For more information, see “Dispatch Function”
on page 3-68.
On systems where the lowest priority non-hardware-tied interrupt is not
the lowest priority interrupt, all lower priority interrupts must run withinterrupts turned off for their entire duration. Failure to do so may resultin undefined behavior.

I/O Interface
The I/O interface provides a mechanism for creating an interface between
the external environment and VDK applications. In VisualDSP++ 5.0,
only device driver objects can be used to construct the I/O interface.
On Blackfin processors, the VDK device driver model has been deprecatedin favour of the system services device driver model. The VDK device
driver model is used still to support I/O for SHARC processors, as well as
multiprocessor messaging for the dual-core Blackfin processors(ADSP-BF561).

I/O Templates
I/O templates are analogous to thread types. I/O templates are used to
instantiate I/O objects. In VisualDSP++ 5.0, the only types of I/O templates available (therefore the only classes of I/O objects) are for device

3-62

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDKdrivers. In order to create an instance of a device driver, a boot I/O object
must be added to the VDK project using the device driver template. You
can distinguish between different instances of the same device driver. For
more information, see “Init” on page 3-71.

Device Drivers
The role of a device driver is to abstract the details of the hardware implementation from the software designer. For example, a software engineer
designing a Finite Impulse Response (FIR) filter does not need to understand the intricacies of the converters and is able to concentrate on the
FIR algorithm. The software can then be reused on different platforms,
where the hardware interface differs.
The Communication Manager controls device drivers in VDK. Using theCommunication Manager APIs, you can maintain the abstraction layers
between device drivers, interrupt service routines, and executing threads.
This section details how the Communication Manager is organized.
Execution
Device drivers and interrupt service routines are tied very closely together.
Typically, DSP developers prefer to keep as much time critical code inassembly as possible. The Communication Manager is designed such thatyou can keep interrupt routines in assembly (the time critical pieces), andinterface and resource management for the device in a high-level language
without sacrificing speed. The Communication Manager attempts to keep
the number of context switches to a minimum, to execute management
code at reasonable times, and to preserve the order of priorities of running
threads when a thread uses a device. However, you need to thoroughly
understand the architecture of the Communication Manager to write yourdevice driver.
There is only one interface to a device driver—through a dispatch function. The dispatch function is called when the device is initialized, when a

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-63

I/O Interface

thread uses a device (open/close, read/write, control), or when an interrupt service routine transfers data to or from the device. The dispatch
function handles the request and returns. Device drivers should not block(pend) when servicing an initialize request or a request for more data by
an interrupt service routine. However, a device driver can block when servicing a thread request and the relevant resource is not ready or available.
Device driver initialization and ISR requests are handled within criticalregions enforced by the kernel, so their execution does not have to bereentrant. A thread-level request must protect global variables within critical or unscheduled regions.
Parallel Scheduling Domains
This section focuses on a unique role of device drivers in the VDK architecture. Understanding device drivers requires some understanding of thetime and method by which device driver code is invoked. VDK applications may be factored into two domains, referred to as the thread domain
and the ISR domain (see Figure 3-18). This distinction is not an arbitraryor unnecessary abstraction. The hardware architecture of the processor aswell as the software architecture of the kernel reinforces this notion. You

3-64

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDKshould consider this distinction when designing an application and apportioning its code.

Thread Domain
software/kernelscheduling isbased onthread priority

Threadselected

ISR Domain
Interrupt

All ISRs
complete andno changeof state

hardwarescheduling isbased oninterrupt priority

All ISRs complete
and DD activatedAll ISRs
complete andstate changed

DeviceDrivers

Scheduler
Device Flags

Figure 3-18. Parallel Scheduling Domains
Threads are scheduled based on their priority and the order in which they
are placed in the ready queue. The scheduling portion of the kernel is
responsible for selecting the thread to run. However, the scheduler does
not have complete control over the processor. It may be preempted by aparallel and higher priority scheduler—the interrupt and exception hardware. While interrupts or exceptions are being serviced, thread priorities
are temporarily moot. The position of threads in the ready queue becomessignificant again only when the hardware relinquishes control back to thesoftware-based scheduler.
Each of the domains has strengths and weaknesses that dictate the type ofcode suitable to be executed in that environment. The scheduler in thethread domain is invoked when threads are moved to or from the readyqueue. Threads each have their own stack and may be written in ahigh-level language. Threads always execute in “supervisor” or “kernel

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-65

I/O Interfacemode” (if the processor makes this distinction). Threads implement algorithms and are allotted processor time based on the completion of higher
priority activity.
In contrast, scheduling in the interrupt domain has the highest systemwide priority. Any “ready” ISR takes precedence over any ready thread(outside critical regions), and this form of scheduling is implemented in
hardware. If ISRs are written in assembly, they must manually restore any
registers that they modify. ISRs respond to asynchronous peripherals at
the lowest level only. The routine should perform only such activities thatare so time critical that data would be lost if the code is not executed assoon as possible. All other activities should occur under the control of thekernel’s scheduler based on priority.
Transferring from the thread domain to the interrupt domain is simple
and automatic, but returning to the thread domain can be much morelaborious. If the ready queue is not changed while in the interrupt
domain, then the scheduler need not run when it regains control of thesystem. The interrupted thread resumes execution immediately. If theready queue has changed, the scheduler must further determine whether
the highest priority thread has changed. If it has changed, the scheduler
must initiate a context switch.
Device drivers fill the gap between the two scheduling domains. They areneither thread code nor ISR code, and they are not directly scheduled byeither the kernel or the interrupt controller. Device drivers are implemented as C++ objects and run on the stack of the currently running
thread. However, they are not “owned” by any thread, and may be used bymany threads concurrently.
Using Device Drivers
From the point of view of a thread, there are five functional interfaces todevice drivers: OpenDevice(), CloseDevice(), SyncRead(), SyncWrite(),and DeviceIOCtl(). The names of the APIs are self-explanatory since

3-66

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDK

threads mostly treat device drivers as black boxes. Figure 3-19 illustrates
the device drivers’ interface.

ISR(interrupt)
OpenDevice()
CloseDevice()
SyncRead()
SyncWrite()
DeviceIOCtl()
MyThread::Run()

VDK_ISR_ACTIVATE_DEVICE_

Device Driver

PendDeviceFlag()
PostDeviceFlag()(return)

Device Flag

Figure 3-19. Device Driver APIs
A thread uses a device by opening it, reading and/or writing to it, andclosing it. The DeviceIOCtl() function is used for sending device-specificcontrol information messages. Each API is a standard C/C++ function callthat runs on the stack of the calling thread and returns when the function
completes. However, when the device driver does not have a needed
resource, one of these functions may cause the thread to be removed fromthe ready queue and block on a signal, similar to a semaphore or an event,called a “device flag.”Interrupt service routines have only one API call relating to device drivers:
VDK_ISR_ACTIVATE_DEVICE_(). This macro is not a function call, and pro-gram flow does not transfer from the ISR to the device driver and back.
Rather, the macro sets a flag indicating that the device driver’s “activate”
routine should execute after all interrupts have been serviced.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-67

I/O Interface

The remaining two API functions, PendDeviceFlag() and PostDeviceFlag(), are typically called from within the device driver itself. For
example, a call from a thread to SyncRead() might cause the device driverto call PendDeviceFlag() if there is no data currently available. This
would cause the thread to block until the device flag is posted by anothercode fragment within the device driver that is providing the data.
As another example, when an interrupt occurs because an incoming data
buffer is full, the ISR might move a pointer so that the device begins filling an empty buffer before calling VDK_ISR_ACTIVATE_DEVICE_(). The
device driver’s activate routine may respond by posting a device flag andmoving a thread to the ready queue so that it can be scheduled to process
the new data.
Dispatch Function

The dispatch function is the core of any device driver. This function takes
two parameters and returns a void* (the return value depends on the input
values). A dispatch function declaration for a device driver is as follows:
C Driver Code:void* MyDevice_DispatchFunction(VDK_DispatchID

inCode,VDK_DispatchUnion

inData);void* MyDevice::DispatchFunction(VDK::DispatchID

inCode,C++ Driver Code:VDK::DispatchUnion&inData);

The first parameter is an enumeration that specifies why the dispatch
function has been called:enum VDK_DispatchID{
VDK_kIO_Init,
VDK_kIO_Activate,
VDK_kIO_Open,

3-68

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDKVDK_kIO_Close,
VDK_kIO_SyncRead,
VDK_kIO_SyncWrite,
VDK_kIO_IOCtl};

The second parameter is a union whose value depends on the enumeration
value:
union VDK_DispatchUnion{
struct OpenClose_t{
void**dataH;char*flags; /* used for kIO_Open only */};struct ReadWrite_t{
void**dataH;
VDK_Ticks
timeout;
unsigned int dataSize;
int*data;};
struct IOCtl_t{
void**dataH;
void*command;char*parameters;};
struct Init_t{
void*pInitInfo;};};

The values in the union are only valid when the enumeration specifies thatthe dispatch function has been called from the thread domain (kIO_Open,kIO_Close, kIO_SyncRead, kIO_SyncWrite, kIO_IOCtl).
A device driver’s dispatch function can be structured as follows:

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-69

I/O Interface

In C:
void* MyDevice_DispatchFunction(VDK_DispatchID
inCode,VDK_DispatchUnion inData){
switch(inCode){case VDK_kIO_Init:/* Init the device */case VDK_kIO_Activate:/* Get more data ready for the ISR */case VDK_kIO_Open:/* A thread wants to open the device... *//* Allocate memory and prepare everything else */case VDK_kIO_Close:/* A thread is closing a connection to the device...*//* Free all the memory, and do anything else */case VDK_kIO_SyncRead:/* A thread is reading from the device *//* Return an unsigned int of the num. of bytes read */case VDK_kIO_SyncWrite:/* A thread is writing to the device *//* Return an unsigned int of the number of bytes *//* written */case VDK_kIO_IOCtl:/* A thread is performing device-specific actions: */default:/* Invalid DispatchID code */return 0;}}

In C++:
void* MyDevice::DispatchFunction(VDK::DispatchID
inCode,
VDK::DispatchUnion &inData){
switch(inCode){case VDK::kIO_Init:

3-70

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDK/* Init the device */case VDK::kIO_Activate:/* Get more data ready for the ISR */case VDK::kIO_Open:/* A thread wants to open the device... *//* Allocate memory and prepare everything else */case VDK::kIO_Close:/* A thread is closing a connection to the device...*//* Free all the memory, and do anything else */case VDK::kIO_SyncRead:/* A thread is reading from the device *//* Return an unsigned int of the num. of bytes read */case VDK::kIO_SyncWrite:/* A thread is writing to the device *//* Return an unsigned int of the number of bytes *//* written */case VDK::kIO_IOCtl:/* A thread is performing device-specific actions: */default:/* Invalid DispatchID code */return 0;}}

Each of the different cases in the dispatch function are discussed below.
Init

The device dispatch function is called with the VDK_kIO_Init parameter
for C-style device and VDK::kIO_Init for C++-style drivers at system boottime. All device-specific data structures and system resources should be set
up at this time. The device driver init function is called within a criticalregion and so should not call any APIs that dispatch an error or can block.
As all device driver init functions are executed before any threads havebeen run, they can be used to run any required initialization code. This isapplicable even if the device driver type is a stub whose only purpose is tocontain the initialization code.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-71

I/O Interface

A union is passed to the device dispatch function whose value is definedwith the Init_t of the VDK_DispatchUnion. The Init_t is defined asfollows.
struct Init_t{
void *pInitInfo;}
Init_t.pInitInfo: A pointer (type void*) to the value defined in the Ini-

tializer field of the Kernel tab for boot I/O objects (see “Device Driver
Parameterization” on page 3-76).
Open and Close

When a thread opens or closes a device with OpenDevice() orCloseDevice(), the device dispatch function is called with VDK_kIO_Open
or VDK_kIO_Close. The dispatch function is called from the thread
domain, so any stack-based variables are local to that thread. Access toshared data (data that may be accessed by threads and/or interrupts and/or
device driver activate functions) should be appropriately protected by theuse of unscheduled regions, critical regions, or other means.
When a thread calls the dispatch function attempting to open or close adevice, the API passes a union to the device dispatch function whose value
is defined with the OpenClose_t of the VDK_DispatchUnion. The
OpenClose_t is defined as follows.
struct OpenClose_t{
void**dataH;char*flags;};/* used for kIO_Open only */OpenClose_t.dataH: A pointer to a thread-specific location that a device
driver can use to hold any thread-specific resources. For example, a thread
can malloc space for a structure that describes the state of a thread associ-

3-72

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDKated with a device. The pointer to the structure can be stored in *dataH,
which is then accessible to every other dispatch call involving this thread.
A device driver can free the space when the thread calls CloseDevice().
OpenClose_t.flags: The second parameter passed to an OpenDevice()call is supplied to the dispatch function as the value of
OpenClose_t.flags. This is used to pass any device-specific flags relevantto the opening of a device. Note that this part of the union is not used ona call to CloseDevice().

[ Atime.maximum of eight devices can be opened per thread at any one
Read and Write

A thread that needs to read or write to a device it has opened calls
SyncRead() or SyncWrite(). The dispatch function is called in the thread
domain and on the thread’s stack. These functions call the device dispatch
function with the parameters passed to the API in the VDK_DispatchUnion,
and the flags VDK_kIO_SyncRead or VDK_kIO_SyncWrite. The ReadWrite_t
is defined as follows:
struct ReadWrite_t{
void**dataH;
VDK::Ticks
timeout;
unsigned int dataSize;
int*data;};
ReadWrite_t.dataH: A thread-specific location, which is passed to the dispatch function on the opening of a device by an OpenDevice() call. Thisvariable can be used to store a pointer to a thread-specific data structure
detailing what state the thread is in while dealing with the device.
ReadWrite_t.timeout: The amount of time in Ticks that a thread is will-

ing to wait for the completion of a SyncRead() or SyncWrite() call. If thisVisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-73

I/O Interface

timeout behavior is required, it must be implemented by using the valueof ReadWrite_t.timeout as an argument to an appropriate PendDeviceFlag() call in the dispatch function.
ReadWrite_t.dataSize: The amount of data that the thread reads from orwrites to the device.
ReadWrite_t.data: A pointer to the location that the thread writes thedata to (on a read), or reads from (on a write).

Like calls to the device dispatch function for opening and closing, the calls
to read and write are not protected with a critical or unscheduled region.
If a device driver accesses global data structures during a read or write, theaccess should be protected with critical or unscheduled regions. See thediscussion in “Device Drivers” on page 3-63 for more information about
regions and pending.
IOCtl

VDK supplies an interface for threads to control a device’s parameterswith the DeviceIOCtl() API. When a thread calls DeviceIOCtl(), thefunction sets up some parameters and calls the specified device’s dispatch
function with the value VDK_kIO_IOCtl and the VDK_DispatchUnion set up
as a IOCtl_t.
The IOCtl_t is defined as follows.
struct IOCtl_t{
void**dataH;

void*command;char*parameters;};
IOCtl_t.dataH: A thread-specific location, which is passed to the dispatch

function on the opening of a device by an OpenDevice() call. This variable

3-74

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDK

can be used to store a pointer to a thread-specific data structure detailingwhat state the thread is in while dealing with the device.
IOCtl_t.command: A device-specific pointer (second parameter from theDeviceIOCtl() function).
IOCtl_t.parameters: A device-specific pointer (third parameter from theDeviceIOCtl() function).

Like read/write and open/close, a device dispatch function call for IOCtl is
not protected by a critical or unscheduled region. If a device accesses
global data structures, the device driver should protect them with a criticalor an unscheduled region.
Activate

Often a device driver needs to respond to state changes caused by ISRs.
The device dispatch function is called with a value VDK_kIO_Activate atsome point after an ISR has called the macro
VDK_ISR_ACTIVATE_DEVICE_().
When the ISR calls VDK_ISR_ACTIVATE_DEVICE_(), a flag is set indicatingthat a device has been activated, and the low priority software interrupt is
triggered to run (see “Reschedule ISR” on page 3-62). When the scheduler
is entered through the low priority software interrupt, the device’s dispatch function is called with the VDK_kIO_Activate value.
The activate part of a device dispatch function should handle posting signals, so that threads waiting on certain device states can continue running.
For example, assume that a D/A ISR runs out of data in its buffer. The
ISR calls VDK_ISR_ACTIVATE_DEVICE_() with the IOID of the device driver.
When the device dispatch function is called with the VDK_kIO_Activate,
the device posts a device flag or semaphore that reschedules any threads
that are pending.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-75

I/O Interface

[ The
and

PostDeviceFlag(), PostSemaphore(), PushCriticalRegion(),

PopCriticalRegion() APIs are the only VDK APIs that aresafe to call from the activate function.

Device Driver Parameterization

Where more than one instance of a particular device driver is to be used,an ‘initializer’ value can be passed to each boot I/O object to provide a
unique instance number. The Initializer field in the Kernel tab is used to
do this for boot I/O objects (see the online Help for details). The initializer is passed into the init dispatch function via Init_t.pInitInfo. Thisis a pointer (type void*) to the value defined in the Initializer field.
The value can be extracted with:
int initializer = *((int *)inUnion.Init_t.pInitInfo);

The value should be then stored in private data belonging to the device;for example, in a member variable.
Device Flags
Device flags are synchronization primitives, similar to semaphores, events,and messages, but device flags have a special association with device drivers. Like semaphores and events, a thread can pend on a device flag. Thismeans that the thread waits until the flag is posted by a device driver. The
post typically occurs from the activate function of a device driver’s dispatch function.
Pending on a Device Flag

When a thread pends on a device flag (unlike with semaphores, events,and messages), the thread always blocks. The thread waits until the flag isposted by another call to the device’s dispatch function. When the flag isposted, all threads that are pending on the device flag are moved to theready queue. Since posting a device flag with the PostDeviceFlag() API
moves an indeterminate number of threads to the ready queue, the call is

3-76

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDK

not deterministic. For more information about posting device flags, see“Posting a Device Flag” on page 3-78.
The rules for pending on device flags are strict compared to other types ofsignals. The “stack” of critical regions must be exactly one level deep whena thread pends on a device flag. In other words, with interrupts enabled,call PushCriticalRegion() exactly once prior to calling PendDeviceFlag()from a thread. The reason for this condition becomes clear if you consider
the reason for pending. A thread pends on a device flag when it is waiting
for a condition to be set from an ISR. However, you must enter a criticalregion before examining any condition that may be modified from an ISR
to ensure that the value you read is valid. Furthermore, PendDeviceFlag()pops the critical region stack once, effectively balancing the earlier call to
PushCriticalRegion().
For example, a typical device driver uses device flags in the following
manner.
VDK_PushCriticalRegion();while(should_loop != 0){/* ... *//* access global data structures *//* and figure out if we should keep looping *//* ... *//* Wait for some device state */VDK_PendDeviceFlag();/* Must reenter the critical region */VDK_PushCriticalRegion();}
VDK_PopCriticalRegion();VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-77

I/O Interface

Figure 3-20 illustrates the process of pending on a device flag.
2). Switch out Thread 11). Invoke Scheduler
No

Open()
Close()
SyncRead()
SyncWrite()
IOCtl()

Device Driver's
MyDispatch()function
PendDeviceFlag()Device Flag isunavailable

Ready Queue
Order threads by
Device Driver posts
priority, then FIFO
Device Flag...
All pending threads
...
...

Is
Thread 1of the highest priority?

Yes

No
Is
timeout Yes
reached?

IsNo
kNoTimeoutError
set?

Call Thread 1's
ErrorFunction()

Thread 1
Yes
Thread 1 continues execution

Figure 3-20. Pending on a Device Flag
Posting a Device Flag

Like semaphores and messages, a device flag can be posted. A device dispatch function posts a device flag with a call to PostDeviceFlag(). Unlike
semaphores and messages, the call moves all threads pending on the device
flag to the ready queue and continues execution. Once PostDeviceFlag()returns, subsequent calls to PendDeviceFlag() cause the thread to block(as before).
Note that the PostDeviceFlag() API does not dispatch any errors. The
reason being is this API function is called typically from the dispatch function when the dispatch function is called with VDK_kIO_Activate. This
happens because the device dispatch function operates on the kernel’s
stack when it is called with VDK_kIO_Activate rather than on the stack of athread.

3-78

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDKFigure 3-21 illustrates the process of posting a device flag.

Open()
Close()
SyncRead()
SyncWrite()
IOCtl()

Device Driver's
MyDispatch()function
PostDeviceFlag()Thread 1

Ready Queue
Order threads bypriority, then FIFO...
...
All pending threads...

Device Flag
is available

Device Flagis unavailable

Thread 1 continues execution

Figure 3-21. Posting a Device Flag
General Notes
Keep the following tips in mind while writing device drivers. Althoughmany of these topics also apply to threads, they deserve special mention
with respect to device drivers.
Variables

Device drivers and ISRs are closely linked. Since ISRs and the dispatch
function access the same variables, declare the variables in the C/C++
device driver routine and access them as extern from within the ISR.
When declaring these variables in the C/C++ source file, you must declarethem as volatile to ensure that the compiler optimizer is aware that theirvalues may be changed externally to the C/C++ code at any time. Additionally, care must be taken in the ISR to refer to variables defined in
C/C++ code correctly, by their decorated/mangled names.
Critical/Unscheduled Regions

Since many of the data structures and variables associated with a device
driver are shared between multiple threads and ISRs, access to them must

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-79

Memory Poolsbe protected within critical regions and unscheduled regions. Criticalregions keep ISRs from modifying data structures unexpectedly, andunscheduled regions prevent other threads from modifying data
structures.
When pending on device flags, care must be taken to remain in the correct
regions. Device flags must be pended on from within a non-nested criticalregion, as discussed in “Pending on a Device Flag” on page 3-76.

Memory Pools
Common problems experienced with memory allocation using malloc are
fragmentation of the heap as well as non-deterministic search times forfinding a free area of the heap with the requested size. The memory pool
manager uses the defined pools to provide an efficient, deterministic
memory allocation scheme as an alternative to malloc. The use of memory
pools for memory allocation can be advantageous when an application
requires significant allocation and deallocation of objects of the same size.
A memory pool is an area of memory subdivided into equally-sized memory blocks. Each memory pool contains memory blocks of a single size,
but multiple pools can be defined, each with a different block size. Furthermore, on architectures that support the definition of multiple heaps,
the heap that is used by a pool can be specified. The maximum number ofactive memory pools in the system is set up when the project is built.

Memory Pool Functionality
Memory pools can be created either at boot time, or dynamically atruntime using the CreatePool() or CreatePoolEx() APIs. When creatinga memory pool, the block size and number of blocks in the pool are specified. The memory pool manager allocates the memory required for thepool and splits it into blocks at creation time, if required. VDK allows
blocks to be created on demand at run time (during a call

3-80

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDK

to MallocBlock())rather than during the creation of a pool. On demand,creation of blocks reduces the overhead at the time the pool is created but
increases the run-time overhead when obtaining a new block from thepool. Additionally, allocation and deallocation (by a call to FreeBlock()or LocateAndFreeBlock()) of a block from a pool is deterministic if theblocks are created when the pool is created.
In order to conform to memory alignment constraints, the block size specified for a pool is rounded up internally, so that its size is a multiple of thesize of a pointer on the architecture in question—all block addresses
returned by MallocBlock() are a multiple of sizeof(void *).
The GetNumAllocatedBlocks() and GetNumFreeBlocks() APIs can be used
to determine the number of used or available blocks respectively in a particular pool.

Multiple Heaps
By default, all VDK elements are allocated in the system heap(s).
on the processor used, VDK creates one or two system
L Depending
heaps. See Appendix A, “Processor-Specific Notes” on page A-1,
for information on specific processors.
In previous versions of VDK, multiple heaps could be used in the definition of memory pools on processors where multiple heap support isprovided. This mechanism has been extended and VDK can now use multiple heaps defined at link time (dynamically created heaps are notallowed) to specify which area of memory is used to allocate the various
VDK elements (semaphores, messages, thread stacks, and so on). The
developer is responsible for setting up the heaps. For more information
regarding how to specify multiple heaps, refer to the C/C++ Compiler andLibrary Manual for your target processor(s).

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-81

Thread Local Storage

To specify a VDK heap, create a new heap in VisualDSP++ (which has a
VDK HeapID). An ID is then associated with this name. This ID must be
the same one used in setting up the heap under the C/C++ run-time(which is an integer or a string depending on the processor). For more
information on how to set up VDK heaps, see the online documentation.

Thread Local Storage
Thread local storage allows the association of data with threads on a perthread basis. A typical usage of this functionality involves allocating thedata required by individual threads for a thread-safe library function (forexample, to store the thread-specific value of errno for each thread for the
C runtime libraries).
There are eight thread local storage slots available for this purpose. Before
a value is stored in the relevant slot in the thread’s slot table, an entry
must be allocated in the global slot table by using either
AllocateThreadSlot() or AllocateThreadSlotEx(). If a slot is available
in the global table, then the corresponding slot is also reserved in eachthread slot table. These APIs return FALSE if there are no free slots available. An allocated entry in the global slot table can subsequently be freed
by a call to FreeThreadSlot(). This mechanism for allocating slots provides one time initialization of slots for thread-specific data for libraryfunctions. Slots are allocated in every thread’s slot table on the first callingof the library function by any thread.
Once a slot has been allocated in the global slot table, the corresponding
value in the slot table of a particular thread can be set by a call to
SetThreadSlotValue() from the thread in question. The value is of typevoid * and can be used to store an integer value or a pointer to allocatedmemory. The use of AllocateThreadSlotEx() to allocate a slot allows the
specification of a cleanup function to be called on thread destruction todeal with any dynamically allocated memory that has been associated with

3-82

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDK

a thread slot. Finally, GetThreadSlotValue() can be used to obtain thevalue stored in the slot table of a particular thread.

Custom VDK History Logging
For fully instrumented libraries, VDK maintains a record of significant
system and user events to aid the debug and development process. VDKlogs details for each event—the event time lines can be viewed graphically
via the VDK State History window.
The history events are logged at runtime into a circular buffer that is queried by the VDK State History window when the application hits a
breakpoint or comes to a halt. The history circular buffer is maintained
and updated internally by VDK and should not be accessed directly. VDKprovides the APIs GetHistoryEvent() and LogHistoryEvent() to accessthe buffer. Any attempt to access the buffer directly can produce unpredictable behavior and may not function with future VisualDSP++ releases
or updates.
Previous versions of VDK provide a mechanism for users to add and additional step to the history logging process with the UserHistoryLog() call.
In addition to this, VDK now allows users to replace the VDK history logging with their own code to control what is stored (if anything) in the
VDK history buffer.

Replacing History Logging Mechanism
The VDK history logging mechanism stores a history event in a circularbuffer with the VDK_ISRAddHistoryEvent() API. Users can modify thisbehavior and replace the call to VDK_ISRAddHistoryEvent() with a call totheir own customized version by calling the ReplaceHistorySubroutine()
API. See “ReplaceHistorySubroutine()” on page 5-209 for more
information.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-83

Custom VDK History Logging

The new functionality provides more flexibility when a history event
occurs. VDK can log history information at thread, kernel and interrupt
levels, so the custom history logging subroutine is called always with interrupts disabled and must comply with certain rules:• It must be written in assembly and cannot assume the presence of a
C run-time environment• It must not call any functions that assume the presence of a C
run-time environment• It must not call any VDK APIs
• It must save and restore all the registers it uses, either implicitly or
explicitly• Calls to the custom history logging subroutine should not be madefrom any other part of a VDK application• It should be used only to trace/monitor system activity, either for
debug or system analysis, and should not be used to affect the operation of the application
The custom history code receives the following arguments when called.
• The time, in Ticks, when the event occurred• A HistoryEnum, an enumerated value that describes the event• An integer value used to pass further details of the event• A ThreadID
The arguments passed to the history logging subroutine are the components of the VDK HistoryEvent data type. For more info, see“HistoryEvent” on page 4-25.

3-84

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDKBefore calling the customized history code, the arguments are placed in
the following registers (Table 3-1).
Table 3-1. Argument Placements for History Logging Subroutines
Argument

TypeBlackfin
Registers

TigerSHARC
Registers

SHARC Registers

Time

VDK::Ticks

R3

J7

R0

Event type

VDK::HistoryEnum

R0

J4

R4

Value

int

R1

J5

R8

Thread ID

VDK::ThreadID

R2

J6

R12

User’s can call VDK_ISRAddHistoryEvent() from the customized history
logging code if they wish to store information in the VDK history buffer.
VDK_ISRAddHistoryEvent() should be called only from the customized
history logging subroutine and not from any other part of an application.
VDK_ISRAddHistoryEvent() expects its arguments in the same registers as
registers listed in Table 3-1.
VDK History window may not be able to display the flow of[ The
threads that have been running in the application if the events
kThreadSwitched or kThreadStatusChange are removed or misused.

UserHistoryLog()
Users that do not require changes to the events logged in the VDK history
buffer can still add an extra function to the VDK history logging mechanism to suit their needs. The intention of this function is to enable acustom history logging function that may be required to do somethingother than simply add an entry to the VDK history buffer.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-85

VDK File Attributes

To use this feature, a _UserHistoryLog() assembly function must be created and added to a VDK project. There are some points to be aware ofwhen writing the function:• VDK calls the function whenever a history log is made, which canhappen at thread, kernel, and interrupt levels. As such, a proper
stack may not be in place when the function is being called; therefore, the function must only be written in assembly.
• As the function can be called from interrupt level, it must save andrestore any registers that are either explicitly or implicitly modified.
•_UserHistoryLog() is called in addition to VDK history logging.

The definition of _UserHistoryLog() does not replace the standard
history logging functions.
The following C/C++ definition is used by VDK to call
_UserHistoryLog().
extern “C” void UserHistoryLog (const

VDK::HistoryEnum,

const

int,

const

VDK::ThreadID);

Each function parameter relates to one of the HistoryEvent data typemembers, a description of which can be found in “HistoryEvent” onpage 4-25.

VDK File Attributes
VDK-based applications generally are large and can require external memory. To help partitioning an application and to mark the code intended
for internal memory, VDK is built with several file attributes in addition
to file attributes used in the runtime libraries.
The entire VDK and TMK libraries are built with the attributes
prefersMem=internal and prefersMemNum=30; with the additional
ADI_OS=VDK attribute in case of the VDK libraries or ADI_OS=TMK attribute
3-86

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDK

in case of the TMK library. Files in the VDK libraries can have other attributes to aid the partitioning of a VDK application into different memoryareas. A VDK file can have one or more of these attributes, depending on
the functions defined in the file. A list of the VDK-specific file attributes
is as follows.
DeviceDrivers
DeviceFlags
ErrorHandling
EventsHeapMarshaller
HistoryAndStatus
ISR
MemoryPools
Messages
MP_Messages
Mutex
OS_Component=DeviceDrivers
OS_Component=DeviceFlags
OS_Component=Events
OS_Component=MemoryPools
OS_Component=Messages
OS_Component=MP_Messages
OS_Component=Mutex
OS_Component=Regions
OS_Component=Semaphores
OS_Component=Threads
OS_Internals
PoolMarshaller
Regions
RoundRobin
Semaphores
Startup
SystemThreads

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-87

VDK File Attributes

Many VDK-specific file attributes indicate the VDK components towhich the APIs in the source file are related. Two attributes are added toall of these files: the component itself (for example, Semaphores) and theattribute OS_Component with the value of the particular component (forexample, OS_Component=Semaphores). The component attributes are:OS_Component=DeviceDrivers
OS_Component=DeviceFlags
OS_Component=Events
OS_Component=MemoryPools
OS_Component=Messages
OS_Component=MP_Messages
OS_Component=Mutex
OS_Component=Regions
OS_Component=Semaphores
OS_Component=Threads

In addition, some VDK files have an extra attribute to specify a particular
type of component, different from the attributes listed above.
•

RoundRobin: the attribute is set in conjunction with the Threads

attribute. The marked code will be linked in only if there areround-robin priorities in the application.
•

HeapMarshaller: the attribute is set in conjunction with the
MP_Messages attribute. The marked code will be linked in only ifthere are multi-processor messages in the application, and the messages are heap-marshalled.
•

PoolMarshaller: the attribute is set in conjunction with the
MP_Messages attribute. The marked code will be linked in only ifthere are multi-processor messages in the application, and the messages are pool-marshalled.

3-88

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Using VDKOther attributes found in VDK are not related to the VDK component towhich the file refers. These attributes are:•

ISR: functions and macros that are likely to be called from ISRlevel, therefore, should be placed in internal memory if possible•

OS_Internals: functions used internally by VDK, should be placed

in internal memory if possible•

System: functions that can read or modify application-wide proper-

ties, such as timer properties or interrupt mask changes•

Startup: functions used by VDK before the start of the Run() func-tion of the highest priority boot thread•

ErrorHandling: functions dealing with VDK error management,such as the DispatchThreadError() API•

HistoryAndStatus: functions used by the VDK history logging

mechanism or APIs used to obtain information displayed in the
VDK Status window

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

3-89

VDK File Attributes

3-90

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

4 VDK DATA TYPESVDK comes with a predefined set of data types. This chapter describes thecurrent release of the kernel. Future releases may include further types.
This chapter contains:• “Data Type Summary” on page 4-1• “Data Type Descriptions” on page 4-3

Data Type SummaryVDK data types are summarized in Table 4-1. A description of each type
begins on page 4-3.
Table 4-1. VDK Data Types
Data Type

Reference Page

Bitfieldon page 4-3

DeviceDescriptor

on page 4-4

DeviceFlagIDon page 4-5

DeviceInfoBlockon page 4-6

DispatchID

on page 4-7

DispatchUnion

on page 4-8

DSP_Family

on page 4-10

DSP_Producton page 4-11

EventBitID

on page 4-17

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

4-1

Data Type Summary

Table 4-1. VDK Data Types (Cont’d)4-2

Data Type

Reference Page

EventIDon page 4-18

EventDataon page 4-19

HeapIDon page 4-20

HistoryEnum

on page 4-21

HistoryEventon page 4-25

IMASKStructon page 4-28

IOID

on page 4-29

IOTemplateID

on page 4-30

MarshallingCodeon page 4-31

MarshallingEntryon page 4-33

MessageDetails

on page 4-34

MessageID

on page 4-35

MsgChannel

on page 4-36

MsgWireFormat

on page 4-38

MutexIDon page 4-40

PanicCodeon page 4-41

PayloadDetails

on page 4-44

PFMarshaller

on page 4-45

PoolIDon page 4-47

Priorityon page 4-48

RoutingDirection

on page 4-49

SemaphoreIDon page 4-50

SystemErroron page 4-51

TCBBitfieldon page 4-57

ThreadCreationBlockon page 4-58

ThreadIDon page 4-61

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK Data Types

Table 4-1. VDK Data Types (Cont’d)Data Type

Reference Page

ThreadStatuson page 4-62

ThreadType

on page 4-63

Ticks

on page 4-64

VersionStructon page 4-65

Data Type Descriptions
The following sections provide descriptions of VDK data types.

Bitfield
The Bitfield type is used to store a bit pattern. The size of a Bitfielditem is the size of a data word, which is 32 bits on SHARC, TigerSHARC,
and Blackfin processors.
In C:
typedef unsigned

int VDK_Bitfield;

In C++:
typedef unsigned int VDK::Bitfield;

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

4-3

Data Type Descriptions

DeviceDescriptor
The DeviceDescriptor type is used to store the unique identifier of an
opened device. The value is obtained dynamically as the return value from
OpenDevice().
In C:
typedef unsigned int VDK_DeviceDescriptor;

In C++:
typedef unsigned int VDK::DeviceDescriptor;

4-4VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK Data Types

DeviceFlagID
The DeviceFlagID type is used to store the unique identifier of a device
flag.
enum DeviceFlagID{/* Defined by IDDE in the VDK.h file. */};The enumeration in VDK.h will only contain the IDs of the device flags
enabled at boot time. Any dynamically-created device flags will have an IDof the same type to allow the compiler to do type checking and prevent
errors.
In C:
typedef enum DeviceFlagID VDK_DeviceFlagID;

In C++:
typedef enum DeviceFlagID VDK::DeviceFlagID;

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

4-5

Data Type Descriptions

DeviceInfoBlock
The DeviceInfoBlock structure holds information on the device driverthat is being used by a routing thread and is passed as an argument to marshalling functions. All fields except the DeviceDescriptor are private to
VDK and should not be used by user code.
In C:
typedef struct{
VDK_DeviceDescriptor

dd;

VDK_PFDispatchFunction

pfDispatchFunction;

struct VDK_IOAbstractBase*pDevObj;

struct VDK_DeviceControlBlock *pDcb;} VDK_DeviceInfoBlock;

In C++:
typedef struct{
VDK::DeviceDescriptor

dd;

VDK::PFDispatchFunction

pfDispatchFunction;

struct VDK::IOAbstractBase*pDevObj;

struct VDK::DeviceControlBlock *pDcb;} VDK::DeviceInfoBlock;where dd is the descriptor for the device. Marshalling functions may use it
as an argument for their SyncRead() and SyncWrite() calls.

4-6

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK Data Types

DispatchID
The DispatchID type enumerates a device driver’s dispatch commands.
In C:
enum VDK_DispatchID{
VDK_kIO_Init,
VDK_kIO_Activate,
VDK_kIO_Open,VDK_kIO_Close,
VDK_kIO_SyncRead,
VDK_kIO_SyncWrite,
VDK_kIO_IOCtl};

In C++:
enum VDK::DispatchID{
VDK::kIO_Init,
VDK::kIO_Activate,
VDK::kIO_Open,
VDK::kIO_Close,
VDK::kIO_SyncRead,
VDK::kIO_SyncWrite,
VDK::kIO_IOCtl};

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

4-7

Data Type Descriptions

DispatchUnion
A variable of the DispatchUnion type is passed as a parameter to a device
driver dispatch function. Calls to OpenDevice(), CloseDevice(), SyncRead(), SyncWrite(), and DeviceIOCtl() set up the relevant members of
this union before calling the device driver’s dispatch function.
In C:
union VDK_DispatchUnion{
struct{void**dataH;char*flags;/* used for kIO_Open only */} OpenClose_t;
struct{void**dataH;
VDK_Ticks
timeout;
unsigned int dataSize;char*data;} ReadWrite_t;
struct{void**dataH;
void*command;char*parameters;} IOCtl_t;
struct{void*pInitInfo;} Init_t;};

4-8VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK Data Types

In C++:
union VDK::DispatchUnion{
struct{void**dataH;char*flags; /* used for kIO_Open only */} OpenClose_t;
struct{void**dataH;
VDK::Ticks
timeout;
unsigned int dataSize;char*data;} ReadWrite_t;
struct{void**dataH;
void*command;char*parameters;} IOCtl_t;
struct{void*pInitInfo;} Init_t;};

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

4-9

Data Type Descriptions

DSP_Family
The DSP_Family type enumerates the processor families supported by
VDK. See also VersionStruct.
In C:
enum VDK_DSP_Family{
VDK_kUnknownFamily,
VDK_kSHARC,
VDK_kTSXXX,
VDK_kBLACKFIN};

In C++:
enum VDK::DSP_Family{
VDK::kUnknownFamily,
VDK::kSHARC,
VDK::kTSXXX,VDK::kBLACKFIN
};

4-10

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK Data Types

DSP_Product
The DSP_Product type enumerates the devices supported by VDK. See also
VersionStruct.
In C:
Type name:
VDK_DSP_ProductPossible values: VDK_kUnknownProduct
VDK_k21060
VDK_k21061
VDK_k21062
VDK_k21065
VDK_k21160
VDK_k21161
VDK_k21261
VDK_k21262
VDK_k21266
VDK_k21267
VDK_k21362
VDK_k21363
VDK_k21364
VDK_k21365
VDK_k21366
VDK_k21367
VDK_k21368
VDK_k21369
VDK_k21371
VDK_k21375
VDK_k21462
VDK_k21465
VDK_k21467
VDK_k21469
VDK_k21472

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

4-11

Data Type Descriptions

VDK_k21475
VDK_k21478
VDK_k21479
VDK_k21481
VDK_k21482
VDK_k21483
VDK_k21485
VDK_k21486
VDK_k21487
VDK_k21488
VDK_k21489
VDK_kBF504
VDK_kBF504F
VDK_kBF506F
VDK_kBF512
VDK_kBF514
VDK_kBF516
VDK_kBF518
VDK_kBF522
VDK_kBF523
VDK_kBF524
VDK_kBF525
VDK_kBF526
VDK_kBF527
VDK_kBF531
VDK_kBF532
VDK_kBF533
VDK_kBF534
VDK_kBF535
VDK_kBF536
VDK_kBF537
VDK_kBF538
VDK_kBF539
VDK_kBF541

4-12

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK Data Types

VDK_kBF542
VDK_kBF544
VDK_kBF548
VDK_kBF549
VDK_kBF542M
VDK_kBF544M
VDK_kBF547M
VDK_kBF548M
VDK_kBF549M
VDK_kBF561
VDK_kBF592A
VDK_kAD6531
VDK_kAD6532
VDK_kAD6901
VDK_kAD6902
VDK_kAD6903
VDK_kTS101
VDK_kTS201
VDK_kTS202
VDK_kTS203

In C++:
Type name:
VDK::DSP_ProductPossible values: VDK::kUnknownProduct
VDK::k21060
VDK::k21061
VDK::k21062
VDK::k21065
VDK::k21160
VDK::k21161
VDK::k21261
VDK::k21262
VDK::k21266
VDK::k21267

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

4-13

Data Type Descriptions

VDK::k21362
VDK::k21363
VDK::k21364
VDK::k21365
VDK::k21366
VDK::k21367
VDK::k21368
VDK::k21369
VDK::k21371
VDK::k21375
VDK::k21462
VDK::k21465
VDK::k21467
VDK::k21469
VDK::k21472
VDK::k21475
VDK::k21478
VDK::k21479
VDK::k21481
VDK::k21482
VDK::k21483
VDK::k21485
VDK::k21486
VDK::k21487
VDK::k21488
VDK::k21489
VDK::kBF504
VDK::kBF504F
VDK::kBF506F
VDK::kBF512
VDK::kBF514
VDK::kBF516
VDK::kBF518
VDK::kBF522

4-14

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK Data Types

VDK::kBF523
VDK::kBF524
VDK::kBF525
VDK::kBF526
VDK::kBF527
VDK::kBF531
VDK::kBF532
VDK::kBF533
VDK::kBF534
VDK::kBF535
VDK::kBF536
VDK::kBF537
VDK::kBF538
VDK::kBF539
VDK::kBF541
VDK::kBF542
VDK::kBF544
VDK::kBF548
VDK::kBF549
VDK::kBF542M
VDK::kBF544M
VDK::kBF547M
VDK::kBF548M
VDK::kBF549M
VDK::kBF561
VDK::kBF592A
VDK::kAD6531
VDK::kAD6532
VDK::kAD6901
VDK::kAD6902
VDK::kAD6903
VDK::kTS101
VDK::kTS201

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

4-15

Data Type Descriptions

VDK::kTS202
VDK::kTS203of the listed processors are not supported in all updates of
L SomeVisualDSP++ 5.0. See the VisualDSP++ update release notes formore information about new processors supported in each update.

4-16

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK Data Types

EventBitID
The EventBitID type is used to store the unique identifier of an event bit.
The total number of event bits in a system is the size of a data word minus
one, which is 31 bits on SHARC, TigerSHARC, and Blackfin processors.
enum EventBitID{/* Defined by IDDE in the VDK.h file. */
};

In C:
typedef enum EventBitID VDK_EventBitID;

In C++:
typedef enum EventBitID VDK::EventBitID;

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

4-17

Data Type Descriptions

EventIDThe EventID type is used to store the unique identifier of an event. The
total number of events in a system is the size of a data word minus one,which is 31 bits on SHARC, TigerSHARC, and Blackfin processors.
enum EventID{/* Defined by IDDE in the VDK.h file. */
};

In C:
typedef enum EventID VDK_EventID;

In C++:
typedef enum EventID VDK::EventID;

4-18

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK Data Types

EventData
The EventData type is used to store the data associated with an event. See
also “Behavior of Events” on page 3-48.
In C:
typedef struct{bool

matchAll;

unsigned int

values;unsigned int

mask;} VDK_EventData;

In C++:
typedef struct{bool

matchAll;

unsigned int

values;unsigned int

mask;} VDK::EventData;

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

4-19

Data Type Descriptions

HeapIDThe HeapID type is used to store the unique identifier of a VDK Heap.
This data type is only available on processors for which multiple heap support is provided.
enum HeapID{/* Defined by IDDE in the VDK.h file */
};

In C:
typedef enum HeapID VDK_HeapID;

In C++:
typedef enum HeapID VDK::HeapID;

4-20

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK Data Types

HistoryEnum
The HistoryEnum type describes the events that can be logged with a callto the LogHistoryEvent() API or VDK_ISR_LOG_HISTORY_() macro. A variable of type HistoryEnum can have the following values.
In C:
Type name:
VDK_HistoryEnum
Possible values: VDK_kThreadCreated
VDK_kThreadDestroyed
VDK_kSemaphorePosted
VDK_kSemaphorePended
VDK_kEventBitSet
VDK_kEventBitCleared
VDK_kEventPended
VDK_kDeviceFlagPended
VDK_kDeviceFlagPosted
VDK_kDeviceActivated
VDK_kThreadTimedOut
VDK_kThreadStatusChange
VDK_kThreadSwitched
VDK_kMaxStackUsed
VDK_kPoolCreated
VDK_kPoolDestroyed
VDK_kDeviceFlagCreated
VDK_kDeviceFlagDestroyed
VDK_kMessagePosted
VDK_kMessagePended
VDK_kSemaphoreCreated
VDK_kSemaphoreDestroyed
VDK_kMessageCreated
VDK_kMessageDestroyed
VDK_kMessageTakenFromQueue

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

4-21

Data Type Descriptions

VDK_kThreadResourcesFreed
VDK_kThreadPriorityChanged
VDK_kMutexCreated
VDK_kMutexDestroyed
VDK_kMutexAcquired
VDK_kMutexReleased
VDK_kUserEvent = 1

In C++:
Type name:
VDK::HistoryEnum
Possible values: VDK::kThreadCreated
VDK::kThreadDestroyed
VDK::kSemaphorePosted
VDK::kSemaphorePended
VDK::kEventBitSet
VDK::kEventBitCleared
VDK::kEventPended
VDK::kDeviceFlagPended
VDK::kDeviceFlagPosted
VDK::kDeviceActivated
VDK::kThreadTimedOut
VDK::kThreadStatusChange
VDK::kThreadSwitched
VDK::kMaxStackUsed
VDK::kPoolCreated
VDK::kPoolDestroyed
VDK::kDeviceFlagCreated
VDK::kDeviceFlagDestroyed
VDK::kMessagePosted
VDK::kMessagePended
VDK::kSemaphoreCreated
VDK::kSemaphoreDestroyed
VDK::kMessageCreated
VDK::kMessageDestroyed

4-22

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK Data Types

VDK::kMessageTakenFromQueue
VDK::kThreadResourcesFreed
VDK::kThreadPriorityChanged
VDK::kMutexCreated
VDK::kMutexDestroyed
VDK::kMutexAcquired
VDK::kMutexReleased
VDK::kUserEvent = 1

In Assembly:
Type name:no HistoryEnum type defined
Possible values: _VDK_kThreadCreated_VDK_kThreadDestroyed_VDK_kSemaphorePosted_VDK_kSemaphorePended_VDK_kEventBitSet_VDK_kEventBitCleared_VDK_kEventPended_VDK_kDeviceFlagPended_VDK_kDeviceFlagPosted_VDK_kDeviceActivated_VDK_kThreadTimedOut_VDK_kThreadStatusChange_VDK_kThreadSwitched_VDK_kMaxStackUsed_VDK_kPoolCreated_VDK_kPoolDestroyed_VDK_kDeviceFlagCreated_VDK_kDeviceFlagDestroyed_VDK_kMessagePosted_VDK_kMessagePended_VDK_kSemaphoreCreated_VDK_kSemaphoreDestroyed_VDK_kMessageCreated

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

4-23

Data Type Descriptions_VDK_kMessageDestroyed_VDK_kMessageTakenFromQueue_VDK_kThreadResourcesFreed_VDK_kThreadPriorityChanged_VDK_kMutexCreated_VDK_kMutexDestroyed_VDK_kMutexAcquired_VDK_kMutexReleased_VDK_kUserEvent

4-24

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK Data Types

HistoryEvent
The HistoryEvent structure combines the four attributes of an event
logged in the history buffer.
In C:
typedef struct{
VDK_Ticks

time;

VDK_ThreadID

threadID;

VDK_HistoryEnum

type;

int

value;} VDK_HistoryEvent;In C++:
typedef struct{
VDK::Ticks

time;

VDK::ThreadID

threadID;

VDK::HistoryEnum

type;

int

value;} VDK::HistoryEvent;time is the time (in Ticks) that the history event is logged.
threadID is the identifier of the thread against which the event is logged.

See ThreadID for more information about thread IDs.
type is used to store the cause of the history event, such as a semaphore
being posted or an event bit being set (see HistoryEnum data type).
value is used to provide further information relevant to the history event;its meaning is dependant on the value of type. value is used to store additional information relevant to the event such as the MessageID when amessage is being posted.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

4-25

Data Type Descriptions

The table below details the data values stored for each HistoryEnum.
History Event

Value

kDeviceActivated

IOID

kDeviceFlagCreatedDeviceFlagID

kDeviceFlagDestroyed

DeviceFlagID

kDeviceFlagPended

DeviceFlagID

kDeviceFlagPosted

DeviceFlagID

kEventBitCleared

EventBitID or (EventBitID | INT_MIN) if the event bit

was set to 1
kEventBitSet

EventBitID or (EventBitID | INT_MIN) if the event bit
was already set to 1

kEventPended

EventID or (EventID | INT_MIN) if the event evaluated to
TRUE

kMaxStackUsed

Bytes usedkMessageCreatedMessageID

kMessageDestroyed

MessageID

kMessagePended

Channel mask

kMessagePosted

MessageID

kMutexAcquired

MutexID

kMutexCreated

MutexID

kMutexDestroyed

MutexID

kMutexReleased

MutexID

kPoolCreated

PoolIDkPoolDestroyed

PoolIDkSemaphoreCreatedSemaphoreID

kSemaphoreDestroyed

SemaphoreID

kSemaphorePended

SemaphoreID or (SemaphoreID | INT_MIN) if the sema-phore was available.

4-26

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK Data Types

History Event

ValuekSemaphorePosted

SemaphoreID or (SemaphoreID | INT_MIN) if the semaphore was already available

kThreadCreatedThreadID

kThreadDestroyed

ThreadID

kThreadPriorityChanged

New priority

kThreadResourcesFreed

ThreadID

kThreadStatusChange

Previous status

kThreadSwitched

Incoming ThreadID

kThreadTimedOut

Object ID

kUserEvent

Value

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

4-27

Data Type Descriptions

IMASKStruct
The IMASKStruct type is a platform-dependent type used by the ClearInterruptMaskBits(), GetInterruptMask(), and SetInterruptMaskBits()
APIs to modify the interrupt mask.
For TigerSHARC processors, this type is defined as:
In C:
typedef unsigned long long VDK_IMASKStruct;

In C++:
typedef unsigned long long VDK::IMASKStruct;

For Blackfin and SHARC processors, the type is defined as:
In C:
typedef unsigned int VDK_IMASKStruct;

In C++:
typedef unsigned int VDK::IMASKStruct;

4-28

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK Data Types

IOID
The IOID type is used to store the unique identifier of an I/O object.
enum IOID{/* Defined by IDDE in the VDK.h file. */
};

In C:
typedef enum IOID VDK_IOID;In C++:
typedef enum IOID VDK::IOID;

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

4-29

Data Type Descriptions

IOTemplateID
The IOTemplateID type is used to store the unique identifier of an I/O
object class.
enum IOTemplateID{/* Defined by IDDE in the VDK.h file. */
};

In C:
typedef enum IOTemplateID VDK_IOTemplateID;

In C++:
typedef enum IOTemplateID VDK::IOTemplateID;

4-30

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK Data Types

MarshallingCode
The MarshallingCode type enumerates the possible reasons for calling a
payload marshalling function.
In C:
enum VDK_MarshallingCode{
TRANSMIT_AND_RELEASE,
ALLOCATE_AND_RECEIVE,
ALLOCATE,
RELEASE};In C++:
enum VDK::MarshallingCode{
TRANSMIT_AND_RELEASE,
ALLOCATE_AND_RECEIVE,
ALLOCATE,
RELEASE};
TRANSMIT_AND_RELEASE indicates that the marshalling function must per-form the following steps in sequence.
1. Modify the message packet, if necessary (optional)
2. Transmit the message packet
3. Transmit the payload contents (optional in certain cases)
4. Deallocate the payload memory

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

4-31

Data Type Descriptions

ALLOCATE_AND_RECEIVE indicates that the marshalling function must per-form the following steps in sequence.
1. Allocate memory for a payload of the type (and size) specified by
the message packet
2. Receive the payload contents into the payload memory
ALLOCATE indicates that the marshalling function must allocate memory

for a payload of the type and size specified by the message packet.
RELEASE indicates that the marshalling function must deallocate the pay-load memory.

4-32

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK Data Types

MarshallingEntry
The MarshallingEntry structure forms the elements of the marshalling
table array g_vMarshallingTable (defined by the IDDE in VDK.cpp).
In C:
typedef struct{
VDK_PFMarshaller pfMarshaller;
unsigned int area;} VDK_MarshallingEntry;

In C++:
typedef struct{
VDK::PFMarshaller pfMarshaller;
unsigned int area;} VDK::MarshallingEntry;
pfMarshaller is a pointer to a system- or user-defined marshalling

function.
area is used by standard marshalling to hold the Heap index (for heap

marshalling) or PoolID (for pool marshalling) in order to parameterize theoperation of the standard functions. It may also be used to parameterize
the operation of custom marshalling functions.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

4-33

Data Type Descriptions

MessageDetails
The MessageDetails structure combines the three attributes that describe
the most recent posting of a message.
In C:
typedef struct{
VDK_MsgChannel channel;
VDK_ThreadID

sender;VDK_ThreadID

target;} VDK_MessageDetails;

In C++:
typedef struct{
VDK::MsgChannel channel;
VDK::ThreadID

sender;

VDK::ThreadID

target;} VDK::MessageDetails;

4-34

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK Data Types

MessageID
The MessageID type is used to store the unique identifier of a message.
enum MessageID{/* Defined by IDDE in the VDK.h file. */};The enumeration in VDK.h will be empty. All the messages are dynamicallyallocated and will have an ID of the MessageID type to allow the compiler
to do type checking and prevent errors.
In C:
typedef enum MessageID VDK_MessageID;

In C++:
typedef enum MessageID VDK::MessageID;

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

4-35

Data Type Descriptions

MsgChannel
The MsgChannel type enumerates the channels a message can be posted orpended on.
In C:
enum VDK_MsgChannel{
VDK_kMsgWaitForAll = 1 << 15,
VDK_kMsgChannel1 = 1 << 14,
VDK_kMsgChannel2 = 1 << 13,
VDK_kMsgChannel3 = 1 << 12,
VDK_kMsgChannel4 = 1 << 11,
VDK_kMsgChannel5 = 1 << 10,
VDK_kMsgChannel6 = 1 << 9,
VDK_kMsgChannel7 = 1 << 8,
VDK_kMsgChannel8 = 1 << 7,
VDK_kMsgChannel9 = 1 << 6,
VDK_kMsgChannel10 = 1 << 5,
VDK_kMsgChannel11 = 1 << 4,
VDK_kMsgChannel12 = 1 << 3,
VDK_kMsgChannel13 = 1 << 2,
VDK_kMsgChannel14 = 1 << 1,
VDK_kMsgChannel15 = 1 << 0};

In C++:
enum VDK::MsgChannel{
VDK::kMsgWaitForAll = 1 << 15,
VDK::kMsgChannel1 = 1 << 14,
VDK::kMsgChannel2 = 1 << 13,
VDK::kMsgChannel3 = 1 << 12,
VDK::kMsgChannel4 = 1 << 11,
VDK::kMsgChannel5 = 1 << 10,

4-36

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK Data Types

VDK::kMsgChannel6 = 1 << 9,
VDK::kMsgChannel7 = 1 << 8,
VDK::kMsgChannel8 = 1 << 7,
VDK::kMsgChannel9 = 1 << 6,
VDK::kMsgChannel10 = 1 << 5,
VDK::kMsgChannel11 = 1 << 4,
VDK::kMsgChannel12 = 1 << 3,
VDK::kMsgChannel13 = 1 << 2,
VDK::kMsgChannel14 = 1 << 1,
VDK::kMsgChannel15 = 1 << 0};VisualDSP++ 5.0 Kernel (VDK) User’s Guide

4-37

Data Type Descriptions

MsgWireFormat
The MsgWireFormat structure is used to transfer a message across a communication link. It is the structure written to and read from the device
drivers that manage the links.
In C:
typedef struct{unsigned int header;
VDK_PayloadDetails payload;} VDK_MsgWireFormat;

In C++:
typedef struct{unsigned int header;
VDK::PayloadDetails payload;} VDK::MsgWireFormat;
MsgWireFormat is four words (16 bytes or 128 bits) in size, of which threewords are made up of the payload description. The remaining (first) word
is the message header, which contains the additional information about
the message, packed using the following format:
Bit Position

31 to 28

27 to 23

22 to 14

13 to 98 to 0Word 0ChannelDestination
node

Destination
threadSource node

Source thread

Word 1

Payload type

Word 2Payload address

Word 3Payload length

4-38

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK Data Types

The header bit allocation allows for up to 32 nodes in the system and up
to 512 threads per node.
Because there are only 15 message channel numbers (1 to 15) used by
VDK, message packets having header bits 28 to 31 set to all zeros (that is,
the non-existent channel 0) are special cases, which may be used internally
by VDK (or by the device drivers) as private control messages.
The message ID is not transferred in the packet, as the message will
L havea different ID on the destination processor.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

4-39

Data Type Descriptions

MutexID
The MutexID type is used to store the unique identifier of a mutex.
enum MutexID{/* Defined by IDDE in the VDK.h file. */};The enumeration in VDK.h is empty. All of the mutexes are dynamicallyallocated and will have IDs of the MutexID type to allow the compiler todo type checking and prevent errors.
In C:
typedef enum MutexID VDK_MutexID;

In C++:
typedef enum MutexID VDK::MutexID;

4-40

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK Data Types

PanicCodeThe PanicCode type enumerates the possible causes of VDK raising a KernelPanic. When VDK enters KernelPanic(), the cause is stored in thevariable VDK::g_KernelPanicCode in C++ (C++ syntax must be used).
In C:
Type name:

VDK_PanicCode

Possible values: VDK_kNoPanic=0
VDK_kThreadError
VDK_kBootError
VDK_kISRError
VDK_kDeprecatedAPI
VDK_kInternalError
VDK_kStackCheckFailure
VDK_kUnhandledException

In C++:
Type name:

VDK::PanicCode

Possible values: VDK::kNoPanic=0
VDK::kThreadError
VDK::kBootError
VDK::kISRError
VDK::kDeprecatedAPI
VDK::kInternalError
VDK::kStackCheckFailure
VDK::kUnhandledException

The g_KernelPanicCode variable has a value of kNoPanic when
KernelPanic() has not been called.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

4-41

Data Type Descriptions

The g_KernelPanicCode variable has a value of kThreadError when athread’s error function does not handle the error (default behavior) or
when an attempt is made to dispatch an error when the running thread is
the Idle thread.
The g_KernelPanicCode variable has a value of kBootError when there has
been a problem creating any of the VDK boot components (threads, semaphores, memory pools, and so on).
The g_KernelPanicCode variable has a value of kISRError when either an
ISR API is invoked with an ID greater than the maximum allowed for theparticular function, or when a VDK API that is not safe to use at ISR or
kernel level has been called from ISR level or kernel level (see “VDK API
Validity” on page 5-19).
The g_KernelPanicCode variable has a value of kDeprecatedAPI when the
API in question is no longer supported.
The g_KernelPanicCode variable has a value of InternalError when VDK
detected internal problems from which it cannot recover.
The g_KernelPanicCode variable has a value of kStackCheckFailure when
VDK has detected a thread which has overrun its stack. Users should not
rely on this to verify that threads have not overrun their stacks as VDK

4-42

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK Data Types

can only detect a specific limited number of cases. This panic code is used
only under the following circumstances:• On all platforms in fully instrumented builds, this panic code is
raised if a pre-emptive context switch detects a write to the lastword in the stack.
• On SHARC processors, if the compiler stack overflow detection
mechanism reports a stack overflow, and the application does nothave its own ISR for CB7I. Stack overflow detection is enabled bydefault on SHARC processors.
• On Blackfin processors, if the compiler stack overflow detection
mechanism reports a stack overflow. Stack overflow detection isdisabled by default on Blackfin processors.
Refer to the stack overflow detection section in the processor-specificappendix for more information.
The g_KernelPanicCode variable has a value of kUnhandledException
when the default UserExceptionHandler added to new projects has
detected an exception that it cannot handle. This panic code is only usedin Blackfin projects created with VisualDSP++ 5.0 update 9 or later.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

4-43

Data Type Descriptions

PayloadDetails
The PayloadDetails structure combines three attributes that describe amessage payload.
In C:
typedef struct
{
int
type;
unsigned int size;
void*addr;} VDK_PayloadDetails;

In C++:
typedef struct
{
int
type;
unsigned int size;
void*addr;} VDK::PayloadDetails;

The type variable is an application-defined value that specifies the interpretation given to the contents of the payload. Negative values of payload
type indicate a user-defined marshalled type, which can be managed automatically by VDK for the purposes of inter-processor messaging.
The size variable is typically the size of the payload in the smallest
addressable units of the processor (sizeof(char)).
The addr variable is typically a pointer to the beginning of the payload
buffer.
However, depending on the application-defined interpretation of the payload’s type, the payload addr and size attributes may contain any
user-defined data that can be stored in two 32-bit fields.

4-44

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK Data Types

PFMarshaller
The PFMarshaller type is a pointer-to-function type, used to hold theaddress of a system- or user-defined marshalling function.
In C:
typedef int (*VDK_PFMarshaller)(VDK_MarshallingCode code,
VDK_MsgWireFormat*inOutMsgPacket,
VDK_DeviceInfoBlock *pDev,
unsigned int
area,
VDK_Ticks
timeout);

In C++:
typedef int (*VDK::PFMarshaller)(VDK::MarshallingCode code,
VDK::MsgWireFormat*inOutMsgPacket,
VDK::DeviceInfoBlock *pDev,
unsigned int
area,
VDK::Ticks
timeout);

Parameterscode tells the marshalling function which operation(s) to perform (seeMarshallingCode).
inOutMsgPacket is a pointer to the formatted message packet.
pDev is a pointer to a DeviceInfoBlock structure describing the VDK

device driver for the connection.
area is the Heap index or PoolID used by standard marshalling.
timeout is the I/O timeout duration (usually set to 0 for indefinite wait).

The marshalling function may invoke the scheduler, depending on theimplementation. The return value from a marshalling function will usually be the result of a SyncRead() or SyncWrite() call that has been

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

4-45

Data Type Descriptions

performed internally, but this value is not presently used. Errors can bedispatched by the marshalling function or by functions called by the marshalling function.

4-46

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK Data Types

PoolID
The PoolID type is used to store the unique identifier of a memory pool.
enum PoolID{/* Defined by IDDE in the VDK.h file. */};The enumeration in VDK.h will contain only the IDs for the memory pools
enabled at boot time. Any dynamically-created memory pools will have an
ID of the same type to allow the compiler to perform type checking andprevent errors.
In C:
typedef enum PoolID VDK_PoolID;

In C++:
typedef enum PoolID VDK::PoolID;

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

4-47

Data Type Descriptions

Priority
The Priority type is used to denote the scheduling priority level of athread:• The highest priority is one (zero is reserved)• The lowest priority is the size of a data word minus two.
For SHARC, TigerSHARC, or Blackfin processors, this value is 30.
In C:
enum VDK_Priority{
VDK_kPriority1,
VDK_kPriority2,
VDK_kPriority3,…
VDK_kPriority30};

In C++:
enum VDK::Priority{
VDK::kPriority1,
VDK::kPriority2,
VDK::kPriority3,…
VDK::kPriority30
};

4-48

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK Data Types

RoutingDirection
The RoutingDirection type enumerates the two distinct operating modesof a routing thread. It is used to specify the operating mode of a routing
thread at the time of its creation.
In C:
enum VDK_RoutingDirection{
kINCOMING,
kOUTGOING};In C++:
enum VDK::RoutingDirection{
kINCOMING,
kOUTGOING};

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

4-49

Data Type Descriptions

SemaphoreID
The SemaphoreID type is used to store the unique identifier of asemaphore.
enum SemaphoreID{/* Defined by IDDE in the VDK.h file. */};The enumeration in VDK.h will contain the IDs only for the semaphores
enabled at boot time. Any dynamically-created semaphores will have an
ID of the same type to allow the compiler to perform type checking andprevent errors.
In C:
typedef enum SemaphoreID VDK_SemaphoreID;

In C++:
typedef enum SemaphoreID VDK::SemaphoreID;

4-50

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK Data Types

SystemError
The SystemError type enumerates system-defined errors dispatched to theerror handler.
In C:
Type name:

VDK_SystemError

Possible values: VDK_kUnknownThreadType
VDK_kUnknownThread
VDK_kInvalidThread
VDK_kThreadCreationFailure
VDK_kUnknownSemaphore
VDK_kUnknownEventBit
VDK_kUnknownEvent
VDK_kInvalidPriority
VDK_kInvalidDelay
VDK_kSemaphoreTimeout
VDK_kEventTimeout
VDK_kBlockInInvalidRegion
VDK_kDbgPossibleBlockInRegion
VDK_kInvalidPeriod
VDK_kAlreadyPeriodic
VDK_kNonperiodicSemaphore
VDK_kDbgPopUnderflow
VDK_kBadIOID
VDK_kBadDeviceDescriptor
VDK_kSSLInitFailure1

VDK_kOpenFailure
VDK_kCloseFailure

1

kSSLInitFailure is introduced in VisualDSP++ 5.0 update 4 and does not exist in releases prior to thatone.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

4-51

Data Type Descriptions

VDK_kReadFailure
VDK_kWriteFailure
VDK_kIOCtlFailure
VDK_kBadIOTemplateID
VDK_kInvalidDeviceFlag
VDK_kDeviceTimeout
VDK_kDeviceFlagCreationFailure
VDK_kMaxCountExceeded
VDK_kSemaphoreCreationFailure
VDK_kSemaphoreDestructionFailure
VDK_kPoolCreationFailure
VDK_kInvalidBlockPointer
VDK_kInvalidPoolParms
VDK_kInvalidPoolID
VDK_kErrorPoolNotEmpty
VDK_kErrorMallocBlock
VDK_kMessageCreationFailure
VDK_kInvalidMessageID
VDK_kInvalidMessageOwner
VDK_kInvalidMessageChannel
VDK_kInvalidMessageRecipient
VDK_kMessageTimeout
VDK_kMessageInQueueVDK_kInvalidTimeout
VDK_kInvalidTargetDSP
VDK_kIOCreateFailure
VDK_kHeapInitialisationFailure
VDK_kInvalidHeapID
VDK_kNewFailure
VDK_kInvalidMarshalledType
VDK_kUncaughtException
VDK_kAbort
VDK_kInvalidMaskBit
VDK_kInvalidThreadStatus

4-52

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK Data Types

VDK_kThreadStackOverflow
VDK_kMaxIDExceeded
VDK_kThreadDestroyedInInvalidRegion
VDK_kNotMutexOwner
VDK_kMutexNotOwned
VDK_kMutexCreationFailure
VDK_kMutexDestructionFailure
VDK_kMutexSpaceTooSmall
VDK_kInvalidMutexID
VDK_kInvalidMutexOwner
VDK_kAPIUsedfromISR
VDK_kMaxHistoryEventExceeded
VDK_kUnhandledExceptionError

1

VDK_kInvalidPointer
VDK_kIntsAreDisabled
VDK_kRescheduleIntIsMasked
VDK_kNoError = 0
VDK_kFirstUserError
VDK_kLastUserError

In C++:
Type name:

VDK::SystemError

Possible values: VDK::kUnknownThreadType
VDK::kUnknownThread
VDK::kInvalidThread
VDK::kThreadCreationFailure
VDK::kUnknownSemaphore
VDK::kUnknownEventBit
VDK::kUnknownEvent
VDK::kInvalidPriority

1

kUnhandledExceptionError is introduced in VisualDSP++ 5.0 update 9 and does not exist in releases
prior to that one.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

4-53

Data Type Descriptions

VDK::kInvalidDelay
VDK::kSemaphoreTimeout
VDK::kEventTimeout
VDK::kBlockInInvalidRegion
VDK::kDbgPossibleBlockInRegion
VDK::kInvalidPeriod
VDK::kAlreadyPeriodic
VDK::kNonperiodicSemaphore
VDK::kDbgPopUnderflow
VDK::kBadIOID
VDK::kBadDeviceDescriptor
VDK::kSSLInitFailure

1

VDK::kOpenFailure
VDK::kCloseFailure
VDK::kReadFailure
VDK::kWriteFailure
VDK::kIOCtlFailure
VDK::kBadIOTemplateID
VDK::kInvalidDeviceFlag
VDK::kDeviceTimeout
VDK::kDeviceFlagCreationFailure
VDK::kMaxCountExceeded
VDK::kSemaphoreCreationFailure
VDK::kSemaphoreDestructionFailure
VDK::kPoolCreationFailure
VDK::kInvalidBlockPointer
VDK::kInvalidPoolParms
VDK::kInvalidPoolID
VDK::kErrorPoolNotEmpty
VDK::kErrorMallocBlock
VDK::kMessageCreationFailure
VDK::kInvalidMessageID
1

kSSLInitFailure is introduced in VisualDSP++ 5.0 update 4 and does not exist in releases prior to that
one.

4-54

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK Data Types

VDK::kInvalidMessageOwner
VDK::kInvalidMessageChannel
VDK::kInvalidMessageRecipient
VDK::kMessageTimeout
VDK::kMessageInQueue
VDK::kInvalidTimeout
VDK::kInvalidTargetDSP
VDK::kIOCreateFailure
VDK::kHeapInitialisationFailure
VDK::kInvalidHeapID
VDK::kNewFailure
VDK::kInvalidMarshalledType
VDK::kUncaughtException
VDK::kAbort
VDK::kInvalidMaskBit
VDK::kInvalidThreadStatus
VDK::kThreadStackOverflow
VDK::kMaxIDExceeded
VDK::kThreadDestroyedInInvalidRegion
VDK::kNotMutexOwner
VDK::kMutexNotOwned
VDK::kMutexCreationFailure
VDK::kMutexDestructionFailure
VDK::kMutexSpaceTooSmall
VDK::kInvalidMutexID
VDK::kInvalidMutexOwner
VDK::kAPIUsedfromISR
VDK::kMaxHistoryEventExceeded
VDK::kUnhandledExceptionError

1

VDK::kInvalidPointer
VDK::kIntsAreDisabled
VDK::kRescheduleIntIsMasked
1

kUnhandledExceptionError is introduced in VisualDSP++ 5.0 update 9 and does not exist in releases
prior to that one.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

4-55

Data Type Descriptions

VDK::kNoError = 0
VDK::kFirstUserError
VDK::kLastUserError

4-56

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK Data Types

TCBBitfield
The TCBBitfield1 type enumerates the different bits that can be set in thesecond argument in a call to CreateThreadEx2(). The argument specifies
the default parameters of a ThreadType that should be overridden withuser-specified values when creating a new thread. To specify multiple
parameters that should be overridden, the flags defined in this enumeration must be ORed together.
In C:
Type name: VDK_TCBBitfield
Possible values: VDK_kSetThreadTemplateID
VDK_kSetThreadStackSize
VDK_kSetThreadPriority
VDK_kSetUserDataPointer
VDK_kSetThreadTemplatePointer
VDK_kSetThreadStackPointer

In C++:
Type name: VDK::TCBBitfield
Possible values: VDK::kSetThreadTemplateID
VDK::kSetThreadStackSize
VDK::kSetThreadPriority
VDK::kSetUserDataPointer
VDK::kSetThreadTemplatePointer
VDK::kSetThreadStackPointer1

TCBBitfield is available only in VisualDSP++ 5.0 update 9 or later.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

4-57

Data Type Descriptions

ThreadCreationBlock
A variable of type ThreadCreationBlock is passed to the CreateThreadEx() and CreateThreadEx2() functions.
The CreateThreadEx() API utilizes any non-zero fields from ThreadCreationBlock, which exists in VisualDSP++ 5.0 or earlier (it cannot use any
new fields for backwards compatibility).
The CreateThreadEx2() API requires a second argument, which indicates
the ThreadCreationBlock fields to set. This makes CreateThreadEx2() anextensible API if new fields are introduced in later versions of VisualDSP++. See the individual API description for details.
CreateThreadEx2() is introduced in VisualDSP++ 5.0 update 9 and isavailable for Blackfin and SHARC processors only.
In C:
typedef struct VDK_ThreadCreationBlock{VDK_ThreadType

template_id;

VDK_ThreadID

thread_id;

unsigned int

thread_stack_size;

VDK_Priority

thread_priority;void*user_data_ptr;

structVDK_ThreadTemplate *pTemplate;unsigned int*stack_pointer;} VDK_ThreadCreationBlock;

In C++:
typedef struct VDK::ThreadCreationBlock{

4-58

VDK::ThreadType

template_id;

VDK::ThreadID

thread_id;

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK Data Typesunsigned int

thread_stack_size;

VDK::Priority

thread_priority;void*user_data_ptr;

struct VDK::ThreadTemplate *pTemplate;unsigned int*stack_pointer;} VDK::ThreadCreationBlock;•

template_id corresponds to a ThreadType defined in the VDK.h and
VDK.cpp files. These files contain the default values for the stacksize and initial priority, which may optionally be overridden by thefollowing fields.

•

thread_id is an output only field. On a successful return, it con-tains the same value as the function return.
•thread_stack_size is expressed in 32-bit words and overrides thedefault stack size implied by the ThreadType.
•thread_priority overrides the default thread priority implied by

the ThreadType.
•user_data_ptr allows a generic argument to be passed (without

interpretation) to the thread creation function and, hence, to thethread constructor. This allows individual thread instances to beparameterized at creation time, without the need to resort to global
variables for argument passing.
•pTemplate is a pointer to the thread template that is used to gener-

ate the thread. This is only required if the template_id is set tokDynamicThreadType. The stack size and initial priority are(optionally) overridden by the values specified in thethread_stack_size and thread_priority fields.
•

stack_pointer is a pointer to a user-allocated area of memory ofsize thread_stack_size. This field is ignored in calls to CreateThreadEx(). On Blackfin processors, VDK stores the thread

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

4-59

Data Type Descriptions

context in the stack and, therefore, the area of memory allocatedmust be stack_size + context_size, where context_size can beobtained with a call to the GetContextRecordSize() API.

4-60

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK Data Types

ThreadID
The ThreadID type is used to store the unique identifier of a thread.
enum ThreadID{/* Defined by IDDE in the VDK.h file. */};The enumeration in VDK.h will contain the IDs only for the threads
enabled at boot time. Any dynamically-created threads will have an ID of
the same type to allow the compiler to perform type checking and prevent
errors.
In C:
typedef enum ThreadID VDK_ThreadID;

In C++:
typedef enum ThreadID VDK::ThreadID;

are two values that strictly are not thread IDs but are used by
L ThereVDK as such:
0xC0000000 means kernel level0x80000000 means interrupt level

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

4-61

Data Type Descriptions

ThreadStatus
The ThreadStatus type is used to enumerate the state of a thread.
In C:
Type name:
VDK_ThreadStatus
Possible values: VDK_kReady
VDK_kSemaphoreBlocked
VDK_kEventBlocked
VDK_kDeviceFlagBlocked,
VDK_kSemaphoreBlockedWithTimeout
VDK_kEventBlockedWithTimeout
VDK_kDeviceFlagBlockedWithTimeout
VDK_kSleeping
VDK_MessageBlocked
VDK_kMessageBlockedWithTimeout
VDK_kMutexBlocked
VDK_kUnknown

In C++:
Type name:
VDK::ThreadStatus
Possible values: VDK::kReady
VDK::kSemaphoreBlocked
VDK::kEventBlocked
VDK::kDeviceFlagBlocked
VDK::kSemaphoreBlockedWithTimeout
VDK::kEventBlockedWithTimeout
VDK::kDeviceFlagBlockedWithTimeout
VDK::kSleeping
VDK::MessageBlocked
VDK::kMessageBlockedWithTimeout
VDK::kMutexBlocked
VDK::kUnknown

4-62

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK Data Types

ThreadType
ThreadType is used to store the unique identifier of a Thread class.
enum ThreadType{/* Defined by IDDE in the VDK.h file. */
};

In C:
typedef enum ThreadType VDK_ThreadType;In C++:
typedef enum ThreadType VDK::ThreadType;

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

4-63

Data Type Descriptions

Ticks
Time is measured in system Tick. A tick is the amount of time between
hardware interrupts generated by a hardware timer.
In C:
typedef unsigned int VDK_Ticks;

In C++:
typedef unsigned int VDK::Ticks;

4-64

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK Data Types

VersionStruct
The VersionStruct constant is used to store four integers that describe thesystem parameters: VDK API version number, processor family supported, base processor product supported, and build number.
In C:
typedef struct{
int

mAPIVersion;

VDK_DSP_Family

mFamily;

VDK_DSP_ProductmProduct;longmBuildNumber;} VDK_VersionStruct;

In C++:
typedef struct{
int

mAPIVersion;

VDK::DSP_Family

mFamily;

VDK::DSP_ProductmProduct;longmBuildNumber;} VDK::VersionStruct;mAPIVersion is an integer of the 0xMMmmUURR format, where MM is the major

version number, mm is the minor version number, UU is the update number,and RR is reserved. This field does not change in any releases of VisualDSP++ but only when the VDK API changes. See the DSP_Family and
DSP_Product data types for more information.
processors can use a common set of the VDK libraries.
L Different
can not correspond to the proBecause of this, the fieldmProduct

cessor in a particular application.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

4-65

Data Type Descriptions

4-66

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5 VDK API REFERENCE

The VDK Application Programming Interface (API) is a library of functions and macros that may be called from your application programs.
Application programs depend on API functions to perform services thatare basic to VDK. These services include interrupt handling, scheduler
management, thread management, semaphore management, memory pool
management, events and event bits, device drivers, and message passing.
All of the VDK functions are written in the C++ programming language.
This chapter describes the current release of the API library. Future
releases may include additional functions.
This chapter provides information on the following topics:• “Calling Library Functions” on page 5-2• “Linking Library Functions” on page 5-2• “Working With VDK Library Header” on page 5-2• “Passing Function Parameters” on page 5-3• “Library Naming Conventions” on page 5-3• “API Summary” on page 5-5• “VDK Error Codes and Error Values” on page 5-11
• “VDK API Validity” on page 5-19
• “API Functions” on page 5-25
• “Assembly Macros and C/C++ ISR APIs” on page 5-235
VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-1

Calling Library Functions

Calling Library Functions
To use an API function or a macro, call it by name and provide the appropriate arguments. The name and arguments for each library entity appear
on its reference page. Note that the function names are C and C++ function names. If you call a C run-time library function from an assembly
language program, prefix the function name with an underscore.
Similar to other functions, library functions should be declared. Declarations are supplied in the VDK.h header file. For more information about
the kernel header file, see “Working With VDK Library Header” onpage 5-2.
The reference pages appear in the “API Summary” on page 5-5.

Linking Library Functions
When your code calls an API function, the call creates a reference resolvedby the linker when linking your program. One way to direct the linker tothe library’s location is to use the default VDK Linker Description File
(VDK-<your_target>.ldf). The default VDK Linker Description Fileautomatically directs the linker to the *.dlb file in the lib subdirectory of
your VisualDSP++ installation.
If you do not use the default VDK .ldf file, add the library file to yourproject’s .ldf file. Alternatively, use the compiler’s -l (library directory)
switch to specify the library to be added to the link line. Library functions
are not linked into the .dxe file unless they are referenced.

Working With VDK Library Header
If one of your program source files needs to call a VDK API library function, include the VDK.h header file with the #include preprocessor

5-2

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

command. The header file provides prototypes for all VDK public functions. The compiler uses prototypes to ensure each function is called withthe correct arguments. The VDK.h file also provides declarations foruser-accessible global variables, macros, type definitions, andenumerations.

Passing Function Parameters
All parameters passed through the VDK library functions listed in “API
Summary” on page 5-5 are either passed by value or as constant objects.
This means VDK does not modify any of the variables passed. Where
arguments need to be modified, they are passed by the address (pointer).

Library Naming Conventions
Table 5-1 and Table 5-2 show coding style conventions that apply to theentities in the library reference section. By following the library and function naming conventions, you can review VDK sources or documentation
and recognize whether the identifier is a function, macro, variable parameter, or a constant.
Table 5-1. Library Naming Conventions
Notation

Description

VDK_Ticks

VDK-defined types are written with the first letter
uppercasekPriority1

Constants are prefixed with a “k”

inTypeInput parameters are prefixed with an “in”

mDevice

Data members are prefixed with an “m”

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-3

Library Naming Conventions

Table 5-2. Function and Macro Naming Conventions

5-4

Notation

Description

VDK_

C-callable function names are prefixed by “VDK_” todistinguish VDK library functions from user functions

VDK::

C++-callable functions are located in the VDK
namespace, thus function names are preceded by“VDK::”VDK_Yield(void)

The remaining portion of the function name is written with the first letter of each sub-word in uppercase

VDK_ISR_SET_EVENTBIT_()

Assembly macros are written in uppercase withwords separated by underscores and a trailing underscore

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

API Summary
Table 5-3 through Table 5-21 list the VDK library entities included in thecurrent software release. These tables list the library entities grouped by aparticular service. The reference pages beginning on page 5-28 appear inalphabetic order.
Table 5-3. Interrupt Handling Functions
Function Name

Reference Page

PopCriticalRegion()on page 5-190

PopNestedCriticalRegions()

on page 5-192

PushCriticalRegion()on page 5-203

Table 5-4. Interrupt Mask Handling Functions
ClearInterruptMaskBits()

on page 5-34

ClearInterruptMaskBitsEx()

on page 5-35

GetInterruptMask()

on page 5-111

GetInterruptMaskEx()

on page 5-113

SetInterruptMaskBits()

on page 5-216

SetInterruptMaskBitsEx()

on page 5-218

Table 5-5. Scheduler Management Functions
PopNestedUnscheduledRegions()

on page 5-194

PopUnscheduledRegion()on page 5-195

PushUnscheduledRegion()on page 5-204

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-5

API Summary

Table 5-6. Block Memory Management Functions
CreatePool()on page 5-45

CreatePoolEx()

on page 5-47

DestroyPool()on page 5-65

FreeBlock()on page 5-78

GetBlockSize()

on page 5-95

GetNumAllocatedBlocks()

on page 5-125

GetNumFreeBlocks()

on page 5-126

LocateAndFreeBlock()on page 5-169

MallocBlock()on page 5-173

Table 5-7. Thread and System Information Functions

5-6

GetClockFrequency()

on page 5-96

GetContextRecordSize()

on page 5-97

GetHeapIndex()

on page 5-107

GetThreadHandle()on page 5-144

GetThreadID()on page 5-145

GetThreadStackUsage()on page 5-151

GetThreadStack2Usage()on page 5-153

GetThreadStatus()

on page 5-155

GetTickPeriod()on page 5-160

GetUptime()on page 5-161

GetVersion()on page 5-162

InstrumentStack()

on page 5-165

LogHistoryEvent()

on page 5-170

ReplaceHistorySubroutine()on page 5-209

SetClockFrequency()

on page 5-213

SetTickPeriod()on page 5-226

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

Table 5-8. Application Status Information Functions
Function Name

Reference Page

GetAllDeviceFlags()

on page 5-85

GetAllMemoryPools()

on page 5-87

GetAllMessages()on page 5-89

GetAllSemaphores()on page 5-91

GetAllThreads()

on page 5-93

GetCurrentHistoryEventNum()on page 5-99

GetDevFlagPendingThreads()

on page 5-100

GetEventPendingThreads()

on page 5-104

GetHistoryBufferSize()

on page 5-108

GetHistoryEvent()

on page 5-109

GetMessageStatusInfo()

on page 5-123

GetNumTimesRun()on page 5-127

GetPoolDetails()

on page 5-129

GetSemaphoreDetails()

on page 5-132

GetSemaphorePendingThreads()

on page 5-134

GetSharcThreadCycleData()

on page 5-138

GetThreadBlockingID()on page 5-140

GetThreadCycleData()

on page 5-142

GetThreadStackDetails()

on page 5-147

GetThreadStack2Details()

on page 5-149

GetThreadTemplateName()on page 5-156

GetThreadTickData()

on page 5-158

Table 5-9. Thread Creation and Destruction Functions
CreateThread()on page 5-51

CreateThreadEx()

on page 5-53

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-7

API Summary

Table 5-9. Thread Creation and Destruction Functions (Cont’d)CreateThreadEx2()

on page 5-55

DestroyThread()on page 5-69

FreeDestroyedThreads()

on page 5-80

Table 5-10. Thread Local Storage Functions
AllocateThreadSlot()on page 5-28

AllocateThreadSlotEx()

on page 5-30

FreeThreadSlot()on page 5-83

GetThreadSlotValue()on page 5-146

SetThreadSlotValue()on page 5-225

Table 5-11. Thread Error Management Functions
ClearThreadError()on page 5-37

DispatchThreadError()on page 5-73

GetLastThreadError()on page 5-115

GetLastThreadErrorValue()on page 5-116

SetThreadError()on page 5-224

Table 5-12. Thread Priority Management Functions
GetPriority()on page 5-131

ResetPriority()on page 5-211

SetPriority()on page 5-222

Table 5-13. Thread Scheduling Control Functions

5-8

Sleep()

on page 5-227

Yield()

on page 5-233

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

Table 5-14. Semaphore Management Functions
CreateSemaphore()on page 5-49

DestroySemaphore()on page 5-67

GetSemaphoreValue()on page 5-136

InstallMessageControlSemaphore()on page 5-163

MakePeriodic()

on page 5-171

PendSemaphore()on page 5-187

PostSemaphore()on page 5-201

RemovePeriodic()

on page 5-207

Table 5-15. Event and EventBit Functions
ClearEventBit()on page 5-32

GetEventBitValue()on page 5-102

GetEventData()

on page 5-103

GetEventValue()on page 5-106

LoadEvent()

on page 5-167

PendEvent()

on page 5-181

SetEventBit()on page 5-214

Table 5-16. Device Flags Functions
CreateDeviceFlag()on page 5-40

DestroyDeviceFlag()on page 5-58

PendDeviceFlag()on page 5-179

PostDeviceFlag()on page 5-197

Table 5-17. Device Driver Functions
CloseDevice()

on page 5-38

DeviceIOCtl()

on page 5-71

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-9

API Summary

Table 5-17. Device Driver Functions (Cont’d)
OpenDevice()

on page 5-177

SyncRead()on page 5-229

SyncWrite()on page 5-231

Table 5-18. Message Functions
CreateMessage()on page 5-41

DestroyMessage()on page 5-59

DestroyMessageAndFreePayload()on page 5-61

ForwardMessage()on page 5-75

FreeMessagePayload()on page 5-81

GetMessageDetails()

on page 5-117

GetMessagePayload()on page 5-119

GetMessageReceiveInfo()

on page 5-121

InstallMessageControlSemaphore()on page 5-163

MessageAvailable()on page 5-175

PendMessage()on page 5-184

PostMessage()on page 5-198

SetMessagePayload()on page 5-220

Table 5-19. Mutex Management Functions
AcquireMutex()

on page 5-26

CreateMutex()

on page 5-43

DestroyMutex()

on page 5-63

ReleaseMutex()

on page 5-205

5-10VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

Table 5-20. Assembly Macros
Macro Name

Reference Page

VDK_ISR_ACTIVATE_DEVICE_()on page 5-237

VDK_ISR_CLEAR_EVENTBIT_()on page 5-238

VDK_ISR_LOG_HISTORY_()

on page 5-239

VDK_ISR_POST_SEMAPHORE_()on page 5-240

VDK_ISR_SET_EVENTBIT_()on page 5-241

Table 5-21. C/C++ ISR API
Function Name

Reference Page

C_ISR_ActivateDevice()

on page 5-242

C_ISR_ClearEventBit()on page 5-244

C_ISR_PostSemaphore()on page 5-246

C_ISR_SetEventBit()on page 5-248

VDK Error Codes and Error Values
The entry for each VDK API function lists the error codes that may result
from calling that function. Additional information is provided, whereappropriate, in the form of an integer value relating to the error code in

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-11

VDK Error Codes and Error Values

question. Table 5-22 summarizes the possible error codes dispatched by
all VDK API functions, along with the associated error value.
Table 5-22. VDK API Error Codes and Error Values
Function Name

Error CodeError Value

All functions

kAPIUsedfromISR

Blackfin processors - IPEND1SHARC processors - IMASKP2
TigerSHARC processors - 0

All functions

kThreadStackOverflow

If raised by the compiler stack
overflow detection:
SHARC processors - PCSTKBlackfin processors - RETS
If detected by a pre-emptive
context switch:
All processors - Thread ID

AcquireMutex()kInvalidMutexID

inMutexID

AcquireMutex()

kDbgPossibleBlockInRegion

Number of nested unscheduled
regions

AcquireMutex()

kBlockInInvalidRegion

Number of nested unscheduled
regions

AcquireMutex()kInvalidMutexOwner

MutexID owner

ClearEventBit()

kUnknownEventBit

inEventBitID

ClearInterruptMaskBitsEx()

kInvalidMaskBit

Bit that does not refer to aninterrupt mask bit

CloseDevice()

kBadDeviceDescriptor

inDD

CreateDeviceFlag()kDeviceFlagCreationFailure-1

CreateMessage()kErrorMallocBlock

Number of free blocks in thepool reserved for messages

CreateMutex()

kMutexCreationFailure

Size of the mutex structure

CreatePool()

kPoolCreationFailure0CreatePool()kInvalidPoolParms

0

CreatePoolEx()

kPoolCreationFailure

0

5-12

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

Table 5-22. VDK API Error Codes and Error Values (Cont’d)
Function Name

Error CodeError Value

CreatePoolEx()

kInvalidPoolParms

0

CreateSemaphore()

kMaxCountExceeded-1CreateSemaphore()kSemaphoreCreationFailure -1

CreateThread()kUnknownThreadType

inTypeCreateThread()kThreadCreationFailureinTypeCreateThreadEx()

kUnknownThreadType

inOutTCB –> Template ID

CreateThreadEx()

kThreadCreationFailure

inOutTCB –> Template ID

CreateThreadEx2()

kIncompatibleArguments

inFieldsRequired

CreateThreadEx2()

kInvalidPointerinOutTCB –> pTemplate if theerror was a bad template or
inOutTCB –> stack_pointerif the error was a misaligned
stack pointerCreateThreadEx2()

kThreadCreationFailure

inOutTCB –> Template ID

CreateThreadEx2()

kUnknownThreadType

inOutTCB –> Template ID

DestroyDeviceFlag()kInvalidDeviceFlag

inDeviceFlagID

DestroyMessage()kInvalidMessageID

inMessageID

DestroyMessage()kMessageInQueueinMessageID

DestroyMessage()kInvalidMessageOwner

inMessageID

DestroyMessageAndFreePayload()kInvalidMessageID

inMessageID

DestroyMessageAndFreePayload()kMessageInQueueinMessageID

DestroyMessageAndFreePayload()kInvalidMessageOwner

inMessageID

DestroyMutex()kInvalidMutexID

inMutexID

DestroyMutex()

kMutexDestructionFailure

inMutexID

DestroyPool()kErrorPoolNotEmpty

inPoolID

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-13

VDK Error Codes and Error Values

Table 5-22. VDK API Error Codes and Error Values (Cont’d)
Function Name

Error CodeError Value

DestroyPool()kInvalidPoolID

inPoolID

DestroySemaphore()kSemaphoreDestructionFailure

inSemaphoreID

DestroySemaphore()

kUnknownSemaphore

inSemaphoreID

DestroyThread()kInvalidThreadinThreadID

DestroyThread()kUnknownThreadinThreadID

DeviceIOCtl()

kBadDeviceDescriptor

inDD

ForwardMessage()kInvalidMessageID

inMessageID

ForwardMessage()kMessageInQueueinMessageID

ForwardMessage()kInvalidMessageOwner

inMessageID

FreeBlock()kInvalidPoolID

inPoolID

FreeBlock()kInvalidBlockPointerinBlockPtr

FreeMessagePayload()kInvalidMessageID

inMessageID

FreeMessagePayload()kMessageInQueueinMessageID

FreeMessagePayload()kInvalidMessageOwner

inMessageID

GetAllDeviceFlags()

kInvalidPointer0

GetAllMemoryPools()

kInvalidPointer0

GetAllMessages()kInvalidPointer0

GetAllSemaphores()kInvalidPointer0

GetAllThreads()

kInvalidPointer0

GetDevFlagPendingThreads()

kInvalidPointer0

GetSemaphorePendingThreads()

kInvalidPointer0

GetBlockSize()kInvalidPoolID

inPoolID

GetEventBitValue()

kUnknownEventBit

inEventBitID

GetEventData()

kUnknownEventinEventID

GetEventValue()

kUnknownEventinEventID

5-14

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

Table 5-22. VDK API Error Codes and Error Values (Cont’d)
Function Name

Error CodeError Value

GetHeapIndex()kInvalidHeapID

inHeapID

GetMessageDetails()

kInvalidMessageID

inMessageID

GetMessageDetails()

kMessageInQueueinMessageID

GetMessageDetails()

kInvalidMessageOwner

inMessageID

GetMessagePayload()kInvalidMessageID

inMessageID

GetMessagePayload()kMessageInQueueinMessageID

GetMessagePayload()kInvalidMessageOwner

inMessageID

GetMessageReceiveInfo()kInvalidMessageID

inMessageID

GetMessageReceiveInfo()

kMessageInQueueinMessageID

GetMessageReceiveInfo()kInvalidMessageOwner

inMessageID

GetNumAllocatedBlocks()

kInvalidPoolID

inPoolID

GetNumFreeBlocks()

kInvalidPoolID

inPoolID

GetPriority()

kUnknownThreadinThreadID

GetSemaphoreValue()

kUnknownSemaphore

0

GetThreadStackUsage()

kUnknownThreadinThreadID

GetThreadStack2Usage()

kUnknownThreadinThreadID

LoadEvent()

kUnknownEventinEventID

LocateAndFreeBlock()kInvalidBlockPointerinBlkPtr

MakePeriodic()kInvalidPeriod

inPeriod

MakePeriodic()

kUnknownSemaphore

inSemaphoreID

MakePeriodic()kInvalidDelay

inDelay

MakePeriodic()kAlreadyPeriodic

inSemaphoreID

MallocBlock()kInvalidPoolID

inPoolID

MallocBlock()kErrorMallocBlock

NumFreeBlocks

MessageAvailable()kInvalidThread

0

MessageAvailable()kInvalidMessageChannel

inMsgChannelMask

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-15

VDK Error Codes and Error Values

Table 5-22. VDK API Error Codes and Error Values (Cont’d)
Function Name

Error CodeError Value

OpenDevice()

kBadIOID

inIDNum

OpenDevice()

kOpenFailure

inIDNum

PendDeviceFlag()kDeviceTimeout

inTimeout

PendDeviceFlag()kBlockInInvalidRegion

Number of nested unscheduled
regions

PendDeviceFlag()kInvalidDeviceFlag

inFlagID

PendDeviceFlag()kInvalidTimeout

inTimeout

PendEvent()

kDbgPossibleBlockInRegion

Number of nested unscheduled
regions

PendEvent()

kBlockInInvalidRegion

Number of nested unscheduled
regions

PendEvent()kEventTimeout

inTimeout

PendEvent()

kUnknownEventinEventID

PendEvent()

kInvalidTimeout

inTimeout

PendMessage()kInvalidThread0

PendMessage()kInvalidTimeout

inTimeout

PendMessage()

kDbgPossibleBlockInRegion

Number of nested unscheduled
regions

PendMessage()kInvalidMessageChannel

inMessageChannelMask

PendMessage()kBlockInInvalidRegion

Number of nested unscheduled
regions

PendMessage()kMessageTimeout

inTimeout

PendMessage()kInvalidMessageID

0

PendSemaphore()kInvalidTimeout

inTimeout

PendSemaphore()

kDbgPossibleBlockInRegion

Number of nested unscheduled
regions

PendSemaphore()

kUnknownSemaphore

inSemaphoreID

PendSemaphore()kSemaphoreTimeout

inTimeout

5-16

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

Table 5-22. VDK API Error Codes and Error Values (Cont’d)
Function Name

Error CodeError Value

PendSemaphore()kBlockInInvalidRegion

Number of nested unscheduled
regions

PopCriticalRegion()kDbgPopUnderflow

kFromPopCriticalRegion

PopNestedCriticalRegions()

kDbgPopUnderflow

kFromPopNestedCriticalRegions

PopNestedUnscheduledRegions()

kDbgPopUnderflow

kFromPopNestedUnscheduledRegions

PopUnscheduledRegion()kDbgPopUnderflow

kFromPopUnscheduledRegion

PostDeviceFlag()kInvalidDeviceFlag

inFlagID

PostMessage()kInvalidMessageChannel

inChannel

PostMessage()kInvalidTargetDSP

dstNode (MP only)

PostMessage()kInvalidMessageOwner

MessageID owner

PostMessage()kInvalidMessageRecipient

Recipient ThreadID

PostMessage()kMessageInQueue

MessageID owner

PostMessage()kInvalidMessageID

inMessageID

PostMessage()

kUnknownThreadinRecipient

PostSemaphore()

kUnknownSemaphore

inSemaphoreID

ReleaseMutex()kInvalidMutexID

inMutexID

ReleaseMutex()

kMutexNotOwned

0

ReleaseMutex()

kNotMutexOwner

MutexID owner

RemovePeriodic()

kUnknownSemaphore

inSemaphoreID

RemovePeriodic()

kNonperiodicSemaphore

inSemaphoreID

ResetPriority()kInvalidThreadinThreadID

ResetPriority()

kUnknownThreadinThreadID

SetEventBit()

kUnknownEventBit

inEventBitID

SetInterruptMaskBitsEx()

kInvalidMaskBit

Bit that does not refer to aninterrupt mask bit

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-17

VDK Error Codes and Error Values

Table 5-22. VDK API Error Codes and Error Values (Cont’d)
Function Name

Error CodeError Value

SetMessagePayload()kInvalidMessageID

inMessageID

SetMessagePayload()kMessageInQueueinMessageID

SetMessagePayload()kInvalidMessageOwner

inMessageID

SetPriority()kInvalidPriority

inPriority

SetPriority()

kUnknownThreadinThreadID

SetPriority()kInvalidThreadinThreadID

Sleep()

kBlockInInvalidRegion

Number of nested unscheduled
regions

Sleep()kInvalidDelay

inSleepTicks

SyncRead()kBadDeviceDescriptor

inDD

SyncWrite()kBadDeviceDescriptor

inDD

Yield()

kBlockInInvalidRegion

Number of nested unscheduled
regions1
2

IVG15 and the reschedule ISR (IVG14) are masked out in the value.
The reschedule ISR (SFT2I) is masked out in the value.

When using the VDK multiprocessor messaging functionality, the Routing Thread Run functions dispatch errors when appropriate. Table 5-23
summarizes the possible error codes dispatched by Routing Threads, alongwith the associated error value.
Table 5-23. Routing Thread Run Function Error Codes and Error Values
Error CodeError ValuekBadIOID

IOID

kInvalidMarshalledType

Payload typekInvalidMessageID

0

kMaxCountExceeded

Payload typekOpenFailure

IOID

5-18

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

VDK API Validity
In a VDK application, user code can execute at different levels – startup,
thread level, kernel level, and interrupt level (see Appendix A “Processor-Specific Notes”). By startup we understand the constructor/Createfunction of a boot thread or the Init part of a device driver’s dispatch
function. VDK does not get initialized until main() is reached, so none of
the VDK APIs should be called in global constructors. It is not safe to use
all VDK APIs at all levels. Table 5-24 details the validity of calling eachVDK API at each of the levels and also from startup code. If an API iscalled from an inappropriate level, a KernelPanic is typically raised.
Table 5-24. API Validity Levels
API Function

Thread Level

Kernel Level

ISR Level

StartupAcquireMutex()

Yes

No

No

No

AllocateThreadSlot()

Yes

No

No

No

AllocateThreadSlotEx()

Yes

No

No

No

C_ISR_ActivateDevice()

No

No

Yes

No

C_ISR_ClearEventBit()

No

No

Yes

No

C_ISR_PostSemaphore()

No

No

Yes

No

C_ISR_SetEventBit()

No

No

Yes

No

ClearEventBit()

Yes

No

No

No

ClearInterruptMaskBits()

Yes

Yes

No

Yes

ClearInterruptMaskBitsEx()

Yes

Yes

No

Yes

ClearThreadError()

Yes

No

No

No

CloseDevice()

Yes

No

No

No

CreateDeviceFlag()

Yes

No

No

Yes

CreateMessage()

Yes

No

No

Yes

CreateMutex()

Yes

No

No

Yes

CreatePool()

Yes

No

No

Yes

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-19

VDK API Validity

Table 5-24. API Validity Levels (Cont’d)
API Function

Thread Level

Kernel Level

ISR Level

StartupCreatePoolEx()

Yes

No

No

Yes

CreateSemaphore()

Yes

No

No

Yes

CreateThread()

Yes

No

No

No

CreateThreadEx()

Yes

No

No

No

CreateThreadEx2()

Yes

No

No

Yes

DestroyDeviceFlag()

Yes

No

No

No

DestroyMessage()

Yes

No

No

No

DestroyMessageAndFreePayload()

Yes

No

No

No

DestroyMutex()

Yes

No

No

No

DestroyPool()

Yes

No

No

No

DestroySemaphore()

Yes

No

No

No

DestroyThread()

Yes

No

No

No

DeviceIOCtl()

Yes

No

No

No

DispatchThreadError()

Yes

No

No

No

ForwardMessage()

Yes

No

No

No

FreeBlock()

Yes

Yes

No

No

FreeDestroyedThreads()

Yes

No

No

No

FreeMessagePayload()

Yes

No

No

No

FreeThreadSlot()

Yes

No

No

No

GetAllDeviceFlags()

Yes

Yes

No

No

GetAllMemoryPools()

Yes

Yes

No

No

GetAllMessages()

Yes

Yes

No

No

GetAllSemaphores()

Yes

Yes

No

No

GetAllThreads()

Yes

Yes

No

No

GetBlockSize()

Yes

Yes

No

No

GetClockFrequency()

Yes

Yes

Yes

Yes

5-20

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

Table 5-24. API Validity Levels (Cont’d)
API Function

Thread Level

Kernel Level

ISR Level

Startup

GetContextRecordSize()

Yes

Yes

Yes

Yes

GetCurrentHistoryEventNum()

Yes

Yes

No

No

GetDevFlagPendingThreads()

Yes

Yes

No

No

GetEventBitValue()

Yes

No

No

No

GetEventData()

Yes

No

No

No

GetEventPendingThreads()

Yes

Yes

No

No

GetEventValue()

Yes

No

No

No

GetHeapIndex()

Yes

No

No

No

GetHistoryBufferSize()

Yes

Yes

No

No

GetHistoryEvent()

Yes

Yes

No

No

GetInterruptMask()

Yes

No

No

No

GetInterruptMaskEx()

Yes

No

No

No

GetLastThreadError()

Yes

No

No

No

GetLastThreadErrorValue()

Yes

No

No

No

GetMessageDetails()

Yes

No

No

No

GetMessagePayload()

Yes

No

No

No

GetMessageReceiveInfo()

Yes

No

No

No

GetMessageStatusInfo()

Yes

No

No

No

GetNumAllocatedBlocks()

Yes

Yes

No

No

GetNumFreeBlocks()

Yes

Yes

No

No

GetNumTimesRun()

Yes

Yes

No

No

GetPoolDetails()

Yes

Yes

No

No

GetPriority()

Yes

No

No

No

GetSemaphoreDetails()

Yes

Yes

No

No

GetSemaphorePendingThreads()

Yes

Yes

No

No

GetSemaphoreValue()

Yes

No

No

No

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-21

VDK API Validity

Table 5-24. API Validity Levels (Cont’d)
API Function

Thread Level

Kernel Level

ISR Level

Startup

GetSharcThreadCycleData()

Yes

Yes

No

No

GetThreadBlockingID()

Yes

Yes

No

No

GetThreadCycleData()

Yes

Yes

No

No

GetThreadHandle()

Yes

No

No

No

GetThreadID()

Yes

No

No

No

GetThreadSlotValue()

Yes

No

No

No

GetThreadStackDetails()

Yes

Yes

No

No

GetThreadStack2Details()

Yes

Yes

No

No

GetThreadStackUsage()

Yes

No

No

No

GetThreadStack2Usage()

Yes

No

No

No

GetThreadStatus()

Yes

No

No

No

GetThreadTemplateName()

Yes

Yes

No

No

GetThreadTickData()

Yes

Yes

No

No

GetTickPeriod()

Yes

Yes

Yes

Yes

GetUptime()

Yes

Yes

Yes

Yes

GetVersion()

Yes

Yes

Yes

Yes

InstallMessageControlSemaphore()

Yes

No

No

No

InstrumentStack()

Yes

No

No

No

LoadEvent()

Yes

No

No

No

LocateAndFreeBlock()

Yes

Yes

No

No

LogHistoryEvent()

Yes

Yes

No

No

MakePeriodic()

Yes

No

No

No

MallocBlock()

Yes

Yes

No

No

MessageAvailable()

Yes

No

No

No

OpenDevice()

Yes

No

No

No

5-22

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

Table 5-24. API Validity Levels (Cont’d)
API Function

Thread Level

Kernel Level

ISR Level

Startup

PendDeviceFlag()

Yes

No

No

No

PendEvent()

Yes

No

No

No

PendMessage()

Yes

No

No

No

PendSemaphore()

Yes

No

No

No

PopCriticalRegion()

Yes

Yes

No

No

PopNestedCriticalRegions()

Yes

Yes

No

No

PopNestedUnscheduledRegions()

Yes

No

No

No

PopUnscheduledRegion()

Yes

No

No

No

PostDeviceFlag()

Yes

Yes

No

No

PostMessage()

Yes

No

No

No

PostSemaphore()

Yes

Yes

No

No

PushCriticalRegion()

Yes

Yes

No

No

PushUnscheduledRegion()

Yes

No

No

No

ReleaseMutex()

Yes

No

No

No

RemovePeriodic()

Yes

No

No

No

ReplaceHistorySubroutine()

Yes

Yes

No

Yes

ResetPriority()

Yes

No

No

No

SetClockFrequency()

Yes

No

No

Yes

SetEventBit()

Yes

No

No

No

SetInterruptMaskBits()

Yes

Yes

No

Yes

SetInterruptMaskBitsEx()

Yes

Yes

No

Yes

SetMessagePayload()

Yes

No

No

No

SetPriority()

Yes

No

No

No

SetThreadError()

Yes

No

No

No

SetThreadSlotValue()

Yes

No

No

No

SetTickPeriod()

Yes

No

No

Yes

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-23

VDK API Validity

Table 5-24. API Validity Levels (Cont’d)
API Function

Thread Level

Kernel Level

ISR Level

Startup

Sleep()

Yes

No

No

No

SyncRead()

Yes

No

No

No

SyncWrite()

Yes

No

No

No

VDK_ISR_ACTIVATE_DEVICE_()

No

No

Yes

No

VDK_ISR_CLEAR_EVENTBIT_()

No

No

Yes

No

VDK_ISR_LOG_HISTORY_()

No

No

Yes

No

VDK_ISR_POST_SEMAPHORE_()

No

No

Yes

No

VDK_ISR_SET_EVENTBIT_()

No

No

Yes

No

Yield()

Yes

No

No

No

5-24

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

API Functions
The following format applies to all of the entries in the library reference
section.
• C Prototype – Provides the C prototype (as it is found in VDK.h)
describing the interface to the function• C++ Prototype – Provides the C++ prototype (as it is found in
VDK.h) describing the interface to the function• Description – Describes the function’s operation• Parameters – Describes the function’s parameters• Scheduling – Specifies whether the function invokes the scheduler• Determinism – Specifies whether the function is deterministic• Return Value – Describes the function’s return value• Errors Dispatched – Specifies errors detected by VDK that can be
dealt with by the thread’s error-handling routines

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-25

VDK API Validity

AcquireMutex()
C Prototype
void VDK_AcquireMutex(VDK_MutexID inMutexID);

C++ Prototype
void VDK::AcquireMutex(VDK::MutexID inMutexID);

Description
Provides the mechanism that allows threads to acquire ownership ofmutexes.
When a mutex is created, it has no owner. If a thread acquires a mutex,
and the mutex is not owned, then that thread becomes the mutex owner,
and the processor control returns to the running thread.
A mutex is available and can be acquired by the current thread when the
mutex has no owner and there are no threads of higher priority waiting toacquire the mutex. If a thread tries to acquire a mutex owned by a different thread, the current thread stops execution until the mutex is released
by its owner and becomes available.
VDK mutexes are recursive, enabling calls to AcquireMutex() be nested.
This means that a mutex can be acquired by its owner multiple times. The
mutex ownership is released only when ReleaseMutex() has been called
once for each time that the mutex was acquired. At that point the mutex
becomes available to all threads, and the mutex can be acquired without
stopping execution.
Parameters
inMutexID of type MutexID is the mutex the thread is trying to acquire.

Scheduling
Invokes the scheduler and can result in a context switch
5-26

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

Determinism
Constant time if no other threads own the mutex
Return ValueNo return value
Errors Dispatched
Full instrumentation and error-checking libraries:•

kInvalidMutexID indicates that inMutexID is not a mutex createdby the CreateMutex() API•

kDbgPossibleBlockInRegion indicates that AcquireMutex() isbeing called in an unscheduled region, causing a potential scheduling conflict•

kBlockInInvalidRegion indicates that AcquireMutex() is trying toblock in an unscheduled region, causing a scheduling conflict•kInvalidMutexOwner indicates that the mutex owner was destroyed,

and the mutex could never become available
Non error-checking libraries: none

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-27

VDK API Validity

AllocateThreadSlot()
C Prototypebool VDK_AllocateThreadSlot(int *ioSlotNum);

C++ Prototypebool VDK::AllocateThreadSlot(int *ioSlotNum);

Description
Assigns a new slot number if *ioSlotNum = VDK::kTLSUnallocated andenters the allocated *ioSlotNum into the global slot identifier table.
• Returns FALSE immediately if the value of *ioSlotNum is not equal
to VDK::kTLSUnallocated (INT_MIN) to guard against multiple
attempts to allocate the same key variable• Returns FALSE if there are no free slots, in which case *ioSlotNum isstill VDK::kTLSUnallocated• Otherwise allocates the first available slot, places the slot number
in *ioSlotNum, and returns TRUE
• Does not access (change) any thread state• Guaranteed to return TRUE once only for a given key variable, so
the return value may be used to control other one-time library
initializations• May be safely called during system initialization (that is, before any
threads are running)• Equivalent to calling AllocateThreadSlot() with a NULL cleanupfunction
Parameters
ioSlotNum is a pointer to a slot identifier.

5-28

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

Scheduling
Does not invoke the scheduler
Determinism
Not deterministic
Return Value
TRUE upon success and FALSE upon failure

Errors Dispatched
None

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-29

VDK API Validity

AllocateThreadSlotEx()
C Prototypebool VDK_AllocateThreadSlotEx(int *ioSlotNum,void(*cleanupFn)(void*));C++ Prototypebool VDK::AllocateThreadSlotEx(int *ioSlotNum,void(*cleanupFn)(void*));Description
Assigns a new slot number if *ioSlotNum = VDK::kTLSUnallocated andenters the allocated *ioSlotNum into the global slot identifier table.
• Returns FALSE immediately if the value of *ioSlotNum is not equal
to VDK::kTLSUnallocated (INT_MIN) to guard against multiple
attempts to allocate the same key variable• Returns FALSE if there are no free slots, in which case *ioSlotNum isstill VDK::kTLSUnallocated• Otherwise, allocates the first available slot, places the slot number
in *ioSlotNum, stores the cleanupFn pointer internally, and returns
TRUE• Does not access (change) any thread state• Guaranteed to return TRUE once only for a given key variable, so
the return value may be used to control other one time library
initialization• May be safely called during system initialization; that is, before any
threads are running

5-30

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

Parameters
ioSlotNum is a pointer to a slot identifier.
cleanupFn is a pointer to a function to handle cleanup of thread-specificdata in the event of thread destruction and:• May be NULL, in which case it does nothing• Is called from within DestroyThread()• Executes in the context of the calling thread, not the thread that isbeing destroyed• Is only called when the slot value is not NULL
• The free() function may be used as the cleanup function where
the slot is used to hold malloc’ed data
Scheduling
Does not invoke the scheduler
Determinism
Not deterministic
Return Value
TRUE upon success and FALSE upon failure

Errors Dispatched
None

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-31

VDK API Validity

ClearEventBit()
C Prototype
void VDK_ClearEventBit(VDK_EventBitID inEventBitID);

C++ Prototype
void VDK::ClearEventBit(VDK::EventBitID inEventBitID);

Description
The ClearEventBit() clears the value of the event bit; that is, sets it to
FALSE, NULL, or 0. Once the event bit is cleared, the value of each dependent event is recalculated. If several event bits are to be cleared (or set) as asingle operation, then the SetEventBit() and/or ClearEventBit() calls
are made from within an unscheduled region. Event recalculation does notoccur until the unscheduled region is popped.
ParametersinEventBitID is the system event bit to clear (see EventBitID).

Scheduling
Invokes the scheduler and may result in a context switch
Determinism
Not deterministic
Return ValueNo return value

5-32

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

Errors Dispatched
Full instrumentation and error-checking libraries:•

kUnknownEventBit indicates that inEventBitID is not a valid
EventBitID

Non error-checking libraries: none

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-33

VDK API Validity

ClearInterruptMaskBits()
C Prototype
void VDK_ClearInterruptMaskBits(VDK_IMASKStruct inMask);

C++ Prototype
void VDK::ClearInterruptMaskBits(VDK::IMASKStruct inMask);

Description
Clears bits in the interrupt mask (see IMASKStruct). In other words, the
new mask is computed as the bitwise AND of the old mask and the one’s
complement of the inMask parameter.
The API does not have the expected behavior when called before
VDK_Initialize(), from boot thread constructors or from the Init part ofdevice drivers.
ParametersinMask specifies which bits are cleared in the IMASKStruct.

Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return ValueNo return value
Errors Dispatched
None

5-34

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

ClearInterruptMaskBitsEx()
C Prototype
void VDK_ClearInterruptMaskBitsEx(VDK_IMASKStruct inMask,
VDK_IMASKStruct inLMask);

C++ Prototype
void VDK::ClearInterruptMaskBitsEx(VDK::IMASKStruct inMask,
VDK::IMASKStruct inLMask);

Description
Clears bits in the IMASK and LMASK interrupt masks (where LMASK is themask component of the IRPTL register). Any bits set in the parameters arecleared in the relevant interrupt mask. In other words, the new masks arecomputed as the bitwise AND of the old mask and the one’s complement of
the specified IMASKStruct. The bits specified for inLMask are shifted by
the relevant amount for the processor in question, thereby allowing theuse of the bit definitions for the LIRPTL register.
The API does not have the expected behavior when called before
VDK_Initialize(), from boot thread constructors or from the Init part ofdevice drivers.
API applies to the ADSP-2116x, ADSP-2126x, ADSP-213xx,
L The
and ADSP-2146x SHARC processors.
ParametersinMask specifies which bits should be cleared in the IMASK interrupt mask.
inLMask specifies which bits should be cleared in the LMASK interrupt

mask.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-35

VDK API Validity

Scheduling
Does not invoke the scheduler
Determinism
Not deterministic
Return ValueNo return value
Errors Dispatched
Full instrumentation and error-checking libraries:•

kInvalidMaskBit if any of the bits in inLmask do not refer to aninterrupt mask (see IMASKStruct)
Non error-checking libraries: none

5-36

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

ClearThreadError()
C Prototype
void VDK_ClearThreadError(void);

C++ Prototype
void VDK::ClearThreadError(void);

Description
Sets the running thread’s error status to kNoError and the error value tozeroParameters
None
Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return ValueNo return value
Errors Dispatched
None

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-37

VDK API Validity

CloseDevice()
C Prototype
void VDK_CloseDevice(VDK_DeviceDescriptor inDD);

C++ Prototype
void VDK::CloseDevice(VDK::DeviceDescriptor inDD);

Description
Closes the specified device. The function calls the dispatch function of thedevice opened with inDD.
Parameters
inDD is the DeviceDescriptor returned from OpenDevice()

Scheduling
Does not invoke the scheduler, but the user-written device driver can callthe scheduler
Determinism
Constant time. Note that this function calls user-written device drivercode that may not be deterministic.
Return ValueNo return value
Errors Dispatched
Full instrumentation and error-checking libraries:•

kBadDeviceDescriptor indicates that inDD is not a valid
DeviceDescriptor

5-38

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

Non error-checking libraries: none
Other errors can be dispatched by user-written device driver code
L executedby this API.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-39

VDK API Validity

CreateDeviceFlag()
C Prototype
VDK_DeviceFlagID VDK_CreateDeviceFlag(void);

C++ Prototype
VDK::DeviceFlagID VDK::CreateDeviceFlag(void);

Description
Creates a new device flag and returns its identifier (DeviceFlagID)
Parameters
None
Scheduling
Does not invoke the scheduler
Determinism
Not deterministic
Return Value
New DeviceFlagID upon success and UINT_MAX upon failure
Errors Dispatched
Full instrumentation and error-checking libraries:•

kDeviceFlagCreationFailure indicates that the kernel is not able

to allocate and/or initialize memory for the device flag
Non error-checking libraries: none

5-40

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

CreateMessage()
C Prototype
VDK_MessageID VDK_CreateMessage(intinPayloadType,unsigned int

inPayloadSize,

void*inPayloadAddr);

VDK::MessageID VDK::CreateMessage(intinPayloadType,C++ Prototype
unsigned int

inPayloadSize,

void*inPayloadAddr);

Description
Creates and initializes a new message object. The return value is the identifier of the new message (see MessageID). The values passed toCreateMessage() can be read by calling GetMessagePayload() and can bereset by calling FreeMessagePayload(). The calling thread becomes theowner of the new message.
Parameters
The inPayloadType is a user-defined value that may be used to convey
additional information about the message and/or the payload to thereceiving thread. This value is not used or modified by the kernel, exceptthat negative values of payload type are reserved for use by VDK. Positive
payload types are reserved for use by the application code. It is recommended that the payload address and size are always interpreted in thesame way for each distinct message type.
The inPayloadSize is the length of the payload buffer in the smallest
addressable unit on the processor architecture (sizeof(char)). When
inPayloadSize has a value of zero, the kernel assumes inPayloadAddr is
not a pointer and may contain any user value of the same size.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-41

VDK API Validity

The inPayloadAddr is a pointer to the start of the data being passed in themessage.
Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return Value
New MessageID upon success and UINT_MAX upon failure
Errors Dispatched
Full instrumentation and error-checking libraries:•

kErrorMallocBlock indicates that there are no free blocks in thesystem memory pool used to allocate messages
Non error-checking libraries: none

5-42

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

CreateMutex()
C Prototype
VDK_MutexID VDK_CreateMutex(void);

C++ Prototype
VDK::MutexID VDK::CreateMutex(void);

Description
Creates and initializes a new mutex object, which can be used for mutual
exclusion. The return value is the identifier of the new mutex. When amutex is created, it has no owner. If a thread wants to acquire the ownership of a mutex, it must use AcquireMutex().
Parameters
None
Scheduling
Does not invoke the scheduler
Determinism
Not deterministic
Return Value
New MutexID upon success and UINT_MAX upon failure
Errors Dispatched
Full instrumentation and error-checking libraries:•

kMutexCreationFailure indicates that the kernel is not able to allocate and/or initialize memory for the mutex

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-43

VDK API Validity

Non error-checking libraries: none

5-44

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

CreatePool()
C Prototype
VDK_PoolID VDK_CreatePool(unsigned int

inBlockSz,

unsigned int

inBlockCount,bool

inCreateNow);

C++ Prototype
VDK::PoolID VDK::CreatePool(unsigned int

inBlockSz,

unsigned int

inBlockCount,bool

inCreateNow);

Description
Creates a new memory pool in the system heap and returns the pool identifier (PoolID).
Parameters
inBlockSz specifies the block size in the lowest addressable unit.
inBlockCount specifies the total number of blocks in the pool.
inCreateNow indicates whether the block construction is done at runtime

on an on-demand basis (FALSE) or as a part of the creation process (TRUE).
Scheduling
Does not invoke the scheduler
Determinism
Constant time if inCreateNow is FALSE.
Not deterministic if inCreateNow value is TRUE.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-45

VDK API Validity

Return Value
New PoolID upon success and UINT_MAX upon failure
Errors Dispatched
Full instrumentation and error-checking libraries:•

kInvalidPoolParms indicates that either inBlockSz or inBlockCount is zero•

kPoolCreationFailure indicates that the kernel is not able to allo-cate and/or initialize memory for the pool
Non error-checking libraries: none

5-46

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

CreatePoolEx()
C Prototype
VDK_PoolID VDK_CreatePoolEx(unsigned int

inBlockSz,

unsigned int

inBlockCount,bool

inCreateNow,

int

inWhichHeap);

C++ Prototype
VDK::PoolID VDK::CreatePoolEx(unsigned int

inBlockSz,

unsigned int

inBlockCount,bool

inCreateNow,

int

inWhichHeap );Description
Creates a new memory pool in the specified heap and returns the pool
identifier (PoolID). When architectures do not support multiple heaps,
inWhichHeap must be initialized to zero. Refer to Appendix A, “Processor-Specific Notes” on page A-1 for architecture-specific information.
Parameters
inBlockSz specifies the block size in the lowest addressable units.
inBlockCount specifies the total number of blocks in the pool.
inCreateNow indicates whether block construction is done at runtime onan done on-demand basis (FALSE) or as a part of the creation process(TRUE).
inWhichHeap specifies the heap in which the pool is to be created. Thisparameter is ignored on single heap architectures. Setting the value ofinWhichHeap to zero specifies the default heap to be used.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-47

VDK API Validity

Scheduling
Does not invoke the scheduler
Determinism
Constant time if inCreateNow is FALSE. Not deterministic if inCreateNow
value is TRUE.
Return Value
New PoolID upon success and UINT_MAX upon failure
Errors Dispatched
Full instrumentation and error-checking libraries:•

kInvalidPoolParms indicates that either inBlockSz or inBlockCount is zero•

kPoolCreationFailure indicates that the kernel is not able to allo-cate and/or initialize memory for the pool
Non error-checking libraries: none

5-48

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

CreateSemaphore()
C Prototype
VDK_SemaphoreID VDK_CreateSemaphore(unsigned

int

inInitialValue,unsignedint

inMaxCount,

VDK_Ticks

inInitialDelay,

VDK_Ticks

inPeriod);

C++ Prototype
VDK::SemaphoreID VDK::CreateSemaphore(unsigned

int

inInitialValue,unsignedint

inMaxCount,

VDK::Ticks

inInitialDelay,

VDK::Ticks

inPeriod);

Description
Creates and initializes a dynamic semaphore. If the value of inPeriod is
non-zero, a periodic semaphore is created.
Parameters
The inInitialValue is the value the semaphore has once it is created. A
value of zero indicates that the semaphore is unavailable. This value
should be between zero and inMaxCount.
The inMaxCount is the maximum number the semaphore’s count can reachwhen posting it. An inMaxCount of one creates a binary semaphore.
The inInitialDelay is the number of Ticks before the first posting of aperiodic semaphore. inInitialDelay must be equal to or greater than one.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-49

VDK API Validity

The inPeriod specifies the period property of the semaphore and thenumber of Ticks to sleep at each cycle after the semaphore is first posted.
If inPeriod is zero, the created semaphore is not periodic.
Scheduling
Does not invoke the scheduler
Determinism
Not deterministic
Return Value
New SemaphoreID upon success and UINT_MAX upon failure
Errors Dispatched
Full instrumentation and error-checking libraries:•

kMaxCountExceeded indicates that inInitialValue is greater thaninMaxCount•kSemaphoreCreationFailure indicates that the kernel is not able toallocate and/or initialize memory for the semaphore
Non error-checking libraries: none

5-50

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

CreateThread()
C Prototype
VDK_ThreadID VDK_CreateThread(VDK_ThreadType inType);

C++ Prototype
VDK::ThreadID VDK::CreateThread(VDK::ThreadType inType);

Description
Creates a thread of the specified type and returns the new thread. The
CreateThread() API must not be called from within a thread constructor.
Parameters
The inType corresponds to a ThreadType defined in the VDK.h and
VDK.cpp files. These files contain the default values for the stack size, initial priority, and other properties.
Scheduling
Invokes the scheduler and may result in a context switch
Determinism
Not deterministic
Return Value
New ThreadID upon success and UINT_MAX upon failure

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-51

VDK API Validity

Errors Dispatched
Full instrumentation and error-checking libraries:•

kUnknownThreadType indicates that inType is not an element of theThreadType, as defined in VDK.h•kThreadCreationFailure indicates that the kernel is not able toallocate and/or initialize memory for the thread
Non error-checking libraries: none

5-52

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

CreateThreadEx()
C Prototype
VDK_ThreadID VDK_CreateThreadEx(
VDK_ThreadCreationBlock *inOutTCB);

C++ Prototype
VDK::ThreadID VDK::CreateThreadEx(
VDK::ThreadCreationBlock *inOutTCB);

Description
Creates a thread with the specified characteristics and returns the new
thread. The CreateThreadEx() API must not be called from within athread constructor.
Parameters
inOutTCB is a pointer to a structure of the ThreadCreationBlock data type.

Scheduling
Invokes the scheduler and may result in a context switch
Determinism
Not deterministic
Return Value
New ThreadID upon success and UINT_MAX upon failure

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-53

VDK API Validity

Errors Dispatched
Full instrumentation and error-checking libraries:•

kUnknownThreadType indicates that inType is not an element of theThreadType, as defined in VDK.h•kThreadCreationFailure indicates that the kernel is not able toallocate and/or initialize memory for the thread
Non error-checking libraries: none

5-54

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

CreateThreadEx2()C Prototype
VDK_ThreadID VDK_CreateThreadEx2(
VDK_ThreadCreationBlock*inOutTCB,

unsigned int

inFieldsRequired);C++ Prototype
VDK::ThreadID VDK::CreateThreadEx2(
VDK::ThreadCreationBlock*inOutTCB,

unsigned int

inFieldsRequired);

Description
VDK_CreateThreadEx2() is available in VisualDSP++ 5.0 update 9 andlater. The API applies to Blackfin and SHARC processors only.
Creates a thread with the specified characteristics and returns the new
thread.
When creating a new thread using CreateThreadEx2(), the inFieldsRequired argument specifies which default ThreadType parameters areoverridden with values from inOutTCB.
Each field in inOutTCB is represented by a corresponding bit in inFieldsRequired. If a bit in inFieldsRequired is set (1), the contents of thematching field in inOutTCB is used when creating the thread. If a bit ininFieldsRequired is clear (0), the matching field in the inOutTCB isignored, and the default setting is used.
VDK provides an enumeration, TCBBitfield, which provides names forthe different bits that can be asserted in inFieldsRequired. The flags provided by the enumeration can be ORed together to specify multiple
parameters to override.
When creating a thread using a ThreadType defined in the Kernel tab, youmust pass the kSetThreadTemplateID flag into inFieldsRequired.
VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-55

VDK API Validity

On Blackfin processors, VDK uses the thread stack to store the thread’s
context information. When manually allocating a thread stack for a Blackfin application, ensure that the area of allocated memory is large enoughto store the information. In this case, it is important that the size of allocated memory is ‘the stack size + the context area size’. The API
GetContextRecordSize() is provided to query the size of the context area.
Parameters
inOutTCB is a pointer to a structure of the ThreadCreationBlock data type.
inFieldsRequired specifies which fields in the ThreadCreationBlock

structure are used to replace the default parameters for the ThreadType.
For a list of valid flags that can be passed into this parameter, see the TCBBitfield data type description
Scheduling
Invokes the scheduler and may result in a context switch
Determinism
Not deterministic
Return Value
New ThreadID upon success and UINT_MAX upon failure

5-56

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

Errors Dispatched
Full instrumentation and error-checking libraries:•

kIncompatibleArguments indicates one of the following.

• Neither kSetThreadTemplateID nor kSetThreadTemplatePointer has been specified in inFieldsRequired.
• Both kSetThreadTemplateID and kSetThreadTemplatePointer have been specified in inFieldsRequired.
• Both kSetThreadStackPointer and kSetStackHeap havebeen specified in inFieldsRequired.
•kSetThreadStackPointer has been specified in inFieldsRequired, but kSetThreadStackSize has not been specified.

•kInvalidPointer indicates one of the following.

•

inOutTCB—>stack_pointer is not correctly aligned. Thiserror is only checked when kSetThreadStackPointer has
been specified in inFieldsRequired.
•inOutTCB—>pTemplate is NULL, and kSetThreadTemplatePointer has been specified in inFieldsRequired.

•kThreadCreationFailure indicates that the kernel is not able toallocate and/or initialize memory for the thread.
•

kUnknownThreadType indicates that inOutTCB–>template_id is nota valid thread type (ThreadType) as declared in the VDK Kerneltab.
Non error-checking libraries: none

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-57

VDK API Validity

DestroyDeviceFlag()
C Prototype
void VDK_DestroyDeviceFlag(VDK_DeviceFlagID inDeviceFlagID);

C++ Prototype
void VDK::DestroyDeviceFlag(VDK::DeviceFlagID inDeviceFlagID);

Description
Deletes the device flag from the system and releases the associated memory
ParametersinDeviceFlagID specifies the device flag (DeviceFlagID) to be destroyed.

Scheduling
Does not invoke the scheduler
Determinism
Not deterministic
Return ValueNo return value
Errors Dispatched
Full instrumentation and error-checking libraries:•

kInvalidDeviceFlag indicates that inDeviceFlagID is not a valid
DeviceFlagID

Non error-checking libraries: none

5-58

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

DestroyMessage()
C Prototype
void VDK_DestroyMessage(VDK_MessageID inMessageID);

C++ Prototype
void VDK::DestroyMessage(VDK::MessageID inMessageID);

Description
Destroys a message object. Only the thread that is the owner of a message
can destroy it. The message payload memory is assumed to be freed by theuser thread. DestroyMessage() does not free the payload and results in amemory leak if the memory is not freed.
ParametersinMessageID is the MessageID of the message to be destroyed.

Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return ValueNo return value

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-59

VDK API Validity

Errors Dispatched
Full instrumentation and error-checking libraries:•

kInvalidMessageID indicates the inMessageID is not a valid
MessageID•

kInvalidMessageOwner indicates the thread attempting to destroy

the message is not the current owner•

kMessageInQueue indicates the message is posted to a thread which
ThreadID is not known at this point, and the message needs to be

removed from the message queue by a call to PendMessage()
Non error-checking libraries: none

5-60

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

DestroyMessageAndFreePayload()
C Prototype
void VDK_DestroyMessageAndFreePayload(
VDK_MessageID inMessageID);

C++ Prototype
void VDK::DestroyMessageAndFreePayload(
VDK::MessageID inMessageID);

Description
Destroys a message object. Only the thread that is the owner of a message
can destroy it. If the payload is of a marshalled type (that is, the sign bit of
the payload type code is set), then the payload is freed by calling the type
marshalling function with the RELEASE code.
ParametersinMessageID is the MessageID of the message to be destroyed.

Scheduling
Does not invoke the scheduler
Determinism
Not deterministic
Return ValueNo return value

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-61

VDK API Validity

Errors Dispatched
Full instrumentation and error-checking libraries:•

kInvalidMessageID indicates the inMessageID is not a valid
MessageID•

kInvalidMessageOwner indicates the thread attempting to destroy
the message is not the current owner•

kMessageInQueue indicates the message is posted to a thread which
ThreadID is not known at this point, and the message needs to be

removed from the message queue by a call to PendMessage()
Non error-checking libraries: none
Other errors can be dispatched by the user-supplied marshalling
L function
or by functions called by it.

5-62

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

DestroyMutex()
C Prototype
void VDK_DestroyMutex(VDK_MutexID inMutexID);

C++ Prototype
void VDK::DestroyMutex(VDK::MutexID inMutexID);

Description
Destroys the mutex associated with inMutexID and frees any memory associated with the mutex. The destruction does not take place if the mutex
has an owner because threads might be waiting to acquire it. This caseresults in an error dispatched in full instrumentation and error-checking
builds.
Parameters
inMutexID of type MutexID is the mutex the thread is trying to release

Scheduling
Does not invoke the scheduler
Determinism
Not deterministic
Return ValueNo return value

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-63

VDK API Validity

Errors Dispatched
Full instrumentation and error-checking libraries:•

kInvalidMutexID indicates that inMutexID is not a mutex createdby the CreateMutex() API•

kMutexDestructionFailure indicates that the mutex cannot be

destroyed because it has an owner and other threads may be waiting to acquire it
Non error-checking libraries: none

5-64

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

DestroyPool()
C Prototype
void VDK_DestroyPool(VDK_PoolID inPoolID);

C++ Prototype
void VDK::DestroyPool(VDK::PoolID inPoolID);

Description
Deletes the pool and cleans up the memory associated with it. If there are
any allocated blocks (which are not freed yet), an error is dispatched in the
fully instrumented and error-checking builds, and the pool is not
destroyed. In the non error-checking build, the pool is destroyed.
Parameters
inPoolID specifies the pool to delete (see PoolID).

Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return ValueNo return value

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-65

VDK API Validity

Errors Dispatched
Full instrumentation and error-checking libraries:•

kInvalidPoolID indicates that the inPoolID (PoolID) is not valid•

kErrorPoolNotEmpty indicates the pool is not empty (there aresome blocks that are not freed) and cannot be destroyed
Non error-checking libraries: none

5-66

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

DestroySemaphore()
C Prototype
void VDK_DestroySemaphore(VDK_SemaphoreID inSemaphoreID);

C++ Prototype
void VDK::DestroySemaphore(VDK::SemaphoreID inSemaphoreID);

Description
Destroys the semaphore associated with inSemaphoreID. The destruction
does not take place if there is any thread pending on the semaphore,
resulting in an error dispatched in fully instrumented and error-checking
builds.
Parameters
inSemaphoreID is the semaphore to destroy (see SemaphoreID).

Scheduling
Does not invoke the scheduler
Determinism
Not deterministic
Return ValueNo return value

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-67

VDK API Validity

Errors Dispatched
Full instrumentation and error-checking libraries:•

kSemaphoreDestructionFailure indicates the semaphore cannot be

destroyed because there are threads pending on it•

kUnknownSemaphore indicates inSemaphoreID is not a valid
SemaphoreID

Non error-checking libraries: none

5-68

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

DestroyThread()
C Prototype
void VDK_DestroyThread(VDK_ThreadID
bool

inThreadID,
inDestroyNow);

C++ Prototype
void VDK::DestroyThread(VDK::ThreadID
bool

inThreadID,
inDestroyNow);

Description
Initiates the process of removing the specified thread from the system.
Although the scheduler never runs the thread again once this function
completes, the kernel may optionally defer deallocation of the memory
resources associated with the thread to the Idle thread. Any references tothe destroyed thread are invalid and can dispatch an error. For more information about the low-priority thread, see “Idle Thread” on page 3-18.
ParametersinThreadID of type ThreadID specifies the thread to remove from thesystem.
inDestroyNow indicates whether the thread’s memory is recovered now(TRUE) or recovered in the low-priority IDLE thread (FALSE).
Scheduling
Invokes the scheduler and results in a context switch only if a thread
passes itself to DestroyThread()
Determinism
Constant time if inDestroyNow is FALSE, not deterministic otherwise

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-69

VDK API Validity

Return ValueNo return value
Errors Dispatched
Full instrumentation and error-checking libraries:•

kUnknownThread indicates inThreadID is not a valid ThreadID•

kInvalidThread indicates there is a intention to destroy the Idle

ThreadNon error-checking libraries: none

5-70

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

DeviceIOCtl()
C Prototype
int VDK_DeviceIOCtl(VDK_DeviceDescriptor inDD,
void*inCommand,char*inParameters);

C++ Prototype
int VDK::DeviceIOCtl(VDK::DeviceDescriptor inDD,
void*inCommand,char*inParameters);

Description
Controls the specified device. The inCommand and inParameters are passed
unchanged to the device driver.
Parameters
inDD is the DeviceDescriptor returned from OpenDevice().
inCommand are the device driver’s specific commands.
inParameters are the device driver’s specific parameters for the above

commands.
Scheduling
Does not invoke the scheduler, but the user-written device driver can callthe scheduler
Determinism
Constant time

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-71

VDK API Validity

Note that this function calls user-written device driver code that may not
be deterministic.
Return Value
Returns the dispatch function’s value if the device exists. If the device does
not exist, DeviceIOCtl() returns the return value of the DispatchThreadError() API for the particular error if the thread’s error function does not
go to KernelPanic.
Errors Dispatched
Full instrumentation and error-checking libraries:•

kBadDeviceDescriptor indicates that inDD is not a valid
DeviceDescriptor

Non error-checking libraries: none
Other errors can be dispatched by user-written device driver code
L executedby this API.

5-72

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

DispatchThreadError()
C Prototype
int VDK_DispatchThreadError(VDK_SystemError
const int

inErr,
inVal);

C++ Prototype
int VDK::DispatchThreadError(VDK::SystemError
const int

inErr,
inVal);

Description
Sets the error and error’s value in the currently running thread and calls
the thread’s error function. If DispatchThreadError() is called before
VDK is initialized, DispatchThreadError() goes to KernelPanic with PanicCode kBootError. The SystemError and panic values are the arguments
inErr and inVal passed to DispatchThreadError().
ParametersinErr is the error enumeration. See SystemError for more information

about errors.
inVal is the value whose meaning is determined by the error enumeration.

Scheduling
Does not invoke the scheduler, but the thread exception handler can
invoke the scheduler
Determinism
Not deterministic

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-73

VDK API Validity

Return Value
The return value of the current thread’s error handler
Errors Dispatched
None

5-74

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

ForwardMessage()
C Prototype
void VDK_ForwardMessage(VDK_ThreadID

inRecipient,

VDK_MessageID

inMessageID,

VDK_MsgChannel inChannel,
VDK_ThreadID

inPseudoSender);C++ Prototype
void VDK::ForwardMessage(VDK::ThreadID

inRecipient,

VDK::MessageID

inMessageID,

VDK::MsgChannel inChannel,
VDK::ThreadID

inPseudoSender);Description
Identical to PostMessage(), except that the sender attribute of the message
is set to the value of the inPseudoSender argument, instead of the ID of
the current thread.
This function is useful where message loopback is being employed between
two threads (that is, the received message is returned to the sender rather
than being destroyed), and a third thread needs to be inserted transparently into the loop.
By querying the message’s sender attribute (using
GetMessageReceiveInfo(), and then passing it as the inPseudoSenderargument to ForwardMessage(), this third thread can ensure that the message is returned to the original sender rather than to itself.
Parameters
inRecipient is the ThreadID of the thread receiving the message.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-75

VDK API Validity

inMessageID is the MessageID of the sent message. A message must be cre-ated before it is posted. This parameter is a return value of the call to
CreateMessage().
inChannel is the FIFO within the recipient’s message queue on which themessage is appended. Its value is kMsgChannel1 throughkMessageChannel15 (see MsgChannel).
inPseudoSender is the ThreadID stored in the sender attribute of themessage.
Scheduling
Non-blocking but invokes the scheduler and may result in a context
switchDeterminism
Not deterministic
Return ValueNo return value
Errors Dispatched
Full instrumentation and error-checking libraries:•

kInvalidMessageChannel indicates the inChannel is not a value

defined in MsgChannel

5-76

•

kUnknownThread indicates inRecipient is not a valid ThreadID•

kInvalidMessageID indicates inMessageID is not a valid MessageID•

kInvalidMessageRecipient indicates inRecipient does not have amessage queue as it has not been enabled for messaging

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference•kInvalidMessageOwner indicates the thread attempting to post themessage is not the current owner. The error value is the ThreadIDof the owner•

kMessageInQueue indicates the message is posted to a thread which
ThreadID is not known at this point, and the message needs to be

removed from the message queue by a call to PendMessage()
Non error-checking libraries: none

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-77

VDK API Validity

FreeBlock()
C Prototype
void VDK_FreeBlock(VDK_PoolID inPoolID, void *inBlockPtr);

C Prototype
void VDK::FreeBlock(VDK::PoolID inPoolID, void *inBlockPtr);

Description
Frees the specified block and returns it to the free block list
Parameters
inPoolID specifies the pool from which the block is to be freed (seePoolID).
inBlockPtr specifies the block to free.

Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return ValueNo return value

5-78

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

Errors Dispatched
Full instrumentation and error-checking libraries:•

kInvalidBlockPointer indicates inBlockPtr is not a valid pointerfrom inPoolID•

kInvalidPoolID indicates inPoolID is not a valid PoolID

Non error-checking libraries: none

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-79

VDK API Validity

FreeDestroyedThreads()
C Prototype
void VDK_FreeDestroyedThreads(void);

C++ Prototype
void VDK::FreeDestroyedThreads(void);

Description
Frees the memory held by the destroyed threads whose resources have notbeen released by the Idle thread. For more information, see “Idle Thread”
on page 3-18.
Parameters
None
Scheduling
Does not invoke the scheduler
Determinism
Not deterministic
Return ValueNo return value
Errors Dispatched
None

5-80

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

FreeMessagePayload()
C Prototype
void VDK_FreeMessagePayload(VDK_MessageID inMessageID);

C++ Prototype
void VDK::FreeMessagePayload(VDK::MessageID inMessageID);

Description
If the payload of the specified message object is of a marshalled type (thatis, the sign bit of the payload type code is set), then the payload is freed
without destroying the message object itself. Only the thread that is theowner of a message can free its payload. The payload is freed by calling thetype marshalling function with the RELEASE code.
The payload type, size, and address attributes of the message object are all
set to zero.
ParametersinMessageID is the MessageID of the message to be destroyed.

Scheduling
Does not invoke the scheduler
Determinism
Not deterministic
Return ValueNo return value

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-81

VDK API Validity

Errors Dispatched
Full instrumentation and error-checking libraries:•

kInvalidMessageID indicates inMessageID is not a valid MessageID•

kInvalidMessageOwner indicates the thread attempting to destroy

the message is not the current owner•

kMessageInQueue indicates that the message has been posted to athread (the ThreadID is not known at this point), and the message
needs to be removed from the message queue by a call to
PendMessage()

Non error-checking libraries: none
Other errors may be dispatched by the user-supplied marshalling
L function,or by functions called by it.

5-82

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

FreeThreadSlot()
C Prototypebool VDK_FreeThreadSlot(int inSlotNum);

C++ Prototypebool VDK::FreeThreadSlot(int inSlotNum);

Description
Releases and clears the slot table entry in the currently running thread’sslot table associated with inSlotNum and:• Returns FALSE if (and only if) the key does not identify a currently
allocated slot
• Releases the slot identified by inSlotNum, which was previously created with the AllocateThreadSlot() function
The application must ensure that no thread local data is associated withthe key at the time it is freed. Any specified cleanup functions(see AllocateThreadSlot()) are called only on thread destruction.
Parameters
inSlotNum is the static library’s preallocated slot number.

Scheduling
Does not invoke the scheduler
Determinism
Constant time

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-83

VDK API Validity

Return Value
TRUE upon success and FALSE upon failure.

Errors Dispatched
None

5-84

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

GetAllDeviceFlags()
C Prototype
int VDK_GetAllDeviceFlags(
VDK_DeviceFlagID

outDevFlagIDArray[],int

inArraySize);

C++ Prototype
int VDK::GetAllDeviceFlags(
VDK::DeviceFlagID

outDevFlagIDArray[],int

inArraySize);

Description
Returns the current number of device flags in the system and fills a supplied array with the corresponding device flag identifiers. Where thenumber of identified device flags is greater than the size of the suppliedarray, the array is filled to capacity and the function returns. It is the
responsibility of the user to allocate sufficient memory for this API call.
The macro VDK_kMaxNumActiveDevFlags defined in VDK.h is set to the
maximum number of device flags allowed in the application, as defined on
the VDK Kernel tab.
Parameters
outDevFlagIDArray points to an array for the return of the device flags

identified in the system. The memory for the array must be allocated prior
to calling the API. If the size of the array is not sufficient to hold all of theidentified device flags, then the array is filled with as many DeviceFlagIDs
as possible before the function returns.
Note that the supplied array is not populated in any order. DeviceFlagIDs
are entered into the array as they are identified in the system.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-85

VDK API Validity

inArraySize is the number of DeviceFlagID elements in the suppliedarray. If inArraySize is zero, then only the number of device flags in thesystem is determined and returned.
Scheduling
Does not invoke the scheduler
Determinism
Not deterministic
Return Value
Returns the number of device flags identified in the system
Errors Dispatched• Fully instrumented and error checking libraries:•

kInvalidPointer if outDevFlagIDArray is NULL and inArraySize is not 0.

• Non error checking libraries: none

5-86

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

GetAllMemoryPools()
C Prototype
int VDK_GetAllMemoryPools(VDK_PoolID
int

outPoolIDArray[],inArraySize);

C++ Prototype
int VDK::GetAllMemoryPools(VDK::PoolID
int

outPoolIDArray[],inArraySize);

Description
Returns the current number of memory pools in the system and fills a supplied array with the corresponding memory pool identifiers. Where thenumber of identified memory pools is greater than the size of the suppliedarray, the array is filled to capacity and the function returns. It is the
responsibility of the user to allocate sufficient memory for this API call.
The VDK_kMaxNumActiveMemoryPools macro, defined in VDK.h, is set to the
maximum number of memory pools allowed in the application, as definedon the VDK Kernel tab.
Parameters
outPoolIDArray points to an array for the return of the memory pools

identified in the system. The memory for the array must be allocated prior
to calling the API. If the size of the array is not sufficient to hold all of theidentified memory pools, then the array is filled to capacity with PoolIDs
and then the function returns.
Please note that the supplied array is not populated in any order. PoolIDs
are entered into the array as they are identified in the system.
inArraySize is the number of PoolID elements in the supplied array. If
inArraySize is zero, then only the number of memory pools in the system

is determined and returned.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-87

VDK API Validity

Scheduling
Does not invoke the scheduler
Determinism
Not deterministic
Return Value
Returns the number of memory pools identified in the system
Errors Dispatched• Fully instrumented and error checking libraries:•

kInvalidPointer if outPoolIDArray is NULL and inArraySize is not 0.

• Non error checking libraries: none

5-88

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

GetAllMessages()
C Prototype
int VDK_GetAllMessages(VDK_MessageID
int

outMessageIDArray[],inArraySize);

C++ Prototype
int VDK::GetAllMessages(VDK::MessageID
int

outMessageIDArray[],inArraySize);

Description
Returns the current number of messages in the system and fills a suppliedarray with the corresponding message identifiers. Where the number ofidentified messages is greater than the size of the supplied array, the arrayis filled to capacity. It is the responsibility of the user to allocate sufficient
memory for this API call. The VDK_kMaxNumActiveMessages macro,defined in VDK.h, is set to the maximum number of messages allowed in
the application, as defined on the VDK Kernel tab.
Parameters
outMessageIDArray points to an array for the return of the messages iden-tified in the system. The memory for the array must be allocated prior to
the API call. If the size of the array is not sufficient to hold all of the identified messages, then the array is filled to capacity with MessageIDs andthen the function returns.
Please note that the supplied array is not populated in any order. MessageIDs are entered into the array as they are identified in the system.
inArraySize is the number of MessageID elements allocated by the user inthe supplied array. If inArraySize is zero, then only the number of messages in the system is determined.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-89

VDK API Validity

Scheduling
Does not invoke the scheduler
Determinism
Not deterministic
Return Value
Returns the current number of messages in the system
Errors Dispatched• Fully instrumented and error checking libraries:•

kInvalidPointer if outMessageIDArray is NULL and inArraySize

is not 0• Non error checking libraries: none

5-90

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

GetAllSemaphores()
C Prototype
int VDK_GetAllSemaphores(
VDK_SemaphoreID

outSemaphoreIDArray[],int

inArraySize);

C++ Prototype
int VDK::GetAllSemaphores(
VDK::SemaphoreID

outSemaphoreIDArray[],int

inArraySize);

Description
Returns the current number of semaphores in the system and fills a supplied array with the corresponding semaphore identifiers. Where thenumber of identified semaphores is greater than the size of the suppliedarray, the array is filled to capacity. It is the responsibility of the user toallocate sufficient memory for this API call. The
VDK_kMaxNumActiveSemaphores macro, defined in VDK.h, is set to the maximum number of semaphores allowed in the application, as defined on the
VDK Kernel tab.
Parameters
outSemaphoreIDArray points to an array for the return of the semaphores

identified in the system. The memory for the array must be allocated prior
to the API call. If the size of the array is not sufficient to hold all of theidentified semaphores, then the array is filled to capacity with SemaphoreIDs and then the function returns.
Please note that the supplied array is not populated in any order. SemaphoreIDs are entered into the array as they are identified in the system.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-91

VDK API Validity

inArraySize is the number of SemaphoreID elements in the supplied array.

If inArraySize is zero, then only the number of semaphores in the system
is determined.
Scheduling
Does not invoke the scheduler
Determinism
Not deterministic
Return Value
The current number of semaphores in the system
Errors Dispatched• Fully instrumented and error checking libraries:•

kInvalidPointer if outSemaphoreIDArray is NULL and inArraySize is not 0• Non error checking libraries: none

5-92

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

GetAllThreads()
C Prototype
int VDK_GetAllThreads(VDK_ThreadID
int

outThreadIDArray[],inArraySize);

C++ Prototype
int VDK::GetAllThreads(VDK::ThreadID
int

outThreadIDArray[],inArraySize);

Description
Returns the current number of threads in the system and fills a suppliedarray with the corresponding thread identifiers. Where the number ofidentified threads is greater than the size of the supplied array, the array isfilled to capacity. It is the responsibility of the user to allocate memory forthis API call. The VDK_kMaxNumThreads macro, defined in VDK.h, is set tothe maximum number of threads allowed in the application, as defined on
the VDK Kernel tab.
Parameters
outThreadArray points to an array for the return of the threads identified

in the system. The memory for the array must be allocated prior to the
API call. If the size of the array is not sufficient to hold all of the identified
threads, then the array is filled to capacity with ThreadIDs and then thefunction returns.
Please note that the supplied array is not populated in any order. ThreadIDs are entered into the array as they are identified in the system; priority,
creation time, and current state have no impact on the array order.
inArraySize is the number of ThreadID elements allocated by the user inthe supplied array. If inArraySize is zero, then only the number of
threads in the system is determined.
VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-93

VDK API Validity

Scheduling
Does not invoke the scheduler
Determinism
Not deterministic
Return Value
Returns the number of threads currently in the system, including the Idle
ThreadErrors Dispatched• Fully instrumented and error checking libraries:•

kInvalidPointer if outThreadIDArray is NULL and inArraysize is not 0• Non error checking libraries: none

5-94

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

GetBlockSize()
C Prototype
unsigned int VDK_GetBlockSize(VDK_PoolID inPoolID);

C ++ Prototype
unsigned int VDK::GetBlockSize(VDK::PoolID inPoolID);

Description
Returns the configured block size for the specified memory poolParameters
inPoolID of type PoolID specifies the pool.
Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return ValueBlock size for the specified pool upon success. Upon failure, UINT_MAX if
using fully instrumented or error checking libraries, and an undefinedvalue if using non-error checking libraries.
Errors Dispatched
Full instrumentation and error-checking libraries:•

kInvalidPoolID indicates that inPoolID is not a valid PoolID

Non error-checking libraries: none

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-95

VDK API Validity

GetClockFrequency()
C Prototype
unsigned int VDK_GetClockFrequency (void);

C++ Prototype
unsigned int VDK::GetClockFrequency (void);

Description
Returns the value of the clock frequency (in MHz) for the application.
The value of clock frequency is specified as part of the configuration of a
VDK project and can be changed at runtime by SetClockFrequency(). It
is the responsibility of the application designer to ensure that the clock
frequency matches that of the hardware used.
Parameters
None
Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return Value
Value of the clock frequency in MHz
Errors Dispatched
None

5-96

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

GetContextRecordSize()
C Prototype
unsigned int VDK_GetContextRecordSize(void);

C++ Prototype
unsigned int VDK::GetContextRecordSize(void);

Description
This API applies to Blackfin and SHARC processors only.
Returns the size of the area of memory required to store the thread information during a context switch.
For any Blackfin applications that manually allocate a thread stack, the
GetContextRecordSize() function can be used to determine the additional amount of space to add to the stack size.
Parameters
None
Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return Value
Returns the size of the context record

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-97

VDK API Validity

Errors Dispatched
None

5-98

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

GetCurrentHistoryEventNum()
C Prototype
unsigned int VDK_GetCurrentHistoryEventNum(void);

C++ Prototype
unsigned int VDK::GetCurrentHistoryEventNum(void);

Description
Returns the current history event number. This is the event number that isabout to be written, not the most recently written event. This API can becalled only when using fully instrumented VDK libraries.
Parameters
None
Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return Value
Returns the index, within the history buffer, of the event that is about tobe written
Errors Dispatched
None

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-99

VDK API Validity

GetDevFlagPendingThreads()
C Prototype
VDK_SystemError VDK_GetDevFlagPendingThreads(
VDK_DeviceFlagID

inDevFlagID,

int*outNumThreads,

VDK_ThreadID

outThreadArray[],int

inArraySize);

C++ Prototype
VDK::SystemError VDK::GetDevFlagPendingThreads(
VDK::DeviceFlagID

inDevFlagID,

int*outNumThreads,

VDK::ThreadID

outThreadArray[],int

inArraySize);

Description
Returns the current number of threads pending on a device flag and fills a
supplied array with the corresponding thread identifiers. The array is populated with threads in the same order as their positions in the pending
queue. Where the number of identified threads is greater than the size ofthe supplied array, the array is filled to capacity. It is the responsibility of
the user to allocate sufficient memory for this API call. The
VDK_kMaxNumThreads macro, defined in VDK.h, is set to the maximum
number of threads allowed in the application, as defined on the VDK Kernel tab.
ParametersinDevFlagID is the device flag identifier ( DeviceFlagID) to be queried.
outNumThreads is populated with the number of threads identified as

pending on the device flag.

5-100

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

outThreadArray points to an array to be populated with the ThreadIDs of

the threads that are pending on the device flag. The memory for the arraymust be allocated prior to the API call. If the size of the array is not sufficient to hold all of the identified threads, then the array is filled tocapacity with ThreadIDs and then the function returns.
inArraySize is the number of ThreadID elements in the supplied array. If
inArraySize is zero, then only the number of threads in the queue isdetermined and returned.
Scheduling
Does not invoke the scheduler
Determinism
Not deterministic
Return Value
Full instrumentation and error-checking libraries:•

kUnknownSemaphore if SemaphoreID is not a valid identifier•kInvalidPointer if the outThreadArray array is NULL and inArraySize is not 0•

kNoError otherwise

Non error-checking libraries: kNoError
Errors Dispatched
None

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-101

VDK API Validity

GetEventBitValue()
C Prototypebool VDK_GetEventBitValue(VDK_EventBitID

inEventBitID);

C++ Prototypebool VDK::GetEventBitValue(VDK::EventBitID

inEventBitID);

Description
Returns the value of the event bit
ParametersinEventBitID specifies the system event bit to query (see EventBitID).

Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return Value
Value of the specified event bit if the event bit exists, and the return valueof the current thread’s error handler if the event bit does not exist
Errors Dispatched
Full instrumentation and error-checking libraries:•

kUnknownEventBit indicates that the inEventBitID is not a valid
EventBitID

Non error-checking libraries: none

5-102

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

GetEventData()
C Prototype
VDK_EventData VDK_GetEventData(VDK_EventID inEventID);

C++ Prototype
VDK::EventData VDK::GetEventData(VDK::EventID inEventID);

Description
Returns the EventData associated with the queried event. Threads can use
this function to get an event’s current values.
ParametersinEventID is the event to query (see EventID).

Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return Value
EventData associated with the specified event bit if it exists, and a struc-ture filled with zeros if the event bit does not exist
Errors Dispatched
Full instrumentation and error-checking libraries:•

kUnknownEvent indicates inEventID is not a valid EventID

Non error-checking libraries: none

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-103

VDK API Validity

GetEventPendingThreads()
C Prototype
VDK_SystemError VDK_GetEventPendingThreads(
VDK_EventID

inEventID,

int*outNumThreads,

VDK_ThreadID

outThreadArray[],int

inArraySize);

C++ Prototype
VDK::SystemError VDK::GetEventPendingThreads(
VDK::EventID

inEventID,

int*outNumThreads,

VDK::ThreadID

outThreadArray[],int

inArraySize);

Description
Returns the current number of threads pending on an event and fills a
supplied array with the corresponding thread identifiers. The array is populated with threads in the same order as their positions in the pending
queue. Where the number of identified threads is greater than the size ofthe supplied array, the array is filled to capacity. It is the responsibility of
the user to allocate sufficient memory for this API call. The
VDK_kMaxNumThreads macro, defined in VDK.h, is set to the maximum
number of threads allowed in the application, as defined on the VDK Kernel tab.
ParametersinEventID is the event identifier (EventID) to be queried.
outNumThreads is populated with the number of threads identified as

pending on the event.

5-104

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

outThreadArray points to an array to be populated with the ThreadIDs of

the threads that are pending on the event. The memory for the array mustbe allocated prior to the API call. If the size of the array is not sufficient tohold all of the identified threads, then the array is filled to capacity withThreadIDs and then the function returns.
outThreadArray is populated in the order that the threads are present in

the pending queue: the highest priority thread that has been waiting thelongest is placed in the initial element of the array.
inArraySize is the number of ThreadID elements in the supplied array. If
inArraySize is zero, then only the number of threads in the queue isdetermined.
Scheduling
Does not invoke the scheduler
Determinism
Not deterministic
Return Value
Full instrumentation and error-checking libraries:•

kUnknownSemaphore if SemaphoreID is not a valid identifier•kInvalidPointer if the outThreadArray array is NULL andinArraySize is not 0•

kNoError otherwise

Non error-checking libraries: kNoError
Errors Dispatched
None

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-105

VDK API Validity

GetEventValue()
C Prototypebool VDK_GetEventValue(VDK_EventID inEventID);

C++ Prototypebool VDK::GetEventValue(VDK::EventID inEventID);

Description
Returns the value of the specified event
ParametersinEventID specifies the event to query (see EventID).

Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return Value
Value of the specified event if it exists, and the return value of the current
thread’s error handler if it does not
Errors Dispatched
Full instrumentation and error-checking libraries:•

kUnknownEvent indicates inEventID is not a valid EventID

Non error-checking libraries: none

5-106

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

GetHeapIndex()
C Prototype
unsigned int VDK_GetHeapIndex(VDK_HeapID inHeapID);

C++ Prototype
unsigned int VDK::GetHeapIndex(VDK::HeapID inHeapID);

Description
Translates a HeapID (as configured in the Kernel tab of the IDDE Project
window) to a Heap index, which can be passed to heap_malloc(),
heap_calloc(), heap_realloc(), and heap_free()Parameters
inHeapID is the HeapID for the returned corresponding Heap index.

Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return Value
Heap index
Errors Dispatched
Full instrumentation and error-checking libraries:•

kInvalidHeapID indicates that inHeapID is not a valid HeapID

Non error-checking libraries: none

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-107

VDK API Validity

GetHistoryBufferSize()
C Prototype
unsigned int VDK_GetHistoryBufferSize(void);

C++ Prototype
unsigned int VDK::GetHistoryBufferSize(void);

Description
Returns the maximum number of history events the history buffer canhold. This API can be called only when using fully instrumented VDKlibraries.
Parameters
None
Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return Value
Returns the maximum number of history events the history buffer canholdErrors Dispatched
None

5-108

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

GetHistoryEvent()
C Prototype
VDK_SystemError VDK_GetHistoryEvent(unsigned int

inHistEventNum,

VDK_HistoryEvent*outHistoryEvent);

C++ Prototype
VDK::SystemError VDK::GetHistoryEvent(unsigned int

inHistEventNum,

VDK::HistoryEvent*outHistoryEvent);

Description
Returns a history event from the VDK history buffer based on the supplied index within the buffer. The API can be called only when using fully
instrumented VDK libraries.
Parameters
inHistEventNum is the index of the required history event. Indexing

increases from 0, to the capacity of the history buffer minus 1.
outHistoryEvent is populated with the desired history event on success.

Scheduling
Does not invoke the scheduler
Determinism
Constant time

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-109

VDK API Validity

Return Value
Returns kNoError on success. If the inHistEventNum is greater than thesize of the history buffer, then kMaxHistoryEventExceeded is returned.
Errors Dispatched
None

5-110

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

GetInterruptMask()
C Prototype
VDK_IMASKStruct VDK_GetInterruptMask(void);

C++ Prototype
VDK::IMASKStruct VDK::GetInterruptMask(void);

Description
Returns the current value of the interrupt mask ( IMASKStruct). Any bitsthat are permanently asserted in the IMASK register are masked out in the
return value of this API function.
On Blackfin processors, the VDK modifies the value of the IMASK registerin order to disable interrupts. When interrupts are disabled on Blackfin
processors, GetInterruptMask() returns an internally saved version of the
IMASK register, which reflects its state when interrupts are enabled.
The API does not have the expected behavior when called before
VDK_Initialize().

Parameters
None
Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return Value
Current value of the interrupt mask (see IMASKStruct)

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-111

VDK API Validity

Errors Dispatched
None

5-112

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

GetInterruptMaskEx()
C Prototype
void VDK_GetInterruptMaskEx(VDK_IMASKStruct
VDK_IMASKStruct*outMask,*outLMask);

C++ Prototype
Void VDK::GetInterruptMaskEx(VDK::IMASKStruct
VDK::IMASKStruct*outMask,*outLMask);

Description
Returns the current value of the IMASK and LMASK interrupt masks (seeIMASKStruct) in *outMask and *outLMask (where LMASK is the mask component of the IRPTL register). Any bits that are permanently asserted in the
IMASK register are masked out in the return value of this API function.
The API applies to the ADSP-2116x, ADSP-2126x, ADSP-213xx, and
ADSP-2146x SHARC processors.
The API does not have the expected behavior when called before
VDK_Initialize(), from boot thread constructors or from the Init part ofdevice drivers.
Parameters*outMask is the current value of IMASK.
*outLMask is the current value of LMASK.

Scheduling
Does not invoke the scheduler

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-113

VDK API Validity

Determinism
Constant time
Return ValueNo return value
Errors Dispatched
None

5-114

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

GetLastThreadError()
C Prototype
VDK_SystemError VDK_GetLastThreadError(void);

C++ Prototype
VDK::SystemError VDK::GetLastThreadError(void);

Description
Returns the running thread’s most recent error. See SystemError for more
information about errors.
Parameters
None
Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return Value
The running thread’s most recent error
Errors Dispatched
None

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-115

VDK API Validity

GetLastThreadErrorValue()
C Prototype
int VDK_GetLastThreadErrorValue(void);

C++ Prototype
int VDK::GetLastThreadErrorValue(void);

Description
Returns the value parameter of the call with the most recent error
Parameters
None
Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return Value
An additional descriptive value whose definition depends on the last errorthat has been dispatched. See Table 5-22 on page 5-12 for further details.
Errors Dispatched
None

5-116

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

GetMessageDetails()
C Prototype
void VDK_GetMessageDetails(
VDK_MessageID

inMessageID,

VDK_MessageDetails*pOutMessageDetails,

VDK_PayloadDetails*pOutPayloadDetails);

C++ Prototype
void VDK::GetMessageDetails(
VDK::MessageID

inMessageID,

VDK::MessageDetails*pOutMessageDetails,

VDK::PayloadDetails*pOutPayloadDetails);

Description
Returns the full set of attributes associated with a message object. The
results are divided into details about the message (channel, sender and target) and about the payload (type, size and address).
The meaning of the message attributes corresponds to the arguments fromthe most recent posting of the message. The meaning of the payload values
is application-specific and corresponds to the arguments passed toCreateMessage().
Only the thread that is the owner of a message may examine the attributesof its payload. If other threads call this API, an error is dispatched, and thecontents of *pOutMessageDetails and *pOutPayloadDetails remainunchanged.
Parameters
The inMessageID of type MessageID specifies the message to query.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-117

VDK API Validity

The pOutMessageDetails is a pointer to a structure of type MessageDetails, which contains channel, sender, and target fields. Channel is oftype MsgChannel, and sender and target are of type ThreadID. The pOutMessageDetails may be NULL, in which case no message details are
returned.
The pOutPayloadDetails is a pointer of type PayloadDetails, which contains type, size, and address fields to describe the message payload. This
information is the same as the one retrieved by GetMessagePayload(). The
pOutPayloadDetails may be NULL, in which case no payload details are
returned.
Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return ValueNo return value
Errors Dispatched
Full instrumentation and error-checking libraries:•

kInvalidMessageID indicates inMessageID is not a valid MessageID•

kInvalidMessageOwner indicates the thread attempting to destroy

the message is not the current owner•

kMessageInQueue indicates the message is posted to a thread (theThreadID is not known at this point), and the message needs to be

removed from the message queue by a call to PendMessage()
Non error-checking libraries: none
5-118

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

GetMessagePayload()
C Prototype
void VDK_GetMessagePayload(VDK_MessageID

inMessageID,

int*outPayloadType,unsigned int*outPayloadSize,void**outPayloadAddr);

C++ Prototype
void VDK::GetMessagePayload(VDK::MessageID

inMessageID,

int*outPayloadType,unsigned int*outPayloadSize,void**outPayloadAddr);

Description
Returns the attributes associated with a message payload: type, size, andaddress.
The meaning of these values is application-specific and corresponds to thearguments passed to CreateMessage(). Only the thread that is the ownerof a message may examine the attributes of its payload. If other threads
call this API, an error is dispatched, and the contents of outPayloadType,outPayloadSize, and outPayloadAddr remain unchanged.
Parameters
The inMessageID of type MessageID specifies the message to query.
The *outPayloadType is an application-specific value that may be used todescribe the contents of the payload. Negative values of payload type arereserved for use by VDK.
The *outPayloadSize is typically the size of the payload in the smallest
addressable units of the processor (sizeof(char)).

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-119

VDK API Validity

The *outPayloadAddr is typically a pointer to the beginning of the payload buffer. However, if the payload size has a value of zero, then the
payload address may contain any user-defined data.
Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return ValueNo return value
Errors Dispatched
Full instrumentation and error-checking libraries:•

kInvalidMessageOwner indicates the argument inMessageID is not

the current owner of the message•

kInvalidMessageID indicates the argument inMessageID is not avalid MessageID•

kMessageInQueue indicates that the message is posted to a thread(the ThreadID is not known at this point), and the message needs tobe removed from the message queue by a call to PendMessage()
Non error-checking libraries: none

5-120

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

GetMessageReceiveInfo()
C Prototype
void VDK_GetMessageReceiveInfo(VDK_MessageID

inMessageID,

VDK_MsgChannel*outChannel,

VDK_ThreadID*outSender);C++ Prototype
void VDK::GetMessageReceiveInfo(VDK::MessageID

inMessageID,

VDK::MsgChannel*outChannel,

VDK::ThreadID*outSender);Description
Returns the parameters associated with how a message is received.
Only the thread that is the owner of a message should call this API. If a
different thread calls the API, there is an error dispatched, and theoutChannel and outSender variables do not contain the right information.
ParametersinMessageID of type MessageID specifies the message to query.
*outChannel of type MsgChannel identifies the channel of the recipient

thread’s message queue the message is posted on.
*outSender of type ThreadID identifies the thread that posted the message.

Scheduling
Does not invoke the scheduler
Determinism
Constant time
VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-121

VDK API Validity

Return ValueNo return value
Errors Dispatched
Full instrumentation and error-checking libraries:•

kInvalidMessageOwner indicates the argument inMessageID is not

the current owner of the message•

kInvalidMessageID indicates the argument inMessageID is not avalid MessageID•

kMessageInQueue indicates that the message is posted to a thread(the ThreadID is not known at this point), and the message needs tobe removed from the message queue by a call to PendMessage()
Non error-checking libraries: none

5-122

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

GetMessageStatusInfo()
C Prototype
VDK_SystemError VDK_GetMessageStatusInfo(VDK_MessageID

inMessageID,

VDK_MessageDetails*outMessageDetails,

VDK_PayloadDetails*outPayloadDetails);

C++ Prototype
VDK::SystemError VDK::GetMessageStatusInfo(
VDK::MessageID

inMessageID,

VDK::MessageDetails*outMessageDetails,

VDK::PayloadDetails*outPayloadDetails);

Description
This API performs the same function as VDK::GetMessageDetails() but
does not dispatch an error if the calling thread is not the owner of themessage.
ParametersinMessageID specifies the message (MessageID) to be queried.
outMessageDetails is a pointer to a structure of type MessageDetails.

The outMessageDetails may be NULL, in which case no message details are
returned.
outPayloadDetails is a pointer of type PayloadDetails. This informationis the same as the one retrieved by the GetMessagePayload() API. The
outPayloadDetails may be NULL, in which case no payload details are
returned.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-123

VDK API Validity

Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return Value
Returns kInvalidMessageID if the MessageID is not a valid identifier; kNoError otherwise
Errors Dispatched
None

5-124

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

GetNumAllocatedBlocks()
C Prototype
unsigned int VDK_GetNumAllocatedBlocks(VDK_PoolID inPoolID);

C++ Prototype
unsigned int VDK::GetNumAllocatedBlocks(VDK::PoolID inPoolID);

Description
Gets the number of allocated blocks in the poolParameters
inPoolID of type PoolID specifies the pool.

Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return Value
Number of allocated blocks from the specified pool upon success. Upon
failure, UINT_MAX if using fully instrumented or error checking libraries,
and an undefined value if using non-error checking libraries.
Errors Dispatched
Full instrumentation and error-checking libraries:•

kInvalidPoolID indicates that inPoolID is not a valid PoolID

Non error-checking libraries: none

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-125

VDK API Validity

GetNumFreeBlocks()
C Prototype
unsigned int VDK_GetNumFreeBlocks(VDK_PoolID inPoolID);

C ++ Prototype
unsigned int VDK::GetNumFreeBlocks(VDK::PoolID inPoolID);

Description
Gets the number of free blocks in the poolParameters
inPoolID of type PoolID specifies the pool to query.

Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return Value
Number of free blocks in the specified pool upon success. Upon failure,
UINT_MAX if using fully instrumented or error-checking libraries, and an
undefined value if using non-error checking libraries.
Errors Dispatched
Full instrumentation and error-checking libraries:•

kInvalidPoolID indicates that inPoolID is not a valid PoolID

Non error-checking libraries: none

5-126

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

GetNumTimesRun()C Prototype
VDK_SystemError VDK_GetNumTimesRun(VDK_ThreadID
unsigned int

inThreadID,*outRunCount);

C++ Prototype
VDK::SystemError VDK::GetNumTimesRun(VDK::ThreadID
unsigned int

inThreadID,*outRunCount);

Description
Retrieves the number of times a thread has run. The API can be called
only when using fully instrumented VDK libraries as this information is
not available for error checking and non-error checking libraries.
ParametersinThreadID is the thread identifier (ThreadID) of the required thread.
outRunCount is populated with the number of times execution has trans-ferred to the given thread’s Run() function.
Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return Value
Returns kUnknownThread if the ThreadID is not a valid identifier; kNoError
otherwise

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-127

VDK API Validity

Errors Dispatched
None

5-128

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

GetPoolDetails()
C Prototype
VDK_SystemError VDK_GetPoolDetails(
VDK_PoolID

inPoolID,

unsigned int*outNumBlocks,

void**outMemoryAddress);

C++ Prototype
VDK::SystemError VDK::GetPoolDetails(
VDK::PoolID

inPoolID,

unsigned int*outNumBlocks,

void**outMemoryAddress);

Description
Returns a set of attributes for the pool object, the number of blocks in thepool, and the starting address of the poolParameters
inPoolID is the identifier of the pool ( PoolID) to be queried.
outNumBlocks is populated with the total number of blocks in the pool,including those blocks that are free and those that are allocated. outNumBlocks can be NULL, in which case the number of blocks in the memory
pool is not returned.
outMemoryAddress is populated with the starting address of the memory

pool queried. outMemoryAddress can be NULL, in which case the start
address of the memory pool is not returned.
Scheduling
Does not invoke the scheduler

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-129

VDK API Validity

Determinism
Constant time
Return Value
Full instrumentation and error-checking libraries:• Returns kInvalidPoolID if PoolID is not a valid identifier; kNoError otherwise
Non error-checking libraries: kNoError
Errors Dispatched
None

5-130

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

GetPriority()
C Prototype
VDK_Priority VDK_GetPriority(VDK_ThreadID inThreadID);

C++ Prototype
VDK::Priority VDK::GetPriority(VDK::ThreadID inThreadID);

Description
Returns the Priority of the specified thread
ParametersinThreadID of type ThreadID is the thread whose priority is being queried.

Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return Value
Priority of the specified thread if the thread exists. If the thread does notexist, UINT_MAX if using fully instrumented or error checking libraries, andan undefined value if using non-error checking libraries.
Errors Dispatched
Full instrumentation and error-checking libraries:•

kUnknownThread indicates that inThreadID is not a valid ThreadID

Non error-checking libraries: none

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-131

VDK API Validity

GetSemaphoreDetails()
C Prototype
VDK_SystemError VDK_GetSemaphoreDetails(
VDK_SemaphoreID

inSemID,

VDK_Ticks*outPeriod,

unsigned int*outMaxCount);

C++ Prototype
VDK::SystemError VDK::GetSemaphoreDetails(
VDK::SemaphoreID

inSemID,

VDK::Ticks*outPeriod,

unsigned int*outMaxCount);

Description
Returns a set of attributes associated with the semaphore object
Parameters
inSemID specifies the semaphore (SemaphoreID) to query.
outPeriod returns the period of the semaphore. outPeriod can be NULL, inwhich case the period of the semaphore is not returned.
outMaxCount returns the maximum count for the semaphore. outMaxCountcan be NULL, in which case the maximum count for the semaphore is not
returned.
Scheduling
Does not invoke the scheduler

5-132

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

Determinism
Constant time
Return Value
Full instrumentation and error-checking libraries:• Returns kUnknownSemaphore if SemaphoreID is not a valid identifier; kNoError otherwise
Non error-checking libraries: kNoError
Errors Dispatched
None

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-133

VDK API Validity

GetSemaphorePendingThreads()
C Prototype
VDK_SystemError VDK_GetSemaphorePendingThreads(
VDK_SemaphoreID

inSemID,

int*outNumThreads,

VDK_ThreadID

outThreadArray[],int

inArraySize);

C++ Prototype
VDK::SystemError VDK::GetSemaphorePendingThreads(
VDK::SemaphoreID

inSemID,

int*outNumThreads,

VDK::ThreadID

outThreadArray[],int

inArraySize);

Description
Returns the current number of threads pending on a semaphore and fills a
supplied array with the corresponding thread identifiers. The array is populated with threads in the same order as their positions in the pending
queue. Where the number of identified threads is greater than the size ofthe supplied array, the array is filled to capacity. It is the responsibility of
the user to allocate sufficient memory for this API call. The
VDK_kMaxNumThreads macro, defined in VDK.h, is set to the maximum
number of threads allowed in the application, as defined on the VDK Kernel tab.
Parameters
inSemID is the semaphore identifier (SemaphoreID) to query.
outNumThreads is populated with the number of threads identified as

pending on the semaphore.

5-134

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

outThreadArray points to an array to be populated with the ThreadIDs of

the threads that are pending on the semaphore. The memory for the arraymust be allocated prior to the API call. If the size of the array is not sufficient to hold all of the identified threads, then the array is filled tocapacity with ThreadIDs and then the function returns.
The outThreadArray is populated in the order that the threads are present
in the pending queue: the highest priority thread that has been waiting thelongest is placed in the initial element of the array.
inArraySize is the number of ThreadID elements in the supplied array. If
inArraySize is zero, then only the number of threads in the queue isdetermined and returned.
Scheduling
Does not invoke the scheduler
Determinism
Not deterministic
Return Value
Full instrumentation and error-checking libraries:•

kUnknownSemaphore if SemaphoreID is not a valid identifier•kInvalidPointer if the outThreadArray array is NULL and inArraySize is not 0•

kNoError otherwise

Non error-checking libraries: kNoError
Errors Dispatched
None

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-135

VDK API Validity

GetSemaphoreValue()
C Prototype
unsigned int VDK_GetSemaphoreValue(
VDK_SemaphoreID inSemaphoreID);

C++ Prototype
unsigned int VDK::GetSemaphoreValue(
VDK::SemaphoreID inSemaphoreID);

Description
Returns the value of the specified semaphore
Parameters
inSemaphoreID of type SemaphoreID points to the semaphore to query.

Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return Value
Value of the specified semaphore if the semaphore exists. If the semaphore
does not exist, UINT_MAX if using fully instrumented or error-checking
libraries, and an undefined value if using non-error checking libraries.

5-136

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

Errors Dispatched
Full instrumentation and error-checking libraries:•

kUnknownSemaphore indicates that inSemaphoreID is not a valid
SemaphoreID

Non error-checking libraries: none

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-137

VDK API Validity

GetSharcThreadCycleData()
C Prototype
VDK_SystemError VDK_GetSharcThreadCycleData (VDK_ThreadID

inThreadID,

unsigned int

outCreationTime[2],unsigned int

outStartTime[2],unsigned int

outLastTime[2],unsigned int

outTotalTime[2]);C++ Prototype
VDK::SystemError VDK::GetSharcThreadCycleData (VDK::ThreadID

inThreadID,

unsigned int

outCreationTime[2],unsigned int

outStartTime[2],unsigned int

outLastTime[2],unsigned int

outTotalTime[2]);Description
Retrieves the cycle count information for a given thread. The API can becalled only when using fully instrumented VDK libraries as this information is not available for error checking and non-error checking libraries.
API is available only for SHARC
L The.
processors; for other processors, use
GetSharcThreadCycleData()

GetThreadCycleData()

ParametersinThreadID is the thread identifier (ThreadID) of the thread to query.
outCreationTime is populated with the cycle count when the thread wascreated. outCreationTime can be NULL, in which case no creation cycles are
returned.

5-138

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

outStartTime is populated with the cycle count when execution trans-ferred to the thread for the first time.outStartTime can be NULL, in whichcase no start time information is returned.
outLastTime is populated with the number of cycles for which the thread

executed during the most recent period of execution. outLastTime can be
NULL, in which case the number of cycles is not returned.
outTotalTime is populated with the cumulative number of cycles forwhich the thread has executed since its creation. outTotalTime can be
NULL, in which case no total time information is returned.
The arrays are populated with the upper (most significant) word of thecycle count in the first element, and the lower (least significant) word in
the second.
Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return Value
Returns kUnknownThread if the ThreadID is not a valid identifier; kNoError
otherwise
Errors Dispatched
None

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-139

VDK API Validity

GetThreadBlockingID()
C Prototype
VDK_SystemError VDK_GetThreadBlockingID(
VDK_ThreadID

inThreadID,

int*outBlockingID);

C++ Prototype
VDK::SystemError VDK::GetThreadBlockingID(
VDK::ThreadID inThreadID,
int*outBlockingID);

Description
Returns the enumerated identifier of the VDK object on which a thread
was last blocked or returns the message channel mask if the thread was
blocked waiting for a message. The object type can be determined fromthe thread status, such that if the thread status is kSemaphoreBlocked, thenthis API returns the semaphore identifier. This attribute is only updated
when a thread blocks and not when a thread unblocks. It is recommended
that GetThreadBlockingID() is used in conjunction with
GetThreadStatus().
ParametersinThreadID specifies the thread (ThreadID) to query.
outBlockingID is populated with the ID of the object on which the thread

was last blocked or the message channel mask if the thread was blocked
waiting for a message.
Scheduling
Does not invoke the scheduler

5-140

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

Determinism
Constant time
Return Value
Full instrumentation and error-checking libraries:• Returns kUnknownThread if ThreadID is not a valid identifier; kNoError otherwise
Non error-checking libraries: kNoError
Errors Dispatched
None

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-141

VDK API Validity

GetThreadCycleData()
C Prototype
VDK_SystemError VDK_GetThreadCycleData (VDK_ThreadID

inThreadID,

unsigned long long int*outCreationTime,unsigned long long int*outStartTime,unsigned long long int*outLastTime,unsigned long long int*outTotalTime);

C++ Prototype
VDK::SystemError VDK::GetThreadCycleData (VDK::ThreadID

inThreadID,

unsigned long long int*outCreationTime,unsigned long long int*outStartTime,unsigned long long int*outLastTime,unsigned long long int*outTotalTime);

Description
Retrieves the cycle count information for a given thread. This API can becalled only when using fully instrumented VDK libraries as this information is not available for error checking and non-error checking libraries.
API is supported only for
L The
the TigerSHARC and Blackfin processors. To retrieve the cycle
VDK_GetThreadCycleData()

data for a SHARC processor, use the GetSharcThreadCycleData()
API.
ParametersinThreadID is the thread identifier (ThreadID) of the thread to query.

5-142

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

outCreationTime is populated with the cycle count when the thread wascreated. outCreationTime can be NULL, in which case no creation cycles are
returned.
outStartTime is populated with the cycle count when the thread wasswitched in for the last time. outStartTime can be NULL, in which case nostart time information is returned.
outLastTime is populated with the number of cycles for which the thread

executed during the most recent period of execution. outLastTime can be
NULL, in which case the number of cycles is not returned.
outTotalTime is populated with the cumulative number of cycles forwhich the thread has executed since its creation. outTotalTime can be
NULL, in which case no total time information is returned.
Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return Value
Returns kUnknownThread if ThreadID is not a valid identifier; kNoError
otherwise
Errors Dispatched
None

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-143

VDK API Validity

GetThreadHandle()
C Prototype
void** VDK_GetThreadHandle(void);

C++ Prototype
void** VDK::GetThreadHandle(void);

Description
Returns a pointer to a thread’s user-defined, allocated data pointer. This
pointer can be used in C and assembly threads for holding thread local
state; for example, member variables.
Parameters
None
Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return Value
Pointer to a thread’s user-defined, allocated data pointerErrors Dispatched
None

5-144

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

GetThreadID()
C Prototype
VDK_ThreadID VDK_GetThreadID(void);

C++ Prototype
VDK::ThreadID VDK::GetThreadID(void);

Description
Returns the identifier (ThreadID) of the currently running thread
Parameters
None
Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return Value
Currently running thread’s ID of type ThreadID or VDK_KERNEL_LEVEL_ if
the code is running at kernel level
Errors Dispatched
None

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-145

VDK API Validity

GetThreadSlotValue()
C Prototype
void* VDK_GetThreadSlotValue(int inSlotNum);

C++ Prototype
void* VDK::GetThreadSlotValue(int inSlotNum);

Description
Returns the value in the currently running thread’s slot table associatedwith inSlotNum. Returns NULL if the key does not identify a currently allocated slot; otherwise, returns the current value held in the slot, which may
also be NULL.
Parameters
inSlotNum is the static library’s preallocated slot number.

Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return Value
Slot value for the slot number specified
Errors Dispatched
None

5-146

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

GetThreadStackDetails()
C Prototype
VDK_SystemError VDK_GetThreadStackDetails(
VDK_ThreadID

inThreadID,

unsigned int*outStackSize,void**outStackAddress);

C++ Prototype
VDK::SystemError VDK::GetThreadStackDetails(
VDK::ThreadID

inThreadID,

unsigned int*outStackSize,void**outStackAddress);

Description
Returns the stack attributes of a given thread: size and start address
ParametersinThreadID specifies the thread (ThreadID) to query.
outStackSize returns the size of the stack in 32-bit words. outstackSize

can be NULL, in which case no stack size information is returned.
outStackAddress returns the start address of the thread’s stack. outStackAddress can be NULL, in which case the start address of the stack is not
returned.

Scheduling
Does not invoke the scheduler

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-147

VDK API Validity

Determinism
Constant time
Return Value
Full instrumentation and error-checking libraries:• Returns kUnknownThread if ThreadID is not a valid identifier; kNoError otherwise
Non error-checking libraries: kNoError
Errors Dispatched
None

5-148

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

GetThreadStack2Details()
C Prototype
VDK_SystemError

VDK_GetThreadStack2Details(
VDK_ThreadID

inThreadID,

unsigned int*outStackSize,void**outStackAddress);

C++ Prototype
VDK::SystemError

VDK::GetThreadStack2Details(
VDK::ThreadID

inThreadID,

unsigned int*outStackSize,void**outStackAddress);

Description
Returns the stack2 attributes for a given thread: size and start address
API is applicable only to processors using two stacks, curL This
rently, those in the ADSP-TSxxx processor family.
ParametersinThreadID specifies the thread (ThreadID) to query.
outStackSize returns the size of the stack in 32-bit words. outstackSize

can be NULL, in which case no stack size information is returned.
outStackAddress returns the start address of the thread’s stack. outStackAddress can be NULL, in which case the start address of the stack is not

returned.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-149

VDK API Validity

Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return Value
Full instrumentation and error-checking libraries:• Returns kUnknownThread if ThreadID is not a valid identifier; kNoError otherwise
Non error-checking libraries: kNoError
Errors Dispatched
None

5-150

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

GetThreadStackUsage()
C Prototype
unsigned int VDK_GetThreadStackUsage(
const VDK_ThreadID inThreadID);

C++ Prototype
unsigned int VDK::GetThreadStackUsage(
const VDK::ThreadID inThreadID);

Description
Gets the maximum used stack for the specified thread at the time of thecall. For applications built with “Full Instrumentation”, the maximum
stack usage returned is either the amount used since the thread creation,or the last call to the InstrumentStack() API. For applications not builtwith “Full Instrumentation”, the thread stacks are not instrumented bydefault. Therefore, this function does not return a meaningful value inthese cases unless the InstrumentStack() API has previously been called
to instrument the stack.
ParametersinThreadID of type ThreadID specifies the thread’s stack usage to query.

Scheduling
Does not invoke the scheduler
Determinism
Not deterministic

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-151

VDK API Validity

Return Value
Maximum stack used since the thread was created (if the application was
built with “Full Instrumentation”) or since the last call to InstrumentStack(). Note that the stack is expressed in 32-bit words.
Errors Dispatched
Full instrumentation and error-checking libraries:•

kUnknownThread indicates that inThreadID is not a valid ThreadID

Non error-checking libraries: none

5-152

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

GetThreadStack2Usage()
C Prototype
unsigned int VDK_GetThreadStack2Usage(
const VDK_ThreadID inThreadID);

C++ Prototype
unsigned int VDK::GetThreadStack2Usage(
const VDK::ThreadID inThreadID);

Description
Gets the maximum used stack2 for the specified thread at the time of thecall. For applications built with “Full Instrumentation”, the maximum
stack usage returned is either the amount used since the thread creation,or the last call to the InstrumentStack() API. For applications not builtwith “Full Instrumentation”, the thread stacks are not instrumented bydefault. Therefore, this function does not return a meaningful value inthese cases unless the InstrumentStack() API has previously been called
to instrument the stack.
API is applicable only to certain processors which use two
L Thisstacks, currently those in the ADSP-TSxxx processor families.
ParametersinThreadID of type ThreadID specifies the thread’s stack usage to query.

Scheduling
Does not invoke the scheduler
Determinism
Not deterministic

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-153

VDK API Validity

Return Value
Maximum stack2 used since the thread was created (if the application was
built with “Full Instrumentation”) or since the last call to InstrumentStack(). Note that the stack is expressed in 32-bit words.
Errors Dispatched
Full instrumentation and error-checking libraries:•

kUnknownThread indicates that inThreadID is not a valid ThreadID

Non error-checking libraries: none

5-154

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

GetThreadStatus()
C Prototype
VDK_ThreadStatus VDK_GetThreadStatus(
const VDK_ThreadID inThreadID);

C++ Prototype
VDK::ThreadStatus VDK::GetThreadStatus(
const VDK::ThreadID inThreadID);

Description
Reports the enumerated status (ThreadStatus) of the specified thread
ParametersinThreadID of type ThreadID points to the thread whose status is being

queried.
Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return Value
Status of the specified thread if it exists and VDK::kUnknown if it does not.
For more information, see ThreadStatus.
Errors Dispatched
None

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-155

VDK API Validity

GetThreadTemplateName()
C Prototype
VDK_SystemError VDK_GetThreadTemplateName(VDK_ThreadID

inThreadID,

char**outName)

C++ Prototype
VDK::SystemError VDK::GetThreadTemplateName(
VDK::ThreadID

inThreadID,

char**outName)

Description
The API retrieves the address of the null-terminated string that contains
the template name of the given thread.
ParametersinThreadID is the thread identifier (ThreadID) of the thread to query.
outName is populated with a pointer to the thread’s template name for the

given thread.
Scheduling
Does not invoke the scheduler
Determinism
Not deterministic

5-156

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

Return Value
Full instrumentation and error-checking libraries:• Returns kUnknownThread if ThreadID is not a valid identifier; kNoError otherwise
Non error-checking libraries: kNoError
Errors Dispatched
None

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-157

VDK API Validity

GetThreadTickData()
C Prototype
VDK_SystemError VDK_GetThreadTickData(
VDK_ThreadID

inThreadID,

VDK_Ticks*outCreationTime,

VDK_Ticks*outStartTime,

VDK_Ticks*outLastTime,

VDK_Ticks*outTotalTime);

C++ Prototype
VDK::SystemError VDK::GetThreadTickData(
VDK::ThreadID

inThreadID,

VDK::Ticks*outCreationTime,

VDK::Ticks*outStartTime,

VDK::Ticks*outLastTime,

VDK::Ticks*outTotalTime);

Description
Retrieves the tick information for a given thread. This API can be called
only with fully instrumented VDK libraries as this information is notavailable for error checking and non-error checking libraries.
ParametersinThreadID is the thread identifier (ThreadID) of the thread to query.
outCreationTime is populated with the tick ( Ticks) when the thread wascreated. outCreationTime can be NULL, in which case no creation cycles are
returned.
outStartTime is populated with the tick (Ticks) when execution trans-ferred to the thread for the first time. outStartTime can be NULL, in whichcase no start time information is returned.
5-158

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

outLastTime is populated with the number of Ticks for which the thread

executed during the most recent period of execution. outLastTime can be
NULL, in which case no execution information is returned.
outTotalTime is populated with the cumulative number of Ticks forwhich the thread has executed since its creation.outTotalTime can be
NULL, in which case no total time information is returned.
Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return Value
Returns kUnknownThread if ThreadID is not a valid identifier; kNoError
otherwise
Errors Dispatched
None

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-159

VDK API Validity

GetTickPeriod()
C Prototype
float VDK_GetTickPeriod(void);

C++ Prototype
float VDK::GetTickPeriod(void);

Description
Returns the value in milliseconds of the tick period for the application
Parameters
None
Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return Value
Value in milliseconds of the tick period
Errors Dispatched
None

5-160

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

GetUptime()
C Prototype
VDK_Ticks VDK_GetUptime(void);

C++ Prototype
VDK::Ticks VDK::GetUptime(void);

Description
Returns the time in Ticks since the last system reset
Parameters
None
Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return Value
Time in Ticks since the last system reset
Errors Dispatched
None

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-161

VDK API Validity

GetVersion()
C Prototype
VDK_VersionStruct VDK_GetVersion(void);

C++ Prototype
VDK::VersionStruct VDK::GetVersion(void);

Description
Returns the current version of VDK (see VersionStruct).
Parameters
None
Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return Value
Current version of VDK in the VersionStruct form
Errors Dispatched
None

5-162

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

InstallMessageControlSemaphore()
C Prototype
void VDK_InstallMessageControlSemaphore(
VDK_SemaphoreID inSemaphore);

C++ Prototype
void VDK::InstallMessageControlSemaphore(
VDK::SemaphoreID inSemaphore);

Description
Sets up a counting semaphore to regulate the allocation and deallocationof message objects by the routing threads. The initial value of the semaphore should be set to the number of free messages reserved for use by the
incoming routing threads. The semaphore is pended (by the incoming
routing threads) prior to each message allocation, and posted (by the outgoing routing threads) after each message deallocation. Provided that thevalue of the semaphore is always less than or equal to the number of freemessages, the allocation by the routing threads never fails (although therouting threads may block, pended on the semaphore) waiting for a freemessage to become available.
Parameters
inSemaphore is the SemaphoreID of the semaphore to be installed.

Scheduling
Does not invoke the scheduler
Determinism
Constant time

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-163

VDK API Validity

Return ValueNo return value
Errors Dispatched
None

5-164

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

InstrumentStack()
C Prototype
void VDK_InstrumentStack(void);

C++ Prototype
void VDK::InstrumentStack(void);

Description
Instruments the stack of the calling thread to allow the determination of
maximum thread stack usage. The GetThreadStackUsage() API is used toobtain the maximum stack usage for instrumented thread stacks.
If the fully instrumented libraries are used, the thread’s stack is instrumented on creation. In this case, the InstrumentStack() API is used toreset the instrumentation of the stack to cover the currently unused section of the stack (for example, to determine the maximum stack usedwhile executing a section of code). If the libraries without full instrumentation are used, the thread’s stack is not instrumented by default and so
InstrumentStack() has to be used to obtain meaningful results from
GetThreadStackUsage().
Parameters
None
Scheduling
Does not invoke the scheduler
Determinism
Not deterministic

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-165

VDK API Validity

Return ValueNo return value
Errors Dispatched
None

5-166

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

LoadEvent()
C Prototype
void VDK_LoadEvent(VDK_EventID
const VDK_EventData

inEventID,
inEventData);

C++ Prototype
void VDK::LoadEvent(VDK::EventID
const VDK::EventData

inEventID,
inEventData);

Description
Loads the data associated with the event. For more information, seeEventData.
ParametersinEventID of type EventID is the event to be reinitialized.
inEventData of type EventData contains the new values for the event.

Scheduling
Causes the value of the event to be recalculated, invokes the scheduler,
and may result in a context switch
Determinism
Not deterministic
Return ValueNo return value

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-167

VDK API Validity

Errors Dispatched
Full instrumentation and error-checking libraries:•

kUnknownEvent indicates that inEventID is not a valid EventID

Non error-checking libraries: none

5-168

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

LocateAndFreeBlock()
C Prototype
void VDK_LocateAndFreeBlock(void *inBlkPtr);

C++ Prototype
void VDK::LocateAndFreeBlock(void *inBlkPtr);

Description
Determines the pool in which the to-be-freed block resides, then frees theblock and returns the block to the free-block list
Parameters
inBlockPtr specifies the block to be freed.

Scheduling
Does not invoke the scheduler
Determinism
Not deterministic
Return ValueNo return value
Errors Dispatched
Full instrumentation and error-checking libraries:•

kInvalidBlockPointer indicates that inBlkPtr does not belong to

any of the active memory pools and cannot be freed
Non error-checking libraries: none

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-169

VDK API Validity

LogHistoryEvent()
C Prototype
void VDK_LogHistoryEvent(VDK_HistoryEnum inEnum, int inValue);

C++ Prototype
void VDK::LogHistoryEvent(VDK::HistoryEnum inEnum, int inValue);

Description
Adds a record to the history buffer. This function does not perform any
action if the project is not linked with the fully instrumented libraries.
Parameters
inEnum is the enumeration value for this type of event. For more informa-tion, see HistoryEnum.
inValue is the value defined by enumeration.

Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return ValueNo return value
Errors Dispatched
None

5-170

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

MakePeriodic()
C Prototype
void VDK_MakePeriodic(VDK_SemaphoreID

inSemaphoreID,

VDK_Ticks

inDelay,

VDK_Ticks

inPeriod);

C++ Prototype
void VDK::MakePeriodic(VDK::SemaphoreID

inSemaphoreID,

VDK::Ticks

inDelay,

VDK::Ticks

inPeriod);

Description
Directs the scheduler to post the specified semaphore after inDelay number of Ticks. After every inPeriod Ticks, the semaphore is posted and thescheduler is invoked. This allows the running thread to acquire the signal
and, if the thread is at the highest priority level, to continue execution.
To be periodic, the running thread must repeat in sequence: perform task
and then pend on the semaphore. Note that this differs from “sleeping” at
the completion of activity.
Parameters
inSemaphoreID of type SemaphoreID is the semaphore to make periodic.
inDelay is the number of Ticks before the first posting of the semaphore.
inDelay must be equal to or greater than one and less than INT_MAX.
inPeriod is the number of Ticks to sleep at each cycle after the first cycle.
inPeriod must be equal to or greater than one and less than INT_MAX.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-171

VDK API Validity

Scheduling
Does not invoke the scheduler
Determinism
Not deterministic
Return ValueNo return value
Errors Dispatched
Full instrumentation and error-checking libraries:•

kUnknownSemaphore indicates inSemaphoreID is not a valid
SemaphoreID•

kInvalidPeriod indicates inPeriod is zero or greater than INT_MAX•

kInvalidDelay indicates inDelay is zero or greater than INT_MAX.

Zero is not an accepted delay because the first posting does notoccur until the next tick.
•kAlreadyPeriodic indicates the semaphore is already periodic andcannot be made periodic again. If the intention is to change theperiod, the semaphore has to be made non-periodic first.
Non error-checking libraries: none

5-172

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

MallocBlock()
C Prototype
void* VDK_MallocBlock(VDK_PoolID inPoolID);

C++ Prototype
void* VDK::MallocBlock(VDK::PoolID inPoolID);

Description
Returns pointer to the next available block from the specified poolParameters:
inPoolID of type PoolID specifies the pool from which the block is to beallocated.
Scheduling:
Does not invoke the scheduler
Determinism
Constant time if inCreateNow was specified to be TRUE when the specified
pool was created.
Not deterministic if inCreateNow was specified to be FALSE
Return Value
Void pointer to a free memory block upon success; NULL if the call fails toallocate a block

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-173

VDK API Validity

Errors Dispatched
Full instrumentation and error-checking libraries:•

kInvalidPoolID indicates inPoolID is not a valid PoolID•

kErrorMallocBlock indicates there are no free blocks in the pool,so a new block cannot be allocated
Non error-checking libraries: none

5-174

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

MessageAvailable()
C Prototypebool VDK_MessageAvailable(unsigned int inMessageChannelMask);

C++ Prototypebool VDK::MessageAvailable(unsigned int inMessageChannelMask);

Description
Enables a thread to use a polling model (rather than a blocking model) to
wait for messages in its message queue. This function returns TRUE if asubsequent call to PendMessage() with the same channel mask does notblock.
ParametersinMessageChannelMask specifies the receive channels. A set bit corre-

sponds to a receive channel, and a clear bit corresponds to a channel thatis ignored.
If the VDK::kMsgWaitForAll flag is set in the channel mask, then the query
operates with AND logic, rather than the default OR logic. By default, only
one message—on any of the receive channels designated in the channel
mask—is required for a true result. The VDK::kMsgWaitForAll flag
requires at least one message be queued on each of the specified receive
channels channel in order for the function to return TRUE.
Scheduling
Does not invoke the scheduler
Determinism
Constant time

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-175

VDK API Validity

Return Value
TRUE if there is a message available and FALSE if there is not

Errors Dispatched
Full instrumentation and error-checking libraries:•

kInvalidMessageChannel indicates inMessageChannelMask is not avalid mask•

kInvalidThread indicates the current thread does not have a mes-sage queue because it has not been enabled for messaging
Non error-checking libraries: none

5-176

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

OpenDevice()
C Prototype
VDK_DeviceDescriptor VDK_OpenDevice(VDK_IOID
charinIDNum,*inFlags);

C++ Prototype
VDK::DeviceDescriptor VDK::OpenDevice(VDK::IOID
char

inIDNum,*inFlags);

Description
Opens the specified device. Note that the returned DeviceDescriptor isvalid only for the thread that made the call to OpenDevice(). Each threadusing a device must make its own call to OpenDevice(). Currently, thereturn value of the device driver dispatch function is ignored by OpenDevice(), so OpenDevice() cannot recognize any failure modes.
A maximum of eight device drivers can be opened per thread at any one
time.
Parameters
inIDNum is the boot I/O identifier ( IOID).
inFlags is uninterpreted data passed through to the device being opened.

Scheduling
Does not call the scheduler, but the user-written device driver can call thescheduler

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-177

VDK API Validity

Determinism
Constant time. Note that this function calls user-written device drivercode that may not be deterministic.
Return Value
New DeviceDescriptor upon success. Upon failure, if the thread’s Error
function does not go to KernelPanic, OpenDevice() returns one of thefollowing:• the return value of the current thread’s Error function
for kBadIOID if the IOID was incorrect• the return value of the current thread’s Error function
for kOpenFailure if there was any other error
Errors Dispatched
Full instrumentation and error-checking libraries:•

kBadIOID indicates that inIDNum is not a valid IOID•

kOpenFailure indicates that no more devices can be open

simultaneously
Non error-checking libraries: none
Other errors can be dispatched by user-written device driver code
L executedby this API.

5-178

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

PendDeviceFlag()
C Prototypebool VDK_PendDeviceFlag(VDK_DeviceFlagID
VDK_Ticks

inFlagID,
inTimeout);

C++ Prototypebool VDK::PendDeviceFlag(VDK::DeviceFlagID
VDK::Ticks

inFlagID,
inTimeout);

Description
Allows a thread to block on a specified device flag.
The thread is blocked and swapped out. Once the device flag is madeavailable via PostDeviceFlag(), all threads waiting for this flag are madeready-to-run. If the thread does not resume execution within inTimeout
Ticks, the thread’s reentry point is changed to its error function, and thethread is made available for scheduling. This behavior can be changed by
ORing the timeout with the constant VDK_kNoTimeoutError in C or
VDK::kNoTimeoutError in C++. In this case, no errors are dispatched ontimeout and the API simply returns after making the thread available forscheduling. If the value of inTimeout is passed as zero, then the thread
may pend indefinitely.
Note that PendDeviceFlag() must be called from within a non-nested
critical region (a critical region with a stack depth of one), but from outside of any unscheduled regions (as explained in “Pending on a Device
Flag” on page 3-76). PendDeviceFlag() pops one level of the criticalregion stack.
Parameters
inFlagID of type DeviceFlagID is the device flag on which the threadpends.
VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-179

VDK API Validity

inTimeout of type Ticks is a value less than INT_MAX that specifies the

maximum duration in ticks for which the thread pends on the device flag.
Scheduling
Invokes the scheduler
Determinism
Not deterministic
Return Value
TRUE if the device flag has been successfully pended on. FALSE if the
PendDeviceFlag() call has timed out but kNoTimeoutError was specified

Errors Dispatched
Full instrumentation and error-checking libraries:•

kBlockInInvalidRegion indicates that PendDeviceFlag() is called

in an unscheduled region or nested critical region (must be called
in a non-nested critical region)•kInvalidDeviceFlag indicates that inFlagID is not a valid
DeviceFlagID•

kDeviceTimeout indicates that the timeout value has expired before

the device flag was posted. This error is not dispatched if the timeout was ORed with the constant kNoTimeoutError•

kInvalidTimeout indicates that inTimeout is UINT_MAX, INT_MAX, or
INT_MIN (equivalent to 0|kNoTimeoutError)

Non error-checking libraries: kDeviceTimeout as above

5-180

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

PendEvent()
C Prototypebool VDK_PendEvent(VDK_EventID inEventID, VDK_Ticks inTimeout);

C++ Prototypebool VDK::PendEvent(VDK::EventID inEventID, VDK::Ticks inTimeout);

Description
Provides the mechanism by which threads pend on events.
If the named event calculates as being available, execution returns to therunning thread. If the event is not available and the timeout specified is1
kDoNotWait , the API returns FALSE and the thread continues execution. If
the event is not available and the timeout is something other than kDoNotWait, the thread pauses execution until the event is available. When theevent becomes available, all threads pending on the event are moved to theready queue.
If the thread does not resume execution within inTimeout Ticks, thethread’s reentry point is changed to its error function, and the thread ismade available for scheduling. This behavior can be changed by ORing thetimeout with the constant VDK_kNoTimeoutError in C or VDK::kNoTimeoutError in C++. In this case, no errors are dispatched on timeout, and the
API simply returns after making the thread available for scheduling. If thevalue of inTimeout is passed as zero, then the thread may pendindefinitely.
ParametersinEventID is the EventID on which the thread pends.

1

VDK::kDoNotWait in C++ and VDK_kDoNotWait in C.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-181

VDK API Validity

inTimeout is a value less than INT_MAX that specifies the maximum dura-tion in Ticks for which the thread pends on the event. This value can be
ORed with kNoTimeoutError if no errors are to be dispatched in the case ofa timeout. The value kDoNotWait indicates that the API should not block
when the event is not available.
Scheduling
Invokes the scheduler and may result in a context switch
Determinism
Constant time if event is available
Return Value
TRUE if:• the event has been successfully pended on.
FALSE if:

• the PendEvent() call has timed out, but kNoTimeoutError was
specified•inTimeout is kDoNotWait and there was no event available

Errors Dispatched
Full instrumentation and error-checking libraries:•

kEventTimeout indicates the timeout value has expired before theevent was available. This error is not dispatched if the timeout was
ORed with the constant kNoTimeoutError
•

5-182

kUnknownEvent indicates inEventID is not a valid EventID

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference•

kBlockInInvalidRegion indicates PendEvent() is trying to block in

an unscheduled region, causing a scheduling conflict•

kDbgPossibleBlockInRegion indicates PendEvent() is being called

in an unscheduled region, causing a potential scheduling conflict•kInvalidTimeout indicates inTimeout is either INT_MAX or(0 | kNoTimeoutError)

Non error-checking libraries: kEventTimeout as above

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-183

VDK API Validity

PendMessage()
C Prototype
VDK_MessageID VDK_PendMessage(unsigned int inMessageChannelMask,
VDK_Ticks

inTimeout);

C++ Prototype
VDK::MessageID VDK::PendMessage(unsigned int inMessageChannelMask,
VDK::Ticks

inTimeout);

Description
Retrieves a message from a thread’s message queue. Unless the timeout
specified is kDoNotWait1, PendMessage() is a blocking call—when thespecified conditions for a valid message in the queue are not met, thethread suspends execution. If the timeout is kDoNotWait and the conditions for a valid message in the message queue are not met, PendMessage()
returns UINT_MAX and the thread continues its execution.
The channel mask allows you to specify which channels (kMsgChannel1
through kMsgChannel15) to examine for incoming messages. The MessageAvailable() API can be used to poll for the presence of a valid
message instead of the blocking behavior of PendMessage().
In addition, the flag VDK::kMsgWaitForAll may be included in (ORed into)
the channel mask to specify that at least one message must be present oneach of the channels specified in the mask. Messages are retrieved from thelowest numbered channels first (kMsgChannel1, then kMsgChannel2, ...).
Once a MessageID is returned by PendMessage(), the message is no longer
in the queue and is owned by the calling thread. If the thread does notresume execution within inTimeout Ticks, the thread’s reentry point ischanged to its error function, and the thread is made available for schedul1

VDK::kDoNotWait in C++ and VDK_kDoNotWait in C.

5-184

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

ing. This behavior can be changed by ORing the timeout with the constant
VDK_kNoTimeoutError in C or VDK::kNoTimeoutError in C++. In this case,no errors are dispatched on timeout and the API simply returns after making the thread available for scheduling. If the value for inTimeout is passed
as zero, then the thread may pend indefinitely.
ParametersinMessageChannelMask specifies the receive channels. A set bit corre-

sponds to a receive channel. A clear bit corresponds to a channel that is
ignored. The parameter may not be zero.
If the VDK::kMsgWaitForAll flag is set in the channel mask, then the pend
operates with AND logic, rather than the default OR logic. By default, only
one message—on any of the receive channels designated in the channel
mask—is required to unblock the pending thread. The VDK::kMsgWaitForAll flag requires at least one message to be queued on each of thespecified receive channels channel in order to unblock.
inTimeout is a value less than INT_MAX that specifies the maximum dura-tion in Ticks for which the thread pends on the receipt of the required
message(s). This value can be ORed with kNoTimeoutError if no errors areto be dispatched in the case of a timeout. The value kDoNotWait indicatesthat the API should not block when there is no message available.
Scheduling
Invokes the scheduler and may result in a context switch
Determinism
Constant time if there is no need to block
Return Value
Identifier of the message the thread pended on upon success; UINT_MAX
otherwise
VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-185

VDK API Validity

Errors Dispatched
Full instrumentation and error-checking libraries:•

kDbgPossibleBlockInRegion indicates PendMessage() is being

called in an unscheduled region, causing a potential schedulingconflict•

kInvalidMessageChannel indicates inMessageChannelMask does

not specify a correct group of channels to mask•

kMessageTimeout indicates the timeout value has expired before thethread removed the message from its message queue. This error is
not dispatched if the timeout was ORed with the constantkNoTimeoutError•

kBlockInInvalidRegion indicates PendMessage() is trying to blockin an unscheduled region, causing a scheduling conflict•kInvalidTimeout indicates inTimeout is either INT_MAX or(0 | kNoTimeouterror)•

kInvalidThread indicates the current thread does not have a mes-sage queue as it has not been enabled for messaging
Non error-checking libraries: kMessageTimeout as above

5-186

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

PendSemaphore()
C Prototypebool VDK_PendSemaphore(VDK_SemaphoreID
VDK_Ticks

inSemaphoreID,
inTimeout);

C++ Prototypebool VDK::PendSemaphore(VDK::SemaphoreID
VDK::Ticks

inSemaphoreID,
inTimeout);

Description
Provides the mechanism that allows threads to pend on semaphores.
If the named semaphore is available (its count is greater than zero), thesemaphore’s count is decremented by one, and processor control returns
to the running thread. If the semaphore is not available (its count is zero)and the timeout specified is kDoNotWait1, the API returns FALSE and thethread continues execution.
If the semaphore is not available and the timeout is something other thankDoNotWait, the thread pauses execution until the semaphore is posted. If
the thread does not resume execution within inTimeout Ticks, thethread’s reentry point is changed to its error function, and the thread ismade available for scheduling. This behavior can be changed by ORing thetimeout with the constant VDK_kNoTimeoutError in C or VDK::kNoTimeoutError in C++. In this case, no errors are dispatched on timeout and the
API simply returns after making the thread available for scheduling. If thevalue of inTimeout is passed as zero, then the thread may pendindefinitely.

1

VDK::kDoNotWait in C++ and VDK_kDoNotWait in C.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-187

VDK API Validity

Parameters
inSemaphoreID of type SemaphoreID is the semaphore on which the threadpends.
inTimeout is a value less than INT_MAX that specifies the maximum dura-tion in Ticks for which the thread pends on the semaphore. This value
can be ORed with kNoTimeoutError if no errors are to be dispatched in thecase of a timeout. The value kDoNotWait indicates that the API should not
block when the semaphore is not available.
Scheduling
Invokes the scheduler and may result in a context switch
Determinism
Constant time if semaphore is available
Return Value
TRUE if:• the semaphore has been successfully pended on by SemaphoreID
FALSE if:

• the PendSemaphore() call has timed out, but kNoTimeoutError was
specified•

5-188

inTimeout was kDoNotWait and there was no semaphore available

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

Errors Dispatched
Full instrumentation and error-checking libraries:•

kSemaphoreTimeout indicates that the timeout value has expired

before the semaphore became available. This error is not be dispatched if the timeout was ORed with the constantkNoTimeoutError•

kUnknownSemaphore indicates inSemaphoreID is not a valid
SemaphoreID•

kBlockInInvalidRegion indicates PendSemaphore() is trying toblock in an unscheduled region, causing a scheduling conflict•

kDbgPossibleBlockInRegion indicates PendSemaphore() may becalled in an unscheduled region, causing a potential schedulingconflict•

kInvalidTimeout indicates inTimeout is either INT_MAX or(0 | kNoTimeoutError)

Non error-checking libraries: kSemaphoreTimeout as above

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-189

VDK API Validity

PopCriticalRegion()
C Prototype
void VDK_PopCriticalRegion(void);

C++ Prototype
void VDK::PopCriticalRegion(void);

Description
Decrements the count of nested critical regions. Use it as a close bracket
call to PushCriticalRegion(). A count is maintained to ensure that eachentered critical region calls PopCriticalRegion() before interrupts are
re-enabled.
Each critical region is also (implicitly) an unscheduled region.
Parameters
None
Scheduling
Invokes the scheduler and may result in a context switch if interrupts are
re-enabled by this call
Determinism
Not deterministic
Return ValueNo return value

5-190

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

Errors Dispatched
Full instrumentation and error-checking libraries:•

kDbgPopUnderflow indicates that there were no critical regions topop
Non error-checking libraries: none

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-191

VDK API Validity

PopNestedCriticalRegions()
C Prototype
void VDK_PopNestedCriticalRegions(void);

C++ Prototype
void VDK::PopNestedCriticalRegions(void);

Description
Resets the count of nested critical regions to zero, thereby, re-enabling
interrupts.
This function does not change the interrupt mask.
Parameters
None
Scheduling
Invokes the scheduler and may result in a context switch unless interrupts
are already enabled
Determinism
Not deterministic
Return ValueNo return value
Errors Dispatched
Full instrumentation and error-checking libraries:
•

5-192

kDbgPopUnderflow indicates there are no critical regions to pop

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

Non error-checking libraries: none

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-193

VDK API Validity

PopNestedUnscheduledRegions()
C Prototype
void VDK_PopNestedUnscheduledRegions(void);

C++ Prototype
void VDK::PopNestedUnscheduledRegions(void);

Description
Resets the count of nested unscheduled regions to zero, thereby,
re-enabling scheduling.
Parameters
None
Scheduling
Invokes the scheduler and may result in a context switch unless schedulingis already enabled
Determinism
Not deterministic
Return ValueNo return value
Errors Dispatched
Full instrumentation and error-checking libraries:•

kDbgPopUnderflow indicates there were no critical regions to pop

Non error-checking libraries: none

5-194

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

PopUnscheduledRegion()
C Prototype
void VDK_PopUnscheduledRegion(void);

C++ Prototype
void VDK::PopUnscheduledRegion(void);

Description
Decrements the count of nested unscheduled regions. Use it as a close
bracket call to PushUnscheduledRegion(). A nesting count is maintained
to ensure that each entered unscheduled region calls PopUnscheduledRegion() before scheduling is resumed.
Parameters
None
Scheduling
Invokes the scheduler and may result in a context switch if scheduling isreenabled by this call
Determinism
Not deterministic
Return ValueNo return value
Errors Dispatched
Full instrumentation and error-checking libraries:•

kDbgPopUnderflow indicates there are no critical regions to pop

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-195

VDK API Validity

Non error-checking libraries: none

5-196

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

PostDeviceFlag()
C Prototype
void VDK_PostDeviceFlag(VDK_DeviceFlagID inFlagID);

C++ Prototype
void VDK::PostDeviceFlag(VDK::DeviceFlagID inFlagID);

Description
Posts the specified device flag (see DeviceFlagID). Once the device flag ismade available, all threads waiting for the flag are in the ready-to-run
state.
Parameters
inFlagID is the DeviceDescriptor returned from OpenDevice().

Scheduling
Invokes the scheduler
Determinism
Not deterministic
Return ValueNo return value
Errors Dispatched
Full instrumentation and error-checking libraries:•

kInvalidDeviceFlag indicates inFlagID is not a valid
DeviceFlagID

Non error-checking libraries: none

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-197

VDK API Validity

PostMessage()
C Prototype
void VDK_PostMessage(VDK_ThreadID

inRecipient,

VDK_MessageID

inMessageID,

VDK_MsgChannel

inChannel);void VDK::PostMessage(VDK::ThreadID

inRecipient,

VDK::MessageID

inMessageID,

VDK::MsgChannel

inChannel);

C++ Prototype

Description
Appends the message inMessageID to the message queue of the threadwith identifier inRecipient on the channel inChannel. The PostMessage() is a non-blocking function—returns execution to the callingthread without waiting for the recipient to run or to acknowledge the newmessage in its queue. The message is considered delivered when PostMessage() returns. Only the thread that is the owner of a message may post it.
At delivery time, ownership of the message and the associated payload istransferred from the sending thread to the recipient thread. Once delivered, all memory references to the payload, which may be held by thesending thread, are invalid. Memory read and write privileges and the
responsibility for freeing the payload memory are passed to the recipient
thread along with ownership.
Parameters
inRecipient is the ThreadID of the thread receiving the message.
inMessageID is the MessageID of the message being sent. A message must

be created before it is posted. This parameter is a return value of the call to
CreateMessage().
5-198

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

inChannel is the FIFO within the recipient’s message queue on which themessage is appended. Its value is kMsgChannel1 through kMsgChannel15(see MsgChannel).
Scheduling
Invokes the scheduler and may result in a context switch
Determinism
Not deterministic
Return ValueNo return value
Errors Dispatched
Full instrumentation and error-checking libraries:•

kInvalidMessageChannel indicates the inChannel is not a channel

value (see MsgChannel)•

kUnknownThread indicates inRecipient is not a valid ThreadID•

kInvalidMessageID indicates inMessageID is not a valid MessageID•

kInvalidMessageRecipient indicates inRecipient does not have amessage queue because it has not been enabled for messaging•

kInvalidMessageOwner indicates the thread attempting to post themessage is not the current owner. The error value is the ThreadIDof the owner

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-199

VDK API Validity•

kMessageInQueue indicates that the message is posted to a thread(the ThreadID is not known at this point), and the message needs tobe removed from the message queue by a call to PendMessage()•kInvalidTargetDSP indicates that the recipient of the message islocated in a core that is not declared in the VDK Kernel tab. Thiserror is only dispatched in multiprocessor messaging.
Non error-checking libraries: none

5-200

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

PostSemaphore()
C Prototype
void VDK_PostSemaphore(VDK_SemaphoreID inSemaphoreID);

C++ Prototype
void VDK::PostSemaphore(VDK::SemaphoreID inSemaphoreID);

Description
Provides the mechanism by which threads post semaphores. Every time asemaphore is posted, its count increases by one until it reaches the maximum value, as specified on creation. Any further posts have no effect.
Note that Interrupt Service Routines (ISRs) must use a different interface,as described in “Assembly Macros and C/C++ ISR APIs” on page 5-235.
Parameters
inSemaphoreID of type SemaphoreID identifies the semaphore to post.

Scheduling
May invoke the scheduler and may result in a context switch
Determinism• No thread pending: constant time
• Low priority thread pending: constant time
• High priority thread pending: constant time plus a context switch
Return ValueNo return value

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-201

VDK API Validity

Errors Dispatched
Full instrumentation and error-checking libraries:•

kUnknownSemaphore indicates that inSemaphoreID is not a valid
SemaphoreID

Non error-checking libraries: none

5-202

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

PushCriticalRegion()
C Prototype
void VDK_PushCriticalRegion(void);

C++ Prototype
void VDK::PushCriticalRegion(void);

Description
Disables interrupts to enable atomic execution of a critical region of code.
Note that critical regions may be nested. A count is maintained to ensure amatching number of calls to PopCriticalRegion() are made before restoring interrupts. Each critical region is also (implicitly) an unscheduled
region.
Parameters
None
Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return ValueNo return value
Errors Dispatched
None

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-203

VDK API Validity

PushUnscheduledRegion()
C Prototype
void VDK_PushUnscheduledRegion(void);

C++ Prototype
void VDK::PushUnscheduledRegion(void);

Description
Disables the scheduler. While in an unscheduled region, the current
thread does not become de-scheduled, even if a higher-priority thread
becomes ready to run. Note that unscheduled regions may be nested. A
count is maintained to ensure a matching number of calls to
PopUnscheduledRegion() are made before scheduling is re-enabled.
SchedulingSuspends scheduling until a matching PopUnscheduledRegion() callParameters
None
Determinism
Constant time
Return ValueNo return value
Errors Dispatched
None

5-204

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

ReleaseMutex()
C Prototype
void VDK_ReleaseMutex(VDK_MutexID inMutexID);

C++ Prototype
void VDK::ReleaseMutex(VDK::MutexID inMutexID);

Description
Provides the mechanism by which threads release ownership of the VDKmutexes.
When a thread no longer requires to keep ownership of a mutex, thethread can release the mutex with a call to ReleaseMutex(). A VDK mutex
is recursive and can be acquired by its owner without blocking with nested
AcquireMutex() calls. The mutex ownership will be released only when
ReleaseMutex() has been called once for each time that the mutex was
acquired. At that point, the mutex becomes available to all threads, and it
can be acquired without stopping execution.

L The API fails if the calling thread does not own the mutex.
Parameters
inMutexID of type MutexID is the mutex the thread is trying to release.

Scheduling
Invokes the scheduler and may result in a context switch

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-205

VDK API Validity

Determinism•

ReleaseMutex() call that does not change the running thread: con-stant time•

ReleaseMutex() call that changes the running thread: constanttime plus a context switch
Return ValueNo return value
Errors Dispatched
Full instrumentation and error-checking libraries:•

kInvalidMutexID indicates that inMutexID is not a mutex createdby the CreateMutex() API•

kMutexNotOwned indicates that the mutex had not been acquired byany threads so it cannot be released•

kNotMutexOwner indicates that a thread other than the running

thread had acquired the mutex
Non error-checking libraries: none

5-206

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

RemovePeriodic()
C Prototype
void VDK_RemovePeriodic(VDK_SemaphoreID inSemaphoreID);

C++ Prototype
void VDK::RemovePeriodic(VDK::SemaphoreID inSemaphoreID);

Description
Stops periodic posting of the specified semaphore. Trying to stop a
non-periodic semaphore has no effect and raises a run-time error.
Parameters
inSemaphoreID specifies the semaphore for which periodic posting ishalted (see SemaphoreID).
Scheduling
Does not invoke the scheduler
Determinism
Not deterministic
Return ValueNo return value

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-207

VDK API Validity

Errors Dispatched
Full instrumentation and error-checking libraries:•

kUnknownSemaphore indicates inSemaphoreID is not a valid
SemaphoreID•

kNonperiodicSemaphore indicates the semaphore is not periodic

Non-error checking libraries: none

5-208

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

ReplaceHistorySubroutine()
C Prototype
void VDK_ReplaceHistorySubroutine (HistoryLoggingFunc inFunc);

where inFunc has the following prototype.
void inFunc(VDK_Ticks

inTick,const

VDK_HistoryEnum

inEnum,

const

int

inValue,

const

VDK_ThreadID

inThreaID);

C++ Prototype
void VDK::ReplaceHistorySubroutine (HistoryLoggingFunc inFunc);

where inFunc has the following prototype.
void inFunc(VDK::Ticks

inTick,const

VDK::HistoryEnum

inEnum,

const

int

inValue,

const

VDK::ThreadID

inThreaID);

Description
Allows customers to replace the VDK history logging mechanism with theuser-defined subroutine inFunc.
Because the history logging mechanism can be invoked from thread, kernel and ISR levels, inFunc must comply with certain rules. See “Replacing
History Logging Mechanism” on page 3-83 for details.
The arguments passed to inFunc are members of the HistoryEvent structure. VDK sets up the arguments to inFunc in the following registers.
The user-defined subroutine can call VDK_ISRAddHistoryEvent() to add
history events to the VDK circular buffer in order to display the events inthe VDK History window. VDK_ISRAddHistoryEvent() takes the same

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-209

VDK API Validity

Argument

TypeBlackfin
Registers

TigerSHARC
Registers

SHARC
Registers

Time

VDK::Ticks

R3

J7

R0

Event type

VDK::HistoryEnum

R0

J4

R4

Value

int

R1

J5

R8

Thread ID

VDK::ThreadID

R2

J6

R12

arguments in the same registers as inFunc. VDK_ISRAddHistoryEvent() iscalled by VDK by default if the VDK history mechanism is not replaced.
ReplaceHistorySoubroutine() can be called at startup or in the construc-tor of a global variable and is only available when using fully instrumented
libraries.
Parameters
inFunc is the subroutine that will replace the default VDK logging code.

Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return ValueNo return value
Errors Dispatched
None

5-210

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

ResetPriority()
C Prototype
void VDK_ResetPriority(const VDK_ThreadID inThreadID);

C++ Prototype
void VDK::ResetPriority(const VDK::ThreadID inThreadID);

Description
Restores the priority of the named thread to the default value specified in
the thread’s template
ParametersinThreadID specifies the thread whose priority is reset (see ThreadID).

Scheduling
Invokes the scheduler and may result in a context switch
Determinism
Not deterministic
Return ValueNo return value
Errors Dispatched
Full instrumentation and error-checking libraries:•

kUnknownThread indicates inThreadID is not a valid ThreadID•

kInvalidThread indicates inThreadID specifies the Idle Thread

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-211

VDK API Validity

Non error-checking libraries: none

5-212

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

SetClockFrequency()
C Prototype
void VDK_SetClockFrequency(unsigned int inFrequency);

C++ Prototype
void VDK::SetClockFrequency(unsigned int inFrequency);

Description
Sets the clock frequency (in MHz) to inFrequency. The clock is stopped,
the clock parameters are recalculated using the new value for clock frequency, and then the clock is restarted. It is the responsibility of theapplication designer to ensure that the clock frequency matches that of the
hardware being used.
Parameters
inFrequency is the new value for the clock frequency in MHz.

Scheduling
Does not invoke the scheduler
Determinism
Not deterministic
Return ValueNo return value
Errors Dispatched
None

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-213

VDK API Validity

SetEventBit()
C Prototype
void VDK_SetEventBit(VDK_EventBitID inEventBitID);

C++ Prototype
void VDK::SetEventBit(VDK::EventBitID inEventBitID);

Description
Sets the value of the event bit. Once the event bit is set (meaning its value
equals to TRUE, 1, occurred, and so on), the value of all dependent events isrecalculated.
If several event bits are set (or cleared) as a single operation, then the
SetEventBit() and/or ClearEventBit() calls should be made from within
an unscheduled region. Event recalculation does not occur until theunscheduled region is popped.
ParametersinEventBitID specifies the system event bit to set (see EventBitID).

Scheduling
Invokes the scheduler and may result in a context switch
Determinism
Not deterministic
Return ValueNo return value

5-214

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

Errors Dispatched
Full instrumentation and error-checking libraries:•

kUnknownEventBit indicates inEventBitID is not a valid
EventBitID

Non error-checking libraries: none

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-215

VDK API Validity

SetInterruptMaskBits()
C Prototype
void VDK_SetInterruptMaskBits(VDK_IMASKStruct inMask);

C++ Prototype
void VDK::SetInterruptMaskBits(VDK::IMASKStruct inMask);

Description
Sets bits in the interrupt mask (see IMASKStruct). Any bits set in theparameter are set in the interrupt mask. In other words, the new mask iscomputed as the bitwise OR of the old mask and the parameter inMask.
The API does not have the expected behavior when called before
VDK_Initialize(), from boot thread constructors or from the Init part ofdevice drivers.
ParametersinMask of type IMASKStruct specifies which bits should be set in the inter-rupt mask.
Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return ValueNo return value

5-216

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

Errors Dispatched
None

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-217

VDK API Validity

SetInterruptMaskBitsEx()
C Prototype
void VDK_SetInterruptMaskBitsEx(VDK_IMASKStruct inMask,
VDK_IMASKStruct inLMask);

C++ Prototype
void VDK::SetInterruptMaskBitsEx(VDK::IMASKStruct inMask,
VDK::IMASKStruct inLMask);

Description
Sets bits in the IMASK and LMASK interrupt masks (where LMASK is the mask
component of the IRPTL register). Any bits set in the parameters are set in
the relevant interrupt mask. In other words, the new masks are computed
as the bitwise OR of the old mask and the specified IMASKStruct. The bits
specified for inLMask are shifted by the relevant amount for the processor
in question, thereby allowing the use of the bit definitions for the LIRPTL
register.
The API does not have the expected behavior when called before
VDK_Initialize(), from boot thread constructors or from the Init part ofdevice drivers.
API applies to the ADSP-2116x, ADSP-2126x, andL The
ADSP-2136x, ADSP-2137x, and ADSP-2146x SHARC
processors.
ParametersinMask specifies which bits should be set in the IMASK interrupt mask.
inLMask specifies which bits should be set in the LMASK interrupt mask.

5-218

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

Scheduling
Does not invoke the scheduler
Determinism
Not deterministic
Return ValueNo return value
Errors Dispatched
Full instrumentation and error-checking libraries:•

kInvalidMaskBit if any of the bits in inLmask do not refer to aninterrupt mask
Non error-checking libraries: none

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-219

VDK API Validity

SetMessagePayload()
C Prototype
void VDK_SetMessagePayload(VDK_MessageID

inMessageID,

int

inPayloadType,unsigned int

inPayloadSize,

void*inPayloadAddr);

C++ Prototype
void VDK::SetMessagePayload(VDK::MessageID

inMessageID,

int

inPayloadType,unsigned int

inPayloadSize,

void*inPayloadAddr);

Description
Sets the values in a message header that describes the payload. The meaning of these values is application-specific and corresponds to thearguments passed to CreateMessage(). This function overwrites the existing values in the message. Only the thread that is the owner of a message
may set the attributes of its payload.
ParametersinMessageID specifies the message to be modified (see MessageID).
inPayloadType is an application-specific value that may be used todescribe the contents of the payload. Negative values of payload type arereserved for use by VDK.
inPayloadSize indicates the size of the payload in the smallest addressable

units of the processor (sizeof(char)).
inPayloadAddr is (typically) a pointer to the beginning of the payload

buffer.

5-220

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return ValueNo return value
Errors Dispatched
Full instrumentation and error-checking libraries:•

kInvalidMessageOwner indicates the running thread is not the cur-rent owner of the message•

kInvalidMessageID indicates the argument inMessageID is not avalid MessageID•

kMessageInQueue indicates the message is posted to a thread (theThreadID is not known at this point), and the message needs to be

removed from the message queue by a call to PendMessage()
Non error-checking libraries: none

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-221

VDK API Validity

SetPriority()
C Prototype
void VDK_SetPriority(const VDK_ThreadID

inThreadID,

const VDK_Priority

inPriority);

C++ Prototype
void VDK::SetPriority(const VDK::ThreadID

inThreadID,

const VDK::Priority

inPriority);

Description
Dynamically sets the Priority of the named thread while overriding thedefault value. All threads are given an initial priority level at creation time.
The thread’s template specifies the priority initial value.
Parameters
inPriority of type Priority is the new priority level.
inThreadID of type ThreadID is the thread to modify.

Scheduling
Invokes the scheduler and may result in a context switch
Determinism
Not deterministic
Return ValueNo return value

5-222

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

Errors Dispatched
Full instrumentation and error-checking libraries:•

kUnknownThread indicates inThreadID is not a valid ThreadID•

kInvalidPriority indicates inPriority is not a valid Priority•

kInvalidThread indicates inThreadID specified the Idle Thread

Non error-checking libraries: none

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-223

VDK API Validity

SetThreadError()
C Prototype
void VDK_SetThreadError(VDK_SystemError inErr, int inVal);C++ Prototype
void VDK::SetThreadError(VDK::SystemError inErr, int inVal);

Description
Sets the running thread’s error value.
ParametersinErr is the error enumeration. See SystemError for more information

about errors.
inVal is the value whose meaning is determined by the error enumeration.

Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return ValueNo return value
Errors Dispatched
None

5-224

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

SetThreadSlotValue()
C Prototypebool VDK_SetThreadSlotValue(int inSlotNum, void *inValue);

C++ Prototypebool VDK::SetThreadSlotValue(int inSlotNum, void *inValue);

Description
Sets the value in the currently running thread’s slot table associated with
inSlotNum. Returns FALSE if (and only if) inSlotNum does not identify acurrently allocated slot. Otherwise, stores inValue in the thread slot identified by inSlotNum and returns TRUE.
Parameters
inSlotNum is the static library’s preallocated slot number.
inValue is the value to store in thread’s slot table (at inSlotNum entry).

Scheduling
Does not invoke the scheduler
Determinism
Constant time
Return Value
FALSE if inSlotNum does not identify a currently allocated slot and TRUE
otherwise

Errors Dispatched
None

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-225

VDK API Validity

SetTickPeriod()
C Prototype
void VDK_SetTickPeriod(float inPeriod);

C++ Prototype
void VDK::SetTickPeriod(float inPeriod);

Description
Sets the tick period to inPeriod milliseconds. The clock is stopped, theclock parameters are recalculated using the new value for tick period, andthen the clock is restarted.
Parameters
inPeriod is the new value for the tick period in milliseconds.

Scheduling
Does not invoke the scheduler
Determinism
Not deterministic
Return ValueNo return value
Errors Dispatched
None

5-226

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

Sleep()C Prototype
void VDK_Sleep(VDK_Ticks inSleepTicks);

C++ Prototype
void VDK::Sleep(VDK::Ticks inSleepTicks);

Description
Causes a thread to pause execution for at least the given number of VDK
Ticks, where each tick represents one occurrence of the VDK Timer ISR.
Once the number of sleep ticks have elapsed, the calling thread returns to
the ready-to-run state and resumes execution only when it is the highest-priority ready thread.
The minimum number of ticks that can be given as an argument toSleep() is 1. A call to Sleep() with a timeout of 1 tick causes the current

thread to enter a sleeping state until the next time the Timer ISR executes.
Depending on the timing of the call to Sleep(), the Timer ISR can execute between 0 and <Timer Period> ms after the call to Sleep(). The
reason for this is that the timer interrupt can be about to expire when thecall to Sleep() is made. In general, if you make a call to Sleep() with atimeout of N, the thread enters a sleeping state for a time between<Timer Period> * (N - 1) and <Timer Period> * N, depending on theexact timing of the call to Sleep().
Parameters
inSleepTicks is a value less than INT_MAX that specifies the duration (inTicks) for the thread “sleep”.

Scheduling
Invokes the scheduler and results in a context switch

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-227

VDK API Validity

Determinism
Not deterministic
Return ValueNo return value
Errors Dispatched
Full instrumentation and error-checking libraries:•

kBlockInInvalidRegion indicates Sleep() is being called in an
unscheduled region, causing a scheduling conflict•kInvalidDelay indicates inSleepTicks is not within the valid

range of 1 to (INT_MAX — 1)
Non error-checking libraries: none

5-228

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

SyncRead()
C Prototype
unsigned int VDK_SyncRead(VDK_DeviceDescriptor

inDD,

char

*outBuffer,const unsigned int

inSize,VDK_Ticks

inTimeout);

C++ Prototype
unsigned int VDK::SyncRead(VDK::DeviceDescriptor

inDD,

char

*outBuffer,const unsigned int

inSize,

VDK::Ticks

inTimeout);

Description
Invokes the read functionality of the driver
Parameters
inDD is the DeviceDescriptor returned from OpenDevice().
outBuffer is the address of the data buffer filled by the device.
inSize is the number of words read from the device.
inTimeout is the number of Ticks before timeout occurs.

Scheduling
Does not call the scheduler, but the user-written device driver can call thescheduler

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-229

VDK API Validity

Determinism
Constant time. Note that this function calls user-written device drivercode that may not be deterministic.
Return Value
Returns the dispatch function’s value if the device exists. Otherwise, SyncRead() returns the return value of the current thread’s Error function for
kBadDeviceDescriptor if the thread’s Error function does not go to
KernelPanic.
Errors Dispatched
Full instrumentation and error-checking libraries:•

kBadDeviceDescriptor indicates that inDD is not a valid
DeviceDescriptor

Non error-checking libraries: none
Other errors can be dispatched by user-written device driver code
L executedby this API.

5-230

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

SyncWrite()
C Prototype
unsigned int VDK_SyncWrite(VDK_DeviceDescriptor

inDD,

char

*outBuffer,const unsigned int

inSize,VDK_Ticks

inTimeout);

C++ Prototype
unsigned int VDK::SyncWrite(VDK::DeviceDescriptor

inDD,

char

*outBuffer,const unsigned int

inSize,

VDK::Ticks

inTimeout);

Description
Invokes the write functionality of the driver
Return Value
Returns the dispatch function’s value if the device exists. Otherwise, SyncWrite() returns the return value of the current thread’s Error function for
kBadDeviceDescriptor if the thread’s Error function does not go to
KernelPanic.
Parameters
inDD is the DeviceDescriptor returned from OpenDevice().
outBuffer is the address of the data buffer read by the device.
inSize is the number of words written to the device.
inTimeout is the number of Ticks before timeout occurs.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-231

VDK API Validity

Scheduling
Does not call the scheduler, but the use- written device driver can call thescheduler
Determinism
Constant time. Note that this function calls user-written device drivercode that may not be deterministic.
Errors Dispatched
Full instrumentation and error-checking libraries:•

kBadDeviceDescriptor indicates that inDD is not a valid
DeviceDescriptor

Non error-checking libraries: none
Other errors can be dispatched by user-written device driver code
L executedby this API.

5-232

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

Yield()C Prototype
void VDK_Yield(void);

C++ Prototype
void VDK::Yield(void);

Description
Yields control of the processor and moves the thread to the end of the wait
queue of threads at its priority level. When Yield() is called from a thread
at a priority level using round-robin multithreading, the call also yields
the remainder of the thread’s time slice.
Parameters
None
Scheduling
Invokes the scheduler and may result in a context switch
Determinism
Constant time and conditional context switch
Return ValueNo return value
Errors Dispatched
Full instrumentation and error-checking libraries:•

kBlockInInvalidRegion indicates that Yield() is called in an

unscheduled region, causing a scheduling conflict

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-233

VDK API Validity

Non error-checking libraries: none

5-234

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

Assembly Macros and C/C++ ISR APIs
This section describes the assembly-language macros and C/C++ ISR APIs
that allow Interrupt Service Routines (ISRs) to communicate with VDK.
These are known collectively as the ISR API and are the only part of VDK
that can be safely called from interrupt level.
In VDK applications, ISRs should execute quickly and should leave as
much of the processing as possible to be performed either by a thread orby a device driver activation. The principle purpose of the ISR API is
therefore to provide the means to initiate such (thread or driver) activity.
In VisualDSP++ 3.5 and earlier releases, VDK provides direct support for
ISRs written in assembly language only. Starting with VisualDSP++ 4.0
release, VDK supports ISRs written in assembly and C/C++.
Writing ISRs in assembly eliminates the overhead of saving and restoring
the processor state, and of setting up a C run-time environment for each
ISR entry. Assembly ISRs are responsible for saving and restoring any registers that they use. No assumptions can be made about the processor stateat the time of entry to an ISR. Each ISR assembly macro saves and restores
all of the registers that it uses, and the macros are safe to use with nested
interrupts enabled.
The ISR assembly macros are:•VDK_ISR_ACTIVATE_DEVICE_()•VDK_ISR_CLEAR_EVENTBIT_()•VDK_ISR_LOG_HISTORY_()•VDK_ISR_POST_SEMAPHORE_()•VDK_ISR_SET_EVENTBIT_()

Writing ISRs in C/C++ may simplify the coding of these routines. However, it must be remembered that there is a performance cost associatedVisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-235

VDK API Validity

with executing ISRs that have been written in C/C++. Additionally, it
should be noted that the majority of the run-time library is not interrupt-safe and so can not be used in ISRs (see the VisualDSP++ 5.0 C/C++
Compiler and Libraries Manual for details).
The VDK APIs callable from C/C++ ISRs are:

5-236

•

C_ISR_ActivateDevice()•

C_ISR_ClearEventBit()•

C_ISR_PostSemaphore()•

C_ISR_SetEventBit()

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

VDK_ISR_ACTIVATE_DEVICE_()
Prototype
VDK_ISR_ACTIVATE_DEVICE_(VDK_IOID inID);

Description
Executes the named device driver prior to execution returning to thethread domain
ParametersinID specifies the device driver to run (see IOID).

Scheduling
Invokes the scheduler prior to returning to the thread domain
Determinism
Constant timeErrors Dispatched
Full instrumentation and error-checking libraries:• Goes to KernelPanic with a g_KernelPanicCode of kISRError anda g_KernelPanicError of kBadIOID if inID is greater than the maximum number of I/O objects allowed in the system
Non error-checking libraries: none

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-237

VDK API Validity

VDK_ISR_CLEAR_EVENTBIT_()
Prototype
VDK_ISR_CLEAR_EVENTBIT_(VDK_EventBitID inEventBit);

Description
Clears the value of inEventBit by setting it to 0 (FALSE). All event bit
clears that occur in the interrupt domain are processed immediately prior
to returning to the thread domain.
ParametersinEventBit specifies the event bit to clear (see EventBitID).

Scheduling
If inEventBit is currently set (1), the macro invokes the scheduler prior to
returning to the thread domain. This allows the value of all dependent
events to be recalculated and may cause a thread context switch.
Determinism
Constant timeErrors Dispatched
Full instrumentation and error-checking libraries:• Goes to KernelPanic with a g_KernelPanicCode of kISRError anda g_KernelPanicError of kUnknownEventBit if the value ofinEventBit is greater than the number of event bits used in thesystemNon error-checking libraries: none

5-238

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

VDK_ISR_LOG_HISTORY_()
Prototype
VDK_ISR_LOG_HISTORY_(VDK_HistoryEnum

inEnum,int

inVal,

VDK_ThreadID

inThreadID);

Description
Adds a record to the history buffer. It is NULL if theVDK_INSTRUMENTATION_LEVEL_ macro is set to 0 or 1. The value of 2 indicates that fully instrumented libraries are in use. See online Help for more
information.
Parameters
inEnum is the enumeration value for this type of event. For more informa-tion, see HistoryEnum.
inVal is the information defined by the enumeration.
inThreadID is the ThreadID stored with History Event.

Scheduling
Does not invoke the scheduler
Determinism
Constant timeErrors Dispatched
None

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-239

VDK API Validity

VDK_ISR_POST_SEMAPHORE_()
Prototype
VDK_ISR_POST_SEMAPHORE_(VDK_SemaphoreID inSemaphoreID);

Description
Posts the named semaphore. Every time a semaphore is posted, its countincreases until it reaches its maximum value, as specified on creation. Any
further posts have no effect. All semaphore posts that occur in the interrupt domain are processed immediately prior to returning to the thread
domain.
Parameters
inSemaphoreID specifies the semaphore to post (see SemaphoreID).

Scheduling
If a thread is pending on inSemaphoreID, the macro invokes the scheduler
prior to returning to the thread domain
Determinism
Constant timeErrors Dispatched
Full instrumentation and error-checking libraries:• Goes to KernelPanic with a g_KernelPanicCode of kISRError anda g_KernelPanicError of kUnknownSemaphore if inSemaphoreID isgreater than the maximum number of semaphores allowed in thesystemNon error-checking libraries: none

5-240

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

VDK_ISR_SET_EVENTBIT_()
Prototype
VDK_ISR_SET_EVENTBIT_(VDK_EventBitID inEventBit);

Description
Sets the value of inEventBit (see EventBitID) by setting it to 1 (TRUE). All
event bit sets that occur in the interrupt domain are processed immediately prior to returning to the thread domain.
ParametersinEventBit of type EventBitID specifies the event bit to set.

Scheduling
If inEventBit is currently clear (zero), the macro invokes the scheduler
prior to returning to the thread domain. This allows the value of alldependent events to be recalculated and may cause a thread context
switch.
Determinism
Constant timeErrors Dispatched
Full instrumentation and error-checking libraries:• Goes to KernelPanic with a g_KernelPanicCode of kISRError anda g_KernelPanicError of kUnknownEventBit if the value ofinEventBit is greater than the number of event bits used in thesystemNon error-checking libraries: none

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-241

VDK API Validity

C_ISR_ActivateDevice()
C Prototype
void VDK_C_ISR_ActivateDevice(VDK_IOID inID);

C++ Prototype
void VDK::C_ISR_ActivateDevice(VDK::IOID inID);

Description
Executes the named device driver prior to execution returning to thethread domain.
ParametersinID specifies the device driver to run (see IOID).

Scheduling
Invokes the scheduler prior to returning to the thread domain
Determinism
Constant time
Return ValueNo return value
Errors Dispatched
Full instrumentation and error-checking libraries:• Goes to KernelPanic with a g_KernelPanicCode of kISRError anda g_KernelPanicError of kBadIOID if inID is greater than the maximum number of I/O objects allowed in the system

5-242

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

Non error-checking libraries: none

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-243

VDK API Validity

C_ISR_ClearEventBit()
C Prototype
void VDK_C_ISR_ClearEventBit(VDK_EventBitID inEventBitID);

C++ Prototype
void VDK::C_ISR_ClearEventBit(VDK::EventBitID inEventBitID);

Description
Clears the value of inEventBitID (see EventBitID) by setting it to 0
(FALSE). All event bit clears that occur in the interrupt domain are processed immediately prior to returning to the thread domain.
ParametersinEventBitID of type EventBitID specifies the event bit to clear.

Scheduling
If inEventBitID is currently set (1), the macro invokes the scheduler prior
to returning to the thread domain. This allows the value of all dependent
events to be recalculated and may cause a thread context switch.
Determinism
Constant time
Return ValueNo return value

5-244

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

Errors Dispatched
Full instrumentation and error-checking libraries:• Goes to KernelPanic with a g_KernelPanicCode of kISRError anda g_KernelPanicError of kUnknownEventBit if the value ofinEventBit is greater than the number of event bits used in thesystemNon error-checking libraries: none

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-245

VDK API Validity

C_ISR_PostSemaphore()
C Prototype
void VDK_C_ISR_PostSemaphore(VDK_SemaphoreID inSemaphoreID);

C++ Prototype
void VDK::C_ISR_PostSemaphore(VDK::SemaphoreID inSemaphoreID);

Description
Posts the named semaphore. Every time a semaphore is posted, its countincreases until it reaches its maximum value, as specified on creation. Any
further posts have no effect. All semaphore posts that occur in the interrupt domain are processed immediately prior to returning to the thread
domain.
Parameters
inSemaphoreID of type SemaphoreID specifies the semaphore to post.

Scheduling
If a thread is pending on inSemaphoreID, the scheduler is invoked prior to
returning to the thread domain
Determinism
Constant time
Return ValueNo return value

5-246

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

Errors Dispatched
Full instrumentation and error-checking libraries:• Goes to KernelPanic with a g_KernelPanicCode of kISRError anda g_KernelPanicError of kUnknownSemaphore if inSemaphoreID isgreater than the maximum number of semaphores allowed in thesystemNon error-checking libraries: none

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-247

VDK API Validity

C_ISR_SetEventBit()
C Prototype
void VDK_C_ISR_SetEventBit(VDK_EventBitID inEventBitID);

C++ Prototype
void VDK::C_ISR_SetEventBit(VDK::EventBitID inEventBitID);

Description
Sets the value of inEventBitID by setting it to 1 (TRUE). All event bit setsthat occur in the interrupt domain are processed immediately prior to
returning to the thread domain.
ParametersinEventBitID of type EventBitID specifies the event bit to set.

Scheduling
If inEventBitID is currently clear (zero), the macro invokes the scheduler
prior to returning to the thread domain. This allows the value of alldependent events to be recalculated and may cause a thread context
switch.
Determinism
Constant time
Return ValueNo return value

5-248

VisualDSP++ 5.0 Kernel (VDK) User’s GuideVDK API Reference

Errors Dispatched
Full instrumentation and error-checking libraries:• Goes to KernelPanic with a g_KernelPanicCode of kISRError anda g_KernelPanicError of kUnknownEventBit if the value ofinEventBit is greater than the number of event bits used in thesystemNon error-checking libraries: none

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

5-249

VDK API Validity

5-250

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

A PROCESSOR-SPECIFICNOTESThis appendix provides processor-specific information for Blackfin,
SHARC and TigerSHARC processors.
This section describes:• “VDK for Blackfin Processors” on page A-1• “VDK for SHARC Processors” on page A-11
• “VDK for TigerSHARC Processors” on page A-23

VDK for Blackfin Processors
This section provides information relevant to the ADSP-BF504,
ADSP-BF504F ADSP-BF506F, ADSP-BF512, ADSP-BF514,
ADSP-BF516, ADSP-BF518, ADSP-BF522, ADSP-BF523,
ADSP-BF524, ADSP-BF525, ADSP-BF526, ADSP-BF527,
ADSP-BF531, ADSP-BF532, ADSP-BF533, ADSP-BF534,
ADSP-BF535, ADSP-BF536, ADSP-BF537, ADSP-BF538,
ADSP-BF539, ADSP-BF542, ADSP-BF544, ADSP-BF548,
ADSP-BF549, ADSP-BF561, and ADSP-BF592-A processors.

User and Supervisor Modes
The Blackfin processor’s architecture makes a distinction between execution in user and supervisor modes. However, all VDK application coderuns entirely in supervisor mode, including all user thread code.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

A-1

VDK for Blackfin Processors

Since supervisor mode provides a superset of the capabilities of user mode,applications using VDK do not need to be aware of the processor modeand do not need to raise exceptions in order to access protected resources.

Thread, Kernel, and Interrupt Execution Levels
VDK reserves execution level 15 as the run-time execution level for mostuser and VDK API code, and reserves execution level 14 for internal VDK
operations. In the following text, these are referred to as “thread level” and“kernel level”, respectively. Execution levels 13–6 are collectively referred
to as “interrupt level”. All of these levels (15–6) execute in supervisormode.
All thread functions execute at thread level (execution level 15), including
Run() and ErrorHandler(). Conversely, all Interrupt Service Routines(ISRs) execute at higher priority (lower numbered) execution levels,
according to the interrupt source that invoked them. The implementation
function for device drivers (their single entry point) may be called by the
kernel at either thread level (execution level 15) or at kernel level (execution level 14), depending on the purpose of the call.
Device driver “activate” functionality (kIO_Activate) is the only user codethat executes at kernel level. All other device driver code executes at threadlevel. Entry to kernel level is, in this case, initiated by an ISR calling
VDK_ISR_ACTIVATE_DEVICE_() or C_ISR_ActivateDevice() and is, therefore, asynchronous with respect to thread level, except within a criticalregion. Thus, care must be taken to synchronize access to shared data
between thread level and kernel level, as well as between thread level andinterrupt level (and also between kernel level and interrupt level). Criticalregions may be used for both of these purposes.
As VDK runs entirely in supervisor mode, system memory-mapped registers (MMRs) can be accessed directly and at any time. It is, however, theuser’s responsibility to ensure the operations are performed correctly andat appropriate times.

A-2

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Processor-Specific Notes

Exceptions
VDK reserves user exception 0 (EXCPT 0) for internal use.
The IDDE automatically adds a source file to all VDK projects for Blackfin processors. The source file contains template code for a user exception
handler and defines an entry point for any service or error exceptions you
wish to trap. When an exception occurs, VDK intercepts the exception. If
it is not the VDK exception, VDK will try to determine whether the
exception is a CPLB miss, in which case cplb_hdr will be invoked. If VDKcannot identify the exception as either VDK or a CPLB miss, then theuser exception handler executes.
The VDK User Exception handler does not return from jumps to either
UserExceptionHandler or cplb_hdr, so short jumps must be used to avoid
potential corruption of the P1 register. Because of this, the LDF must set
the sections L1_code and cplb_code close in memory to avoid link errors.

ISR API Assembly Macros
The Blackfin processor’s assembly syntax requires the use of separate API
macros, depending on whether the arguments are constants (immediate
values, enumerations) or data registers (R0 through R7). The arguments tothe default assembly macros, described in Chapter 5, “VDK API Reference”, must be constants. When passing data registers as arguments,
append “REG_” to the macro name as follows:
VDK_ISR_POST_SEMAPHORE_REG_(semaphore_num_);
VDK_ISR_ACTIVATE_DEVICE_REG_(dev_num_);
VDK_ISR_SET_EVENTBIT_REG_(eventbit_num_);
VDK_ISR_CLEAR_EVENTBIT_REG_(eventbit_num_);
VDK_ISR_LOG_HISTORY_REG_(enum_, value_, threadID_);

The assembly macros, as defined in “Assembly Macros and C/C++ ISRAPIs” (without “REG_”), only accept constants as arguments. Passing a register name results in an assembler error.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

A-3

VDK for Blackfin Processors

Interrupts
The following hardware events (interrupts) are reserved by default for use
by VDK on Blackfin processors.
•

EVT_EVX – the software exception handler. User code handles soft-

ware exceptions by modifying the source file created by
VisualDSP++ named ExceptionHandler-<processor_name>.asm,
for example ExceptionHandler-BF533.asm.
•

EVT_IVTMR – the interrupt associated with the timer integral to theprocessor core. This timer generates the interrupts for system ticks
and provides all VDK timing services. Disabling the timer stops
sleeping, round-robin scheduling, pending with timeout, periodic
semaphores, and meaningful VDK history logging. The interrupt
dedicated for the timer can be changed or set to none on the Kerneltab.
•

EVT_IVG14 – general interrupt #14. This interrupt is reserved foruse by VDK and may not be used in any other manner.
•

EVT_IVG15 – general interrupt #15. This interrupt is reserved toprovide a supervisor mode runtime for user and VDK code andmay not be used in any other manner.
Blackfin processors designate hardware events seven (EVT_IVG7) throughthirteen (EVT_IVG13) as “general interrupts” and maps each to more than
one physical peripheral. The IDDE generates source code templates with asingle entry point per interrupt level, rather than for each peripheral.
Therefore, you are responsible for dispatching interrupts when more than
one peripheral is used at the same level. The technique used depends on
the application, but, typically, either chaining or a jump table is used.
When chaining, a handler will check to see whether the interrupt wascaused by the specific peripheral it knows how to handle. If not, execution
is passed to the next handler in the chain. A jump table uses an identifier

A-4

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Processor-Specific Notes

or a constant as an index to a table of function pointers when searching forthe appropriate interrupt handler.
Due to the nature of the non-maskable interrupt (EVT_NMI), the VDK ISR
APIs cannot be used in ISRs that service the NMI interrupt.
Blackfin processors, it is possible to manipulate the
L On
ter directly, rather than being restricted to the

IMASK regis-

SetInterruptMaskBits() or ClearInterruptMaskBits() API. This

direct manipulation is not permitted in boot thread constructors ordevice drivers’ Init() functions.
It is recommended that the System Services initialization is done inmain() after a call to VDK_Initialize() in C or VDK::Initialize() in C++ because many of the System Services initialization
APIs modify IMASK directly. See “VDK and main()” on page 3-2
for more information.

Timer
VDK Ticks are derived from the timer implemented in the inner processor core of Blackfin processors and are synchronized to the main coreclock CCLK. However, this timer is disabled when a Blackfin processor
enters low power mode. Thus, all VDK timing services (such as sleeping,timeouts, and periodic semaphores) do not operate while the core is in
IDLE or low power mode. By default, VDK does not use or modify thegeneral-purpose timers.
On Blackfin processors, you can register interrupts with the run-time
library function register_handler() or the system services API
adi_int_CECHook(), with no need to declare the interrupts in the VDK
Kernel tab. Interrupts registered outside VDK must not use the same IVG
level as any interrupt defined in the VDK Kernel tab.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

A-5

VDK for Blackfin Processorsthat VDK is fully initialized before an interrupt that uses
[ ToVDKensure
signals is serviced, do not callorregister_handler()

adi_int_CECHook() before the Run() function of the highest prior-

ity boot thread is reached (or before the VDK::Run() function if
VDK’s main() has been replaced).
not use[ Do
VDK. Calling

adi_int_CECHook for the interrupt levels reserved by
adi_int_CECHook on interrupt levels 3, 14, or 15 ina VDK application returns an error if the application uses the System Services Debug Libraries. If the application uses the Release
System Services libraries, then the VDK interrupts may be overwritten, and the application may not work as intended.

Idle Thread
As specified in “Idle Thread” on page 3-18, the idle thread frees theresources of threads that have been destroyed. After this, the VDK idle
thread loops indefinitely and does not make the processor enter low power
mode. The reason for this is that the core timer stops when the processor
idles, stopping the operation of the VDK timing services.

Blackfin Processor Memory
The default VDK linker description files for Blackfin processors(VDK-BF531.ldf, VDK-BF532.ldf, etc.) place code, data, and the system
heap into default memory areas. These default assignments can bechanged by customizing the .ldf file used by a project. Refer to the
VisualDSP++ 5.0 Linker and Utilities Manual for details on how to do
this. An alternative mapping is included in the default .ldf files, whichuses part or all of the L1 SRAM as cache (assumes that external memory ispresent). However, caching of code and data is not enabled by default. For
details on how to enable and configure caching, see the VisualDSP++ 5.0
C/C++ Compiler and Library Manual for Blackfin Processors.

A-6

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Processor-Specific Notes

Thread StackFor efficiency in the Blackfin architecture, VDK needs to store the thread
context on the thread stack. For this reason, the thread stack is made 45
words larger than specified in the Kernel tab. The Stack Size field in the
VDK Status window displays the size of memory allocated for both stackand context, so it differs from the thread stack size value entered in the
Kernel tab.

Interrupt Nesting
VDK fully supports nested interrupts:• The skeleton Interrupt Service Routines, which are generated by
the VisualDSP++ 5.0 IDDE for user-defined interrupt handlers,
include instructions to enable the nesting of interrupts if required.
• The VDK ISR API is fully reentrant.

System Stack
There are two types of a VDK stack: thread and system. The thread stackis allocated on a per-thread basis, and the stack’s memory resources areallocated from the heap. Thread stack usage by interrupts on Blackfin processors is described in the following section.
The system stack is used for most kernel operations, such as the initialization of VDK and thread scheduling. The following text describes whenVDK uses the system stack, and some considerations for determining thesystem stack requirements for an application:• At startup, the system stack is used from the system reset address to
the Run() function of the first boot thread. This includes the initialization of the C/C++ runtime environment, global variable

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

A-7

VDK for Blackfin Processors

constructors, the initialization of VDK, constructors for VDK C++
boot threads, the InitFunction() for C/assembly boot threads, andthe Init section for any boot IO objects.
• Once the first boot thread has started to execute, the system stack isused only for short periods during VDK thread scheduling and forany deferred procedure calls. VDK uses deferred procedure calls forinternal updates, such as timeouts, and for some user-configurable
deferred procedure calls, which include:• The “activate” part of VDK device drivers• Any system services deferred callbacks• Interrupts can occur while VDK is using the system stack. There
should be enough space configured for the system stack to accommodate the stack requirements for any of the ISRs in the system (ifany interrupts can be nested, then the amount of the required system stack also increases). This applies to C, C++, and assemblyinterrupts.

Thread Stack Usage by Interrupts
Because all thread code executes in supervisor mode, there is no automatic
switching between user and system stack pointers. Therefore, all ISRs execute using the stack of the current thread, which is the thread that is
executing at the time the interrupt is serviced. This means each thread
stack must—in addition to the thread’s own requirements—reserve sufficient space for the requirements of ISRs. This is also applicable to the Idle
thread’s stack and the size of the Idle thread’s stack can be configured
within the IDDE (see online Help for further information). When interrupt nesting is enabled, the worst-case space requirement is the total of therequirements of the individual ISRs. When nesting is disabled, therequirement is only the largest of the individual ISR requirements, which
is one possible reason for disabling interrupt nesting.

A-8

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Processor-Specific Notes

Interrupt Latency
Every effort has been made to minimize the duration of the intervals inwhich interrupts are disabled by VDK. Interrupts are disabled only where
necessary for synchronization with interrupt level and for the shortest feasible number of instructions. The instruction sequences executed during
these interrupts-off periods are deterministic. It is, therefore, quite possible that the worst-case interrupts-off time will be set by critical regions inuser code. Ensure that such usage does not impact the interrupt latency ofthe system to an unacceptable degree.
Within VDK itself, synchronization between thread level and kernel levelis achieved by selectively masking the kernel level interrupt, while leaving
the higher priority interrupts unmasked.

Multiprocessor Messaging
The dual-core ADSP-BF561 processor is the only processor in the Blackfin family for which out-of-the-box multiprocessor messaging support isprovided. A device driver that uses the two Internal Memory DMA(IMDMA0 and IMDMA1) channels for communication between the two cores is
included under the examples directories in the VisualDSP++ 5.0
installation.
Because the IMDMA channels only support L1 and L2 memory, care needs
to be exercised if external memory (SDRAM) is also in use. Memory payloads placed in external memory cannot be written or read by the IMDMA
device driver and, therefore, cannot automatically be transferred by themarshalling functions. However, since external memory is visible to bothcores at the same addresses, it is not normally necessary to copy the payload contents between the cores. Provided that the application is carefully
designed, it should be possible to pass the payload address and size as an
unmarshalled payload type and to access the payload contents in placefrom either core. This is also the more efficient solution.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

A-9

VDK for Blackfin Processors

Also because IMDMA channels only support L1 and L2 memory, therouting threads’ stacks must be allocated from a heap that is in L1 or L2
memory (as in VDK’s default configuration). In Lwip projects, the system
heap is in SDRAM by default, so if multi-processor messaging is required,users must configure an extra heap in L1 or L2 and modify the VDK Kernel tab so the routing threads’ stacks are allocated from the heap ininternal memory.
Note that there is no cache-coherency between the two cores of the
ADSP-BF561 processor. Therefore, if caching is enabled, then any memory regions that are accessed from both cores (this applies both to L2
memory and to external SDRAM) must be defined as uncached in the
CPLB tables. See the “Caching and Memory Protection” section in the
VisualDSP++ 5.0 C/C++ Compiler and Library Manual for Blackfin Processors for more information about CPLBs.
Additionally, the thread stacks for Routing Threads must not be placed inexternal memory. This is because the buffer structures used for the transmission and reception of message packets are stored on the stack—thesemust be located in either L1 or L2 memory.

Stack Overflow
Stack overflow is a particularly common problem in multi-threaded applications where thread stacks sizes are fixed at build time. Space restrictions
normally mean that the thread stack sizes are squeezed to the minimum
necessary, which can cause stack overflows when circumstances (such as
timing) change.
From VisualDSP++ 5.0 update 9 onwards, the Blackfin compiler provides
facilities to detect stack overflows (the -stack-detect switch is used toenable stack overflow detection). The compiler facilities rely on a global
structure being updated at all points to get information about the stack
being used. In a multi-threaded application, this means having to context-switch the structure every time the current thread changes.

A-10

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Processor-Specific Notes

Not to make the context switching slower if you do not require stack overflow detection, VDK provides a specific version of its context switch thatmust be used if stack overflow detection is enabled.
To select the correct VDK context switch for your application, your project’s LDF must be updated to include the following code (or equivalent
for your particular LDF).
#ifdef _ADI_SOV_DETECTION
TMK-BF532_sov.dlb,#else
TMK-BF532.dlb,#endif

You can find this code in the default VDK LDF in your VisualDSP++ 5.0
update 9 (or later) installation folder. If you do not apply this change tothe LDF while enabling stack overflow detection, your application will
result in a KernelPanic.
In case of a stack overflow being detected, the compiler calls the
adi_stack_overflowed function, which, in VDK case, calls KernelPanic
with panic code kStackCheckFailure.
For more information about the Blackfin compiler stack overflow detection, see the C/C++ Compiler Manual for SHARC Processors.

VDK for SHARC Processors
This section provides information relevant to the use of VDK on
ADSP-21060, ADSP-21061, ADSP-21062, ADSP-21065L,
ADSP-21160, ADSP-21161, ADSP-21261, ADSP-21262, ADSP-21266,
ADSP-21267, ADSP-21362, ADSP-21363, ADSP-21364, ADSP-21365,
ADSP-21366, ADSP-21367, ADSP-21368, ADSP-21369, ADSP-21371,
ADSP-21375, ADSP-21462, ADSP-21465, ADSP-21467, ADSP-21469,
ADSP-21472, ADSP-21475, ADSP-21478, ADSP-21479, ADSP-21481,

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

A-11

VDK for SHARC Processors

ADSP-21482, ADSP-21483, ADSP-21485, ADSP-21486, ADSP-21487,
ADSP-21488, and ADSP-21489 processors.

Thread, Kernel and Interrupt Execution Levels
VDK runs most user and VDK API code at the normal (non-interrupt)
execution level but also reserves one of the low-priority interrupt levels forinternal VDK operations. In the following text, these are referred to as“thread level” and “kernel level”, respectively. The remaining interrupt
levels are collectively referred to as “interrupt level.”
All thread functions execute at thread level, including Run() andErrorHandler(). Conversely, all Interrupt Service Routines execute at
higher-priority execution levels according to the interrupt source thatinvoked them. The implementation function for device drivers (their single entry point) may be called by the kernel at either thread level or atkernel level, depending on the purpose of the call.
Device driver “activate” (kIO_Activate) functionality is the only user code
which executes at kernel level (all other device driver code executes atthread level). Entry to kernel level is, in this case, initiated by an ISR calling VDK_ISR_ACTIVATE_DEVICE_() or C_ISR_ActivateDevice() and is,therefore, asynchronous with respect to thread level (except within a critical region). For this reason, care must be taken to synchronize access toshared data between thread level and kernel level, as well as between
thread level and interrupt level (and also between kernel level and interrupt level). Critical regions may be used for both of these purposes.

VDK Interrupts and Run-Time Library Interrupt
Dispatchers
VDK does not support the run-time library interrupt dispatchers
documented in the C/C++ Compiler Manual for SHARC Processors.
Instead, VDK hooks calls for the appropriate interrupt service routines

A-12

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Processor-Specific Notes

directly in the corresponding location in the interrupt vector table. Thismeans that:• For interrupt service routines written in C and C++, VDK uses
interrupt templates which use the pragmas interrupt_complete
and interrupt_complete_nesting to ensure that registers used are
saved and restored as required.
• Interrupt service routines written in assembly must save and restore
registers that they use directly or indirectly. You cannot rely on the
run-time library interrupt dispatchers to do this.
Declaring all interrupts via the VDK Kernel tab ensures that a call toappropriate interrupt service routines is placed in the corresponding
interrupt vector address in the interrupt vector table.

Interrupt Latency
Every effort has been made to minimize the duration of the intervals
where interrupts are disabled by VDK. Interrupts are disabled only where
necessary for synchronization with interrupt level, and then for the shortest feasible number of instructions. The instruction sequences executedduring these interrupts-off periods are deterministic. It is, therefore, quitepossible that the worst-case interrupts-off time will be set by criticalregions in user code. Ensure that such usage does not impact the interrupt
latency of the system to an unacceptable degree.
Within VDK itself, synchronization between thread level and kernel levelis achieved by selectively masking the kernel level interrupt, while leaving
the higher priority interrupts unmasked.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

A-13

VDK for SHARC Processors

Interrupt Nesting
VDK fully supports nested interrupts:• The skeleton Interrupt Service Routines, which are generated by
the VisualDSP++ 5.0 IDDE for user-defined interrupt handlers,
include instructions to enable the nesting of interrupts if required.
• The ISR API is re-entrant between different interrupt levels.

Interrupts on ADSP-2106x Processors
The following interrupts are reserved for use by VDK on the
ADSP-21060, ADSP-21061, ADSP-21062 and ADSP-21065L
processors.
•

TMZHI – the timer interrupt. The core timer (Timer0 on

ADSP-21065L processors) generates the interrupts for system ticks
and provides all VDK timing services. Disabling this timer stops
sleeping, round-robin scheduling, pending with timeout, periodic
semaphores, and meaningful VDK history logging. The interrupt
dedicated for the timer can be changed or set to none on the Kerneltab.
•

SFT2I and SFT3I – the kernel interrupts. These two interrupts arereserved by VDK and cannot be used in any other manner.
Note that the low priority interrupt for the timer (TMZLI) is available foruse, either as a software interrupt, or to support a second timer where one
is present in the hardware (as with ADSP-21065L processors). By default,
VDK assigns Timer1 to the low-priority timer interrupt (IRPTL/IMASK
bit 23), so using it only requires an interrupt handler to be defined for
TMZLI and for Timer1 to be initialized.

A-14

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Processor-Specific Notes

Interrupts on ADSP-2116x, ADSP-2126x,
ADSP-213xx, and ADSP-214xx Processors
The following interrupts are reserved for use by VDK on the
ADSP-21160, ADSP-21161, ADSP-21261, ADSP-21262, ADSP-21266,
ADSP-21267, ADSP-21362, ADSP-21363, ADSP-21364, ADSP-21365,
ADSP-21366, ADSP-21367, ADSP-21368, ADSP-21369, ADSP-21371,
ADSP-21375, ADSP-21462, ADSP-21465, ADSP-21467, ADSP-21469,
ADSP-21472, ADSP-21475, ADSP-21478, ADSP-21479, ADSP-21481,
ADSP-21482, ADSP-21483, ADSP-21485, ADSP-21486, ADSP-21487,
ADSP-21488, and ADSP-21489 processors.
•

TMZHI – the timer interrupt. The core timer generates the interrupts

for system ticks and provides all VDK timing services. Disabling
this timer stops sleeping, round-robin scheduling, pending withtimeout, periodic semaphores, and meaningful VDK history logging. The interrupt dedicated for the timer can be changed or set tonone on the Kernel tab.
•SFT2I and SFT3I – the kernel interrupts. These two interrupts arereserved by VDK and cannot be used in any other manner.
The ClearInterruptMaskBitsEx() and SetInterruptMaskBitsEx() APIs
must be used to manipulate the mask component of the LIRPTL register.
The status stack is automatically pushed on entry to an ISR and popped
on exit from an ISR for the following interrupts: IRQx, VIRPT and Timer.
For all other interrupts this must be performed manually in the ISR(push sts;/pop sts;). Instructions are included in the skeleton code generated when an ISR is added to a VDK project. For further details, see therelevant hardware manual or programming reference for the processor thatyou are using.
that VDK does not change the value of; although, the
L NoteC/C++ runtime startup code does modify it from the default reset
MMASK

value (see the VisualDSP++ 5.0 C/C++ Compiler Manual for

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

A-15

VDK for SHARC Processors

SHARC Processors for details). A push of the status stack will clear
the bits in the MODE1 register that have been set in MMASK by thestartup code (assuming that MMASK has not been changed by application code). This will have the effect of disabling SIMD mode.
This is significant as VDK uses SIMD mode to accelerate the context switching code. If SIMD mode is not disabled by pushing thestatus stack when required, then unexpected behavior can occur.

Timer
Where only one timer is provided by the hardware, the timer is reserved
by VDK by default for its internal timekeeping functions and may not be
used in any other manner.
Where more than one timer is provided, one timer is reserved by VDK bydefault for its internal timekeeping functions and may not be used in any
other manner. Any other timers may be used by user code.
The interrupt dedicated for the timer can be changed or set to none on the
Kernel tab. If the interrupt selected for the VDK timing services is not
TMZHI or TMZLI, VDK does not set up or use the core timer.
This timer generates the interrupts for system ticks and provides all VDKtiming services. Disabling the timer stops sleeping, round-robin scheduling, pending with timeout, periodic semaphores, and meaningful VDK
history logging.

Idle Thread
As specified in “Idle Thread” on page 3-18, the idle thread frees theresources of threads that have been destroyed. After this, the VDK idle
thread loops indefinitely and does not make the processor enter low power
mode.

A-16

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Processor-Specific Notes

MemoryBy default, the VDK .ldf files place most user and VDK code in the program section, mapped to PM memory. Certain VDK code is likely to betime-critical or likely to be used from interrupt level. VDK places thiscode in the seg_int_code section, which should be placed in internal
memory. Global and static data is placed in the data1 section, mapped to
DM memory. Certain VDK data also must be located in internal memory.
This data is placed in the internal_memory_data section; this input section must be mapped to an internal memory output section. A separate
memory region in DM memory is used for the system heap.
A system stack also exists in DM memory. This stack is used by VDK itself
for kernel-level processing. This means that whenever a device driver’s“activate” code is invoked, the system stack is in use. Therefore, ensurethat the stack size is sufficient for the requirements of user-supplied activate code. For more information, see “System Stack” on page A-20.
These default arrangements can be customized by editing the project’s.ldf file. Refer to the VisualDSP++ 5.0 Linker and Utilities Manual for
information on segmenting your code. Refer to the VisualDSP++ 5.0
C/C++ Compiler Manual for SHARC Processors for information about
defining additional heaps.
external memory port on SHARC processors supports only
L The
32-bit access. On SHARC processors, apart from the ADSP-2106x,
the VDK context-switch code uses double-word operations inorder to minimize the number of cycles required to save and restore
the register set. The code requires the context storage region to be

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

A-17

VDK for SHARC Processorsin 64-bit capable memory. By default, the system heap is used tostore the context of a thread, but this is user-configurable (seeonline Help for details).
If you wish to place the system heap in external memory, then it isessential that none of the threads’ context areas are allocated fromthe system heap, but rather a separate heap located within internal
memory. For details on declaring additional heaps refer to the
VisualDSP++ 5.0 C/C++ Compiler Manual for SHARC Processors.

Register UsageSHARC processors provide a set of alternate (or background) registers forboth the computation units and the DAGs. VDK does not save and restore
these alternate registers during context switches but instead employs themto accelerate entry to and exit from the scheduler interrupt by providing itwith a dedicated C run-time environment.
This means that the alternate registers listed in Table A-1 contain fixedvalues and must not be changed by user code.
Table A-1. SHARC Processor Alternate Registers
RegisterValue

M5’, M13’0

M6’, M14’1

M7’, M15’-1

B6’, B7’

System Stack base

L6’, L7’

System Stack length

L2’—L5’, L10’—L15’

0

Since these registers are used at interrupt level (which may be entered at
any time), it is not sufficient to save these registers and restore them afteruse, except within a critical region.

A-18

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Processor-Specific Notes

The following alternate registers are not used by VDK and are available
for use by user code:
I0’, M0’, B0’, L0’,
I1’, M1’, B1’, L1’,
I8’, M8’, B8’, L8’,
I9’, M9’, B9’, L9’,

Note that these registers do not form part of the thread context and,hence, are not context-switched between threads. Therefore, their mostappropriate use is in implementing fast I/O interrupt handlers for devices
where DMA is not available.
The remaining alternate registers:
R0’—R15’
I2’—I7’, I10’—I15’,
M2’—M4’, M10’—B12’,B2’—B5’, B10’—B15’

are used by the scheduler ISR and, hence, may change at any time (unlessinside a critical region). If these registers are to be used in a user-defined
ISR, then their contents must be saved and restored before returning fromthe interrupt, as for the primary registers.
Note that the background multiplier result register, MRB, is not considered
to be an alternate register in the above discussion, and that both MRB and
MRF are context-switched between threads.

40-bit Register Usage
The ALU registers of the SHARC processors are 40 bits in width in orderto support the 40-bit extended precision floating-point mode. However,
the C/C++ run-time environment does not support this mode and,instead, runs with 32-bit rounding enabled (bit RND32=1 in the MODE1 register). The eight additional Least Significant Bits (LSBs) of the mantissa

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

A-19

VDK for SHARC Processors

are, therefore, not used in C/C++ applications. 40-bit computations canonly be performed in assembly code. The RND32 bit should be explicitly
cleared and set around the computation code.
VDK preserves the 40-bit form of the data registers during a context
switch (but only when the RND32 bit is cleared to indicate that 40-bit arithmetic is enabled). Additionally, the VDK Timer ISR protects against
overwriting the 40-bit data registers by running in the alternate registerset.
For user ISRs created with VisualDSP++ 5.0 update 7 (or later), the VDK
C and C++ ISR templates select the new compiler pragma
save_restore_40_bits if the macro VDK_SAVE_RESTORE_40_BITS is
defined. Defining VDK_SAVE_RESTORE_40_BITS in a VDK assembly ISR
before the inclusion of the VDK.h file also ensures that the 40 bits of theregisters are saved and restored by the VDK ISR macros. Using these macros incurs in both performance and space penalties.
There is an alternative for the VisualDSP++ 5.0 update 7 (or later) users
who do not want to have the penalty and have ISRs written in assembly.
User ISRs calling the VDK ISR APIs can clear the eight additional LSBsof the F0, F1, F4, F8, and F12 registers. If the VDK ISR APIs are called,then to protect these registers from being overwritten, switch into thealternate register set for the duration of the ISR. This does not incur inany performance or space penalties. This is the only mechanism available
to the VisualDSP++ 5.0 update 6 (or earlier) users.
ISR uses the alternate registers (see “Register Usage” on
L Ifpagean A-18),
the register contents must be saved on entry to the ISR
and restored before returning.

System Stack
There are two types of a VDK stack: thread and system. The thread stackis allocated on a per-thread basis, and the stack’s memory resources areallocated from the heap. Thread stack usage by interrupts on SHARC pro-

A-20

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Processor-Specific Notes

cessors is described in “Interrupts on ADSP-2106x Processors” onpage A-14 and “Interrupts on ADSP-2116x, ADSP-2126x, ADSP-213xx,
and ADSP-214xx Processors” on page A-15.
The system stack is used for most kernel operations, such as the initialization of VDK and thread scheduling.
• At startup, the system stack is used from the system reset address to
the Run() function of the first boot thread. This includes the initialization of the C/C++ runtime environment, global variable
constructors, the initialization of VDK, constructors for VDK C++
boot threads, the InitFunction() for C/assembly boot threads, andthe Init section for any boot IO objects.
• Once the first boot thread has started to execute, the system stack isused only for short periods during VDK thread scheduling and forany deferred procedure calls. VDK uses deferred procedure calls forinternal updates, such as timeouts, and for some user-configurable
deferred procedure calls, which include any “activate” part of VDK
device drivers.
• Interrupts can occur while VDK is using the system stack. There
should be enough space configured for the system stack to accommodate the stack requirements for any of the ISRs in the system (ifany interrupts can be nested, then the amount of the required system stack also increases). This applies to C, C++, and assemblyinterrupts.

Multiprocessor Messaging
The ADSP-21060, ADSP-21062, ADSP-21160, and ADSP-21161 processors are the only processors in the SHARC processor family for which
out-of-the-box multiprocessor messaging support is provided (these being
the SHARC processor variants that include link port hardware). Device
drivers that use the link port hardware for communication between pro-

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

A-21

VDK for SHARC Processors

cessors are included under the examples directories in the
VisualDSP++ 5.0 installation.
In the example projects, device driver instances (boot I/O objects) are provided for at least two link ports. The selection of which devices to use formessage routing can be configured by the user according to the routing
topology that best fits their hardware, but the presence of two links per
node allows (at least) construction of a ring topology containing any number of nodes. Note that it is possible to use link ports bi-directionally, so
as to carry both incoming and outgoing messages over the same port.
Where two ports are available, however, the unidirectional mode may beslightly more efficient as the link hardware never needs to switch
direction.
Support for the cluster bus address space is provided via a standard marshalling type (ClusterBusMarshaller), which automatically translates
local payload addresses into multiprocessor space addresses prior to transmission in a message, and translates incoming payload addresses to local
addresses whenever the portion of the multiprocessor space corresponds tothe local processor. In an appropriately designed application, this canallow payloads to be passed by reference, rather than by copying, evenbetween processors. However, the overall efficiency of such an approach(that is, accessing payload contents in-place across the cluster bus rather
than copying to local memory) is an issue for the application designer toconsider. It is also necessary to ensure that payload memory blocks are
freed only by the processor that originally allocated them.

VDK ISR Macros
The ADSP-2136x processors introduced a five-stage pipeline that, in turn,introduced difference in behavior from previous SHARC processors as
documented in EE-342: Loop Resource Manipulation for SHARC Processors.
The EE note is available on the Analog Devices Web site.

A-22

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Processor-Specific Notes

Because of this, on the ADSP-2136x processors, the VDK ISR macros
have been modified not to push and pop any entries of the PC stack thatexist before calling the macro. This means that VDK uses an extra level in
the PC stack for each interrupt that uses the VDK ISR macros.
issues regarding pushing and popping of the PC stack within
L The
an arithmetic loop are not applicable to later SHARC processors,
such as the ADSP-2137x and ADSP-2146x.

Stack Overflow
Stack overflow is a particularly common problem in multi-threaded applications where thread stacks sizes are fixed at build time. Space restrictions
normally mean that the thread stack sizes are squeezed to the minimum
necessary, which can cause stack overflows when circumstances (such as
timing) change.
From VisualDSP++ 5.0 update 9 onwards, the SHARC compiler provides
a facility to detect stack overflows (enabled by default). The compiler uses
its own implementation of the CB7 ISR to call adi_stack_overflowed.
In the VDK case, adi_stack_overflowed then calls KernelPanic withpanic code kStackCheckFailure. If your application has its own implementation of the CB7 ISR, the interrupt is still latched and, if theinterrupt has been enabled, your own interrupt service routine is run.
For more information about the SHARC compiler stack overflow detection, see the C/C++ Compiler Manual for SHARC Processors.

VDK for TigerSHARC Processors
This section provides information relevant to the use of VDK on the
ADSP-TS101, ADSP-TS201, ADSP-TS202, and ADSP-TS203 processors. VDK supports the ADSP-TS20x processors of silicon revision 1.0
and higher.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

A-23

VDK for TigerSHARC Processors

Thread, Kernel, and Interrupt Execution Levels
VDK runs most user and VDK API code at the normal (non-interrupt)
execution level but also reserves one of the low-priority interrupt levels forinternal VDK operations. In the following text, these are referred to as“thread level” and “kernel level,” respectively. The remaining interrupt
levels are collectively referred to as “interrupt level.”
All thread functions execute at thread level, including Run() andErrorHandler(). Conversely, all Interrupt Service Routines (ISRs) executeat higher priority execution levels, according to the interrupt source thatinvoked them. The implementation function for device drivers (their single entry point) may be called by the kernel at either thread level or atkernel level, depending on the purpose of the call.
Device driver “activate” (kIO_Activate) functionality is the only user code
which executes at kernel level (all other device driver code executes atthread level). Entry to kernel level is, in this case, initiated by an ISR calling VDK_ISR_ACTIVATE_DEVICE_() or C_ISR_ActivateDevice() and is,therefore, asynchronous with respect to thread level (except within a critical region). For this reason, care must be taken to synchronize access toshared data between thread level and kernel level, as well as between
thread level and interrupt level (and also between kernel level and interrupt level). Critical regions may be used for both of these purposes.

Exceptions
VDK reserves user exception 0 (TRAP 0) for internal use.
The IDDE automatically adds a source file ExceptionHandler-<Processor_Name>.asm to all VDK projects for TigerSHARC
processors. The source file contains template code for a user exception
handler and defines an entry point for any service or error exceptions you
wish to trap. When an exception occurs, VDK intercepts the exception. If
it is not the VDK exception, then this user exception handler executes.

A-24

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Processor-Specific Notes

User exception 31 (TRAP 31) is reserved for Monitor-based debuggers. In
such debug environments, monitor code on the TigerSHARC processor
communicates with the host on which the debugger is running. Control
passes from the application running on the TigerSHARC to the monitor
code by means of a TRAP 31 instruction (which the host or the monitor
code has previously inserted into specific points in the application). The
VDK exception handler checks for the exception having been generated bya TRAP 31 instruction. If so, control transfers to the monitor code.
If you are developing a monitor-based debugger, then upon loading theuser application and monitor code onto the processor, but before starting
the application running, you should write the address of the monitor’s
main entry point into the IVSW register. If you are not developing or using
a monitor-based debugger, simply ensure that your application does not
use TRAP 31.

Interrupts
The following interrupts are reserved by default for VDK on TigerSHARC processors.
•

Timer1HP – the timer interrupt. The Timer1 generates the inter-rupts for system ticks and provides all VDK timing services.
Disabling this timer stops sleeping, round-robin scheduling, pending with timeout, periodic semaphores, and meaningful VDK
history logging. The interrupt dedicated for the timer can bechanged or set to none on the Kernel tab.
•Timer0LP (ADSP-TS101) or Kernel (ADSP-TS20x) – the kernelinterrupt. This interrupt is reserved for use by VDK and may not
be used in any other manner.
The corresponding priority levels for each timer, Timer1LP and Timer0HP,
are also reserved if the timer is being used by VDK.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

A-25

VDK for TigerSHARC Processors

Timer
On ADSP-TS101 processors, both Timer0 and Timer1 are reserved by
VDK for its internal functions and may not be used in any other manner.
On ADSP-TS20x processors, Timer1 is reserved by VDK for its internalfunctions.

Idle Thread
As specified in “Idle Thread” on page 3-18, the idle thread frees theresources of threads that have been destroyed. After this, the VDK idle
thread makes the processor enter low power mode with the idle instruction. The processor then remains in the low power mode until aninterrupt occurs.

MemoryBy default, the VDK .ldf files place most user and VDK code into a single section named program. There is certain VDK code that is time-criticalor likely to be used from interrupt level. VDK places this code in a section
VDK_ISR_code; the code should be placed in internal memory. By default,
the VDK .ldf files place global and static data into specific named sections. Other named sections are available for explicit access to specificmemory blocks.
VDK defines a primary heap (system_heap0) and a secondary heap
(system_heap1) in two different memory blocks. VDK thread stacks areallocated from heap space, and the use of two heaps allows VDK to allocate the thread J and K stacks in different memory blocks.
“System” J and K stacks are also defined in two different memory blocks.
This stack pair is used by VDK itself for kernel level processing. Thismeans that when device-driver “activate” code is invoked, it is these system stacks which are in use. Therefore, you need to ensure that the size of

A-26

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Processor-Specific Notes

these stacks is sufficient for the requirements of the user supplied activate
code.
For further information regarding the use of two stacks on TigerSHARC
processors, refer to the Compiler chapter of Compiler and Library Manual
for TigerSHARC Processors.
These default arrangements can be customized by editing the project’s
LDF file. Refer to the VisualDSP++ 5.0 Linker and Utilities Manual for
information on segmenting your code. Refer to the VisualDSP++ 5.0
C/C++ Compiler and Library Manual for TigerSHARC Processors for information about defining additional heaps. The VisualDSP++ installation
also contains a VDK example of how to define multiple heaps.

System Stack
There are two types of a VDK stack: thread and system. The thread stackis allocated on a per-thread basis, and the stack’s memory resources areallocated from the heap.
The system stack is used for most kernel operations, such as the initialization of VDK and thread scheduling. The following text describes whenVDK uses the system stack, and some considerations for determining thesystem stack requirements for an application:• At startup, the system stack is used from the system reset address to
the Run() function of the first boot thread. This includes the initialization of the C/C++ runtime environment, global variable
constructors, the initialization of VDK, constructors for VDK C++
boot threads, the InitFunction() for C/assembly boot threads, andthe Init section for any boot IO objects.
• Once the first boot thread has started to execute, the system stack isused only for short periods during VDK thread scheduling and forany deferred procedure calls. VDK uses deferred procedure calls for

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

A-27

VDK for TigerSHARC Processors

internal updates, such as timeouts, and for some user-configurable
deferred procedure calls, which include the “activate” part of VDK
device drivers.
• Interrupts can occur while VDK is using the system stack. There
should be enough space configured for the system stack to accommodate the stack requirements for any of the ISRs in the system (ifany interrupts can be nested, then the amount of the required system stack also increases). This applies to C, C++, and assemblyinterrupts.

Interrupt Nesting
VDK fully supports nested interrupts:• The skeleton Interrupt Service Routines, which are generated by
the VisualDSP++ 5.0 IDDE for user-defined interrupt handlers,
include instructions to enable the nesting of interrupts if required.
• The ISR API is re-entrant between different interrupt levels.

Interrupt Latency
Every effort has been made to minimize the duration of the intervals
where interrupts are disabled by VDK. Interrupts are disabled only whennecessary for synchronization with interrupt level, and then for the shortest feasible number of instructions. The instruction sequences executedduring these interrupts-off periods are deterministic. It is, therefore, quitepossible that the worst-case interrupts-off time will be set by criticalregions in user code. Ensure that such usage does not impact the interrupt
latency of the system to an unacceptable degree.
Within VDK itself, synchronization between thread level and kernel levelis achieved by selectively masking the kernel level interrupt, while leaving
the higher priority interrupts unmasked.

A-28

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Processor-Specific Notes

Multiprocessor Messaging
Out-of-the-box multiprocessor messaging support is provided for the
ADSP-TS101, ADSP-TS201, ADSP-TS202, and ADSP-TS203 processors. Device drivers that use the link port hardware for communication
between Processors are included under the examples directories in the
VisualDSP++ 5.0 installation.
In the example projects, device driver instances (boot I/O objects) are provided for all four link ports. The selection of which devices to use formessage routing can be configured by the user according to the routing
topology that best fits their hardware, but by default the projects are configured for the ADSP-TS101 and ADSP-TS201 EZ-KIT Lite boards, as
follows.
• ADSP-TS101 EZ-KIT Lite board:
Link port 2 carries messages out of CoreA (outgoing) and into
CoreB (incoming). Link port 3 carries messages out of CoreB (outgoing) and into CoreA (incoming).
• ADSP-TS201 EZ-KIT Lite board:
Link port 2 carries messages both out of and into both cores (outgoing and incoming).
These arrangements reflect the hardwired port interconnections on the
EZ-KIT boards and hence do not require the use of external link port
patch cables.
Note that it is possible to use ADSP-TS101 link ports bi-directionally, so
as to carry both incoming and outgoing messages over the same port
(as on ADSP-TS201 processors). Where two ports are available, however,the unidirectional mode may be slightly more efficient as the link hardware never needs to switch direction. This is not an issue on the
ADSP-TS201 processor as the transmit and receive sides of each link port
are independent.

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

A-29

VDK for TigerSHARC Processors

Support for the cluster bus address space is provided via a standard marshalling type (ClusterBusMarshaller), which automatically translates
local payload addresses into multiprocessor space addresses prior to transmission in a message, and translates incoming payload addresses to local
addresses whenever the portion of the multiprocessor space corresponds tothe local processor. In an appropriately designed application, this feature
can allow payloads to be passed by reference, rather than by copying, evenbetween processors. However, the overall efficiency of such an approach(accessing payload contents in-place across the cluster bus rather thancopying to local memory) is an issue for the application designer to consider. It will also be necessary to ensure that payload memory blocks are
freed only by the processor that originally allocated them.

A-30

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

I

INDEX

A
abstract base thread class, 3-7
abstracted hardware implementation, 3-63
AcquireMutex() API, 3-28, 5-26, 5-43, 5-205
ADSP-21xxx processors, See SHARC
processors
ADSP-TSxxx processors, See TigerSHARC
processors
allocate memory with malloc/new, 3-6, 3-8
AllocateThreadSlot() API, 3-82, 5-28, 5-83
AllocateThreadSlotEx() API, 3-82, 5-30
ALU (alternate) registers, SHARC processors,
A-18, A-19
APIs
See also APIs, assembly macros by namedocumented format, 5-25
error codes/values, 5-11
function parameters, 5-3
header file (vdk.h), 2-2, 2-7, 4-5, 4-35, 4-47,
4-50, 4-59, 4-61, 5-2listed by service, 5-5naming conventions, 5-3
processed by linker, 5-2
validity levels, 5-19
applications, See VDK applications

application status APIslist of, 5-7
GetAllDeviceFlags(), 5-85
GetAllMemoryPools(), 5-87
GetAllMessages(), 5-89
GetAllSemaphores(), 5-91
GetAllThreads(), 5-93
GetCurrentHistoryEventNum(), 5-99
GetDevFlagPendingThreads(), 5-100
GetEventPendingThreads(), 5-104
GetHistoryBufferSize(), 5-108
GetHistoryEvent(), 5-109
GetMessageStatusInfo(), 5-123
GetNumTimesRun(), 5-127
GetPoolDetails(), 5-129
GetSemaphoreDetails(), 5-132
GetSemaphorePendingThreads(), 5-134
GetSharcThreadCycleData(), 5-138
GetThreadBlockingID(), 5-140
GetThreadCycleData(), 5-142
GetThreadStack2Details(), 5-149
GetThreadStackDetails(), 5-147
GetThreadTemplateName(), 5-156
GetThreadTickData(), 5-158
assembly macros
See also assembly macros, APIs by namelist of, 5-11
assembly threads, 3-8
association of data with threads, 3-82

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

I-1

IndexB
Bitfield data type, 4-3
Blackfin processors
exceptions, A-3
execution levels, A-2
interrupt latency, A-9interrupt nesting, A-7
ISR APIs, A-3
memory usage, A-6
multiprocessor messaging, A-9
reserved interrupts, A-4
supervisor/uses modes, A-2
thread stacks, A-7, A-8
timer, A-5
blocked on semaphore threads, 3-19, 3-22
block memory APIs, See memory managementAPIsboot threads, 3-6, 3-37
breakpoints
non-thread-aware, 2-5
thread-specific, 2-5

Ccalls to library functions, 5-2
C/C++ heaps, 3-45
C_ISR_ActivateDevice() assembly macro,5-242, A-12, A-24
C_ISR_ClearEventBit() assembly macro,
5-244
C_ISR_PostSemaphore() assembly macro,
5-246
C_ISR_SetEventBit() assembly macro, 5-248
ClearEventBit() API, 3-49, 3-53, 5-32, 5-214
ClearInterruptMaskBits() API, 3-57, 5-34
ClearInterruptMaskBitsEx() API, 5-35
ClearThreadError() API, 5-37
CloseDevice() API, 3-66, 3-72, 3-73, 5-38
cluster bus address, 3-43
communication manager, 3-63

I-2

component attributes, 3-88
configuration of
VDK based applications, 3-47
VDK projects, 2-1
constructors, C++ threads, 3-5, 3-6, 3-7, 3-8
context switches, 3-23, 3-25, 3-53, 3-54, 3-62
cooperative
multithreading, 3-14
scheduling, 3-14
CPLB tables, A-10
CreateDeviceFlag() API, 5-40
CreateMessage() API, 5-41, 5-76, 5-117,
5-119, 5-198, 5-220
CreateMutex() API, 5-27, 5-43, 5-64, 5-206
CreatePool() API, 3-80, 5-45
CreatePoolEx() API, 3-80, 5-47
CreateSemaphore() API, 5-49
CreateThread() API, 3-5, 3-8, 3-9, 5-51
CreateThreadEx2() API, 3-3, 3-5, 3-9, 3-10,
5-55
CreateThreadEx() API, 3-3, 3-5, 3-9, 5-53
critical regions, 3-12, 3-56, 3-57, 3-59, 3-64,
3-72, 3-80
C threads, 3-8
C++ threads, 3-7
customhistory logs, See history
marshalling functions, 3-44
customer support, xxii

Ddata transfers, 3-43
data types
See also data types by namesummary of, 4-1
debugging VDK applications, 2-2, 2-5
DestroyDeviceFlag() API, 5-58
DestroyMessageAndFreePayload() API, 5-61
DestroyMessage() API, 5-59
DestroyMutex() API, 5-63

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

IndexDestroyPool() API, 5-65
DestroySemaphore() API, 5-67
DestroyThread() API, 3-4, 3-6, 3-18, 5-31,
5-69
destructor function of threads, 3-6
DeviceDescriptor data type, 4-4, 5-38, 5-71,
5-177, 5-197, 5-229, 5-231
device driver APIslist of, 5-9
CloseDevice(), 5-38
DeviceIOCtl(), 5-71
OpenDevice(), 5-177
SyncRead(), 5-229
SyncWrite(), 5-231
device drivers
definition and use, 1-10, 3-63, 3-66, 3-79
dispatch function, 3-62, 3-63, 3-68, 3-78
execution, 3-63
for messaging, 3-46
init functions, 3-63, 3-71, 3-76
interacting with ISRs, 3-63
interacting with threads, 3-66, 3-72
parameterization, 3-76
variables, 3-79
Blackfin processors, A-2
SHARC processors, A-12, A-17, A-22
TigerSHARC processors, A-24, A-29
device flag APIslist of, 5-9CreateDeviceFlag(), 5-40
DestroyDeviceFlag(), 5-58
PendDeviceFlag(), 5-179
PostDeviceFlag(), 5-197
DeviceFlagID data type, 4-5, 5-40, 5-58, 5-85,
5-100, 5-179, 5-197
device flags
definition and use, 3-55, 3-76
pending on, 3-76
posting, 3-55, 3-78
DeviceInfoBlock data type, 4-6

DeviceIOCtl() API, 3-66, 3-74, 5-71
disabled
interrupts, 1-8, 3-56
scheduling, 1-8, 3-15
dispatch function, 3-69, 3-78
See also PostDeviceFlag() API
DispatchID data type, 4-7
DispatchThreadError() API, 3-5, 5-73
DispatchUnion data type, 4-8
DispatchUnion parameter of dispatch
function, 3-69
domains, interrupt and thread, 3-22
DSP_Family data type, 4-10
DSP_Product data type, 4-11
dynamic threads, creating, 3-5E
enumeration
error functions, 3-5priorities of threads, 3-4
error
codes and values, 3-11, 5-11
functions, threads, 3-5
handling, definition and use, 3-11
management functions of threads, 5-8
ErrorFunction() function, 3-11
ErrorHandler() function, A-12, A-24
event and event bit APIslist of, 5-9
ClearEventBit(), 5-32
GetEventBitValue(), 5-102
GetEventData(), 5-103
GetEventValue(), 5-106
LoadEvent(), 5-167
PendEvent(), 5-181
SetEventBit(), 5-214
EventBitID data type, 4-17, 5-32, 5-102,
5-214, 5-238, 5-241, 5-244, 5-248

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

I-3

Index

event bits
See also events
definition and use, 3-48
from interrupt domain, 3-54
from thread domain, 3-53
global variables, 3-49
EventData data type, 4-19, 5-103, 5-167
EventID data type, 4-18, 5-103, 5-104, 5-106,
5-167, 5-181
eventsSee also event bits
definition and use, 3-48
calculation, 3-49, 3-51, 3-54
data structure, 3-49
loading new event data, 3-55
EVT_EVX hardware interrupt, A-4
EVT_IVG hardware interrupt, A-4
EVT_IVTMR hardware interrupt, A-4
exceptions
Blackfin processors, A-3, A-4
TigerSHARC processors, A-24
execution levels
Blackfin processors, A-2
SHARC processors, A-12
TigerSHARC processors, A-24
execution modes, Blackfin processors, A-1, A-4.EXTERN assembly directive, 3-11

F
file attributes, See VDK file attributes
ForwardMessage() API, 3-37, 5-75
FreeBlock() API, 3-81, 5-78
FreeDestroyedThreads() API, 5-80
FreeMessagePayload () API, 5-81
FreeMessagePayload() API, 5-41
FreeThreadSlot() API, 3-82, 5-83

G
GetAllDeviceFlags() API, 5-85

I-4

GetAllMemoryPools() API, 5-87
GetAllMessages() API, 5-89
GetAllSemaphores() API, 5-91
GetAllThreads() API, 5-93
GetBlockSize() API, 5-95
GetClockFrequency() API, 5-96
GetContextRecodeSize() API, 5-97
GetContextRecordSize() API, 3-10
GetCurrentHistoryEventNum() API, 5-99
GetDevFlagPendingThreads() API, 5-100
GetEventBitValue() API, 5-102
GetEventData() API, 3-55, 5-103
GetEventPendingThreads() API, 5-104
GetEventValue() API, 5-106
GetHeapIndex() API, 5-107
GetHistoryBufferSize() API, 5-108
GetHistoryEvent() API, 3-83, 5-109
GetInterruptMask() API, 3-57, 5-111
GetInterruptMaskEx() API, 5-113
GetLastThreadError() API, 3-11, 5-115
GetLastThreadErrorValue() API, 3-11, 5-116
GetMessageDetails() API, 5-117, 5-123
GetMessagePayload() API, 3-35, 5-41, 5-118,
5-119, 5-123
GetMessageReceiveInfo() API, 3-35, 5-75,
5-121
GetMessageStatusInfo() API, 5-123
GetNumAllocatedBlocks() API, 3-81, 5-125
GetNumFreeBlocks() API, 3-81, 5-126
GetNumTimesRun() API, 5-127
GetPoolDetails() API, 5-129
GetPriority() API, 5-131
GetSemaphoreDetails() API, 5-132
GetSemaphorePendingThreads() API, 5-134
GetSemaphoreValue() API, 5-136
GetSharcThreadCycleData() API, 5-138,
5-142
GetThreadBlockingID() API, 5-140
GetThreadCycleData() API, 5-138, 5-142
GetThreadHandle() API, 3-8, 5-144

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Index

GetThreadID() API, 3-3, 5-145
GetThreadSlotValue() API, 3-83, 5-146
GetThreadStack2Details() API, 5-149
GetThreadStack2Usage() API, 5-153
GetThreadStackDetails() API, 5-147
GetThreadStackUsage() API, 5-151, 5-165
GetThreadStatus() API, 5-140, 5-155
GetThreadTemplateName() API, 5-156
GetThreadTickData() API, 5-158
GetTickPeriod() API, 5-160
GetUptime() API, 5-161
GetVersion() API, 5-162.GLOBAL assembly directive, 3-11
global variables, 3-11, 3-59, 3-64, 4-59, 5-3

H
header files
for C/assembly threads, 3-8
vdk.h, 2-2, 2-7, 4-5, 4-35, 4-47, 4-50, 4-59,
4-61, 5-2
HeapID data type, 3-82, 4-20, 5-107
heaps, See memory heaps
history
buffers, 2-3, 3-83, 5-170
logging functions, 3-83, 3-85, 5-99, 5-108,
5-109, 5-170, 5-239
window, 2-3
HistoryEnum data type, 4-21, 4-26, 5-170,
5-239
HistoryEvent data type, 3-84

I
idle threads, 1-7, 2-4, 2-5, 3-18
IMASKStruct data type, 4-28, 5-34, 5-35,
5-111, 5-113, 5-216, 5-218
Import list (Kernel tab), 3-37

init functions
C/assembly, 3-5, 3-6, 3-7, 3-8
C++ constructor, 3-5, 3-6, 3-7, 3-8
Initialize() function, 3-2
InstallMessageControlSemaphore() API, 3-42,
5-163
instrumented build, 2-3
InstrumentStack() API, 5-151, 5-153, 5-165
internal memory DMA (IMDMA), A-9interrupt dispatchers
run-time library, A-12
interrupt execution levels
Blackfin processors, A-2
SHARC processors, A-12, A-13
TigerSHARC processors, A-24
interrupt handling APIslist of, 5-5
PopCriticalRegion(), 5-190
PopNestedCriticalRegions(), 5-192
PushCriticalRegion(), 5-203
interrupt latency
critical regions effect, 3-57
Blackfin processors, A-9
SHARC processors, A-13
TigerSHARC processors, A-28
interrupt mask APIslist of, 5-5
ClearInterruptMaskBits(), 5-34
ClearInterruptMaskBitsEx(), 5-35
GetInterruptMask(), 5-111
GetInterruptMaskEx(), 5-113
SetInterruptMaskBits(), 5-216
SetInterruptMaskBitsEx(), 5-218
interrupt nesting
Blackfin processors, A-7
SHARC processors, A-14
TigerSHARC processors, A-28

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

I-5

Indexinterrupts
See also ISRs, interrupt nesting, reserved
interrupts, interrupt latency
architecture of, 3-57
disabling, 1-8, 3-15, 3-56
domain, 3-64
latching, 3-25
on Blackfin processors, A-3
on SHARC processors, A-14
on TigerSHARC processors, A-25
I/O
interface, 3-62
templates, 3-62
IOCtl_t struct, 3-74
IOID data type, 4-29, 5-177, 5-237, 5-242
IOTemplateID data type, 4-30
ISRs
See also interrupts
activating device drivers, 3-75
definition and use, 3-56
disabling (masking), 3-56
enabling (unmasking), 3-56
interaction with thread domain, 3-59

K
kernel execution level, A-2, A-12, A-24
KernelPanic, 5-237
definition and use, 2-5
in thread error handling, 3-5, 3-12
in VDK libraries, 5-237, 5-240, 5-242,
5-245, 5-247, 5-249

I-6

L
library
list of APIs, 5-5
documentation format, 5-25
header file (vdk.h), 5-2
linking APIs, 5-2
thread-safe, 2-2
linker description files, 2-2
linker description files (.ldf), 2-2, 5-2, A-6,
A-17, A-26
LoadEvent() API, 3-55, 5-167
LocateAndFreeBlock() API, 3-81, 5-169
LogHistoryEvent() API, 3-83, 5-170
lowest priority interrupts, 3-58, 3-60, 3-62,
3-75

M
main() function, 3-2
MakePeriodic() API, 5-171
malloc, allocating memory, 3-80
MallocBlock() API, 3-81, 5-173
MarshallingCode data type, 4-31
MarshallingEntry data type, 4-33
marshalling table, 3-43
memory allocations, 3-80
memory blocks
See also memory heaps, memory poolsalignment constraints, 3-46, 3-81
freeing with free/delete, 3-6
memory heaps
See also HeapID data typeallocated for threads, 3-3
creating new, 3-82
fragmentation, 3-80
indexing, 3-44, 4-33, 4-45
in external memory (SHARC processors),
A-18
marshalling, 4-33, 4-45
multiple, 3-81, 4-20

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Indexmemory management APIslist of, 5-6
CreatePool(), 5-45
CreatePoolEx(), 5-47
DestroyPool(), 5-65
FreeBlock(), 5-78
GetBlockSize(), 5-95
GetNumAllocatedBlocks(), 5-125
GetNumFreeBlocks(), 5-126
LocateAndFreeBlock(), 5-169
MallocBlock(), 5-173
memory pools
See also memory heaps, memory blocks
definition and use, 3-80
messageloopback, 3-45
payload, 3-37
message APIslist of, 5-10
CreateMessage(), 5-41
DestroyMessage(), 5-59
DestroyMessageAndFreePayload(), 5-61
ForwardMessage(), 5-75
FreeMessagePayload(), 5-81
GetMessageDetails(), 5-117
GetMessagePayload(), 5-119
GetMessageReceiveInfo(), 5-121
InstallMessageControlSemaphore(), 5-163
MessageAvailable(), 5-175
PendMessage(), 5-184
PostMessage(), 5-198
SetMessagePayload(), 5-220
MessageAvailable() API, 3-33, 5-175, 5-184
MessageDetails data type, 4-34, 5-123
MessageID data type, 4-35, 5-41, 5-59, 5-61,
5-76, 5-81, 5-89, 5-117, 5-119, 5-121,
5-123, 5-184, 5-198, 5-220

messagesdefinition and use, 3-32
interacting with threads, 3-34
multiprocessor support, A-29
ownership, 3-33
pending on, 3-34
posting from scheduled regions, 3-35
posting from unscheduled regions, 3-36
priorities of, 3-32
message transfer (messaging)See also multiprocessor messaging
on Blackfin (ADSP-BF561) processors, A-9
on TigerSHARC processors, A-29
with device drivers, 3-46
MsgChannel data type, 4-36, 4-38, 5-76,
5-118, 5-121, 5-199
MsgFormat data type, 4-38
multiprocessor messaging
definition and use, 3-37
Blackfin (ADSP-BF561) processors, A-9
SHARC processors, A-21
TigerSHARC processors, A-29
mutex APIslist of, 5-10
AcquireMutex(), 5-26
CreateMutex(), 5-43
DestroyMutex(), 5-63
ReleaseMutex(), 5-205
mutexes
definition and use, 3-26
aquiring process, 3-28
releasing process, 3-28
MutexID data type, 5-26, 5-43, 5-63, 5-205

N
namespace (VDK), 3-8, 5-4
nested protected regions, 3-15
nodes in multiprocessor systems, 3-37, 3-47
non-maskable interrupts (NMIs), A-5
non-thread-aware breakpoints, 2-5

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

I-7

Indexnotation conventions of API library, 5-3

Oopen/close functions, threads, 3-72
OpenClose_t struct, 3-72
OpenDevice() API, 3-66, 3-72, 3-73, 5-38,
5-71, 5-177, 5-197, 5-229, 5-231

P
PanicCode data type, 4-41
parallel scheduling domains, 3-64
parameterization of device drivers, 3-76
parameters, passing to APIs, 5-3PayloadDetails data type, 4-44, 5-118, 5-123
payload marshalling, 3-32, 3-43
PendDeviceFlag() API, 3-56, 3-68, 3-77, 3-78,
5-179
PendEvent() API, 3-52, 5-181
pending
on a message, 3-34
on device flags, 3-76
on semaphores, 3-21
PendMessage() API, 3-35, 5-60, 5-62, 5-77,
5-82, 5-118, 5-122, 5-175, 5-184, 5-200,
5-221
PendSemaphore() API, 3-22, 5-187
periodic semaphores, 3-20, 3-25
PFMarshaller data type, 4-45
PoolID data type, 4-47, 5-45, 5-47, 5-48, 5-65,
5-78, 5-87, 5-95, 5-125, 5-126, 5-129,
5-173
pool marshalling, 3-45, 4-33
PopCriticalRegion() API, 3-57, 5-190, 5-203
PopNestedCriticalRegions() API, 5-192
PopNestedUnscheduledRegions() API, 3-16,
5-194
PopUnscheduledRegion() API, 3-15, 3-49,
5-195, 5-204

I-8

PostDeviceFlag() API, 3-56, 3-68, 3-76, 3-78,
5-179, 5-197
posting a message, 3-35
PostMessage() API, 3-36, 3-37, 5-75, 5-198
PostSemaphore() API, 3-23, 3-26, 5-201
preemption, 1-7
preemptive scheduling, 3-14
priorities of threads, 1-6, 3-4
Priority data type, 4-48, 5-131, 5-222
protected regions, 1-7, 3-11, 3-12, 3-74, 3-79
PushCriticalRegion() API, 3-57, 3-77, 5-190,
5-203
PushUnscheduledRegion() API, 3-15, 5-195,
5-204

Q
queue
of ready threads, See ready queueof waiting threads, 3-5

R
rapid application development (RAD), 1-2
ReadWrite_t struct, 3-73
ready queue, 1-6, 3-12, 3-14, 3-22, 3-26, 3-48,
3-55
reentrancy, 3-11
ReleaseMutex() API, 3-29, 5-26, 5-205
RemovePeriodic() API, 5-207
ReplaceHistorySubroutine() API, 3-83, 5-209
reschedule ISRs, 3-58, 3-62
reserved interrupts
lowest priority (reschedule), 3-58, 3-62
timer, 3-58, 3-61
on Blackfin processors, A-4
on SHARC processors, A-14, A-15
on TigerSHARC processors, A-25
ResetPriority() API, 3-4, 5-211
ring configuration of nodes, 3-47
round-robin scheduling, 3-14

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

Indexrouting
table, 3-38
threads (RThreads), 3-38, 5-18, A-10
topology, 3-47
RoutingDirection data type, 4-49
Run() function, 3-2
Run() function, C++ threads, 3-4
RunFunction() function, C/assembly threads,
3-4
run-time library interrupt dispatchers, A-12

S
scheduled regions
posting a message, 3-36
posting a semaphore, 3-23, 3-25
releasing a mutex, 3-30
reschedule ISR, 3-62
state of an event bit, 3-49, 3-53, 3-54
scheduler
definition and use, 1-5, 3-12
disabling, 3-15
enabling, 3-26
entering from API calls, 3-16
entering from interrupts, 3-16, 3-54
managing periodic threads, 3-25
methods/modes, 3-14
scheduler management APIslist of, 5-8
PopNestedUnscheduledRegions(), 5-194
PopUnscheduledRegion(), 5-195
PushUnscheduledRegion(), 5-204

semaphore APIslist of, 5-9CreateSemaphore(), 5-49
DestroySemaphore(), 5-67
GetSemaphoreValue(), 5-136
InstallMessageControlSemaphore(), 5-163
MakePeriodic(), 5-171
PendSemaphore(), 5-187
PostSemaphore(), 5-201
RemovePeriodic(), 5-207
SemaphoreID data type, 4-50, 5-50, 5-67,
5-91, 5-132, 5-133, 5-134, 5-136, 5-163,
5-171, 5-188, 5-201, 5-207, 5-240, 5-246
semaphores
definition and use, 3-19
periodic, 3-20
posting from interrupt domains, 3-25
posting from thread domains, 3-23
SetClockFrequency() API, 5-96, 5-213
SetEventBit() API, 3-49, 3-53, 5-32, 5-214
SetInterruptMaskBits() API, 3-57, 5-216
SetInterruptMaskBitsEx() API, 5-218
SetMessagePayload() API, 3-35, 5-220
SetPriority() API, 3-4, 5-222
SetThreadError() API, 5-224
SetThreadSlotValue() API, 3-82, 5-225
SetTickPeriod() API, 5-226

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

I-9

IndexSHARC processors
ADSP-2106x processor ISRs, A-14
ADSP-2116x processor ISRs, A-15
ADSP-2126x processor ISRs, A-15
ADSP-2136x processor ISRs, A-15
ALU (40-bit) registers, A-18, A-19
execution levels, A-12
interrupt latency, A-13
interrupt nesting, A-14
memory usage, A-17
multiprocessor messaging, A-21
reserved interrupts, A-14, A-15
system stack, A-17
timer, A-16
signals
device flags, See device flags
events, See events and event bits
mutexes, See mutexes
semaphores, See semaphores
Sleep() API, 5-227
stack
on SHARC processors, A-17
size, of threads, 3-3
stack overflow, A-10, A-23
synchronization of threads, 3-19, 3-48
SyncRead() API, 3-39, 3-44, 3-66, 3-73, 5-229
SyncWrite() API, 3-39, 3-44, 3-66, 3-73,
5-231
SystemError APIs, 3-5
SystemError data type, 4-51, 5-73, 5-115,
5-224
system heaps, See memory heaps

I-10

system information APIslist of, 5-6
GetClockFrequency(), 5-96
GetContextRecodeSize(), 5-97
GetHeapIndex(), 5-107
GetThreadHandle(), 5-144
GetThreadID(), 5-145
GetThreadStack2Usage(), 5-153
GetThreadStatus(), 5-155
GetTickPeriod(), 5-160
GetUptime(), 5-161
GetVersion(), 5-162
InstrumentStack(), 5-165
LogHistoryEvent(), 5-170
ReplaceHistorySubroutine(), 5-209
SetClockFrequency(), 5-213
SetTickPeriod(), 5-226

T
TCBBitfield data type, 3-10, 4-57
threadcreate functions, 3-5, 5-7, 5-51, 5-53, 5-55
destructor functions, 3-6, 5-7, 5-69, 5-80
entry points, 3-4
execution levels, A-2, A-12, A-24
inter-communication, 3-32
local storage, 3-82
parameterization, 3-8
stack (on Blackfin processors), A-7
templates, 3-7
thread APIsSee also thread error management APIs
CreateThread(), 5-51
CreateThreadEx(), 5-53
CreateThreadEx2(), 5-55
DestroyThread(), 5-69
FreeDestroyedThreads(), 5-80
GetThreadStackUsage(), 5-151
ThreadCreationBlock data type, 3-10, 4-58,
5-53, 5-56

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

IndexThreadCreationBlock data types, 3-9
thread domain
calling dispatch function, 3-69
communicating with, 3-59
parallel scheduling, 3-64
posting semaphores, 3-22
software scheduling, 1-10
thread error management APIslist of, 5-8
ClearThreadError(), 5-37
DispatchThreadError(), 5-73
GetLastThreadError(), 5-115
GetLastThreadErrorValue(), 5-116
SetThreadError(), 5-224
ThreadID data typedefinition and use, 3-3, 4-61
in history logging, 5-239
in message APIs, 5-75, 5-121, 5-198
in thread APIs, 5-69, 5-93, 5-101, 5-105,
5-127, 5-131, 5-135, 5-138, 5-140,
5-145, 5-147, 5-149, 5-151, 5-153,
5-156, 5-158, 5-211, 5-222
thread interactingwith device flags, 3-56
with events, 3-51
with hardware, 1-9
with semaphores, 3-20
thread local storage APIslist of, 5-8
AllocateThreadSlot(), 5-28
AllocateThreadSlotEx(), 5-30
FreeThreadSlot(), 5-83
GetThreadSlotValue(), 5-146
SetThreadSlotValue(), 5-225
thread parameters
priority, 3-4
stack size, 3-3

thread pending
on device flags, 3-55
on events, 3-48, 3-52
on messages, 3-33
thread postinga message, 3-32, 3-36
a semaphore, 3-22
thread priority management APIslist of, 5-8
GetPriority(), 5-131
ResetPriority(), 5-211
SetPriority(), 5-222
threads
definition and use, 3-2, 3-3
acquiring a mutex, 3-26, 3-28
allocated dynamically, 3-6
blocked, 1-7, 3-55
C/assembly implemented, 3-8
C++ implementated, 3-7
control over device parameters, 3-74
creating a message, 3-32
error functions, 3-5, 3-22
lowest priority (idle), 2-4
open/close device drivers, 3-72
parameters, 3-3, 3-4
reading to and writing from, 3-73
releasing a mutex, 3-28
routing threads (RThreads), 3-38, 5-18,
A-10
Run() functions, 3-4
setting/clearing event bits, 3-53
state and status data, 2-4
user-defined stack, 3-10
thread-safe libraries, 2-2
thread scheduling APIslist of, 5-8
Sleep(), 5-227
Yield(), 5-233
thread-specific breakpoints, 2-5
ThreadStatus data type, 4-62, 5-155

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

I-11

IndexThreadType data type, 4-63, 5-54, 5-55
tick period, 5-160
Ticks data type, 4-64, 5-49, 5-158, 5-161,
5-171, 5-179, 5-181, 5-184, 5-187,
5-227, 5-229, 5-231
TigerSHARC processors
exceptions, A-24
execution levels, A-24
interrupt latency, A-28
interrupt nesting, A-28
memory, A-26
multiprocessor messaging, A-29
reserved processors, A-25
timeout, 3-19, 3-22, 4-45
timer ISR, 3-58, 3-61
Blackfin processor, A-5
SHARC processors, A-16
TigerSHARC processors, A-26
time slicing (round-robin) sheduling, 3-14

Uunscheduled regions
definition and use, 3-12
acquiring a mutex, 3-28
disabling/enabling ISRs, 3-57, 3-80
disabling scheduler, 3-15
open/close device drivers, 3-72
posting a message, 3-36
releasing a mutex, 3-31
state of an event bit, 3-51, 3-54
UserHistoryLog() API, 3-83, 3-85
user mode (VDK execution mode), A-1, A-2

I-12

V
validity levels of VDK APIs, 5-19
VDK
Communication Manager, 3-63
file attributes, 3-86
history logging, 2-3, 3-83
memory pools, 3-45
namespace, 3-8, 5-4
State History window, 2-3
Status window, 2-4
target load graph, 2-4
vector table, 3-58
VDK applications
code reuse, 1-3
debugginghardware abstraction, 1-4
partitioning, 1-4
rapid application development (RAD), 1-2
routing topology, 3-47
VDK file attributes, 3-86
vdk.h header file, 2-2, 2-7, 4-5, 4-35, 4-50,
4-59, 4-61, 5-2
VDK_ISR_ACTIVATE_DEVICE_()assembly macro, 3-67, 3-75, 5-237, A-2,
A-12, A-24
VDK_ISRAddHistoryEvent() API, 3-83
VDK_ISR_CLEAR_EVENTBIT_() assembly
macro, 3-54, 5-238
VDK_ISR_LOG_HISTORY_EVENT_()
assembly macro, 4-21, 5-239
VDK_ISR_POST_SEMAPHORE_()
assembly macro, 3-25, 3-26, 3-60, 5-240
VDK_ISR_SET_EVENTBIT_() assembly
macro, 3-54, 5-241

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

IndexVDK library
list of functions, 5-5
API calls validity levels, 5-19
assembly macros, 5-234
error codes/values, 5-12
header file (vdk.h), 5-2
linking library functions, 5-2naming conventions, 5-3
reference format, 5-25
VDK projects, 2-2
VersionStruct data type, 4-65, 5-162

VisualDSP++
multiple heap API extensions, 3-45
State History window, 2-3
Target Load graph, 2-4
Thread History window, 3-18
volatile variables, 3-79

W
working with library headers, 5-2

Y
Yield() API, 3-14, 5-233

VisualDSP++ 5.0 Kernel (VDK) User’s Guide

I-13