Linux的UDEV机制


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.mfbz.cn/a/574264.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Instagram运营5大技巧,防封攻略

对于企业和个人而言&#xff0c;运营Instagram已成为吸引流量、增加曝光、提升品牌知名度的重要手段。然而&#xff0c;许多人在初次尝试Ins运营时可能会遇到困难&#xff0c;不知道从何入手。本文将为您分享五大技巧&#xff0c;帮助您更好地运营Instagram&#xff0c;吸引更多…

【文章转载】Lance Martin的关于RAG的笔记

转载自微博黄建同学 从头开始学习 RAG&#xff0c;看Lance Martin的这篇笔记就行了&#xff0c;包含了十几篇论文和开源实现&#xff01; —— 这是一组简短的&#xff08;5-10 分钟视频&#xff09;和笔记&#xff0c;解释了我最喜欢的十几篇 RAG 论文。我自己尝试实现每个想…

迪拜之行回顾:CESS 的 DePIN 创新之旅

迪拜最近是一个关键热词&#xff0c;成为了一系列 Web3 和加密活动的中心&#xff0c;吸引了行业领导者、创新者和爱好者&#xff0c;探索区块链和去中心化技术的最新发展。从 4 月中旬&#xff0c;一系列行业会议和活动陆续举行&#xff0c;吸引了一众与会者。然而暴雨积水又成…

vue集成百度地图vue-baidu-map

文章目录 vue集成百度地图vue-baidu-map1. Vue Baidu Map文档地址2. 设置npm数据源3. 安装vue-baidu-map4. 配置vue-baidu-map4.1 main.js全局注册4.2 vue页面设置4.3 效果 vue集成百度地图vue-baidu-map 1. Vue Baidu Map文档地址 https://dafrok.github.io/vue-baidu-map/#…

从0到1—POC编写基础篇(四)

接着上一篇 cprint 模块 Python内置的 print 函数可以输出任何类型的数据&#xff0c;但有时候输出的内容不够简洁、美观&#xff0c;难以直观地了解程序运行状态。cprint 库就是为了解决这个问题而生的&#xff0c;它可以让Python输出更简洁、更美观。 cprint 库是一个基于装…

ubuntu20.04开机运行java的sh脚本

用到了 rc.local 1、修改 /usr/lib/systemd/system/rc-local.service 在最下面添加 [Install] WantedBymulti-user.target 2、 系统没有 rc.local&#xff0c;需要手动创建 cd /etc vi rc.local在里面写入 /opt/start.sh chmod x /etc/rc.local # 添加可执行权限 chmod x…

基于51单片机空气质量监测报警仿真LCD1602液晶显示( proteus仿真+程序+设计报告+原理图+讲解视频)

基于51单片机空气质量监测报警仿真LCD显示 1. 主要功能&#xff1a;2. 讲解视频&#xff1a;3. 仿真设计&#xff1a;4. 程序代码5. 设计报告6. 原理图7. 设计资料内容清单&&下载链接 基于51单片机空气质量监测报警仿真LCD显示( proteus仿真程序设计报告原理图讲解视频…

前端CSS基础10(浮动)

前端CSS基础10&#xff08;浮动&#xff09; 浮动元素浮动后的特点浮动后的特点浮动后的影响及解决 浮动布局小练习 浮动 CSS中的浮动是一种布局技术&#xff0c;常用于实现元素的排列和定位。通过使用float属性&#xff0c;可以让元素在页面中左浮动或右浮动&#xff0c;使得…

ubuntu18.04系统编译openwrt21.02.3

搭建ubuntu18.04环境 使用虚拟机安装ubuntu环境网上教程很多&#xff0c;这里不做赘述&#xff0c;主要是安装一些我们在编译openwrt时可能会用到的一些工具环境 sudo apt-get update sudo apt instll libncurses-dev gawk sudo apt-get install build-essential libncurses5…

pytest数据驱动DDT(数据库/execl/yaml)

常见的DDT技术 数据结构&#xff1a; 列表、字典、json串 文件&#xff1a; txt、csv、excel 数据库&#xff1a; 数据库链接 数据库提取 参数化&#xff1a; pytest.mark.parametrize() pytest.fixture() …

2023年图灵奖揭晓,Avi Wigderson成为双冠王

文章目录 Avi Wigderson双冠王个人简介约翰纳什致敬 Avi Wigderson 2024年4月10日&#xff0c;ACM宣布Avi Wigderson为2023年ACM A.M.图灵奖获得者&#xff0c;以表彰他对计算理论的基础性贡献&#xff0c;包括帮助我们重新理解随机性在计算中的作用&#xff0c;以及他在理论计…

第一届长城杯半决赛wp和AWD笔记

目录 AWD 渗透 cfs 单节点1 AWD笔记 AWD工具 文件比较工具 Web漏洞扫描工具 waf工具 代码审计工具 批量网站备份文件泄露扫描工具 cms通杀漏洞的利用 通杀脚本和批量提交flag脚本 防御流程 攻击流程 注意 AWD 解题思路] 首先就是fscan快速扫描对应C段&#xf…

【Qt 学习笔记】Qt常用控件 | 显示类控件 | LCD Number的使用及说明

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Qt常用控件 | 显示类控件 | LCD Number的使用及说明 文章编号&#xf…

贪吃蛇的C语言实现

目录 一、游戏流程设计 二、游戏实现原理 2.1如何创建并管理数据 2.2如何实现蛇身移动 2.3如何实现食物随机放置 2.4如何检测按键与调整光标位置 三、源代码 3.1 test.c 3.2 snake.h 3.3 snake.c 一、游戏流程设计 GameStart WelcomeToGame&#xff1a;打印欢迎界面…

架构师系列-消息中间件(九)- RocketMQ 进阶(三)-消费端消息保障

5.2 消费端保障 5.2.1 注意幂等性 应用程序在使用RocketMQ进行消息消费时必须支持幂等消费&#xff0c;即同一个消息被消费多次和消费一次的结果一样&#xff0c;这一点在使用RoketMQ或者分析RocketMQ源代码之前再怎么强调也不为过。 “至少一次送达”的消息交付策略&#xff…

开启医疗数据新纪元:山海鲸可视化智慧医疗解决方案

在数字化浪潮席卷而来的今天&#xff0c;智慧医疗作为医疗行业的创新力量&#xff0c;正以其独特的技术优势&#xff0c;推动着医疗服务的升级和变革。而在这场变革中&#xff0c;山海鲸可视化以其出色的数据可视化能力&#xff0c;为智慧医疗提供了强大的技术支持&#xff0c;…

用Python和Pygame实现简单贪吃蛇游戏

1.pip安装pygame pygam插件安装 pip install 插件名字 # 安装 pip uninstall 插件名字 # 卸载 pip install 插件名字 -i 指定下载的镜像网址 pip show 插件名字 # 查看插件名字 pip install pygame -i https://pypi.tuna.tsinghua.edu.cn/simple pip show p…

【网络编程】网络编程概念 | TCP和UDP的区别 | UDP数据报套接字编程 | Socket

文章目录 网络编程一、什么是网络编程1.TCP和UDP的区别 二、UDP数据报套接字编程DatagramSocketDatagramPacket回显服务器&#xff08;echo server&#xff09; 网络编程 一、什么是网络编程 通过网络&#xff0c;让两个主机之间能够进行通信。基于通信来完成一定的功能。 ​…

MacOS 下gif 文件的几种压缩方法

categories: Tips tags: Tips GIF 写在前面 最近想转换几个 tg 的 tgs 文件到 gif, 然后上传到微信, 所以又涉及到了 gif 的操作了. 工具介绍 安装 brew install imagemagick gifsicleimagemagick 是专业的图像处理工具, gifsicle 是专门处理 gif 的小工具 ,都是开源的. …

C++之AVL树的使用以及原理详解

1.AVL树 1.1AVL树的概念 1.2AVL树的定义 1.3AVL树的插入 1.4AVL树的旋转 1. 右单旋 2. 左单旋 3. 左右双旋 4. 右左双旋 1.5AVL树的验证 1.6AVL的实现 在之前对map/multimap/set/multiset进行了简单的介绍&#xff08;C之map_set的使用-CSDN博客&#xff09;&#xff0c;…