How to Use PWM on Torizon OS
Introduction
This article explains how to use PWM in Torizon OS. The first part of the article focuses on using a pin that is configured by default as a PWM. The second part of the article provides information on how to enable or disable PWM channels using the device tree.
This article complies with the Typographic Conventions for Torizon Documentation.
Prerequisites
- Learn how to use a PWM on Linux by reading the article PWM (Linux).
Use Available PWMs
PWM can either be controlled by your application, or by a device driver. If a device driver uses a PWM, you will not be able to control it from your application, therefore you must first list the available PWMs:
# sudo cat /sys/kernel/debug/pwm
- Those shown as
null
are either not exported or in use by a driver. Try to export them as explained on PWM (Linux); if successful, you will be able to use them. - Those shown as
sysfs
are exported to userspace control and ready-to-use.
Sample Application
Toradex has provided a sample code written in C that basically writes to files, just like as explained on PWM (Linux) except C is used instead of the command-line. Toradex provides a repository that contains all the sample code related to the Torizon OS project, clone it to your PC:
$ git clone https://github.com/toradex/torizon-samples
Build and Run the Sample
The sample code sets the settings of the PWM channel at the pwmchip0
controller interface. If required, set controller and settings according to the needs in samples/pwm/pwm/pwm.c.
Move to the PWM directory:
$ cd toradex/torizon-samples/pwm/
Select your architecture below and execute the command
to build an image:
$ docker build . -t pwm-sample
$ docker build . --build-arg GCC_PREFIX=aarch64-linux-gnu --build-arg CROSS_TC_IMAGE_ARCH=arm64 --build-arg ARCH_ARG=linux/arm64 -t pwm-sample
Please remember that if you once built your image for one architecture, you need to pass the --pull
argument to build for another architecture. According to the Docker documentation, the pull
argument will always attempt to pull a newer version of the image.
Example:
$ docker build --pull .
Deploy the image to the board according to the article Deploying Container Images to Torizon OS.
Now the image can be run but the container needs access to the pwm sysfs interface. Access can be granted either by mounting the /sys
or if access is needed to be tightly controlled, sub-directory of /sys
containing the required interface can only be mounted.
Mounting /sys
:
# docker run -it --rm -v /sys:/sys pwm-sample
In a case that a restricted control to a desired interface is required:
# docker run -it --rm -v /sys/class/pwm/pwmchip0:/sys/class/pwm/pwmchip0 pwm-sample
In case of PWM, mounting the /sys/class/pwm/ and trying to write to the files will result in a read-only filesystem issue, because its contents are symbolic links to the actual device in /sys/devices/soc/xxx/xxx/pwm/. Therefore, use absolute paths of symbolic links like /sys/class/pwm/pwmchip0.
Sample Explained
In the first stage of the build process, the image is based on debian-cross-toolchain-$CROSS_TC_IMAGE_ARCH
to cross-compile the sample application on the host machine (your PC).
ARG CROSS_TC_IMAGE_ARCH=armhf
# First stage, x86_64 build container
FROM torizon/debian-cross-toolchain-$CROSS_TC_IMAGE_ARCH:2 AS cross-container
In the second stage, the binary is copied from the first stage image to the /usr/local/bin
of the final image (second stage). This will produce the final application container in a small and deployable image with the tag pwm-sample
:
ARG ARCH_ARG=linux/arm
ARG IMAGE_TAG=3-bookworm
# Second stage, container for target
FROM torizon/debian:$IMAGE_TAG AS deploy-container
# get the compiled program from the Build stage
COPY /project/build/* /usr/local/bin/
CMD pwm
Enable PWM Channel
Toradex modules have all PWM channels enabled by default, some modules have dedicated a PWM channel for backlight control. You can use that channel for a different purpose if the backlight is not required.
It is possible to disable the Backlight of a PWM channel by either modifying the device tree or creating a device tree overlay.
Modify Device Tree
Backlight support can be removed to free up the PWM channel by deleting the backlight node in the device tree file.
/delete-node/backlight;
For more information about this, please refer to Device Tree Customization.
Device Tree Overlay
As the device tree overlay does not support deleting a node, it can be set to disabled
to mark it powered off/ not plugged in.
/dts-v1/;
/plugin/;
/ {
fragment@0 {
target = <&backlight>;
__overlay__ {
status = "disabled";
};
};
};
The recommended way to apply device tree changes to Torizon OS is through the TorizonCore Builder Tool. Please refer to Device Tree Overlays article for more information.