Power management (PM) allows control of the power consumption by managing voltages and frequencies of the different elements in a SOC. Digi provides an API with a set of functions to control the power consumption of the module by managing the frequency of the CPU and GPU.

To use this API, include the following header file:

#include <libdigiapix/pwr_management.h>

Manage governors

Governors are power schemes for the CPU. Only one governor may be active at a time. For details, see the kernel documentation in the kernel source. You can configure and set the governor with the following functions:

Function Description

governor_mode_t ldx_cpu_get_governor()

Returns the current governor struct.

int ldx_cpu_set_governor (governor_mode_t governor)

Sets the CPU governor to the given value. Returns EXIT_SUCCESS on success, EXIT_FAILURE otherwise.

int ldx_cpu_is_governor_available(governor_mode_t governor)

Checks whether the governor is supported in the CPU. Returns EXIT_SUCCESS if the governor is supported, EXIT_FAILURE otherwise.

governor_mode_t ldx_cpu_get_governor_type_from_string (const char *governor_string)

Returns the governor struct for the given string.

const char * ldx_cpu_get_governor_string_from_type(governor_mode_t governor)

Returns the string representation of the given governor struct.

Some governors may not be available for your platform.
List and set governor
[...]

int i;
governor_mode_t governor_mode;

/* List available governors */
printf("These are the available governors:\n");
for (i = 0; i < MAX_GOVERNORS; i++) {
    if (ldx_cpu_is_governor_available(i) == EXIT_SUCCESS) {
        printf("\t\t\t%s\n", ldx_cpu_get_governor_string_from_type(i));
    }
}

printf("This is the current governor: %s\n", ldx_cpu_get_governor_string_from_type(ldx_cpu_get_governor()));

/* Set the userspace governor */
governor_mode = ldx_cpu_get_governor_type_from_string("userspace");
if (governor_mode != GOVERNOR_INVALID) {
    ldx_cpu_set_governor(governor_mode);
}

[...]

Establish CPU frequencies

You can use the following functions to set and read CPU frequencies:

Function Description

available_frequencies_t ldx_cpu_get_available_freq()

Returns an available_frequencies_t struct with the following fields:

  • data: An array with the values of the frequencies.

  • len: The size of the data array

You must free the requested available_frequencies_t struct when it is no longer required.

void ldx_cpu_free_available_freq(available_frequencies_t freq)

Frees a previously requested available_frequencies_t struct.

List available frequencies
[...]

int i;
available_frequencies_t freq = ldx_cpu_get_available_freq();

printf("These are the available frequencies:\n");
for (i = 0; i < freq.len; i++) {
    printf("\t\t\t%d\n", freq.data[i]);
}
ldx_cpu_free_available_freq(freq);

[...]
Function Description

int ldx_cpu_get_max_freq();

Returns the maximum frequency supported by the CPU, -1 on error.

int ldx_cpu_get_min_freq();

Returns the minimum frequency supported by the CPU, -1 on error.

Get the minimum and maximum frequencies
[...]

printf("This is the minimum frequency of the CPU %d\n", ldx_cpu_get_min_freq());

printf("This is the maximum frequency of the CPU %d\n", ldx_cpu_get_max_freq());

[...]

The scaling frequency is used in by the governors to determine the operation frequency.

Function Description

int ldx_cpu_get_max_scaling_freq();

Returns the maximum scaling frequency of the CPU, -1 on error.

int ldx_cpu_set_max_scaling_freq(int freq);

Sets the maximum scaling frequency of the CPU. It returns EXIT_SUCCESS on success, EXIT_FAILURE otherwise.

int ldx_cpu_get_min_scaling_freq();

Returns the minimum scaling frequency of the CPU, -1 on error.

int ldx_cpu_set_min_scaling_freq(int freq);

Sets the minimum scaling frequency of the CPU. It returns EXIT_SUCCESS on success, EXIT_FAILURE otherwise.

int ldx_cpu_get_scaling_freq();

Returns the current scaling frequency of the CPU, -1 on error.

int ldx_cpu_set_scaling_freq(int freq);

Sets the scaling frequency of the CPU. It returns EXIT_SUCCESS on success, EXIT_FAILURE otherwise.

Get and set minimum and maximum scaling frequencies
[...]

int min_scaling_freq, max_scaling_freq;

min_scaling_freq = ldx_cpu_get_min_scaling_freq();
printf("This is the minimum scaling frequency of the CPU %d\n", min_scaling_freq);

max_scaling_freq = ldx_cpu_get_max_scaling_freq();
printf("This is the maximum scaling frequency of the CPU %d\n", max_scaling_freq);

/* To obtain better performance, set min_scaling_freq to the maximum frequency */
ldx_cpu_set_min_scaling_freq(max_scaling_freq);

[...]

Establish GPU frequency

The ConnectCore 6UL does not have a GPU, so the functions in this section have no effect on this platform.

Another way to reduce the power consumption of the module is to lower the GPU frequency. Digi provides a set of functions to lower the frequency by controlling the GPU prescaler.

Note that lowering the GPU clock frequency will impact graphic performance.
Function Description

int ldx_gpu_get_min_multiplier();

Returns the minimum multiplier of the GPU, -1 on error.

int ldx_gpu_set_min_multiplier(int multiplier);

Sets the minimum multiplier of the GPU. This multiplier is applied when the CPU temperature reaches the passive trip point. It returns EXIT_SUCCESS on success, EXIT_FAILURE otherwise.

int ldx_gpu_get_multiplier();

Returns the current multiplier of the GPU, -1 on error.

int ldx_gpu_set_multiplier(int multiplier);

Sets the current multiplier for the GPU. It returns EXIT_SUCCESS on success, EXIT_FAILURE otherwise.

Get and set GPU multiplier
[...]

int min_multiplier = ldx_gpu_get_min_multiplier();
printf("This is the GPU min scaling: %d\n", min_multiplier);

/* To reduce power consumption, set the current scale to a lower value*/
/* This will impact GPU performance */
ldx_gpu_set_multiplier(ldx_gpu_get_multiplier() / 2);

[...]

Manage temperature

Module temperature is directly related to power consumption. Digi’s power management API allows you to read and define temperatures thresholds. The Linux kernel defines two temperature trip points:

  • passive: when the CPU temperature exceeds this temperature, the kernel takes certain cooling actions such as reducing the GPU scaling frequency.

  • critical: when the CPU temperature exceeds this temperature, the system shuts down.

Function Description

int ldx_cpu_get_current_temp()

Returns the current temperature reported by the CPU, -1 on error.

int ldx_cpu_get_passive_trip_point()

Returns the passive temperature of the CPU, -1 on error.

int ldx_cpu_set_passive_trip_point(int temp)

Sets the passive trip point of the CPU. It returns EXIT_SUCCESS on success, EXIT_FAILURE otherwise.

int ldx_cpu_get_critical_trip_point();

Returns the critical temperature of the CPU, -1 on error.

int ldx_cpu_set_critical_trip_point(int temp)

Sets the critical trip point of the CPU. It returns EXIT_SUCCESS on success, EXIT_FAILURE otherwise.

Manage temperature trip points

[...]

printf("This is the current CPU temperature: %d\n", ldx_cpu_get_current_temp());
printf("This is the current critical trip point: %d\n", ldx_cpu_get_critical_trip_point());
printf("This is the current passive trip point: %d\n", ldx_cpu_get_passive_trip_point());

[...]

Manage CPU cores

Another way to reduce the power consumption of the module is to disable CPU cores.

Function Description

int ldx_cpu_get_usage()

Returns CPU usage in percentage, -1 on error.

int ldx_cpu_get_number_of_cores()

Gets the number of cores available in the CPU, -1 on error.

int ldx_cpu_enable_core(int core)

Enables the core selected by its index. Return EXIT_SUCCESS on success, EXIT_FAILURE otherwise. The index starts at 0.

int ldx_cpu_disable_core(int core)

Disables the core selected by its index. Return EXIT_SUCCESS on success, EXIT_FAILURE otherwise. The index starts at 0.

You can disable all cores but one. If you attempt to disable the last remaining core, the system returns an error.
Work with the CPU
[...]
int cores = ldx_cpu_get_number_of_cores();
printf("This is the number of cores: %d\n", cores);

printf("This is the current CPU usage: %d\n", ldx_cpu_get_usage());

if (cores >= 2) {
    /* If we have two or more cores disable one */
    ldx_cpu_disable_core(0);
}

[...]

Power management example

The following examples demonstrate how to manage the CPU using the APIx:

  • apix-cpu-example: demonstrates how to obtain and set different CPU parameters.

  • apix-pm-application: demonstrates how to manage the CPU & GPU using the APIX.

Import the power management API examples in Eclipse using the Digi Embedded Yocto plugin. For more information, seeĀ Create a new DEY sample project. These examples are included in Digi Embedded Yocto. Go to GitHub to see the source code.