RK3568驱动指南|第十篇 热插拔-第116章netlink监听广播信息实验

news2024/11/24 3:23:39

瑞芯微RK3568芯片是一款定位中高端的通用型SOC,采用22nm制程工艺,搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码,支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU,可用于轻量级人工智能应用。RK3568 支持安卓 11 和 linux 系统,主要面向物联网网关、NVR 存储、工控平板、工业检测、工控盒、卡拉 OK、云终端、车载中控等行业。


【公众号】迅为电子

【粉丝群】824412014(加群获取驱动文档+例程)

【视频观看】嵌入式学习之Linux驱动(第十期_热插拔_全新升级)_基于RK3568

【购买链接】迅为RK3568开发板瑞芯微Linux安卓鸿蒙ARM核心板人工智能AI主板


第116章netlink监听广播信息实验

在上一章的实验中,我们填充了三个回调函数,分别为.filter = myfilter,  .uevent = myevent,  .name = myname,但在最后的实验中只验证filter过滤了kset中的kobject1,那另外两个回调函数要如何验证呢?

内核通过kobject uevent接口发送广播事件之后,用户空间可以通过netlink来监听这些广播信息。通过监听广播信息,就可以获取到携带环境变量的事件,在本章节将会对netlink进行详细的讲解。

116.1 netlink机制介绍

Netlink是Linux内核中用于内核和用户空间之间进行双工通信的机制。它基于socket通信机制,并提供了一种可靠的、异步的、多播的、有序的通信方式。

Netlink机制的主要特点包括:

(1)双工通信:Netlink允许内核和用户空间之间进行双向通信,使得内核可以向用户空间发送消息,同时也可以接收来自用户空间的消息。

(2)可靠性:Netlink提供了可靠的消息传递机制,保证消息的完整性和可靠性。它使用了确认和重传机制,以确保消息的可靠传输。

(3)异步通信:Netlink支持异步通信,即内核和用户空间可以独立地发送和接收消息,无需同步等待对方的响应。

(4)多播支持:Netlink允许向多个进程或套接字广播消息,以实现一对多的通信。

(5)有序传输:Netlink保证消息的有序传输,即发送的消息按照发送的顺序在接收端按序接收。

Netlink的应用广泛,常见的应用包括:

(1)系统管理工具:如ifconfig、ip等工具使用Netlink与内核通信来获取和配置网络接口的信息。

(2)进程间通信:进程可以使用Netlink进行跨进程通信,实现进程间的数据交换和协调。

(3)内核模块和用户空间应用程序的通信:内核模块可以通过Netlink向用户空间应用程序发送通知或接收用户空间应用程序的指令。

116.2 netlink的使用

116.2.1 创建socket

在Linux socket编程中,创建套接字是构建网络应用程序的第一步。套接字可以理解为应用程序和网络之间的桥梁,用于在网络上进行数据的收发和处理。该系统调用的原型和所需头文件如下所示:

所需头文件

函数原型

#include <sys/types.h>          

#include <sys/socket.h>

int socket(int domain, int type, int protocol);

其中,domain参数指定了套接字的协议族,type参数指定了套接字的类型,protocol参数指定了套接字所使用的具体协议。下面分别介绍这三个参数的含义:

(1)协议族

协议族指定了套接字所使用的协议类型,常用的协议族包括AF_INET、AF_INET6、AF_UNIX等。其中,AF_INET表示IPv4协议族,AF_INET6表示IPv6协议族,AF_UNIX表示Unix域协议族,这里的协议族为netlink,所以该参数要在程序中设置为AF_ NETLINK。

(2)套接字类型

套接字类型指定了套接字的数据传输方式,常用的套接字类型包括SOCK_STREAM、SOCK_DGRAM、SOCK_RAW等。其中,SOCK_STREAM表示面向连接的流套接字,主要用于可靠传输数据,例如TCP协议。SOCK_DGRAM表示无连接的数据报套接字,主要用于不可靠传输数据,例如UDP协议。在本实验中该参数要设置为SOCK_RAW表示原始套接字,可以直接访问底层网络协议。

(3)协议类型

协议类型指定了套接字所使用的具体协议类型,常用的协议类型包括IPPROTO_TCP、IPPROTO_UDP、IPPROTO_ICMP等。其中,IPPROTO_TCP表示TCP协议,IPPROTO_UDP表示UDP协议,IPPROTO_ICMP表示ICMP协议,在本实验中,我们要设置为NETLINK_ _KOBJECT_ UEVENT

在本小节中将使用以下代码创建一个新的套接字:

1 

int socket_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT);

AF_NETLINK:指定了使用Netlink协议族。Netlink协议族是一种Linux特定的协议族,用于内核和用户空间之间的通信。

SOCK_RAW:指定了创建原始套接字,这种套接字类型可以直接访问底层协议,而不需要进行协议栈处理。在这种情况下,我们可以直接使用Netlink协议进行通信。

NETLINK_KOBJECT_UEVENT:指定了Netlink协议的一种类型,即kobject uevent类型。kobject uevent用于内核对象相关的事件通知,当内核中的kobject对象发生变化时,会通过此类型的Netlink消息通知用户空间。

116.2.2绑定套接字

创建套接字后,需要将其与一个网络地址绑定,以便其他计算机可以访问该套接字。在Linux系统下,可以使用bind()系统调用绑定套接字和地址。该系统调用的原型和所需头文件如下所示:

所需头文件

函数原型

1 

2

#include <sys/types.h>          

#include <sys/socket.h>

int bind(int sockfd, const struct sockaddr *addr,

socklen_t addrlen);

  1. sockfd参数指定了需要绑定的套接字描述符,
  2. addr参数指定了需要绑定的地址信息,这里使用sockaddr_nl结构体,sockaddr_nl结构体的定义如下:
struct sockaddr_nl {
    sa_family_t nl_family;  // AF_NETLINK
    unsigned short nl_pad;  // zero
    uint32_t nl_pid;        // port ID
    uint32_t nl_groups;     // multicast groups mask
};

nl_family:表示地址族,此处固定为AF_NETLINK,指示使用Netlink协议族。

nl_pad:填充字段,设置为0。在结构体中进行字节对齐时使用。

nl_pid:端口ID,表示进程的标识符。可以将其设置为当前进程的PID,也可以设为0,表示不加入任何多播组。

nl_groups:多播组掩码,用于指定感兴趣的多播组。当设置为1时,表示用户空间进程只会接收内核事件的基本组的内核事件。这意味着,用户空间进程将只接收到属于基本组的内核事件,而不会接收其他多播组的事件。

  1. addrlen参数:addrlen参数是一个整数,指定了addr所指向的结构体对应的字节长度。它用于确保正确解析传递给addr参数的结构体的大小。

具体编程示例如下所示:

struct sockaddr_nl *nl;  // 定义一个指向 struct sockaddr_nl 结构体的指针 nl

bzero(nl, sizeof(struct sockaddr_nl));  // 将 nl 指向的内存区域清零,确保结构体的字段初始化为0

nl->nl_family = AF_NETLINK;  // 设置 nl 结构体的 nl_family 字段为 AF_NETLINK,指定地址族为 Netlink
nl->nl_pid = 0;  // 设置 nl 结构体的 nl_pid 字段为 0,表示目标进程 ID 为 0,即广播给所有进程
nl->nl_groups = 1;  // 设置 nl 结构体的 nl_groups 字段为 1,表示只接收基本组的内核事件

ret = bind(socket_fd, (struct sockaddr *)nl, sizeof(struct sockaddr_nl));  // 使用 bind 函数将 socket_fd 套接字与 nl 地址结构体绑定在一起

if (ret < 0) {
    printf("bind error\n");
    return -1;
}

116.2.3接收数据

Netlink套接字在接收数据时不需要调用listen函数,而是可以直接使用recv函数进行接收。下面是recv函数的相关说明:

头文件:

#include <sys/types.h>
#include <sys/socket.h>

函数原型:

ssize_t recv(int sockfd, void *buf, size_t len, int flags);

函数参数:

sockfd:指定套接字描述符,即要接收数据的Netlink套接字。

buf:指向数据接收缓冲区的指针,用于存储接收到的数据。

len:指定要读取的数据的字节大小。

flags:指定一些标志,用于控制数据的接收方式。通常情况下,可以将其设置为0。

返回值:

成功情况下,返回实际读取到的字节数。

如果返回值为0,表示对方已经关闭了连接。

如果返回值为-1,表示发生了错误,可以通过查看errno变量来获取具体的错误代码。

使用recv函数可以从指定的Netlink套接字中接收数据,并将其存储在提供的缓冲区中。函数的返回值表示实际读取到的字节数,可以根据返回值来判断是否成功接收到数据。

接收数据的具体代码示例如下所示:

while (1) {
    bzero(buf, 4096);  // 将缓冲区 buf 清零,确保数据接收前的初始化
    len = recv(socket_fd, &buf, 4096, 0);  // 从 socket_fd 套接字接收数据,存储到缓冲区 buf 中,最大接收字节数为 4096

    for (i = 0; i < len; i++) {
        if (*(buf + i) == '\0') {  // 如果接收到的数据中有 '\0' 字符,将其替换为 '\n',以便在打印时换行显示
            buf[i] = '\n';
        }
    }

    printf("%s\n", buf);  // 打印接收到的数据
}

116.3 实验程序的编写

本应用程序对应的网盘路径为:iTOP-RK3568开发板【底板V1.7版本】\03_【iTOP-RK3568开发板】指南教程\02_Linux驱动配套资料\04_Linux驱动例程\80_netlink

根据上一小节所讲解的内容,使用netlink监听广播信息的应用程序netlink.c.c代码如下所示:

#include <stdio.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/netlink.h>

int main(int argc, char *argv[]) {
    int ret;
    struct sockaddr_nl *nl;  // 定义一个指向 struct sockaddr_nl 结构体的指针 nl
    int len = 0;
    char buf[4096] = {0};  // 数据接收缓冲区
    int i = 0;

    bzero(nl, sizeof(struct sockaddr_nl));  // 将 nl 指向的内存区域清零,确保结构体的字段初始化为0
    nl->nl_family = AF_NETLINK;  // 设置 nl 结构体的 nl_family 字段为 AF_NETLINK,指定地址族为 Netlink
    nl->nl_pid = 0;  // 设置 nl 结构体的 nl_pid 字段为 0,表示目标进程 ID 为 0,即广播给所有进程
    nl->nl_groups = 1;  // 设置 nl 结构体的 nl_groups 字段为 1,表示只接收基本组的内核事件

    int socket_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT);  // 创建一个 Netlink 套接字
    if (socket_fd < 0) {
        printf("socket error\n");
        return -1;
    }

    ret = bind(socket_fd, (struct sockaddr *)nl, sizeof(struct sockaddr_nl));  // 使用 bind 函数将 socket_fd 套接字与 nl 地址结构体绑定在一起
    if (ret < 0) {
        printf("bind error\n");
        return -1;
    }

    while (1) {
        bzero(buf, 4096);  // 将缓冲区 buf 清零,确保数据接收前的初始化
        len = recv(socket_fd, &buf, 4096, 0);  // 从 socket_fd 套接字接收数据,存储到缓冲区 buf 中,最大接收字节数为 4096

        for (i = 0; i < len; i++) {
            if (*(buf + i) == '\0') {  // 如果接收到的数据中有 '\0' 字符,将其替换为 '\n',以便在打印时换行显示
                buf[i] = '\n';
            }
        }

        printf("%s\n", buf);  // 打印接收到的数据
    }

    return 0;
}

116.4 运行测试

116.4.1 编译应用程序

下面进行应用程序编译,因为测试APP是要在开发板上运行的,所以需要aarch64-linux-gnu-gcc来编译,输入以下命令,编译完成以后会生成一个netlink的可执行程序,如下图(图116-1)所示:

aarch64-linux-gnu-gcc -o netlink netlink.c

图 116-1

下面进行程序的测试。

116.4.2 运行测试

本小节测试所使用的驱动文件为上一章编译生成的uevent_ops.ko,应用程序为上一小节编译出来的netlink。

开发板启动之后,首先使用以下命令让应用程序在后台运行,如下图(图116-2)所示:

./netlink &

图 116-2

然后继续使用以下命令加载uevent_ops.ko驱动,打印如下图(116-3)所示:

insmod uevent_ops.ko

图 116-3

SUBSYSTEM=my_kset,表示设备或对象所属的子系统。在这里,子系统是 "my_kset"。MYDEVICE表示设备的名称或标识。在这里,设备的名称是 "TOPEET",正是我们在回调函数中所设置的。

最后可以使用以下命令进行驱动的卸载,如下图(图116-4)所示:

rmmod uevent_ops.ko 

图 116-4

至此,使用netlink监听广播信息实验就完成了。


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

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

相关文章

CES 2024:AI智能大爆发,引领科技新纪元

美国当地时间1月9日&#xff0c;2024年国际消费类电子产品展览会&#xff08;CES&#xff09;如期在内华达州拉斯维加斯举行。作为全球最盛大的科技盛会&#xff0c;每年&#xff0c;来自世界各地的顶尖科技企业都会参加CES&#xff0c;展示他们的最新科技产品和创新&#xff0…

Python的安装与卸载【Windows系统】

在 Windows 上安装与卸载 Python Python的安装 下载Python 安装Python 下载完后打开安装包 注意最底下的"Add Python 3.8 to Path"&#xff08;将Python加入环境变量&#xff09;一定要勾选&#xff01;&#xff01;&#xff01;这样就可以免去之后环境配置的烦恼…

在本地测试nginx中localhost不行,需要写成127.0.0.1

在Windows 10系统的命令提示符cmd中&#xff0c;执行命令ping localhost&#xff0c;并没有出现我与其的ip地址“127.0.0.1”&#xff0c;而是“[::1]”。 问题原因 在cmd中ping localhost解析出来的是ipv6的::1的原因是windows有个优先解析列表&#xff0c;当ipv6的优先级高于…

【cmu15445c++入门】(4)c++中的模板方法

一、template模板方法 模板方法是c的一个特性&#xff0c;可以让你的代码在不指定数据类型的情况下&#xff0c;运行不同的数据类型。 你可以创建模板方法和模板类&#xff0c;本文讨论模板方法。 二、代码 // Includes std::cout (printing) for demo purposes. #include &…

4S店汽车行业万能通用小程序源码系统:功能强大,集合汽车在线展示+在线预约+贷款计算器......附带完整的搭建教程

在移动互联网高速发展的今天&#xff0c;越来越多的消费者选择通过手机端了解汽车信息、预约试驾、计算贷款等。4S店需要紧跟时代步伐&#xff0c;提供更加便捷、高效的服务。因此&#xff0c;开发一款集合汽车在线展示、在线预约、贷款计算器等多项功能的通用小程序成为市场趋…

数据结构02附录02:哈希表[C++]

图源&#xff1a;文心一言 上机题目练习整理~&#x1f95d;&#x1f95d; 本篇作为线性表的代码补充&#xff0c;每道题提供了优解和暴力解算法&#xff0c;供小伙伴们参考~&#x1f95d;&#x1f95d; 第1版&#xff1a;在力扣新手村刷题的记录&#xff0c;优解是Bard老师提…

语义补全任务2023年论文总结

一、3D Semantic Scene Completion: a Survey 语义场景补全SSC旨在联合估计出一个场景完整的几何和语义信息&#xff0c;假设只需要部分稀疏输入数据。 1、数据集 2、场景表示 Point Cloud&#xff0c;点云是一种方便的、记忆高效的表示方法&#xff0c;它将三维连续世界中的…

网站怎么做google搜索引擎优化?

网站想做google搜索引擎优化&#xff0c;作为大前提&#xff0c;您必须确保网站本身符合google规范&#xff0c;我们不少客户实际上就连这点都无法做到 有不少客户公司自己本身有技术&#xff0c;就自己弄一个网站出来&#xff0c;做网站本身不是难事&#xff0c;但前提是您需要…

OpenShift 4 - 在 OpenShift 上运行物体检测 AI 应用

《OpenShift / RHEL / DevSecOps 汇总目录》 说明&#xff1a;本文已经在 OpenShift 4.14 RHODS 2.5.0 的环境中验证 说明&#xff1a;请先根据《OpenShift 4 - 部署 OpenShift AI 环境&#xff0c;运行 AI/ML 应用&#xff08;视频&#xff09;》一文完成 OpenShift AI 环境…

基于k8s Deployment的弹性扩缩容及滚动发布机制详解

k8s第一个重要设计思想&#xff1a;控制器模式。k8s里第一个控制器模式的完整实现&#xff1a;Deployment。它实现了k8s一大重要功能&#xff1a;Pod的“水平扩展/收缩”&#xff08;horizontal scaling out/in&#xff09;。该功能从PaaS时代开始就是一个平台级项目必备编排能…

Kali改变为中文

更新kali源之后【如果没有更新&#xff0c;可以参考我的Kakli更新源】。 执行下面的命令&#xff1a; # apt-get update && apt-get upgrade && apt-get clean # dpkg-reconfigure locales 如果没有权限&#xff1f;可以通过sudo命令进行授权 1、先取消英文&…

KT6368A双模蓝牙芯片批量生产使用主机芯片KT6358M测试很方便

一、简介 KT6368A双模蓝牙芯片批量生产使用主机芯片测试很方便 KT6368A批量生产怎么办&#xff1f;不可能用手机一个一个的去连吧&#xff0c;太慢了 别慌&#xff0c;这个问题&#xff0c;我们早就考虑清楚了&#xff0c;答案如下&#xff0c;分为两个方法&#xff1a; 详细…

2024数字安全十大技术趋势预测,不容忽视!

2023年是技术爆发的一年&#xff0c;ChatGPT、量子计算、常温超导体争相刷新眼球&#xff1b;2023年是风云变幻的一年&#xff0c;局部战争、网络战、全球经济震荡交替冲击……无数个值得记忆的瞬间&#xff0c;都对网络安全行业产生着深远影响。 通过观察2023年的国际国内环境…

路由器实验总结(静态路由配置)

1、静态路由的配置 R2(config)#int s0/0/0 R2(config)#ip add 192.168.3.2 255.255.255.0 R2(config)# no shut R1(config)#int s0/0/0 R1(config)#ip add 192.168.3.1 255.255.255.0 R1(config)# no shut串口的配置是这样的&#xff0c;静态路由如下&#xff1a; R2(config)#…

项目经理快速晋升应当具备的四个能力

项目的成功与失败都直接压在项目经理的肩上。不论问题的根源在何处&#xff0c;最终承担责任的总是项目经理。身为项目经理&#xff0c;你务必清楚&#xff0c;自己背负的是何等的重任。 1、计划能力 计划是行动的灯塔&#xff0c;若管理者无法制定计划&#xff0c;又如何引…

低功耗智能雨量监测站现代化雨水情监测网络

低功耗智能雨量监测站现代化雨水情监测网络产品概述 低功耗雨量监测站基于传感技术、无线通信、处理与控制等物联网技术的开发&#xff0c;利用传感技术&#xff0c;通过传感器测量降雨量&#xff0c;并使用物联网进行传输。无需专门的通信线路&#xff0c;在联网的状态下&…

vscode 创建文件自动添加注释信息

随机记录 目录 1. 背景介绍 2. "Docstring Generator"扩展 2.1 安装 2.2 设置注释信息 3. 自动配置py 文件头注释 1. 背景介绍 在VS Code中&#xff0c;您可以使用扩展来为新创建的Python文件自动添加头部注释信息。有几个常用的扩展可以实现此功能&#xff0…

VUE element-ui实现表格动态展示、动态删减列、动态排序、动态搜索条件配置

1、实现效果 1.1、文件目录 1.2、说明 1、本组件支持列表的表头自定义配置&#xff0c;checkbox实现 2、本组件支持列表列排序&#xff0c;vuedraggable是拖拽插件&#xff0c;上图中字段管理里的拖拽效果 &#xff0c;需要的话请自行npm install 3、本组件支持查询条件动态…

基于ssm阅微文学网站的设计与开发+vue论文

摘 要 信息数据从传统到当代&#xff0c;是一直在变革当中&#xff0c;突如其来的互联网让传统的信息管理看到了革命性的曙光&#xff0c;因为传统信息管理从时效性&#xff0c;还是安全性&#xff0c;还是可操作性等各个方面来讲&#xff0c;遇到了互联网时代才发现能补上自古…

【AI】AI和医疗大数据(1/3)

目录 一、医疗大数据有哪些 二、医疗大数据的特性 1. 隐私性 2. 复杂性 3. 不均衡性 4. 时序性 三、医疗大数据的目标和挑战 博主曾经在医疗智能设备领域创业&#xff0c;由于当时选择的模式过于复杂&#xff0c;包括了机械硬件、智能终端软硬件、院后微信生态做随访服务…