Android内核之Binder读写通信:binder_ioctl_write_read用法实例(七十)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!

优质专栏:Audio工程师进阶系列原创干货持续更新中……】🚀
优质专栏:多媒体系统工程师系列原创干货持续更新中……】🚀
优质视频课程:AAOS车载系统+AOSP14系统攻城狮入门实战课原创干货持续更新中……】🚀

人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

更多原创,欢迎关注:Android系统攻城狮

欢迎关注Android系统攻城狮

🍉🍉🍉文章目录🍉🍉🍉

    • 🌻1.前言
    • 🌻2.Android内核之binder_ioctl_write_read介绍
    • 🌻3.代码实例
      • 🐓3.1 发送Binder消息
      • 🐓3.2 接收Binder消息
      • 🐓3.3 Binder事件通知

🌻1.前言

本篇目的:Android内核之IPC通信:binder_ioctl_write_read用法实例

🌻2.Android内核之binder_ioctl_write_read介绍

  • binder_ioctl_write_read是Android系统中Binder驱动的关键函数之一,用于在用户空间和内核空间之间进行进程间通信(IPC)。Android的Binder机制是一种高效的IPC机制,用于在Android系统中进行进程间通信,特别是在应用程序和系统服务之间。

  • 该函数的主要作用是通过ioctl系统调用在用户空间和内核空间之间传递数据。在Binder中,进程可以通过Binder节点向Binder驱动发送请求消息,而Binder驱动负责将这些消息传递到目标进程。在内核空间中,这些请求消息和响应消息被表示为数据结构,并通过binder_ioctl_write_read函数进行读写。

  • 具体而言,binder_ioctl_write_read函数的作用包括:

  1. 消息传递: 通过该函数,应用程序可以向Binder驱动发送请求消息,例如调用远程服务的请求或发送数据给其他进程。

  2. 数据交换: 该函数允许应用程序和内核空间之间交换数据,实现进程间通信。数据可以是任何形式的信息,如函数调用、参数、返回值等。

  3. 事件通知: Binder机制还支持事件通知,例如进程间的状态变化或系统服务的可用性。binder_ioctl_write_read函数可以用于发送和接收这些事件通知。

  4. 错误处理: 除了消息传递外,该函数还负责处理可能发生的错误情况。例如,当发送消息失败或接收到无效的消息时,函数会返回相应的错误码,应用程序可以据此进行错误处理。

  • 使用binder_ioctl_write_read函数需要一定的内核编程知识和经验。开发者需要了解Binder驱动的工作原理以及消息传递的机制,同时要熟悉ioctl系统调用的使用方法。在实际开发中,通常会使用高级别的API和框架来进行Binder通信,这些API和框架会封装底层的细节,简化开发过程。

  • binder_ioctl_write_read函数在Android系统中扮演着至关重要的角色,它为应用程序提供了一种强大的IPC机制,支持应用程序之间和应用程序与系统服务之间的通信,促进了Android系统的功能丰富和性能优化。

🌻3.代码实例

🐓3.1 发送Binder消息

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/android/binder.h>

#define DEVICE_NAME "binder_example"
#define BINDER_DEV_PATH "/dev/binder_example"

static int major_number;
static struct class *binder_class = NULL;
static struct device *binder_device = NULL;

// 打开Binder设备
static int binder_open(struct inode *inode, struct file *file) {
    printk(KERN_INFO "Binder device opened\n");
    return 0;
}

// 释放Binder设备
static int binder_release(struct inode *inode, struct file *file) {
    printk(KERN_INFO "Binder device closed\n");
    return 0;
}

// 实现Binder设备的ioctl操作
static long binder_ioctl(struct file *file, unsigned int cmd, unsigned long arg) {
    int ret = 0;
    struct binder_write_read bwr;

    switch (cmd) {
        case BINDER_SEND_MESSAGE:
            // 发送Binder消息
            // 在这里构造消息数据,并使用binder_ioctl_write_read发送消息
            break;
        default:
            printk(KERN_ERR "Unknown command\n");
            ret = -EINVAL;
            break;
    }

    return ret;
}

// 初始化Binder设备
static int __init binder_init(void) {
    // 分配主设备号
    major_number = register_chrdev(0, DEVICE_NAME, &binder_fops);
    if (major_number < 0) {
        printk(KERN_ALERT "Failed to register a major number\n");
        return major_number;
    }

    // 创建设备类
    binder_class = class_create(THIS_MODULE, DEVICE_NAME);
    if (IS_ERR(binder_class)) {
        unregister_chrdev(major_number, DEVICE_NAME);
        printk(KERN_ALERT "Failed to register device class\n");
        return PTR_ERR(binder_class);
    }

    // 创建设备节点
    binder_device = device_create(binder_class, NULL, MKDEV(major_number, 0), NULL, DEVICE_NAME);
    if (IS_ERR(binder_device)) {
        class_destroy(binder_class);
        unregister_chrdev(major_number, DEVICE_NAME);
        printk(KERN_ALERT "Failed to create the device\n");
        return PTR_ERR(binder_device);
    }

    printk(KERN_INFO "Binder module initialized\n");
    return 0;
}

// 卸载Binder设备
static void __exit binder_exit(void) {
    device_destroy(binder_class, MKDEV(major_number, 0));
    class_unregister(binder_class);
    class_destroy(binder_class);
    unregister_chrdev(major_number, DEVICE_NAME);
    printk(KERN_INFO "Binder module exit\n");
}

module_init(binder_init);
module_exit(binder_exit);
MODULE_LICENSE("GPL");

🐓3.2 接收Binder消息

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/android/binder.h>

#define DEVICE_NAME "binder_example"
#define BINDER_DEV_PATH "/dev/binder_example"

static int major_number;
static struct class *binder_class = NULL;
static struct device *binder_device = NULL;

// 打开Binder设备
static int binder_open(struct inode *inode, struct file *file) {
    printk(KERN_INFO "Binder device opened\n");
    return 0;
}

// 释放Binder设备
static int binder_release(struct inode *inode, struct file *file) {
    printk(KERN_INFO "Binder device closed\n");
    return 0;
}

// 实现Binder设备的ioctl操作
static long binder_ioctl(struct file *file, unsigned int cmd, unsigned long arg) {
    int ret = 0;
    struct binder_write_read bwr;

    switch (cmd) {
        case BINDER_RECEIVE_MESSAGE:
            // 接收Binder消息
            // 在这里构造消息数据,并使用binder_ioctl_write_read接收消息
            break;
        default:
            printk(KERN_ERR "Unknown command\n");
            ret = -EINVAL;
            break;
    }

    return ret;
}

// 初始化Binder设备
static int __init binder_init(void) {
    // 分配主设备号
    major_number = register_chrdev(0, DEVICE_NAME, &binder_fops);
    if (major_number < 0) {
        printk(KERN_ALERT "Failed to register a major number\n");
        return major_number;
    }

    // 创建设备类
    binder_class = class_create(THIS_MODULE, DEVICE_NAME);
    if (IS_ERR(binder_class)) {
        unregister_chrdev(major_number, DEVICE_NAME);
        printk(KERN_ALERT "Failed to register device class\n");
        return PTR_ERR(binder_class);
    }

    // 创建设备节点
    binder_device = device_create(binder_class, NULL, MKDEV(major_number, 0), NULL, DEVICE_NAME);
    if (IS_ERR(binder_device)) {
        class_destroy(binder_class);
        unregister_chrdev(major_number, DEVICE_NAME);
        printk(KERN_ALERT "Failed to create the device\n");
        return PTR_ERR(binder_device);
    }

    printk(KERN_INFO "Binder module initialized\n");
    return 0;
}

// 卸载Binder设备
static void __exit binder_exit(void) {
    device_destroy(binder_class, MKDEV(major_number, 0));
    class_unregister(binder_class);
    class_destroy(binder_class);
    unregister_chrdev(major_number, DEVICE_NAME);
    printk(KERN_INFO "Binder module exit\n");
}

module_init(binder_init);
module_exit(binder_exit);
MODULE_LICENSE("GPL");

🐓3.3 Binder事件通知

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/android/binder.h>

#define DEVICE_NAME "binder_example"
#define BINDER_DEV_PATH "/dev/binder_example"

static int major_number;
static struct class *binder_class = NULL;
static struct device *binder_device = NULL;

// 打开Binder设备
static int binder_open(struct inode *inode, struct file *file) {
    printk(KERN_INFO "Binder device opened\n");
    return 0;
}

// 释放Binder设备
static int binder_release(struct inode *inode, struct file *file) {
    printk(KERN_INFO "Binder device closed\n");
    return 0;
}

// 实现Binder设备的ioctl操作
static long binder_ioctl(struct file *file, unsigned int cmd, unsigned long arg) {
    int ret = 0;
    struct binder_write_read bwr;

    switch (cmd) {
        case BINDER_RECEIVE_EVENT:
            // 接收Binder事件通知
            // 在这里构造事件数据,并使用binder_ioctl_write_read接收事件
            break;
        default:
            printk(KERN_ERR "Unknown command\n");
            ret = -EINVAL;
            break;
    }

    return ret;
}

// 初始化Binder设备
static int __init binder_init(void) {
    // 分配主设备号
    major_number = register_chrdev(0, DEVICE_NAME, &binder_fops);
    if (major_number < 0) {
        printk(KERN_ALERT "Failed to register a major number\n");
        return major_number;
    }

    // 创建设备类
    binder_class = class_create(THIS_MODULE, DEVICE_NAME);
    if (IS_ERR(binder_class)) {
        unregister_chrdev(major_number, DEVICE_NAME);
        printk(KERN_ALERT "Failed to register device class\n");
        return PTR_ERR(binder_class);
    }

    // 创建设备节点
    binder_device = device_create(binder_class, NULL, MKDEV(major_number, 0), NULL, DEVICE_NAME);
    if (IS_ERR(binder_device)) {
        class_destroy(binder_class);
        unregister_chrdev(major_number, DEVICE_NAME);
        printk(KERN_ALERT "Failed to create the device\n");
        return PTR_ERR(binder_device);
    }

    printk(KERN_INFO "Binder module initialized\n");
    return 0;
}

// 卸载Binder设备
static void __exit binder_exit(void) {
    device_destroy(binder_class, MKDEV(major_number, 0));
    class_unregister(binder_class);
    class_destroy(binder_class);
    unregister_chrdev(major_number, DEVICE_NAME);
    printk(KERN_INFO "Binder module exit\n");
}

module_init(binder_init);
module_exit(binder_exit);
MODULE_LICENSE("GPL");

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

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

相关文章

Python专题:三、数字和运算(2)

目录 一、数学运算 二、赋值运算 一、数学运算 1、运算符号 加法 减法- 乘法* 除法/ 计算机中浮点数表示有精度限制&#xff0c;Python有限&#xff0c;所以近似取数 2、除法取整// Python2中 整数/整数 值为整数 Python3中 整数/整数 整数or浮点数 //计算除法对结果取…

植被参数光学遥感反演方法(Python)及遥感与生态模型数据同化算法

原文链接&#xff1a;植被参数光学遥感反演方法(Python)及遥感与生态模型数据同化算法https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247603741&idx4&sn5b92ff13edfd6e146b7df22ac504c6d5&chksmfa8217facdf59eec9255d24b3e6f6f66b4d2814cae70f85d0ff1a…

月薪从 6k 到 30k,我做对了这3点

本文首发于公众号 极客枫哥 &#xff0c;日更分享各种好玩的软件、编程知识和个人成长故事 大家好啊&#xff5e;我是枫哥。今天跟大家聊一聊我的个人工作经历。 我是 2014 年来的上海&#xff0c;来到上海后第一份工作做的是 java 开发&#xff0c;转正后的工资是 6000。 这…

中国 Copilot 能在笔记本电脑上起飞吗?

AI PC 是 PC 的下一个进化体&#xff1f; 中国能打造出自己的 AI 研发助手吗&#xff1f; 企业如何构建 AI 竞争力&#xff1f; AI 时代&#xff0c;个体如何避免被取代&#xff1f; 如果你也有此困惑&#xff0c;那就锁定这场直播吧&#xff01; 视频号搜索【极狐GitLab】预约…

Leecode42:接雨水

第一反应是按照高低这个思路来求解&#xff0c;因为可以把盛雨水的容器想成是从左往右的&#xff0c;遇到一个沟就存一点雨水。 这个思路 看了下题解&#xff0c;发现自己的思路其实没问题&#xff0c;确实是按照最高最低来求&#xff0c;但是这个地方太复杂了求的&#xff0c…

【spark】win10 pyspark3.5.1 安装超级简单

下载地址&#xff1a;https://spark.apache.org/downloads.html 下载完成&#xff1a; 复制文件到自己的路径下&#xff0c;路径最好不要有中文、空格&#xff1b; 解压tgz文件&#xff1a; 修改环境变量&#xff1a; 创建SPARK_HOME&#xff1a; D:\software_download\spar…

STM32F103学习笔记 | 报错界面及解决方案 | 1.keil5中文注释的横竖(正与斜)问题

文章目录 一、报错界面二、解决方案参考文献 一、报错界面 二、解决方案 打开设置 在打开的设置选项卡中&#xff0c;图中Font显示的是这个软件当前设置的字体&#xff0c;可以看到字体是仿宋&#xff0c;这就是问题出现的原因&#xff0c;将之改成没有的字体就行了。 可以看…

黑马点评项目总结

登录 基于session登录 短信验证码登录 配置登录拦截器 向 Spring MVC 框架中添加拦截器&#xff0c;LoginInterceptor 是一个自定义的拦截器&#xff0c;用于拦截用户的登录请求。 excludePathPatterns这一句是设置拦截器需要放行的请求路径列表。 "/user/code", …

【Linux】常用基本指令

目录 食用说明 用户管理 whoami/who clear tree 目录结构和路径 pwd ls 文件 隐藏文件 常用选项 cd 家目录、根目录、绝对路径和相对路径 touch 常用选项 mkdir rmdir/rm man cp mv cat nano echo 输出重定向 > 输入重定向 < more/less head/…

选修选课|基于Springboot+vue的大学生选修选课系统的设计与实现(源码+数据库+文档)

大学生选修选课系统 目录 基于Springboot&#xff0b;vue的大学生选修选课系统设计与实现 一、前言 二、系统设计 三、系统功能设计 1用户信息管理 2 课程信息管理 3排课信息管理 4公告信息管理 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题…

【数据库原理及应用】期末复习汇总高校期末真题试卷06

试卷 一、选择题 1&#xff0e; ________是长期存储在计算机内的有组织,可共享的数据集合. A.数据库管理系统 B.数据库系统 C.数据库 D.文件组织 1&#xff0e; 有12个实体类型&#xff0c;并且它们之间存在15个不同的二元联系&#xff0c;其中4个是1:1联系类型&#xff0c;5…

二、双fifo流水线操作——verilog练习与设计

文章目录 一、案例分析二、fifo_ctrl模块设计2.1 波形设计&#xff1a;2.2 代码实现2.2.1 fifo_ctrl2.2.2 顶层文件top_fifo_ctrl&#xff08;rx和tx模块省略&#xff09;2.2.3 仿真文件tb_fifo_ctrl 2.3波形仿真 一、案例分析 案例要求&#xff1a;写一个 fifo 控制器&#x…

直播产品实习生实习体验报告,笔灵AI生成模版分享

实习体验报告&#xff1a;直播产品实习生 如果有不同的岗位需要写的话可以去笔灵生成一下 网址&#xff1a;https://ibiling.cn/scene/inex?fromcsdnsx 一、实习背景我是XXX&#xff0c;作为一名直播产品实习生&#xff0c;我在XX公司进行了为期X个月的实习。在这段时间里&…

Bumblebee X系列用于高精度机器人应用的新型立体视觉产品

Bumblebee X是最新的GigE驱动立体成像解决方案&#xff0c;为机器人引导和拾取应用带来高精度和低延迟。 近日&#xff0c;51camera的合作伙伴Teledyne FLIR IIS推出一款用于高精度机器人应用的新型立体视觉产品Bumblebee X系列。 Bumblebee X产品图 BumblebeeX系列&#xff…

使用C++ __builtin_expect优化程序性能后,程序体积不改变原因

结论 使用__builtin_expect优化程序性能&#xff0c;开启-O3的情况下&#xff0c;确实程序的体积可能不改变&#xff0c;但是还是会产生优化效果。 测试代码 不使用__builtin_expect #include <iostream>void fun(int a, int b) {// 不使用__builtin_expectif (a <…

poisson分布及其stata实现

1. 概念 泊松回归&#xff08;Poisson regression&#xff09;是用来为计数资料和列联表建模的一种回归分析。泊松回归假设反应变量Y是泊松分布&#xff0c;并假设它期望值的对数可被未知参数的线性组合建模。泊松回归模型有时&#xff08;特别是当用作列联表模型时&#xff0…

libcity笔记:详细流程(以DeepMove为例)

0 前置操作 这边我选择了gowalla的前1000条数据做例子&#xff1a; 0.1 生成样例dyna import pandas as pd geopd.read_csv(/home_nfs/liushuai/Bigscity-LibCity/raw_data/gowalla_test/gowalla.dyna)geo_tstgeo.iloc[:1000,:] geo_tst geo_tst.to_csv(/home_nfs/liushuai/…

电脑小工具总结(下载哔哩哔哩视频等)

哔哩哔哩视频下载器 https://www.jijidown.com/

HFSS-day3-HFSS的工作界面

工作界面也称为用户界面&#xff0c;是HFSS软件使用者的工作环境:了解、熟悉这个工作环境是掌握HFSS软件使用的第一步 HFSS工作环境介绍 1.HFSS工作界面简单的组成说明2.工作界面中各个工作窗口功能主菜单工具栏项目管理窗口属性窗口信息管理窗口进程窗口三维模型窗口 3.HFSS主…

【ITK配准】第七期 尺度(Metric)- 均方Metric

很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 公众号:VTK忠粉 前言 本文分享ITK中的均方Metric,即itk::MeanSquaresImageToImageMetricv4,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就是我的动力…