IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android usb读卡器sd卡热插拔心得 -> 正文阅读

[移动开发]Android usb读卡器sd卡热插拔心得

Android usb读卡器sd卡热插拔心得

最近跟usb打了一段时间交道,处理了一些storage方面的项目需求,现在记录一些调试思路,同时分享给一些有缘人,希望能够给予一些灵感。
平台是qnx hypervisor,但是这个usb控制器是完全pass给了Android hlos,所以纯Android这么做大概也能行。主要的需求如下介绍:

主机两个usb口,分别插u盘和usb读卡器,同时工作。第一个需求是要让usb读卡器支持sd卡的热插拔;第二个需求是要区分出sd card 和 udisk

先说热插拔的做法

先做对比,发现ubuntu20的电脑支持sd card的热插拔,然后看了看dmesg,没啥有效帮助。
然后是设备上插入读卡器尝试热插拔,发现插拔前后没有变化,看了看dmesg,也没啥帮助。
但是这一对比,发现sd card的热插拔,对于电脑来说只是partition的变化,也就是

插上读卡器会多了一个sda设备,读卡器有卡的时候会再多sda1这些分区,拔掉sd卡这些分区就消失了

以此为切入点去read the fuck code。哦对了,前面提了一嘴ubuntu20,是因为内核版本是5.4 。而我用的设备代码有两套,一套是4.14,一套是5.4.86 。当时以为该需求只是内核版本的问题,后来两个版本都试了热插拔无效。

首先,大概过了一遍probe,个人习惯,无从下手先随便喽一眼,来两套代码流,虽然没得啥子帮助

module_usb_stor_driver
	usb_stor_host_template_init.usb_stor_host_template
	usb_register(usb_storage_driver)
		usb_storage_driver.storage_probe // scsi
			usb_stor_probe1 + usb_stor_probe2

sd_probe_async -> sd_revalidate_disk -> sd_spinup_disk -> scsi_execute -> blk_execute_rq -> __blk_run_queue_uncond -> scsi_request_fn -> scsi_dispatch_cmd -> queuecommand_lck -> usb_stor_control_thread

sd_probe_async -> device_add_disk -> register_disk -> blkdev_get -> rescan_partitions

提一嘴, usb storage 、 scsi 、 sd 这三块是联系在一起的。
然后想找找扫描分区的线索,发现了rescan的接口,从class设备节点中尝试rescan发现木得效果(这时是在4.14的os中),于是去看了看代码

 static void sd_rescan(struct device *dev)
 { 
     struct scsi_disk *sdkp = dev_get_drvdata(dev);
     revalidate_disk(sdkp->disk);   
}

肥肠八嘎,就是调用了probe里的 sd_revalidate_disk,没有疗效
接下来接着想办法去搜线索,发现了partprobe这个玩意可以扫描分区

用法:partprobe [选项] [设备]…
将分区表的变更通报操作系统。
-d, --dry-run 并非真的通报操作系统
-s, --summary 印出内容的概要
-h, --help 显示这个说明然后离开
-v, --version 输出版本信息然后离开
如果没有指定任何设备,探查所有分区。

但是设备上没有,去toybox里搜了搜,是它的一个子命令。下一步,展示
这次我在两个版本os都试了, 发现4.14版本会报设备busy,而5.4版本扫描成功,实现目标

跟踪partprobe的函数流,发现其通过IOCTL向块设备做请求,最后走到了check_events, 4.14版本的check_events接口被某些老吊干掉了。重新恢复回来,然后起了一个service 定期扫描sda分区,实现sd卡热插拔。
整体看代码,综合fs、block、sd、scsi、usb_storage就能弄明白这块,有心人可以盘它

再说说区分udisk和sdcard的做法

前面看插拔usb storage全设备log时,打开scsi log开关,得到了一个线索,对这个需求有很大帮助
就是他会有一套交互协议,发送一串cmd

Command INQUIRY (6 bytes)
Command TEST_UNIT_READY (6 bytes)
Command READ_CAPACITY (10 bytes)
Command MODE_SENSE (6 bytes)
Command ALLOW_MEDIUM_REMOVAL (6 bytes)
Command READ_10 (10 bytes)

而这个INQUIRY能够获取很多基本信息存入了scsi_device中记录。 在sd_probe中利用好这些信息,通过strcmp来比较vendor、model判断读卡器和u盘,固定index来固定sdx偏移量,以及major和minor

vold在通过netlink接收 events时是根据major和minor去/dev/block/vold/下去mknod,然后进行mount挂载。固定了minor就相当于固定了这里的节点,进一步也就能够区别mount出udisk和sdcard各自的路径

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-12-14 16:03:59  更:2021-12-14 16:06:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 8:25:54-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码