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. 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.

It 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.

It 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

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. The index starts at 0.

It returns EXIT_SUCCESS on success, EXIT_FAILURE otherwise.

int ldx_cpu_disable_core(int core)

Disables the core selected by its index. The index starts at 0.

It returns EXIT_SUCCESS on success, EXIT_FAILURE otherwise.

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.