Reputation: 68
How can I write a C program (in userspace) to call functions that are part of a kernel driver? If it's not possible to do directly, how else do I do it?
CONTEXT: I am trying to use the PWM pins of my single-board computer (Intel NUC DE3815TYBE) so that I can control fans. A linux driver called pwm_lpss allows control of these pins (driver developed by Intel, source code here). I have verified that this driver is installed by using the lsmod
command. Here is the driver information after typing modinfo pwm_lpss
:
filename: /lib/modules/3.19.0-25-generic/kernel/drivers/pwm/pwm-lpss.ko
license: GPL v2
author: Mika Westerberg <[email protected]>
description: PWM driver for Intel LPSS
srcversion: 44AA14AF3E2F96C813770A8
depends:
intree: Y
vermagic: 3.19.0-25-generic SMP mod_unload modversions
signer: Magrathea: Glacier signing key
sig_key: 6A:AA:11:D1:8C:2D:3A:40:B1:B4:DB:E5:BF:8A:D6:56:DD:F5:18:38
sig_hashalgo: sha512
So I know where the driver module is (the pwm-lpss.ko
file) and I have the source code which I know has a function in it called pwm_lpss_config()
that I'd like to use. How do I call the function from my userspace C program? How would I go about #including it? Or is this not possible to do from userspace?
Unfortunately Intel has provided zero documentation for how to use this driver. I thought drivers normally map their functionality to some user-accessible file. I was able to find some PWM-related files after some digging, but I haven't been able to find a file that looks like it can set PWM duty cycle/frequency.
Upvotes: 2
Views: 7552
Reputation: 39316
It's a standard Linux PWM driver, so no special documentation is necessary.
Check the /sys/class/pwm/
directory. (/sys
is the interface the kernel provides for access to its data structures. It just looks and acts like a filesystem.) You should have something like /sys/class/pwm/pwmchip0/
. Each such directory corresponds to a PWM chip.
The directory will have the following entries. You may need superuser privileges to access these (as you wouldn't want everybody to mess with them):
npwm
: Read this to find out how many PWM channels this chip has.
export
: Write a channel number (0 to whatever-the-number-in-npwm
-1) to make that channel available via this sysfs interface
unexport
: Write a channel number to remove the channel from sysfs interface control
Each PWM channel exported to be used via the sysfs interface will show up as a subdirectory named pwmN
, where N
is the channel number. Here, you can read and write to entries
period
: Total period (off + on) in nanoseconds.
duty_cycle
: On time in nanoseconds. Must be less than period.
polarity
: If the chip supports reversing the signal polarity, you can write inversed
here to invert the polarity; normal
is the default/normal polarity.
enable
: 1
if enabled, 0
if disabled.
When reading or writing to these entries, no special locking is necessary. The kernel will receive all data in one write()
, and return all data in one read()
operation. When a write()
succeeds, the kernel has applied the setting.
Upvotes: 6
Reputation: 20080
some ioctl
? The ioctl() function manipulates the underlying device parameters of special files.
Along the lines
fd = open("/dev/pwm0", O_RDONLY); // put whatever device you've got
if (ioctl(fd, STATUSGET, &status) == -1) // magic constant should be set
....
} else {
....
}
Upvotes: 1