三明市建设局网站,南昌网站小程序开发,国际新闻最新消息今天2024年,seo如何优化一个网站这个宏我们在内核里面使用非常频繁#xff0c;这个宏的作用可以抛出sys设备节点给用户使用。用户可以读写sys/class下面的文件节点#xff0c;以达到控制内核驱动的功效。比如#xff0c;像这样的设备节点weiqifa:/sys/class/zigbee/onoff $ ls
gpio_en power subsystem uev… 这个宏我们在内核里面使用非常频繁这个宏的作用可以抛出sys设备节点给用户使用。用户可以读写sys/class下面的文件节点以达到控制内核驱动的功效。比如像这样的设备节点weiqifa:/sys/class/zigbee/onoff $ ls
gpio_en power subsystem uevent
weiqifa:/sys/class/zigbee/onoff $
使用方法static ssize_t gpio_store_en(struct device *dev,struct device_attribute *attr,const char *buf, size_t count)
{struct gpio_dev_data *dev_data dev_get_drvdata(dev);unsigned long value 0;int ret;/*将echo进来的buf转换成整型*/ret kstrtoul(buf, 16, value);if (ret 0) {printk( %s:kstrtoul failed, ret%d\n, __func__, ret);return ret;}printk(%s: en value : %d\n, __func__, (int)value);if (value) {gpio_direction_output(dev_data-en_pin, dev_data-en_val);dev_data-gpio_val 1;} else {gpio_direction_output(dev_data-en_pin, !dev_data-en_val);dev_data-gpio_val 0;}return count;
}static char mybuf[10]123;/*cat命令时,将会调用该函数*/
static ssize_t gpio_show_en(struct device *dev,struct device_attribute *attr, char *buf)
{struct gpio_dev_data *dev_data dev_get_drvdata(dev);snprintf(mybuf,sizeof(mybuf),%d,dev_data-gpio_val);return sprintf(buf, %s\n, mybuf);
}static DEVICE_ATTR(gpio_en,0664,gpio_show_en, gpio_store_en);...dev_class class_create(THIS_MODULE, class_name);
ctl_dev device_create(dev_class, NULL, 0, NULL, onoff);
if (IS_ERR(ctl_dev)) {dev_err(ctl_dev, Failed to create device\n);ret PTR_ERR(ctl_dev);goto err_create_dev;
}err device_create_file(ctl_dev, dev_attr_gpio_en);
if (err){printk(driver_create_file %d\n, err);
}DEVICE_ATTR 0777 引发的血案如果你想给一个节点设置 0777 或者写操作那你编译的时候会出现下面的编译错误。/home/weiqifa/mt8167s-9.0-sdk/kernel-4.4/include/linux/kernel.h:840:3: note: in expansion of macro BUILD_BUG_ON_ZEROBUILD_BUG_ON_ZERO((perms) 2) \^
/home/weiqifa/mt8167s-9.0-sdk/kernel-4.4/include/linux/sysfs.h:102:12: note: in expansion of macro VERIFY_OCTAL_PERMISSIONS.mode VERIFY_OCTAL_PERMISSIONS(_mode) }, \^
/home/weiqifa/mt8167s-9.0-sdk/kernel-4.4/include/linux/device.h:573:45: note: in expansion of macro __ATTRstruct device_attribute dev_attr_##_name __ATTR(_name, _mode, _show, _store)^
/home/weiqifa/mt8167s-9.0-sdk/kernel-4.4/drivers/misc/gpio_control.c:62:8: note: in expansion of macro DEVICE_ATTRstatic DEVICE_ATTR(gpio_en,0777,gpio_show_en, gpio_store_en);
这个错误的原因主要是出现在VERIFY_OCTAL_PERMISSIONS
这个宏上面这个宏定义在include/linux/
下面/* Permissions on a sysfs file: you didnt miss the 0 prefix did you? */
#define VERIFY_OCTAL_PERMISSIONS(perms) \(BUILD_BUG_ON_ZERO((perms) 0) \BUILD_BUG_ON_ZERO((perms) 0777) \/* USER_READABLE GROUP_READABLE OTHER_READABLE */ \BUILD_BUG_ON_ZERO((((perms) 6) 4) (((perms) 3) 4)) \BUILD_BUG_ON_ZERO((((perms) 3) 4) ((perms) 4)) \/* USER_WRITABLE GROUP_WRITABLE */ \BUILD_BUG_ON_ZERO((((perms) 6) 2) (((perms) 3) 2)) \/* OTHER_WRITABLE? Generally considered a bad idea. */ \BUILD_BUG_ON_ZERO((perms) 2) \(perms))
#endif
BUILD_BUG_ON_ZERO 的作用这个宏的作用是如果里面传进来的值是 「true」编译的时候就会出错。写个代码举个例子#include stdio.h
#include stdbool.h
//#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
/* Force a compilation error if condition is true */
#define BUILD_BUG_ON(condition) ((void)BUILD_BUG_ON_ZERO(condition))
/* Force a compilation error if condition is true, but also produce aresult (of value 0 and type size_t), so the expression can be usede.g. in a structure initializer (or where-ever else comma expressionsarent permitted). */
#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); }))
int main()
{BUILD_BUG_ON(1!0);bool zero false;printf(%d\n, !!zero);printf(%d\n, !zero);return 0;
}
输出VERIFY_OCTAL_PERMISSIONS 的作用所以在回到这个宏这个宏的作用就是限制我们在内核里面设置DEVICE_ATTR的权限如果你要是设置 0777那肯定就会给你提示编译错误。0777 对应的是 8进制整个流程整个流程是如上图代码是在mode部分那里做了限制。怎么让DEVICE_ATTR 0777 生效既然我们知道是VERIFY_OCTAL_PERMISSIONS 这个宏限制的那就直接把这个宏修改就好了。当然了这样使用是不符合要求的如果这样很容易被裁员的哦毕竟用户可能随便写一段代码就可能让你的系统不正常。看烧录看效果 推荐阅读 专辑|Linux文章汇总 专辑|程序人生 专辑|C语言嵌入式Linux微信扫描二维码关注我的公众号