linux中用中断模拟热插拔

2024-06-13 20:08

本文主要是介绍linux中用中断模拟热插拔,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、介绍

        在linux中,常用的用户层和内核层通信方法有:系统调用(如copy_to_user/copy_from_user)、proc、ioctl和netlink。热插拔模式就是linux基于nelink实现的。netlink的讲解,可以看教程:http://blog.csdn.net/zcabcd123/article/details/8272423。

二、实现步骤

1、填充结构

         在Linux系统中,当系统配置发生变化时,如:添加kset到系统;移动kobject, 一个通知会从内核空间发送到用户空间,这就是热插拔事件。热插拔事件会导致用户空间中相应的处理程序(如udev,mdev)被调用, 这些处理程序会通过加载驱动程序, 创建设备节点等来响应热插拔事件。
  Struct kset_uevent_ops {
    int (*filter)(struct kset *kset, struct kobject *kobj);
    const char *(*name)(struct kset *kset, struct kobject *kobj);
    int (*uevent)(struct kset *kset, struct kobject *kobj,
    struct kobj_uevent_env *env);
  }
  当该kset所管理的kobject和kset状态发生变化时(如被加入,移动),这三个函数将被调用。
    Filter:决定是否将事件传递到用户空间。如果filter返回0,将不传递事件。
    Name:负责将相应的字符串传递给用户空间的热插拔处理程序。
    Uevent:将用户空间需要的参数添加到环境变量中。
  因此我们首先填充kset_uevent_ops这个结构体:

static struct kobj_type ktype =
{
};
static int kset_filter(struct kset *kset,struct kobject *kobj)
{return 1;
}static const char *kset_name(struct kset *kset,struct kobject *kobj)
{static char buf[20];sprintf(buf,"%s","SmartCover");return buf;
}static int kset_uevent(struct kset *kset,struct kobject *kobj, struct kobj_uevent_env *env)
{return 0;
}static struct kset_uevent_ops uevent_ops =
{.filter = kset_filter,.name = kset_name,.uevent = kset_uevent,
};struct kset *kset_p;
struct kset *kset_c;
2、初始化和注销

在probe函数中加入:

    kset_p = kset_create_and_add("kset_p", &uevent_ops, NULL);kset_c = kzalloc(sizeof(*kset_c), GFP_KERNEL);  //初始化kset结构体kobject_set_name(&kset_c->kobj,"kset_c");kset_c->kobj.kset = kset_p;kset_c->kobj.ktype = &ktype;
在release函数中加入注销函数(一般来说,系统不会有机会执行到它):

    kset_unregister(kset_p);
3、具体模拟

 因为添加/删除kset到系统的时候,就会有通知从内核发送到用户层,也就是热插拔。因此我们可以设置在第一次中断的时候是插入,下一次是拔出,以此内推:

	if(add){                    //插入还是拔出的状态判断kset_unregister(kset_c);   //删除kset模拟热插拔的拔出。注意当删除kset结构时候,kset_unregister函数会free掉kset_c结构体,所以下次需要用到该结构体时候,要先重新分配并初始化该结构体。if(!kset_c){kset_c = kzalloc(sizeof(*kset_c), GFP_KERNEL);}kobject_set_name(&kset_c->kobj,"kset_c");kset_c->kobj.kset = kset_p;kset_c->kobj.ktype = &ktype;}else if(!add){   //插入还是拔出的状态判断kset_register(kset_c); //添加kset,模拟为热插拔的add。}
三、上层测试

在Android上层中使用UEventObserver方法来检测热插拔的发生。大概实现步骤如下:
  1、设置要监听的热插拔文件路径。
   上文中模拟的热插拔文件位置为/sys/kset_p,所以设置文件路径为/kset_p

	private String ueventTest = "DEVPATH=/kset_p";
2、重写UEventObserver.onUEvent方法

    private final UEventObserver mUEventObserver = new UEventObserver() {@Overridepublic void onUEvent(UEventObserver.UEvent event){Log.e("Seven", "yulinghan UEVENT: "+event.toString());}};
3 、启动监听

	mUEventObserver.startObserving(ueventTest);
四、参考资料

1、Android测试监听的apk代码下载:

http://download.csdn.net/detail/u011630458/7364653
2、Android上层测试的教程,可以看blog:http://blog.csdn.net/lushengchu_luis/article/details/9466405

3、测试的完整代码如下:(注意必须在Android源代码下编译)

package com.example.ueventtest;import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.widget.TextView;
import android.os.Handler;
import android.os.UEventObserver;
import android.os.Message;
import java.util.Timer;
import java.util.TimerTask;public class MainActivity extends Activity {private TextView tv;private TextView tv2;private String ueventTest = "DEVPATH=/kset_p";private String ueventTest2 = "/devices/virtual/android_usb/android0";private String test;private String test2;private Handler myHandler;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);tv = (TextView)findViewById(R.id.test);tv2 = (TextView)findViewById(R.id.test2);mUEventObserver.startObserving(ueventTest);mUEventObserver.startObserving(ueventTest2);mUEventObserver.startObserving("DEVPATH=/devices/virtual/switch/h2w");tv.setText("sdcjbdjvkc");myHandler = new Handler(){public void handleMessage(Message msg) {tv.setText(test);tv2.setText(test2);}};}private final UEventObserver mUEventObserver = new UEventObserver() {@Overridepublic void onUEvent(UEventObserver.UEvent event){Log.e("Seven", "yulinghan UEVENT: "+event.toString());test = "ACTION:" + event.get("ACTION");test2 = "SUBSYSTEM:" + event.get("SUBSYSTEM");myHandler.sendEmptyMessage(0x01);}};
}

这篇关于linux中用中断模拟热插拔的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1058295

相关文章

linux-基础知识3

打包和压缩 zip 安装zip软件包 yum -y install zip unzip 压缩打包命令: zip -q -r -d -u 压缩包文件名 目录和文件名列表 -q:不显示命令执行过程-r:递归处理,打包各级子目录和文件-u:把文件增加/替换到压缩包中-d:从压缩包中删除指定的文件 解压:unzip 压缩包名 打包文件 把压缩包从服务器下载到本地 把压缩包上传到服务器(zip

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

usaco 1.2 Transformations(模拟)

我的做法就是一个一个情况枚举出来 注意计算公式: ( 变换后的矩阵记为C) 顺时针旋转90°:C[i] [j]=A[n-j-1] [i] (旋转180°和270° 可以多转几个九十度来推) 对称:C[i] [n-j-1]=A[i] [j] 代码有点长 。。。 /*ID: who jayLANG: C++TASK: transform*/#include<

Linux_kernel驱动开发11

一、改回nfs方式挂载根文件系统         在产品将要上线之前,需要制作不同类型格式的根文件系统         在产品研发阶段,我们还是需要使用nfs的方式挂载根文件系统         优点:可以直接在上位机中修改文件系统内容,延长EMMC的寿命         【1】重启上位机nfs服务         sudo service nfs-kernel-server resta

【Linux 从基础到进阶】Ansible自动化运维工具使用

Ansible自动化运维工具使用 Ansible 是一款开源的自动化运维工具,采用无代理架构(agentless),基于 SSH 连接进行管理,具有简单易用、灵活强大、可扩展性高等特点。它广泛用于服务器管理、应用部署、配置管理等任务。本文将介绍 Ansible 的安装、基本使用方法及一些实际运维场景中的应用,旨在帮助运维人员快速上手并熟练运用 Ansible。 1. Ansible的核心概念

Linux服务器Java启动脚本

Linux服务器Java启动脚本 1、初版2、优化版本3、常用脚本仓库 本文章介绍了如何在Linux服务器上执行Java并启动jar包, 通常我们会使用nohup直接启动,但是还是需要手动停止然后再次启动, 那如何更优雅的在服务器上启动jar包呢,让我们一起探讨一下吧。 1、初版 第一个版本是常用的做法,直接使用nohup后台启动jar包, 并将日志输出到当前文件夹n