0

I am pretty new to linux kernel.I am trying to generate PWM through linux. The API man talks about a sysfs interface. I want to implement a userspace program in C. But using PWM forces me to use a command line. Furthermore, using read, write is a problem in C as when I am using cd, it is changing path directory. Thus the path is variable. Is there any way I can pass values to pwm_config() without using sysfs? Perhaps through ioctl? If yes, then what would be the procedure? Application C code:

void main(){

    int export = open("/sys/class/pwm/pmwchip0/export",O_WRONLY);
    int period,duty_cycle,enable;

    if(export == -1)
    {
        perror("Export:");
    }

and so on for other files like period and duty cycle.

When I try to run my application I get the following error.

Export:: No such file or directory
Export_write: Bad file descriptor
Period_write:: Bad file descriptor
Duty_cycle_write:: Bad file descriptor
Enable_write:: Bad file descriptor
gPats
  • 315
  • 2
  • 17
  • By changing path i mean the path automaically changes from /sys/class/pwm/pwmchip0 to /sys/devices/soc0/amba/f8001000.timer/pwm/pwmchip0 – gPats Sep 11 '17 at 16:41
  • When you `cd` the current directory changes because it is a symbolic link to another directory and some shells do that. But if you use a C program you should really use absolute paths, so open `/sys/class/pwm/pwmchip0` should just work. – rodrigo Sep 11 '17 at 18:07

1 Answers1

1

As far as I know, the sysfs is the only standard userspace interface to PWM. But anything you can do from the command line can be done in C (the shell is written in C, after all).

The problem you are having with cd is not actually a problem. Inside sysfs the directories in /sys/class/pwd/* are actually symbolic links to the proper devices. In your case /sys/class/pwm/pwmchip0 is a symlink to /sys/devices/soc0/amba/f8001000.timer/pwm/pwmchip0.

The funny thing is that some shells, when you cd a symbolic link will resolve to the real directory, but other shells will actually keep the symlink name as the current directory.

But that issue with the directory symlinks should not be an issue for you. A C program willing to manage PWM devices should not change the working directory. Instead open the files with the full path:

open("/sys/class/pwm/pwmchip0/npwm", O_RDONLY);

and so on.

rodrigo
  • 94,151
  • 12
  • 143
  • 190
  • hey rodrigo, I tried to write a user space application in C. But I get no such file or directory when I try to open /sys/class/pwm/pwmchip0/export – gPats Sep 12 '17 at 18:19
  • @gPats: What do you get when you run `ls -l /sys/class/pwm/pwmchip0/`? – rodrigo Sep 12 '17 at 18:42
  • I get `lrwxrwxrwx 1 root root 0 Jan 1 00:00 device -> ../../../f8001000.timer --w------- 1 root root 4096 Jan 1 00:00 export -r--r--r-- 1 root root 4096 Jan 1 00:00 npwm drwxr-xr-x 2 root root 0 Jan 1 00:00 power lrwxrwxrwx 1 root root 0 Jan 1 00:00 subsystem -> ../../../../../../class/pwm -rw-r--r-- 1 root root 4096 Jan 1 00:00 uevent --w------- 1 root root 4096 Jan 1 00:00 unexport ` – gPats Sep 13 '17 at 14:14
  • @gPats: Your directory listing is correct, and this file does exist. I find hard to believe that you try to open that file and you get `ENOENT`. Maybe you get `EPERM`?. Or maybe your C code is incorrect? Can you edit your original post and post your C program? – rodrigo Sep 13 '17 at 14:50
  • 1
    @gPats. Hmmm, looking carefully at your code, you try to open a `pmwchip0` but you actually have a `pwmchip0`! Note the P**M**W vs P**W**M! – rodrigo Sep 13 '17 at 16:10
  • Thank you so much @rodrigo I apologise it was a silly mistake – gPats Sep 13 '17 at 16:12