There may be multiple ledger instances in a system. There are
two types of ledgers: 1. a group ledger, and 2. a private ledger.
A group ledger may have two or more users. A private ledger has
exactly two users. When a processor creates a private ledger,
that processor may not create any additional ledgers of any type.
A private ledger is typicaly used by the ARP32 processor.
The ledger type is identified by the role used to access it.
- Role_PEER
-
This role is used to access a group ledger instance. This
ledger instance is used by multiple processors. The ledger
is an array of GroupLedgerElem elements. Each processor
uses one entry in the ledger. The size of the ledger must
equal the number of users.
All users of this ledger are peers. The ledger is not created
by any processor, it must be defined in the memory map.
- Role_OWNER
-
This role is used to access a private ledger. This ledger
is used by only two processors: the local processor (the
owner) and a remote processor (the user). The ledger is
allocated in the local processor's memory map. This same
ledger must be defined by a Role_USER role on one other
processor.
- Role_USER
-
This role is used to access a private ledger. This role is the
complement of the Role_OWNER role. When using a private ledger,
the actual ledger is created by the other processor.
A processor using the Role_USER role, will access the ledger with
the given address, but it does not allocate the ledger.
It is possible to access multiple private ledgers from the
same processor. Each Role_USER corresponds to a private ledger
created by another processor.
struct TimestampProvider_Ledger |
 |
Define a ledger used in the system
typedef struct TimestampProvider_Ledger {
// role used to access the ledger
Ptr base;
// base address of the ledger
Int size;
// number of users
Int index;
// entry assigned to this processor
} TimestampProvider_Ledger;
FIELDS
role
Defines how this processor will be using the ledger. The role
also implicitly defines which type of ledger is created. See
the Role enumeration for details.
base
The base address of the ledger as seen by the local processor.
size
The number of users of the current ledger. When adding a new
user to a ledger, be sure to update this value for all processors
using the same ledger.
index
The entry index in the ledger to be used by this processor. Each
processor must have its own unique entry. The index is zero based
(as in array indexing). Index values range from 0 - (size-1).
DETAILS
A ledger is used to keep track of which processors are running.
Depending on the ledger role, there can be two or more users of
the same ledger instance. You can define multiple ledgers. See
ledgers for examples of creating ledgers.
config TimestampProvider_L_latch // module-wide |
 |
Log event raised at the end of the timer isr
extern const Log_Event TimestampProvider_L_latch;
DETAILS
The timer isr maintains a global tick value used by System
Analyzer to correlate the log events across processor boundaries.
This event is raised at the end of the timer isr. The latch count
should be the same on all processors. The isr timestamp is also
reported. This value can be used to measure the accuracy of the
event correlation. The isr timestamp is captured at the very
beginning of the timer isr.
config TimestampProvider_L_suspend // module-wide |
 |
Log event raised when loggers are to be suspended
extern const Log_Event TimestampProvider_L_suspend;
DETAILS
The module has determined that the system state is not nominal. To
preserve the events in the log buffers leading up to this point,
the loggers will be suspended. This event is raised shortly before
the loggers are actually suspended.
config TimestampProvider_cpuIntrNum // module-wide |
 |
Specify cpu interrupt to receive timer interrupt
extern const Int TimestampProvider_cpuIntrNum;
DETAILS
For accurate event correlation in System Analyzer, it is
recommended not to share this interrupt.
The following table indicates possible interrupt numbers, but
this is device specific. Please consult your manual.
Processor |
Timer ID |
DSP |
4-15 |
EVE |
8-11 |
config TimestampProvider_estCpuFreq // module-wide |
 |
Estimate the cpu frequency using timestamp sample buffer
extern const Bool TimestampProvider_estCpuFreq;
DETAILS
When enabled, this module will save timestamps in the sample
buffer which are then used to calculate an estimate of the
cpu frequency. Run the processor continuously for 30 seconds
to ensure the sample buffer is full. Open ROV and select the
Module tab. The calculated cpu frequency is displayed in the
estCpuFreq column. The timestamp samples are displayed in the
Sample Buffer tab.
Set this config param to false to reduce the data footprint in
your released product.
config TimestampProvider_eventId // module-wide |
 |
Specify interrupt controller event to receive timer interrupt
extern const Int TimestampProvider_eventId;
DETAILS
The eventId specifies which interrupt controller event should
receive the timer interrupt. This value is used to route the
timer interrupt through the Interrupt Crossbar to the interrupt
controller event. It is also used to route the interrupt event
to the cpu interrupt specified in
cpuIntrNum.
The following table indicates possible event ids, but this is
device specific. Please consult your manual.
Processor |
Event ID |
DSP |
63-78, 81 |
EVE |
32-39 |
config TimestampProvider_ledgers // module-wide |
 |
Define the ledgers to be managed by this processor
DETAILS
Ledgers are used to keep track of the other processors. This
is needed to support the auto-logging feature and to issue
LogSync events. Each processor must define at least one ledger.
There are two types of ledgers: a group ledger, and a private
ledger. See the
Role enumeration for details.
Use as few ledgers as possible. However, some system constraints
will require additional ledgers. For example, the EVE processors
have very slow data access to on-chip or external memory. Therefore,
we recommend that each EVE processor use a private ledger. Place
the private ledger in DMEM to ensure fast memory access.
Add the following to your EVE1 configuration script.
var TimestampProvider = xdc.useModule('ti.uia.family.dm.dra7xx.TimestampProvider');
// use private ledger, role = owner
TimestampProvider.ledgers.$add(
new TimestampProvider.Ledger({
role: TimestampProvider.Role_OWNER,
base: 0x40020000
})
);
Each private ledger has exactly two users: an owner (Role_OWNER)
and a user (Role_USER). In the example above, the EVE would always
be the owner. Typically, the DSP would be the corresponding user.
Add the following to your DSP1 configuration script.
var TimestampProvider = xdc.useModule('ti.uia.family.dm.dra7xx.TimestampProvider');
// eve1 ledger, role = user
TimestampProvider.ledgers.$add(
new TimestampProvider.Ledger({
role: TimestampProvider.Role_USER,
base: 0x42020000
})
);
Note in the example above, the EVE defines the ledger address
using its local address (e.g. 0x40020000). However, the DSP must
use the interconnect address (e.g. 0x42020000).
For the remaining processors in the system, you could use one
group ledger. All processors using the same group must agree on
the ledger address, and the number of entries. Each processor must
be assigned its own entry in the ledger.
The following example defines a single group ledger used by two
processors: DSP1 and DSP2. Add the following to your DSP1
configuration script.
var TimerSupport = xdc.useModule('ti.sysbios.family.shared.vayu.TimerSupport');
// group ledger, role = peer
TimestampProvider.ledgers.$add(
new TimestampProvider.Ledger({
role: TimestampProvider.Ledger_PEER,
base: 0x40500000,
size: 2, // DSP1 DSP2
index: 0 // DSP1
})
);
Add the following to your DSP2 configuration script.
var TimerSupport = xdc.useModule('ti.sysbios.family.shared.vayu.TimerSupport');
// group ledger, role = peer
TimestampProvider.ledgers.$add(
new TimestampProvider.Ledger({
role: TimestampProvider.Role_PEER,
base: 0x40500000,
size: 2, // DSP1 DSP2
index: 1 // DSP2
})
);
It is also possible to partition the remaining processors into
groups and assign a group ledger to each processor group. This
might be done to support independent application domains. However,
one requirement is that the processor which owns the timer must
participate in all group ledgers. For example, if DSP1 has
TimestampProvider.owner = true;
then DSP1 must participate in all group ledgers (i.e. Role_PEER).
config TimestampProvider_maxBusClockFreq // module-wide |
 |
The highest bus clock frequency used to drive the timer
extern const Types_FreqHz TimestampProvider_maxBusClockFreq;
DETAILS
The default ticks per second rate of the timer is calculated by dividing
the timer's bus clock frequency by the cyclesPerTick config parameter.
RETURNS
the 32 MSBs of the highest bus clock frequency used to drive
the timer.
config TimestampProvider_maxTimerClockFreq // module-wide |
 |
The highest timer clock frequency
extern const Types_FreqHz TimestampProvider_maxTimerClockFreq;
DETAILS
The default ticks per second rate of the timer is calculated by dividing
the timer's bus clock frequency by the cyclesPerTick config parameter.
RETURNS
the 32 LSBs of the highest timer clock frequency
(i.e. ticksPerSecond).
config TimestampProvider_owner // module-wide |
 |
Determine ownership of the timer
extern const Bool TimestampProvider_owner;
DETAILS
When set to true, the timer will be enabled and configured
during the boot phase. The owner should run before any other
processor using this same timer. Only one processor should
be configured as the owner of the timer. This processor will
also listen for the timer interrupt and acknowledge it.
When set to false, it is expected that another processor will
enable and configure the timer. This processor will simply
listen for the timer interrupt and acknowledge it.
Note: The ARP32 does not support timer ownership. This config
param must always be false when running on the ARP32.
config TimestampProvider_syncInterval // module-wide |
 |
Specify the interval for logging sync events
extern const UInt TimestampProvider_syncInterval;
DETAILS
UIA Sync events are used by System Analyzer to correlate the
events from each processor onto a global time base. Only the
last sync event is actually used.
This configuration parameter specifies how frequently the sync
events should be raised. In order to maintain accurate event
correlation, you should raise one sync event within each log
data window. For example, if your log buffer contains 100 ms
of data, then you should raise a sync event each 0.1 seconds
(100 ms = 0.1 sec).
Each syncInterval is 0.001953125 seconds. Divide the data window
by this value to get the syncInterval (round down).
0.1 sec / 0.001953125 sec = 51.2
TimestampProvider.syncInterval = 51;
When using multiple logger instances, the data window for each
instance is probably different. Use System Analyzer to measure
the data overlap of your region of interest. Use the length of
this region to calculate the syncInterval.
The syncInterval should be as large as possible to reduce logging
overhead, yet small enough to yield accurate event correlation.
config TimestampProvider_timerId // module-wide |
 |
Identify which timer to use as the timestamp clock source
extern const UInt TimestampProvider_timerId;
DETAILS
The timers are named Timer1-Timer16; their corresponding ids
are 0-15 (e.g. for Timer3, use id=2). Not all timers are
appropriate clock sources for this module. Use one of the
following timers:
Timer Name |
Description |
Timer[3,4,9,11,13,14,15,16] |
PD_L4PER power domain |
Timer[5,6,7,8] |
PD_IPU power domain |
All executables must use the same timer in order to support
event correlation in System Analyzer.
TimestampProvider_get32() // module-wide |
 |
Return a 32-bit timestamp
Bits32 TimestampProvider_get32();
RETURNS
Returns a 32-bit timestamp value.
Use
getFreq to convert this value into units of real time.
SEE
TimestampProvider_get64() // module-wide |
 |
Return a 64-bit timestamp
ARGUMENTS
result
pointer to 64-bit result
This parameter is a pointer to a structure representing a 64-bit
wide timestamp value where the current timestamp is written.
If the underlying hardware does not support 64-bit resolution, the
hi field of
result is always set to 0; see
xdc.runtime.Types.Timestamp64. So, it is possible for
the
lo field to wrap around without any change to the
hi field.
Use
getFreq to convert this value into units of real
time.
SEE
TimestampProvider_getFreq() // module-wide |
 |
Get the timestamp timer's frequency (in Hz)
ARGUMENTS
freq
pointer to a 64-bit result
This parameter is a pointer to a structure representing a 64-bit
wide frequency value where the timer's frequency (in Hz)
is written; see
xdc.runtime.Types.FreqHz.
This function provides a way of converting timestamp
values into units of real time.
SEE
Module-Wide Built-Ins |
 |
// Get this module's unique id
Bool TimestampProvider_Module_startupDone();
// Test if this module has completed startup
// The heap from which this module allocates memory
Bool TimestampProvider_Module_hasMask();
// Test whether this module has a diagnostics mask
Bits16 TimestampProvider_Module_getMask();
// Returns the diagnostics mask for this module
Void TimestampProvider_Module_setMask(Bits16 mask);
// Set the diagnostics mask for this module
enum TimestampProvider.Role |
 |
Define roles for each ledger instance
values of type TimestampProvider.Role
const TimestampProvider.Role_PEER;
// shared by multiple processors
const TimestampProvider.Role_OWNER;
// shared with one remote processor
const TimestampProvider.Role_USER;
// shared with one remote processor
DETAILS
There may be multiple ledger instances in a system. There are
two types of ledgers: 1. a group ledger, and 2. a private ledger.
A group ledger may have two or more users. A private ledger has
exactly two users. When a processor creates a private ledger,
that processor may not create any additional ledgers of any type.
A private ledger is typicaly used by the ARP32 processor.
The ledger type is identified by the role used to access it.
- Role_PEER
-
This role is used to access a group ledger instance. This
ledger instance is used by multiple processors. The ledger
is an array of GroupLedgerElem elements. Each processor
uses one entry in the ledger. The size of the ledger must
equal the number of users.
All users of this ledger are peers. The ledger is not created
by any processor, it must be defined in the memory map.
- Role_OWNER
-
This role is used to access a private ledger. This ledger
is used by only two processors: the local processor (the
owner) and a remote processor (the user). The ledger is
allocated in the local processor's memory map. This same
ledger must be defined by a Role_USER role on one other
processor.
- Role_USER
-
This role is used to access a private ledger. This role is the
complement of the Role_OWNER role. When using a private ledger,
the actual ledger is created by the other processor.
A processor using the Role_USER role, will access the ledger with
the given address, but it does not allocate the ledger.
It is possible to access multiple private ledgers from the
same processor. Each Role_USER corresponds to a private ledger
created by another processor.
C SYNOPSIS
struct TimestampProvider.Ledger |
 |
Define a ledger used in the system
var obj = new TimestampProvider.Ledger;
// role used to access the ledger
obj.base = Ptr ...
// base address of the ledger
obj.size = Int ...
// number of users
obj.index = Int ...
// entry assigned to this processor
FIELDS
role
Defines how this processor will be using the ledger. The role
also implicitly defines which type of ledger is created. See
the Role enumeration for details.
base
The base address of the ledger as seen by the local processor.
size
The number of users of the current ledger. When adding a new
user to a ledger, be sure to update this value for all processors
using the same ledger.
index
The entry index in the ledger to be used by this processor. Each
processor must have its own unique entry. The index is zero based
(as in array indexing). Index values range from 0 - (size-1).
DETAILS
A ledger is used to keep track of which processors are running.
Depending on the ledger role, there can be two or more users of
the same ledger instance. You can define multiple ledgers. See
ledgers for examples of creating ledgers.
C SYNOPSIS
config TimestampProvider.L_latch // module-wide |
 |
Log event raised at the end of the timer isr
msg: "L_latch: latch=0x%x:0x%x, isr ts=0x%x:0x%x"
};
DETAILS
The timer isr maintains a global tick value used by System
Analyzer to correlate the log events across processor boundaries.
This event is raised at the end of the timer isr. The latch count
should be the same on all processors. The isr timestamp is also
reported. This value can be used to measure the accuracy of the
event correlation. The isr timestamp is captured at the very
beginning of the timer isr.
C SYNOPSIS
config TimestampProvider.L_suspend // module-wide |
 |
Log event raised when loggers are to be suspended
msg: "L_suspend: loggers suspended"
};
DETAILS
The module has determined that the system state is not nominal. To
preserve the events in the log buffers leading up to this point,
the loggers will be suspended. This event is raised shortly before
the loggers are actually suspended.
C SYNOPSIS
config TimestampProvider.cpuIntrNum // module-wide |
 |
Specify cpu interrupt to receive timer interrupt
TimestampProvider.cpuIntrNum = Int undefined;
DETAILS
For accurate event correlation in System Analyzer, it is
recommended not to share this interrupt.
The following table indicates possible interrupt numbers, but
this is device specific. Please consult your manual.
Processor |
Timer ID |
DSP |
4-15 |
EVE |
8-11 |
C SYNOPSIS
config TimestampProvider.estCpuFreq // module-wide |
 |
Estimate the cpu frequency using timestamp sample buffer
TimestampProvider.estCpuFreq = Bool false;
DETAILS
When enabled, this module will save timestamps in the sample
buffer which are then used to calculate an estimate of the
cpu frequency. Run the processor continuously for 30 seconds
to ensure the sample buffer is full. Open ROV and select the
Module tab. The calculated cpu frequency is displayed in the
estCpuFreq column. The timestamp samples are displayed in the
Sample Buffer tab.
Set this config param to false to reduce the data footprint in
your released product.
C SYNOPSIS
config TimestampProvider.eventId // module-wide |
 |
Specify interrupt controller event to receive timer interrupt
TimestampProvider.eventId = Int undefined;
DETAILS
The eventId specifies which interrupt controller event should
receive the timer interrupt. This value is used to route the
timer interrupt through the Interrupt Crossbar to the interrupt
controller event. It is also used to route the interrupt event
to the cpu interrupt specified in
cpuIntrNum.
The following table indicates possible event ids, but this is
device specific. Please consult your manual.
Processor |
Event ID |
DSP |
63-78, 81 |
EVE |
32-39 |
C SYNOPSIS
config TimestampProvider.ledgers // module-wide |
 |
Define the ledgers to be managed by this processor
DETAILS
Ledgers are used to keep track of the other processors. This
is needed to support the auto-logging feature and to issue
LogSync events. Each processor must define at least one ledger.
There are two types of ledgers: a group ledger, and a private
ledger. See the
Role enumeration for details.
Use as few ledgers as possible. However, some system constraints
will require additional ledgers. For example, the EVE processors
have very slow data access to on-chip or external memory. Therefore,
we recommend that each EVE processor use a private ledger. Place
the private ledger in DMEM to ensure fast memory access.
Add the following to your EVE1 configuration script.
var TimestampProvider = xdc.useModule('ti.uia.family.dm.dra7xx.TimestampProvider');
// use private ledger, role = owner
TimestampProvider.ledgers.$add(
new TimestampProvider.Ledger({
role: TimestampProvider.Role_OWNER,
base: 0x40020000
})
);
Each private ledger has exactly two users: an owner (Role_OWNER)
and a user (Role_USER). In the example above, the EVE would always
be the owner. Typically, the DSP would be the corresponding user.
Add the following to your DSP1 configuration script.
var TimestampProvider = xdc.useModule('ti.uia.family.dm.dra7xx.TimestampProvider');
// eve1 ledger, role = user
TimestampProvider.ledgers.$add(
new TimestampProvider.Ledger({
role: TimestampProvider.Role_USER,
base: 0x42020000
})
);
Note in the example above, the EVE defines the ledger address
using its local address (e.g. 0x40020000). However, the DSP must
use the interconnect address (e.g. 0x42020000).
For the remaining processors in the system, you could use one
group ledger. All processors using the same group must agree on
the ledger address, and the number of entries. Each processor must
be assigned its own entry in the ledger.
The following example defines a single group ledger used by two
processors: DSP1 and DSP2. Add the following to your DSP1
configuration script.
var TimerSupport = xdc.useModule('ti.sysbios.family.shared.vayu.TimerSupport');
// group ledger, role = peer
TimestampProvider.ledgers.$add(
new TimestampProvider.Ledger({
role: TimestampProvider.Ledger_PEER,
base: 0x40500000,
size: 2, // DSP1 DSP2
index: 0 // DSP1
})
);
Add the following to your DSP2 configuration script.
var TimerSupport = xdc.useModule('ti.sysbios.family.shared.vayu.TimerSupport');
// group ledger, role = peer
TimestampProvider.ledgers.$add(
new TimestampProvider.Ledger({
role: TimestampProvider.Role_PEER,
base: 0x40500000,
size: 2, // DSP1 DSP2
index: 1 // DSP2
})
);
It is also possible to partition the remaining processors into
groups and assign a group ledger to each processor group. This
might be done to support independent application domains. However,
one requirement is that the processor which owns the timer must
participate in all group ledgers. For example, if DSP1 has
TimestampProvider.owner = true;
then DSP1 must participate in all group ledgers (i.e. Role_PEER).
C SYNOPSIS
config TimestampProvider.maxBusClockFreq // module-wide |
 |
The highest bus clock frequency used to drive the timer
DETAILS
The default ticks per second rate of the timer is calculated by dividing
the timer's bus clock frequency by the cyclesPerTick config parameter.
RETURNS
the 32 MSBs of the highest bus clock frequency used to drive
the timer.
C SYNOPSIS
config TimestampProvider.maxTimerClockFreq // module-wide |
 |
The highest timer clock frequency
TimestampProvider.
maxTimerClockFreq =
Types.FreqHz undefined;
DETAILS
The default ticks per second rate of the timer is calculated by dividing
the timer's bus clock frequency by the cyclesPerTick config parameter.
RETURNS
the 32 LSBs of the highest timer clock frequency
(i.e. ticksPerSecond).
C SYNOPSIS
config TimestampProvider.owner // module-wide |
 |
Determine ownership of the timer
TimestampProvider.owner = Bool undefined;
DETAILS
When set to true, the timer will be enabled and configured
during the boot phase. The owner should run before any other
processor using this same timer. Only one processor should
be configured as the owner of the timer. This processor will
also listen for the timer interrupt and acknowledge it.
When set to false, it is expected that another processor will
enable and configure the timer. This processor will simply
listen for the timer interrupt and acknowledge it.
Note: The ARP32 does not support timer ownership. This config
param must always be false when running on the ARP32.
C SYNOPSIS
config TimestampProvider.syncInterval // module-wide |
 |
Specify the interval for logging sync events
TimestampProvider.syncInterval = UInt 50;
DETAILS
UIA Sync events are used by System Analyzer to correlate the
events from each processor onto a global time base. Only the
last sync event is actually used.
This configuration parameter specifies how frequently the sync
events should be raised. In order to maintain accurate event
correlation, you should raise one sync event within each log
data window. For example, if your log buffer contains 100 ms
of data, then you should raise a sync event each 0.1 seconds
(100 ms = 0.1 sec).
Each syncInterval is 0.001953125 seconds. Divide the data window
by this value to get the syncInterval (round down).
0.1 sec / 0.001953125 sec = 51.2
TimestampProvider.syncInterval = 51;
When using multiple logger instances, the data window for each
instance is probably different. Use System Analyzer to measure
the data overlap of your region of interest. Use the length of
this region to calculate the syncInterval.
The syncInterval should be as large as possible to reduce logging
overhead, yet small enough to yield accurate event correlation.
C SYNOPSIS
config TimestampProvider.timerId // module-wide |
 |
Identify which timer to use as the timestamp clock source
TimestampProvider.timerId = UInt undefined;
DETAILS
The timers are named Timer1-Timer16; their corresponding ids
are 0-15 (e.g. for Timer3, use id=2). Not all timers are
appropriate clock sources for this module. Use one of the
following timers:
Timer Name |
Description |
Timer[3,4,9,11,13,14,15,16] |
PD_L4PER power domain |
Timer[5,6,7,8] |
PD_IPU power domain |
All executables must use the same timer in order to support
event correlation in System Analyzer.
C SYNOPSIS
metaonly config TimestampProvider.common$ // module-wide |
 |
Common module configuration parameters
DETAILS
All modules have this configuration parameter. Its name
contains the '$' character to ensure it does not conflict with
configuration parameters declared by the module. This allows
new configuration parameters to be added in the future without
any chance of breaking existing modules.
generated on Tue, 14 Feb 2017 00:15:12 GMT