操作系统 = Ubuntu 服务器
我不知道最好的方法来做到这一点,希望得到任何指点。
我正在使用 SBC(橙色 pi 5b),并且使用 Wiringpi 时 PWM 支持被破坏。
我可以在以 root 身份登录时执行以下命令,在引脚 2 上创建 50Hz 方波
echo 0 > /sys/class/pwm/pwmchip5/export
echo 20000000 > /sys/class/pwm/pwmchip5/pwm0/period
echo 1000000 > /sys/class/pwm/pwmchip5/pwm0/duty_cycle
echo 1 > /sys/class/pwm/pwmchip5/pwm0/enable
我无法使用 sudo 在用户帐户中执行相同的命令或更改 pwmchip5 目录的权限
我想要实现的是创建一个以root身份运行的守护进程/服务/api/rpc(最好是Python,但我对c有一点技巧)(在启动时使用crontab或作为服务),并且任何非- root 用户可以向它发送类似的命令
pwmservice init pwmchip5
pwmservice period pwmchip5 20000000
pwmservice duty_cycle pwmchip5 1000000
pwmservice enable pwmchip5
无需成为 root 或使用 sudo。请注意,最后 4 个命令将使服务以 root 身份执行上面的 bash 命令
这可能吗?有人能指出我正确的方向吗?另外,像这样的东西会起作用还是有更好的方法。
https://betterprogramming.pub/a-simple-way-to-make-rpcs-with-python-52ad8e9286c1
干杯
我认为这更多的是一个 Linux 权限问题,而不是一个编程问题,但尽管如此:
您可以使用
ls -l
来确定 /sys/class/pwm/...
中文件的组所有者,例如,这可能是组 gpio
。然后使用 adduser username gpio
将需要执行这些命令的所有用户添加到该组。也许您首先需要一些 udev 规则来设置组所有权。
或者您可以为此编写一个小型 C 程序,对其进行编译,然后将编译后的二进制文件放入
/usr/local/bin/pwmcontrol
中,并使用 SETGID 放入 gpio
组(或拥有控制文件的任何组)1。然后它将始终以该组的权限运行:
gcc main.c -o pwmcontrol
sudo cp pwmcontrol /usr/local/bin/
sudo chgrp gpio /usr/local/bin/pwmcontrol
sudo chmod g+s /usr/local/bin/pwmcontrol
这里有一些可以帮助您入门的 C 代码,包括错误处理。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int pwm_enable() {
/// TODO implement
return 0; // success
}
int pwm_disable() {
/// TODO implement
return 0; // success
}
int write_file(const char *path, const char *data) {
FILE *f = fopen(path, "w");
if (!f) return 1;
size_t length = strlen(data);
size_t written = fwrite(data, 1, length, f);
fclose(f);
return (length != written) ? 1 : 0; // 0 == success, 1 == fail
}
int pwm_export() {
/// TODO implement
return 0; // success
}
void err_exit(const char *message, int exitcode) {
perror(message);
pwm_disable(); // for safety reasons, turn off PWM if something went wrong
exit(exitcode);
}
int pwm_set(const char *period, const char *duty_cycle) {
if (0 != write_file("/sys/class/pwm/pwmchip5/pwm0/period", period)) {
return 1;
}
if (0 != write_file("/sys/class/pwm/pwmchip5/pwm0/duty_cycle", duty_cycle)) {
return 1;
}
return 0; // success
}
int main(int argc, char **argv) {
// Determine what to do according to the first argument
if (argc == 4 && strcmp(argv[1], "set") == 0) {
if (0 != pwm_export()) {
err_exit("Error exporting PWM chip", 1);
}
if (0 != pwm_set(argv[2], argv[2])) {
err_exit("Error setting PWM period and duty cycle", 1);
}
if (0 != pwm_enable()) {
err_exit("Error enabling PWM", 1);
}
exit (0); // 0 == success
}
else if (argc == 2 && strcmp(argv[1], "start") == 0) {
// TODO
exit (0); // 0 == success
}
else if (argc == 2 && strcmp(argv[1], "stop") == 0) {
// TODO
exit (0); // 0 == success
}
printf("Usage:\n");
printf(" %s set PERIOD DUTYCYCLE\n", argv[0]);
printf(" %s start\n", argv[0]);
printf(" %s stop\n", argv[0]);
exit(1);
}
1 当然,您也可以使用 SETUID root (
chown root
+ chmod u+s
),但是以 root 身份运行某些东西是危险的。特别是如果它是您自己编写的 C 程序,而不了解 C 安全漏洞如何工作。