CPU Programming Guide#
This section contains the following topics:
Using CPU Core Features#
Before using the other functions, the CPU module needs to be initialized using CPU_Init() (see the example below).
Listing - Example of call to CPU_Init()#
void main (void)
{
:
:
CPU_Init(); /* Initialize the CPU Module. */
:
:
}
CPU Name#
For debugging (or other) purposes, an application can set a name for the CPU currently executing the code. An application can clear the CPU name with CPU_NameClr(), set it with CPU_NameSet() and read it with CPU_NameGet(). See the example below for a usage sample.
Listing - Example of call to CPU_NameClr(), CPU_NameSet() and CPU_NameGet()#
const CPU_CHAR App_CoreName[] = "MMIX";
:
:
void App_SomeTask (void *p_arg)
{
RTOS_ERR err;
:
:
CPU_NameClr(); /* Clear previously used CPU name. */
/* Set CPU Name. */
CPU_NameSet(&App_CoreName[0], /* Set name to 'MMIX'. */
&err);
if (err.Code != RTOS_ERR_NONE) {
/* Handle error on CPU name set. */
}
:
:
}
void App_SomeOtherTask (void *p_arg)
{
RTOS_ERR err;
CPU_CHAR cpu_name[CPU_CFG_NAME_SIZE];
:
:
/* Get CPU Name. */
CPU_NameGet(&cpu_name[0], /* Pointer to user allocated character buffer. */
&err);
if (err.Code != RTOS_ERR_NONE) {
/* Handle error on CPU name get. */
}
:
:
}
Optimized Operations#
The CPU module offers a series of functions frequently used by real-time kernels, and the CPU port can implement these functions to optimize their usage. An application can use CPU_CntLeadZeros() to count the number of most-significant bits set to zero. Conversely, CPU_CntTrailZeros() obtains the number of least-significant bits set to zero.
Listing - Example of call to CPU_CntLeadZeros() and CPU_CntTrailZeros()#
void App_SomeTask (void *p_arg)
{
CPU_DATA value;
CPU_DATA zeroes;
:
:
zeroes = 0x1FFFFFFF; /* Count number of leading zeros. */
value = CPU_CntLeadZeros(zeros); /* Should be 3. */
:
:
zeroes = 0xFFFFFFF8; /* Count number of trailing zeros. */
value = CPU_CntTrailZeros(zeros); /* Should be 3. */
:
:
}
Timestamp#
The CPU module offers services that use a built-in timestamp counter (if available), which feature a number of time value types. Therefore, the CPU module has 32-bit and 64-bit width operations.
The CPU_TS_Get32() function returns the current value of the timestamp counter, in timestamp ticks.
The CPU_TS_Get64() function can be used instead if the counter is more than 32-bits wide.
An application can convert the value read in timestamp ticks to microseconds using CPU_TS32_to_uSec() or CPU_TS64_to_uSec(), depending on the type of the timestamp counter. An application can use CPU_TS_TmrFreqGet() to obtain the frequency at which the timestamp counter is currently ticking.
The following example shows how to use the 32-bit width functions. However, the same method can be applied to 64-bit functions.
Listing - Example of call to CPU_TS_Get32(), CPU_TS32_to_uSec() and CPU_TS_TmrFreqGet().#
void App_SomeTask (void *p_arg)
{
CPU_TS32 timestamp;
CPU_INT64U usecs;
CPU_TS_TMR_FREQ freq;
RTOS_ERR err;
:
:
timestamp = CPU_TS_Get32(); /* Read current timestamp counter value. */
usecs = CPU_TS32_to_uSec(timestamp); /* Convert timestamp counter to microseconds. */
:
:
freq = CPU_TS_TmrFreqGet(&err); /* Get the timestamp counter's frequency. */
if (err.Code != RTOS_ERR_NONE) {
/* Handle error on timestamp frequency get. */
}
:
:
}
Miscellaneous#
The CPU module uses abstractions to insert a break instruction and to trap software exceptions.
CPU_BREAK() function inserts a break.
CPU_SW_EXCEPTION() traps software exceptions.
Listing - Example of call to CPU_BREAK() and CPU_SW_EXCEPTION().#
void App_SomeTask (void *p_arg)
{
:
:
if (/* Some debug event*/) {
CPU_BREAK();
}
:
:
}
void App_SomeOtherTask (void *p_arg)
{
:
:
if (/* Some unrecoverable error */) {
CPU_SW_EXCEPTION();
}
:
:
}