Linux的UDEV机制

news2024/10/1 15:03:26


udev 机制引入:

 手机接入Linux热拔插相关
a. 把手机接入开发板
b. 安装adb工具,在终端输入adb安装指令: sudo apt-get install adb
c. dmeg能查看到手机接入的信息,但是输入adb devices会出现提醒
dinsufficient permissions for device: user in plugdev group; are your udev
rules wrong?
d. 配置文件,以支持USB设备的热拔插,支持UDEV的机制
在/etc/udev/rules.d 文件夹下创建规则文件
cd /etc/udev/rules.d/
sudo vim 51-android.rules
在文件中添加内容 SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", MODE="0666"
e. 在手机开发者选项中,打开USB调试,重新

udev 概念引入: 

udev是一个设备管理工具,udev以守护进程的形式运行,通过侦听内核发出来的uevent来管
/dev目录下的设备文件。udev在用户空间运行,而不在内核空间 运行。它能够根据系统中的硬
件设备的状态动态更新设备文件,包括设备文件的创建,删除等。设备文件通常放在/dev目录下。
使用udev后,在/dev目录下就只包含系统中真正存在的设备


------------------------------------------------


图形理解: 

下面是一张linux 架构图: 

Linux 下面 一切都是文件  -- open 来打开

调用过程: 

我们在应用层 调用  open 函数(存放在库函数中)  -->  库函数中的open 系统调用 sys_open
 --> 系统调用的 sys_read  再调用内核的 kernel_open  -->  内核的kernal_open 负责调用硬件的寄存器处理 


-------------------------------------

查看进程基础与技巧: 

一般形式:

ps -elf | grep a.out  

#unix标准风格组合,其中-e 代表列出所有进程,-l 代表长格式,-f 代表完整的格式

消除grep干扰

在平时查看进程得到时候一般都会 多出一个 grep 进程---> 影响判断

比如下图 中的第二个进程  grep: 


我们可以这样

忽略 grep进程:   ps -elf | grep a.out | grep -v grep  

       //检索 a.out 的进程,同时忽略 grep 进程

& -- 指定进程后台运行


./a.out &    // 后台进程 a.out

//  普通程序 依托 于终端,终端关闭就结束

init -- 进程 pid  - 1 

显示行号

    显示行号:末行模式下输入 **set number** 或 **set nu** 回车
    关闭行号:末行模式下输入 **set nonumber** 或 **set nonu** 回车

守护进程:

概念

Linux Daemon(守护进程)是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行
某种任务或等待处理某些发生的事件。它不需要用户输入就能运行而且提供某种服务,不是对整个
系统就是对某个用户程序提供服务。Linux系统的大多数服务器就是通过守护进程实现的。

常见的守护进程包括系统日志进程syslogd、 web服务器httpd、邮件服务器sendmail和数据库服务器mysqld等。守护进程的名称通常以d结尾

UDEV守护进程,它能够根据系统中的硬件设备的状态动态更新设备文件,包括设备文件的创建,删除等。


基本特点


1)生存周期长[非必须],一般操作系统启动的时候就启动,关闭的时候关闭。
2)守护进程和终端无关联,也就是他们没有控制终端,所以当控制终端退出,也不会导致守护进程退出
3)守护进程是在后台运行,不会占着终端,终端可以执行其他命令

4)一个守护进程的父进程是init进程,因为它真正的父进程在fork出子进程后就先于子进程exit退出了,所以它是一个由init继承的孤儿进程
linux操作系统本身是有很多的守护进程在默默执行,维持着系统的日常活动。大概30-50个

普通守护进程   和 内核适合进程

ppid = 0:内核进程,跟随系统启动而启动,生命周期贯穿整个系统。
cmd列名带[]这种,叫内核守护进程
老祖init:也是系统守护进程,它负责启动各运行层次特定的系统服务;所以很多进程的PPID是init,也负责收养孤儿进程。
cmd列中名字不带[]的普通守护进程(用户集守护进程)

图解如下:

======================================================

守护进程的开发: 

daemon()函数


直接借助daemon()函数完成。 daemon  -- 守护进程

头文件: 

#include <unistd.h>

函数原型: 
int daemon(int nochdir, int noclose);
函数参数:
nochdir:为0时表示将当前目录更改至“/”
noclose:为0时表示将标准输入、标准输出、标准错误重定向至“/dev/null”
返回值:
成功则返回0,失败返回-1

守护进程 和 后台进程区别

1. 守护进程和终端不挂钩;后台进程能往终端上输出东西(和终端挂钩);
2. 守护进程关闭终端时不受影响,守护进程不会随着终端的退出而退出;

额外补充:

//C 库函数 char *asctime(const struct tm *timeptr) 返回一个指向字符串的指针,它代表了结
构 struct timeptr 的日期和时间。
//C 库函数 struct tm *localtime(const time_t *timer) 使用 timer 的值来填充 tm 结构。
timer 的值被分解为 tm 结构,并用本地时区表示。
/*

对应的结构体:

struct tm {
int tm_sec; 秒,范围从 0 到 59
int tm_min; 分,范围从 0 到 59
int tm_hour; 小时,范围从 0 到 23
int tm_mday; 一月中的第几天,范围从 1 到 31
int tm_mon; 月份,范围从 0 到 11
int tm_year; 自 1900 起的年数
int tm_wday; 一周中的第几天,范围从 0 到 6
int tm_yday; 一年中的第几天,范围从 0 到 365
int tm_isdst; 夏令时
};

----------------------------------------------------------
注: bool  类型变量linux C不认识,需要包含 一个头文件: <stdbool.h>

exit(0),exit(1) 和 exit(-1)的区别

exit(0)表示程序正常退出;除了0之外,其他参数均代表程序异常退出,如:exit(1),exit(-1)。
exit(1)和exit(-1)是分别返回1和-1到主调程序。
exit(0)则是返回0。exit(0)表示程序正常退出,非0表示非正常退出。

log文件是记录系统活动信息的几个文件,通过它可以帮助快速定位问题,常见的有

----------------------------------------------------------


验证程序:

case1:  创建一个守护进程 , 创建/打开~目录下的daemon.log文件,每10s 写入一次系统时间到文件中

#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <time.h>
#include <stdio.h>
#include<stdbool.h>

static bool flag = true;

void handler(int sig) // 收到信号 后就 把 flag =false ---> 进入 main 里面的判断 -- 需要退出了
{
printf("I got a signal %d\nI'm quitting.\n", sig);
flag = false;
}

int main()
{
time_t t;
int fd;
//创建守护进程 int daemon(int nochdir, int noclose); -- 返回值 成功0 ,失败-1
// 第一个参数 -- nochdir:为0时表示将当前目录更改至“/”
// 第二个参数 -- noclose:为0时表示将标准输入、标准输出、标准错误重定向至“/dev/null”
if(-1 == daemon(0, 0))
{
printf("daemon error\n");
exit(1); //异常退出
}
//设置信号处理函数
struct sigaction act;
act.sa_handler = handler;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
if(sigaction(SIGQUIT, &act, NULL)) // if 这个进程收到 SIGQUIT 信号,退出进程 exit(0) -正常退出
{
printf("sigaction error.\n");
exit(0);
}

//进程工作内容
while(flag) // flag  没收到退出信号的时候一直在执行 以下工作
{
fd = open("/home/orangepi/daemon.log", O_WRONLY | O_CREAT | O_APPEND,0644); // 在我们的~目录下创建daemon.log文件
if(fd == -1)
{
printf("open error\n");
}
t = time(0);
// asctime -- 把系统默认的时间类型 数据转换为 字符串类型的   localtime 拿到本地时间
char *buf = asctime(localtime(&t));
write(fd, buf, strlen(buf)); // 将获得时间数据写入文件
close(fd);
sleep(10);  // 每10s写入一次
}
return 0;
}

-------------------------------------------------------

 
 

 开机启动守护进程: 


sudo vi /etc/rc.local

里面添加我们创建的守护进程的 可执行文件 tdaemon , 不要用a.out, 使用 -o 改个名

/home/orangepi/hardwareSoft/udev/tdaemon

注意:  这里一定要用绝对路径,不要用相对路径,因为我们的守护进程会调到根目录,相对路径不一定能访问到

/home/orangepi/douyin/douyin /dev/ttyS5
/home/orangepi/douyin/shouhuDouyin

===================================================

需求:要求语音刷手机的程序一直保持运行,防止应用程序崩溃意外,先实现case2


case2 : 编写判断某进程是否在运行的程序:

  1 #include<stdio.h>
  2 #include<string.h>
  3
  4 int main()
  5 {
  6
  7     FILE *file;
  8     char buf[128]={'\0'};
  9     char *cmd="ps -elf | grep douyin | grep -v grep "; // 通过指令查看
 10     file = popen(cmd,"r");
 11     fgets(buf,128,file);
 12
 13     printf("buf: %s\n",buf);
 14     if(strstr(buf,"douyin")!=NULL){ // 子串没有进程名字,什么进程不运行
 15     puts("douyinPro is running");
 16     }
 17     else {
 18     puts("douyinPro is exited");
 19     }
 20
 21
 22     return 0;
 23 }


----------------------------------------
以popen的 方式去运行 cmd
同时,能把指令执行的结果拿到手

---------------------------------------------------------------------


case 3 :  守护进程实现 关不掉是 声控刷抖音

声控刷抖音代码参考这篇:串口小项目 - 声控刷抖音-CSDN博客

/home/orangepi/douyin

注意:  守护进程会默认把 路口切换到根目录,执行cmd 的时候要给绝对路径

效果图: 

这里kill 程序,模拟程序崩溃

可以看到 我们的抖音进程 一直杀不死, 因为守护进程 一直在后台执行着
只要抖音程序一被关掉就会马上重新创建一个新的的进程

#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <time.h>
#include <stdio.h>
#include<stdbool.h>


int  judMent() // 这就是case2的 判断进程是否运行函数
{
    FILE *file;
    char buf[128]={'\0'};
    char *cmd="ps -elf | grep douynUnit | grep -v grep ";
    file = popen(cmd,"r");
    fgets(buf,128,file);

    printf("buf: %s\n",buf);
    if(strstr(buf,"douyin")!=NULL){
    return 0;
    }
    else {
    return -1;
    }

}


static bool flag = true; // 初始化为true -- 让main 中while一直执行


void handler(int sig) //收到对应信号后  退出
{
    printf("I got a signal %d\nI'm quitting.\n", sig);
    flag = false;
}
int main()
{
    time_t t;
    int fd;
    //创建守护进程
    if(-1 == daemon(0, 0))
    {
        printf("daemon error\n");
        exit(1);
    }
    //设置信号处理函数
    struct sigaction act;
    act.sa_handler = handler;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
    if(sigaction(SIGQUIT, &act, NULL)) //收到信号SIGQUIT,执行act -这个槽(处理)函数
    {
        printf("sigaction error.\n");
        exit(0);
    }
    //进程工作内容
    while(flag)
    {
        if(judMent() == -1)//进程被杀死后再打开 -- 杀不死的进程
            fd = system("/home/orangepi/douyin/douyinUnit /dev/ttyS5 &");
       sleep(2);
    }
    return 0;
}

--------------------------------------------------------------------------------

UDEV 配置文件:

规则文件是 udev 里最重要的部分,默认是存放在 /etc/udev/rule.d/ 下。所有的规则文件必须以 ".rules"为后缀名


简单的规则举例:


KERNEL=="sda", NAME="my_root_disk", MODE="0660"


KERNEL 是匹配键,NAME 和 MODE 是赋值键。这条规则的意思是:如果有一个设备的内核名称为sda,则该条件生效,执行后面的赋值:在 /dev 下产生一个名为my_root_disk 的设备文件,并把设备文件的权限设为 0660。

查看设备详细信息

udevadm info --attribute-walk --name=/dev/设备名字

比如我的手机在这里:   /dev/bus/usb/001/003       -- 只需要把 = 后的改为这串即可

udevadm info --attribute-walk --name=/dev/bus/usb/001/003

查询到的信息可以写入设备的规则文件中,比如: 
    ATTRS{idProduct}=="0002"
    ATTRS{idVendor}=="1d6b"

//多乐两天匹配键 -- 来判断设备

如下: 


==================


udev 规则的匹配键:

ACTION:事件(uevent)的行为,例如:add(添加设备)、remove(删除设备);
KERNEL:内核设备名称,例如:sda,cdrom;
DEVPATH:设备的 devpath 路径;
SUBSYSTEM:设备的子系统名称,例如:sda 的系统为 block;
BUS:设备在 devpath 里的总线名称,例如:usb;
DRIVER:设备在 devpath 的设备驱动名称,例如:ide-cdrom;
ID:设备在 devpath 里的识别号;
SYSFS{filename}:设备的 devpath 路径下,设备的属性文件 "filename" 里的内容;

ENV{key}:环境变量。在一条规则中,可以设定最多五条环境变量的 匹配键;
PROGRAM:调用外部命令;
RESULT:外部命令 PROGRAM 的返回结果。


===================================================、

U盘的自动挂载:

一般情况:(手动挂载)

一般U盘插入orangepi 需要挂载才能查看里面内容

// 将 u 盘挂载到 mnt 下,才能查看里面内容
sudo mount /dev/sda  /mnt/

然后 就可以 cd/mnt  去查看我们的 U盘 内容了

要取消挂载: sudo umount /mnt

也可以通过上面的指令来详细查看U盘数据: udevadm info --attribute-walk --name=/dev/设备名字
比如: U盘的匹配条件:

    KERNELS=="sdb"
    SUBSYSTEMS=="block"

配置规则文件, 实现自动挂载U盘


 在规则文件下(比如我们在/etc/udev/rule.d/下创建 usbBlock.rules ),加入:
支持挂载多个U盘:


ACTION=="add", SUBSYSTEMS=="usb", SUBSYSTEM=="block", RUN{program}+="/bin/mkdir
/media/%k" ,RUN{program}+="/usr/bin/systemd-mount --no-block --collect $devnode
/media/%k"


 然后重启udev 服务即可:
sudo service udev restart

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1613743.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

酷开会员 | 酷开系统带你足不出户获得同电影院一般的观影体验

在繁忙、混乱的快节奏工作中&#xff0c;人们总是渴望在下班后&#xff0c;逃离工作的桎梏找到一丝慰藉&#xff0c;看电影&#xff0c;则成为了很多人宣泄情感、放松心情的一种方式。但是&#xff0c;电影院的时间和地点总是那么不受控制&#xff0c;要么地点太远、要么场次不…

k8s安装,linux-ubuntu上面kubernetes详细安装过程

官方文档&#xff1a;https://kubernetes.io/zh-cn/docs/setup/production-environment/container-runtimes/ 环境配置 该部分每个主机都要执行 如果你确定不需要某个特定设置&#xff0c;则可以跳过它。 设置root登录 sudo passwd root sudo vim /etc/ssh/sshd_config Perm…

密码学 | 数字证书:应用

&#x1f951;原文&#xff1a;数字签名和数字证书的原理解读 - 知乎 &#x1f951;前文&#xff1a;密码学 | 数字签名 数字证书 - CSDN &#x1f951;提示&#xff1a;把客户端想成 Alice&#xff0c;服务器端想成 Bob 即可。客户端实际上指的是客户端浏览器。 下面&#…

Ubuntu 22最新dockers部署redis哨兵模式,并整合spring boot和配置redisson详细记录(含spring boot项目包)

dockers部署redis哨兵模式&#xff0c;并整合spring boot 环境说明相关学习博客一、在docker中安装redis1、下载dockers镜像包和redis配置文件&#xff08;主从一样&#xff09;2、编辑配置文件3、启动redis&#xff08;主从一样&#xff09;4、进入容器测试&#xff08;主从一…

PyTorch与深度学习:探索现代神经网络的魅力

在科技飞速发展的今天&#xff0c;深度学习作为人工智能领域的重要分支&#xff0c;已经在图像识别、自然语言处理、语音识别等多个领域取得了突破性的进展。而PyTorch&#xff0c;作为一款开源的深度学习框架&#xff0c;以其简洁易用、动态计算图等特性&#xff0c;赢得了广大…

react合成事件与原生事件区别备忘

朋友问起在做一个下拉框组件&#xff0c;下拉的点击事件是用react的onClick触发&#xff0c;外部区域点击关闭则用dom的原生点击事件绑定&#xff0c;问题是下拉的点击事件无法阻止冒泡到dom的原生事件。 我说&#xff0c;react的合成事件 和 原生事件是不一样的&#xff0c;尽…

【科学研究】那些考进精英大学的农家子弟们

::: block-1 “时问桫椤”是一个致力于为本科生到研究生教育阶段提供帮助的不太正式的公众号。我们旨在在大家感到困惑、痛苦或面临困难时伸出援手。通过总结广大研究生的经验&#xff0c;帮助大家尽早适应研究生生活&#xff0c;尽快了解科研的本质。祝一切顺利&#xff01;—…

Ollama教程——生成内容API:利用Ollama的原生API进行AI应用开发

相关文章: Ollama教程——入门&#xff1a;开启本地大型语言模型开发之旅 Ollama教程——模型&#xff1a;如何将模型高效导入到ollama框架 Ollama教程——兼容OpenAI API&#xff1a;高效利用兼容OpenAI的API进行AI项目开发 Ollama教程——使用langchain&#xff1a;ollama与…

iTwin Capture Modeler-23中文版下载地址及安装教程

文章目录 一、iTwin Capture Modeler23中文版安装教程二、iTwin Capture Modeler23中文版下载地址一、iTwin Capture Modeler23中文版安装教程 1. 解压安装包。订阅专栏(可获取专栏内所有文章阅读权限与软件安装包)后,从文末获取安装包解压,如下所示: 2. 右击安装包,选择以…

火绒安全的详细用法

1. 引言 本章将介绍火绒安全软件的基本概述和用法。火绒安全是一款功能强大的安全软件,提供了多种保护功能和工具,可以帮助您保护计算机免受恶意软件、网络攻击和其他安全威胁的侵害。 2. 火绒安全的功能 火绒安全具有以下主要功能: 实时防护:火绒安全提供实时监测和防护…

9.Eureka服务发现+Ribbon+RestTemplate服务调用

order-service服务通过服务名称来代替 ip:port的方式访问user-service服务的接口。 原来的请求代码&#xff1a; Service public class OrderServiceImpl implements OrderService {Autowiredprivate OrderMapper orderMapper;Autowiredprivate RestTemplate restTemplate;Ov…

修改Ubuntu22.04系统图标

在Ubuntu 22.04中更改开机时显示的Ubuntu图标需要修改的设置。 主要思路是用自己图片替换系统图片&#xff0c;保持系统图片同名&#xff0c;同格式。 以下是一般的步骤&#xff1a; 修改启动界面的logo&#xff1a; sudo cp 新logo.png /usr/share/plymouth/themes/spinn…

江苏鲁岳轴承制造有限公司:石墨轴承与耐高温轴承的制造翘楚

耐高温轴承的优质生产地&#xff1a;江苏鲁岳轴承制造有限公司。石墨轴承与耐高温轴承的完美生产商&#xff1a;江苏鲁岳轴承制造有限公司的专业承诺。 石墨轴承是一种具有独特耐高温性能的轴承产品&#xff0c;广泛应用于各种高温、高速、高负载的工业环境中。江苏鲁岳轴承制…

C++的初步知识——命名空间,缺省参数,重载函数

C 首先写一段代码&#xff1a; #include <stdio.h>int main() {printf("Hello world\n");return 0; }这段C语言代码在cpp文件中仍可运行。我们了解C是兼容C语言的&#xff0c;C的关键字中就包含了C语言的关键字和自身的关键字。关于关键字&#xff0c;我们简…

排序算法之计数排序

目录 一、简介二、代码实现三、应用场景 一、简介 算法平均时间复杂度最好时间复杂度最坏时间复杂度空间复杂度排序方式稳定性计数排序O(nk )O(nk)O(nk)O(k)Out-place稳定 稳定&#xff1a;如果A原本在B前面&#xff0c;而AB&#xff0c;排序之后A仍然在B的前面&#xff1b; 不…

Python 实现视频去抖动技术

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 视频去抖动是视频处理中的一项重要技术&#xff0c;它可以有效地减少视频中由于相机震动或手…

Eclipse 配置JDK版本,Eclipse Maven install 时使用的JDK版本

Eclipse配置JDK版本 Eclipse 配置JDK版本的地方&#xff1f; 在Eclipse中配置JDK版本的步骤如下&#xff1a; 打开Eclipse IDE。转到菜单栏并选择 “Window”&#xff08;窗口&#xff09;选项。在下拉菜单中选择 “Preferences”&#xff08;首选项&#xff09;&#xff0c;或…

密钥密码学(三)

原文&#xff1a;annas-archive.org/md5/b5abcf9a07e32fc6f42b907f001224a1 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 第十六章&#xff1a;三次通行协议 本章内容包括 基于指数的三次通行协议 基于矩阵乘法的三次通行协议 基于双边矩阵乘法的三次通行协议 …

Quarto Dashboards 教程 1:Overview

「写在前面」 学习一个软件最好的方法就是啃它的官方文档。本着自己学习、分享他人的态度&#xff0c;分享官方文档的中文教程。软件可能随时更新&#xff0c;建议配合官方文档一起阅读。推荐先按顺序阅读往期内容&#xff1a; 1.quarto 教程 1&#xff1a;Hello, Quarto 2.qu…

mmclassification 训练自己的数据集

文章目录 从源码安装数据集准备config文件训练附录 从源码安装 git clone https://github.com/open-mmlab/mmpretrain.git cd mmpretrain pip install -U openmim && mim install -e .下面是我使用的版本 /media/xp/data/pydoc/mmlab/mmpretrain$ pip show mmcv mmpr…