Template:ArticleBasedOnModel Template:ArticleMainWriter Template:ArticleApprovedVersion Template:ReviewsComments Template:ReviewsComments
1. Article purpose[edit source]
The purpose of this article is the following:
- introduce PWM (pulse width modulation) Linux® Framework
- provide general information of PWM
- describe the main components and stakeholders
- give examples of PWM usage:
- user space (sysfs) usage
- kernel space (API) usage
2. PWM overview[edit source]
2.1. Component description[edit source]
- PWM user (User space)
The user can use PWM sysfs interface, from a user terminal or a custom application, to control PWM device(s) from user space.
- PWM user (Kernel space)
User drivers can use PWM API to control PWM external device(s) from kernel space (such as back-light, vibrator, LED or fan drivers).
- PWM framework (Kernel space)
The PWM core provides sysfs interface and PWM API. They can be used to implement PWM user and PWM controller drivers.
- PWM drivers (Kernel space)
Provider drivers such as STM32 TIM Linux driver and STM32 LPTIM Linux driver that expose PWM controller(s) to the core.
- PWM hardware
PWM controller(s) such as TIM internal peripheral[1] and LPTIM internal peripheral[2] used to drive external PWM controlled devices.
2.2. API description[edit source]
Documentation on PWM interface can be found under kernel Documentation/pwm.txt
2.2.1. Kernel PWM API[edit source]
The main useful user API are the following:
- devm_pwm_get() or pwm_get() / pwm_put(): this API is used to look up, request, then free a PWM device.
- pwm_init_state(), pwm_get_state(), pwm_apply_state(): this API is used to initialize, retrieve and apply the current PWM device state.
- pwm_config(): this API updates the PWM device configuration (period and duty cycle).
- ...
2.2.2. Sysfs interface[edit source]
In addition to Documentation/pwm.txt[3] details on ABI are available in Documentation/ABI/testing/sysfs-class-pwm[4].
3. PWM configuration[edit source]
3.1. Kernel configuration[edit source]
Activate PWM framework in the kernel configuration through the Linux menuconfig tool, Menuconfig or how to configure kernel (CONFIG_PWM=y):
PWM) Support --->Device Drivers ---> [*] Pulse-Width Modulation (
Activate PWM drivers for STM32 PWM drivers: STM32 TIM Linux driver and/or STM32 LPTIM Linux driver
3.2. Device tree configuration[edit source]
- PWM generic DT bindings:
PWM DT bindings documentation[5] describes device tree properties related to standard PWM user nodes and PWM controller nodes.
- Detailed DT configuration for STM32 internal peripherals:
TIM device tree configuration and/or LPTIM device tree configuration
4. How to use PWM[edit source]
PWM can be used either from the user or the kernel space.
4.1. How to use PWM with sysfs interface[edit source]
The available PWM controllers are listed in sysfs:
$ ls /sys/class/pwm
pwmchip0
The number of channels per controller can be read in npwm (read-only)
$ cd /sys/class/pwm/pwmchip0
$ cat npwm
4
Each channel is exported (requested for sysfs activation) by writing the corresponding number in 'export'.
As an example, proceed as follows to export the first channel (e.g. channel 0): Template:ReviewsComments
$ echo 0 > export
$ ls
device export npwm power pwm0 subsystem uevent unexport
The period and duty cycle must be configured before enabling any channel.
As an example, proceed as follows to set a period of 100 ms with a duty cycle of 60% on channel 0:
$ echo 100000000 > pwm0/period
$ echo 60000000 > pwm0/duty_cycle
$ echo 1 > pwm0/enable
The polarity can be inverted or set to normal by using the polarity entry:
$ echo "inversed" > pwm0/polarity
$ cat pwm0/polarity
inversed
$ echo "normal" > pwm0/polarity
$ cat pwm0/polarity
normal
4.2. How to use PWM capture with sysfs interface[edit source]
PWM capture is available on some PWM controllers such as TIM internal peripheral[1] (see TIM configured in PWM input capture mode ).
PWM input on it: $ cd /sys/class/pwm/pwmchip0 $ echo 0 > export $ cd pwm0 $ ls capture duty_cycle enable period polarity power uevent $ cat capture 10000 1002 Template:Highlight# First export a channel (e.g. 0), then capture
4.3. Example of PWM usage with kernel PWM API[edit source]
Several in-kernel drivers use kernel PWM API. Below a few examples:
- pwm-beeper: drivers/input/misc/pwm-beeper.c[6] driver, Template:CodeSource DT binding documentation.
- pwm-vibrator: drivers/input/misc/pwm-vibra.c[7] driver, Template:CodeSource DT binding documentation.
5. How to trace and debug the framework[edit source]
5.1. How to monitor with debugfs[edit source]
PWM usage can be monitored from debugfs 'pwm' entry. For example:
PWM devices Template:Highlight pwm-0 (sysfs ): requested enabled period: 1000000 ns duty: 500000 ns polarity: normal Template:Highlight pwm-1 ((null) ): period: 0 ns duty: 0 ns polarity: normal pwm-2 ((null) ): period: 0 ns duty: 0 ns polarity: normal Template:Highlight pwm-3 ((null) ): period: 0 ns duty: 0 ns polarity: normal$ cd /sys/kernel/debug/ $ cat pwm platform/44000000.timer:pwm, 4
6. References[edit source]
- ↑ Jump up to: 1.0 1.1 TIM internal peripheral
- ↑ LPTIM internal peripheral
- ↑ Documentation/pwm.txt, Linux PWM interface overview
- ↑ Documentation/ABI/testing/sysfs-class-pwm, Linux PWM Application binary interface
- ↑ Documentation/devicetree/bindings/pwm/pwm.txt, PWM DT bindings documentation
- ↑ Template:CodeSource, Example to use kernel PWM API
- ↑ Template:CodeSource, Example to use kernel PWM API