设备管理器库 libudev
2015-12-03 14:49
991 查看
eudev-1.5.3
参考说明:http://blog.csdn.net/coroutines/article/details/38067805
1. 初始化
首先调用udev_new,创建一个udev library context。udev library context采用引用记数机制,创建的context默认引用记数为1,使用udev_ref和udev_unref增加或减少引用记数,如果引用记数为0,则释放内部资源。
2. 枚举设备
使用udev_enumrate_new创建一个枚举器,用于扫描系统已接设备。使用udev_enumrate_ref和udev_enumrate_unref增加或减少引用记数。
使用udev_enumrate_add_match/nomatch_xxx系列函数增加枚举的过滤器,过滤关键字以字符表示,如"block"设备。
使用udev_enumrate_scan_xxx系列函数扫描/sys目录下,所有与过滤器匹配的设备。扫描完成后的数据结构是一个链表,使用udev_enumerate_get_list_entry获取链表的首个结点,使用udev_list_entry_foreach遍历整个链表。
3. 监控设备插拔 udev的设备插拔基于netlink实现。
使用udev_monitor_new_from_netlink创建一个新的monitor,函数的第二个参数是事件源的名称,可选"kernel"或"udev"。基于"kernel"的事件通知要早于"udev",但相关的设备结点未必创建完成,所以一般应用的设计要基于"udev"进行监控。
使用udev_monitor_filter_add_match_subsystem_devtype增加一个基于设备类型的udev事件过滤器,例如: "block"设备。
使用udev_monitor_enable_receiving启动监控过程。监控可以使用udev_monitor_get_fd获取一个文件描述符,基于返回的fd可以执行poll操作,简化程序设计。
插拔事件到达后,可以使用udev_monitor_receive_device获取产生事件的设备映射。调用udev_device_get_action可以获得一个字符串:"add"或者"remove",以及"change", "online", "offline"等,但后三个未知什么情况下会产生。
4、获取设备信息
使用udev_list_entry_get_name可以得到一个设备结点的sys路径,基于这个路径使用udev_device_new_from_syspath可以创建一个udev设备的映射,用于获取设备属性。获取设备属性使用udev_device_get_properties_list_entry,返回一个存储了设备所有属性信息的链表,使用udev_list_entry_foreach遍历链表,使用udev_list_entry_get_name和udev_list_entry_get_value获取属性的名称和值。
参考代码:
void *thread_hdmi(void *param)
{
struct udev *udev = NULL;
struct udev_monitor *mon = NULL;
if ((udev = udev_new()) == NULL) {
printf("%s: Can't create udev\n", __func__);
return NULL;
}
if( (mon = udev_monitor_new_from_netlink(udev, "udev")) == NULL ) {
printf("%s: Can't create monitor\n", __func__);
udev_unref(udev);
return NULL;
}
udev_monitor_filter_add_match_subsystem_devtype(mon, "switch", NULL);
udev_monitor_enable_receiving(mon);
fd_set readfds;
const char *action = NULL;
const char *name = NULL;
const char *state = NULL;
while (1) {
FD_ZERO(&readfds);
FD_SET(udev_monitor_get_fd(mon), &readfds);
printf("%s():wait for subsystem(switch) udev event\n",__func__);
select(udev_monitor_get_fd(mon) + 1, &readfds, NULL, NULL, NULL);
if ( FD_ISSET(udev_monitor_get_fd(mon), &readfds) ) {
struct udev_device *dev = udev_monitor_receive_device(mon);
if(dev) {
action = udev_device_get_action(dev);
printf("%s():ACTION: %s\n", __func__, action);
if ((name = udev_device_get_property_value(dev, "SWITCH_NAME")) != NULL)
printf("%s():SWITCH_NAME: %s\n", __func__, name);
if ((state = udev_device_get_property_value(dev, "SWITCH_STATE")) != NULL)
printf("%s():SWITCH_STATE: %s\n", __func__, state);
if( ! strcmp(name, "hdmi") ) {
AppHdmi::setHdmiState( atoi(state) );
}
udev_device_unref(dev);
}
// This is not really needed... But we want to make shure not to eat 100% CPU if anything breaks. ;)
usleep(50 * 1000);
}
}
printf("%s():exit.....\n", __func__);
udev_monitor_unref(mon);
udev_unref(udev);
return NULL;
}
参考说明:http://blog.csdn.net/coroutines/article/details/38067805
1. 初始化
首先调用udev_new,创建一个udev library context。udev library context采用引用记数机制,创建的context默认引用记数为1,使用udev_ref和udev_unref增加或减少引用记数,如果引用记数为0,则释放内部资源。
2. 枚举设备
使用udev_enumrate_new创建一个枚举器,用于扫描系统已接设备。使用udev_enumrate_ref和udev_enumrate_unref增加或减少引用记数。
使用udev_enumrate_add_match/nomatch_xxx系列函数增加枚举的过滤器,过滤关键字以字符表示,如"block"设备。
使用udev_enumrate_scan_xxx系列函数扫描/sys目录下,所有与过滤器匹配的设备。扫描完成后的数据结构是一个链表,使用udev_enumerate_get_list_entry获取链表的首个结点,使用udev_list_entry_foreach遍历整个链表。
3. 监控设备插拔 udev的设备插拔基于netlink实现。
使用udev_monitor_new_from_netlink创建一个新的monitor,函数的第二个参数是事件源的名称,可选"kernel"或"udev"。基于"kernel"的事件通知要早于"udev",但相关的设备结点未必创建完成,所以一般应用的设计要基于"udev"进行监控。
使用udev_monitor_filter_add_match_subsystem_devtype增加一个基于设备类型的udev事件过滤器,例如: "block"设备。
使用udev_monitor_enable_receiving启动监控过程。监控可以使用udev_monitor_get_fd获取一个文件描述符,基于返回的fd可以执行poll操作,简化程序设计。
插拔事件到达后,可以使用udev_monitor_receive_device获取产生事件的设备映射。调用udev_device_get_action可以获得一个字符串:"add"或者"remove",以及"change", "online", "offline"等,但后三个未知什么情况下会产生。
4、获取设备信息
使用udev_list_entry_get_name可以得到一个设备结点的sys路径,基于这个路径使用udev_device_new_from_syspath可以创建一个udev设备的映射,用于获取设备属性。获取设备属性使用udev_device_get_properties_list_entry,返回一个存储了设备所有属性信息的链表,使用udev_list_entry_foreach遍历链表,使用udev_list_entry_get_name和udev_list_entry_get_value获取属性的名称和值。
参考代码:
void *thread_hdmi(void *param)
{
struct udev *udev = NULL;
struct udev_monitor *mon = NULL;
if ((udev = udev_new()) == NULL) {
printf("%s: Can't create udev\n", __func__);
return NULL;
}
if( (mon = udev_monitor_new_from_netlink(udev, "udev")) == NULL ) {
printf("%s: Can't create monitor\n", __func__);
udev_unref(udev);
return NULL;
}
udev_monitor_filter_add_match_subsystem_devtype(mon, "switch", NULL);
udev_monitor_enable_receiving(mon);
fd_set readfds;
const char *action = NULL;
const char *name = NULL;
const char *state = NULL;
while (1) {
FD_ZERO(&readfds);
FD_SET(udev_monitor_get_fd(mon), &readfds);
printf("%s():wait for subsystem(switch) udev event\n",__func__);
select(udev_monitor_get_fd(mon) + 1, &readfds, NULL, NULL, NULL);
if ( FD_ISSET(udev_monitor_get_fd(mon), &readfds) ) {
struct udev_device *dev = udev_monitor_receive_device(mon);
if(dev) {
action = udev_device_get_action(dev);
printf("%s():ACTION: %s\n", __func__, action);
if ((name = udev_device_get_property_value(dev, "SWITCH_NAME")) != NULL)
printf("%s():SWITCH_NAME: %s\n", __func__, name);
if ((state = udev_device_get_property_value(dev, "SWITCH_STATE")) != NULL)
printf("%s():SWITCH_STATE: %s\n", __func__, state);
if( ! strcmp(name, "hdmi") ) {
AppHdmi::setHdmiState( atoi(state) );
}
udev_device_unref(dev);
}
// This is not really needed... But we want to make shure not to eat 100% CPU if anything breaks. ;)
usleep(50 * 1000);
}
}
printf("%s():exit.....\n", __func__);
udev_monitor_unref(mon);
udev_unref(udev);
return NULL;
}
相关文章推荐
- Log4j配置很详细
- Object-c字符串与数组
- 关于优先级反转【转】
- UVA 11922 Permutation Transformer(Splay Tree)
- 传统企业信息化
- 圆角Panel
- c#连接mysql
- Java中判断字符串是否为数字的五种方法
- Moodle 平台中如何批量设置选择题选项 随机排列
- Dnsmasq安装与配置
- acm新手 偶数求和做法。。。
- Android中弹出PopupWindow让屏幕变暗
- C#访问修饰符(Public/Private/Protected/Internal)
- 计算Java List中的重复项出现次数
- impala初期使用零碎记录
- java串口的使用
- mvc项目架构分享系列之架构搭建之Infrastructure
- php+nginx/php-fpm
- NULL 不能 参数 avg 等函数的 使用吗?
- SqlServer应用之sys.dm_os_waiting_tasks 引发的疑问(中)