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. |
[...]
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:
|
||
void ldx_cpu_free_available_freq(available_frequencies_t freq) |
Frees a previously requested available_frequencies_t struct. |
[...]
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. |
[...]
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. |
[...]
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. |
[...]
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. |
[...]
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.
|
[...]
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.