自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(42)
  • 收藏
  • 关注

原创 焦现军博士北大 openWiFi 讲座记录

WiFi 的芯片之间会相互避免干扰,就例如上面的 packet 被调制成信号后要发出,会受到 CSMA 的管控。而接收信号就不会被管控。minstrel_ht 速率调整主要是通过先发送小速率的包试探,如果可以,会进一步加大速率,如果还能被接收响应,那么还会继续加大速率。这个芯片的开放程度实际上不高,但是有一个德国的反向团队该芯片进行了很多工作,目前也被研究得比较透。这个我是最关心的,因为此时我还是一个驱动工程师,上图是我研究的主要方向。白色字体的是Linux自带的,黄色字体的是WiFi芯片需要适配的部分。

2024-07-29 15:51:58 472

原创 802.11 Omnipeek 抓包

设备准备环节和前面一样,本文不再赘述,参考前面的文章:https://blog.csdn.net/m0_55334946/article/details/140671901采用 Omnipeek 抓包分析,我可以说比起 wireshark 已经赢了一半了。不仅仅是因为 Omnipeek 更加便捷直观的界面和支持更多网卡,更在于其对 802.11 帧会有自动分析。因此,我们想要通过 Omnipeek 来分析 802.11 帧,只需要将帧结构整理成一本字典,直接对着分析病因即可。

2024-07-24 21:50:14 376

原创 802.11 wireshark 抓包

本人习惯使用 Omnipeek 抓包分析,所以 wireshark 的实验只讲到抓包完成。Windows 环境采用 wireshark 抓包是比较麻烦的,因为支持在 Windows 环境中支持抓包的网卡并不多,所以本次直接用 Linux 环境来做试验。使用网卡为:RT3070L,70块钱一张的网卡。

2024-07-24 21:03:52 1289

原创 802.11无线网络权威指南(二):无线帧结构

RTS/CTS技术通过引入两个新的控制帧,即RTS帧和CTS帧,来协调发送方和接收方之间的通信,有效减少信号冲突,提高网络传输效率。CTS 帧发送端会将 RTS 帧的 duration 值减去传送 CTS 帧及其后的短帧间间隔送需要的时间,然后将计算结果置于 CTS 的 duration 字段中。而用来响应 RTS 的 CTS 帧的发送端会以 RTS 帧的 duration 值作为持续时间的计算基准。超过该门限值的数据帧由 RTS/CTS 先行清空介质,而较小的帧则直接传送,不需要发送。

2024-07-24 17:26:23 1450

原创 深入理解Linux网络(八):内核如何发送网络包

深入理解Linux网络(八):内核如何发送网络包一、总览二、网卡启动准备三、ACCEPT 创建新 SOCKET四、开始发送数据send 系统调⽤实现传输层处理传输层拷贝传输层发送网络层发送原理邻居⼦系统网络设备子系统软中断调度igb网卡驱动发送发送完成硬件中断五、问题一、总览⽤户数据被拷⻉到内核态,然后经过协议栈处理后进⼊到了 RingBuffer 中。随后⽹卡驱动真正将数据发送了出去。当发送完成,硬中断来通知 CPU 触发清理 RingBuffer 的代码。调用顺序如下:应用层:send()

2024-07-23 19:13:22 986

原创 深入理解Linux网络(七):网络包处理之CPU开销汇总

wa(等待):等待I/O操作完成的时间,即CPU等待输入输出操作完成的时间。sy(系统空间):系统态占用CPU的时间,即操作系统内核进程执行的时间。us(用户空间):用户态占用CPU的时间,即用户进程或应用程序执行的时间。st: 12%:在虚拟化环境中,偷取时间占12%,表示有其他虚拟机正在共享物理资源并占用部分CPU时间。这是CPU未被占用的时间。sy: 15%:系统空间占用CPU的15%,表示操作系统内核进程正在执行一些任务。id: 45%:空闲时间占45%,表示大部分时间CPU处于空闲状态。

2024-07-23 18:14:21 394

原创 深入理解Linux网络(六):IO 复用 epoll 内部实现

IO复用解决的真正问题是什么?:每次⼀个进程专⻔为了等⼀个 socket 上的数据就得被从 CPU 上拿下来。然后再换上另⼀个进程。等到数据 ready 了,睡眠的进程⼜会被唤醒。总共两次进程上下⽂切换开销,根据之前的测试来看,每⼀次切换⼤约是 3-5 us(微秒)左右。如果是⽹络 IO 密集型的应⽤的话,CPU 就不停地做进程切换这种⽆⽤功。也就是频繁进程上下文切换的开销巨大。

2024-07-22 17:28:30 801

原创 深入理解Linux网络(五):TCP接收唤醒

在 recv 函数执⾏的时候,使⽤ DEFINE_WAIT() 定义等待队列项的细节,内核把 curr->func 设置成了 autoremove_wake_function。回想上⾯我们在 创建 socket 流程⾥执⾏到的 sock_init_data 函数,在这个函数⾥已经把 sk_data_ready 设置成 sock_def_readable 函数了。在 tcp_rcv_established 中通过调⽤ tcp_queue_rcv 函数中完成了将接收数据放到 socket 的接收队列上。

2024-07-22 15:14:36 990

原创 深入理解Linux网络(四):TCP接收阻塞

进⼊系统调⽤后,⽤户进程就进⼊到了内核态,通过执⾏⼀系列的内核协议层函数,然后到 socket 对象的接收队列中查看是否有数据,没有的话就把⾃⼰添加到 socket 对应的等待队列⾥。这样后⾯当内核收完数据产⽣就绪时间的时候,就可以查找 socket 等待队列上的等待项,进⽽就可以找到回调函数和在等待该 socket 就绪事件的进程了。紧接着在 sk_wait_data 中 调⽤ sk_sleep 获取 sock 对象下的等待队列列表头 wait_queue_head_t。

2024-07-20 02:34:19 456

原创 深入理解Linux网络(三):TCP对象创建

inet_create 中根据类型 SOCK_STREAM 查找到对于 tcp 定义的操作⽅法实现集合 inet_stream_ops 和 tcp_prot。当软中断上收到数据包时会通过调⽤ sk_data_ready 函数指针(实际被设置成了 sock_def_readable()) 来唤醒在 sock 上等待的进程。sock_init_data 中将 sock 中的 sk_data_ready 函数指针进⾏了初始化,设置为默认 sock_def_readable()。

2024-07-20 02:05:04 485

原创 深入理解Linux网络(二):UDP接收内核探究

代码⾥调⽤的 recvfrom 是⼀个 glibc 的库函数,该函数在执⾏后会将⽤户进⾏陷⼊到内核态,进⼊到 Linux 实现的系统调⽤ sys_recvfrom。如果没有数据,且⽤户也允许等待,则将调⽤ wait_for_more_packets() 执⾏等待操作,它加⼊会让⽤户进程进⼊睡眠状态。对于 udp 来说,是通过 inet_dgram_ops 来定义的,其中注册了 inet_recvmsg ⽅法。接收队列⼤⼩受内核参数。具体是怎么进⼊睡眠状态的,和 TCP 的实现一样,属于进程的基本知识了。

2024-07-20 01:00:57 1095 1

原创 深入理解Linux网络(一):内核如何接收网络包

在上⾯的代码中跟踪函数调⽤, __igb_open => igb_request_irq => igb_request_msix , 在 igb_request_msix 中我们看到了,对于多队列的⽹卡,为每⼀个队列都注册了中断,其对应的中断处理函数是 igb_msix_ring(该函数也在 drivers/net/ethernet/intel/igb/igb_main.c 下)。如协议注册⼩节看到 inet_protos 中保存着 tcp_v4_rcv() 和 udp_rcv() 的函数地址。

2024-07-18 19:12:46 940

原创 802.11无线网络权威指南(一):概念解析

第二种是虚拟载波监听功能,判断媒介是否处于忙碌状态,以NAV作为判断标准,大多数帧会在NAV字段中指定一段时间,礼貌性要求其他工作站在这段期间暂时停止访问传输媒介,直到该帧被传送出去为止。将宽频带分割后,通过这些较窄的子频带,以多路传送与还原数据技术传送。network allocation vector,主要用于实现虚拟载波监听功能,如果传输媒介处于忙碌状态,工作站就会延迟访问,RTS 请求传送,用来开始 RTS-CTS 清空过程的帧,当所要传送的帧大于RTS限制阈值时就会用到RTS帧。

2024-06-26 22:28:48 703

原创 STM32 HAL 串口理论和实例

因为最近老板突发奇想,想要做一个轻量级的AI工具,其他保密,我负责整理采集到的数据并上传到服务器。趁此大好机会,赶紧复习一下串口的知识。一些和实际开发不相关的基础知识我就直接跳过了。

2023-09-28 15:12:20 589

原创 供应商系统工具剖析

每个命令的名称、说明、回调函数、获取参数的函数、普通参数做成了一个表。a_argc 是 main 函数的参数个数,a_argv 是 main 函数的所有参数组成的字符串。可以看到是通过 std 标准库来实现的,而且为了减少内存和提高翻问速度,队列里存放的是任务指针。其实我们关心的并不是这个工具的结构,而是这个工具的实现方法,是否有通用的软件工具开发方法?下面简单讲一下这个工具的业务处理,对比两个命令的执行流程来了解一下。软件框架上就是这样,简单的框架,复杂的任务。GetCommandByName 原型。

2023-09-20 17:02:48 159

原创 SPI驱动理论与实例分析2

/将一字节十进制数字转换成二进制 debug用,一般用于查看寄存器每个位的数值//将一字节十进制数字转换成二进制 debug用,一般用于查看寄存器每个位的数值 # define PRINTF_BINARY_PATTERN_INT8 "%c %c %c %c %c %c %c %c" # define PRINTF_BYTE_TO_BINARY_INT8(i) \(((i) & 0x80ll)?

2023-09-18 18:03:25 243

原创 PWM驱动理论与分析

瑞芯微 PWM 控制器驱动源码:/kernel/drivers/pwm/pwm-rockchip.c目前主流的 pwm 设备驱动都是集成到 sysfs 文件系统中,通过 cat 和 echo 操作来控制,我接到的任务也是这样。所以编写 pwm 设备驱动的核心就是完成 sysfs 操作集,通过 sysfs 来操作脉冲宽度。PWM的原理是通过调整周期性波形的高电平时间宽度,从而改变有效信号的占空比,实现对设备的供电控制。

2023-09-13 17:28:49 539

原创 自组织网络设计和开发

功能正常组网都是需要人工在各个节点上输入 SSID、密码、信道完成组网的;如果是远距离基站组网,那么用的设备数量就会比较少,但是距离遥远,每个站点都需要人工控制;如果是短距离组网,就意味着节点数量多,那么人工操作就会繁琐。如果可以将设备安置好位置后,一键上电,设备会自动连接,那么就可以避免繁琐重复的人工操作。前置模块wpa_supplicant 是开源项目,是 wifi 驱动的标配工具,用于管理 wifi 的所有功能。

2023-09-09 14:05:24 57

原创 无线网络隔离设计和开发

该软件用于将不同型号的无线通信设备隔离开,由于目前的无线 WIFI 都是通过 SSID 和 KEY 来连接的。虽然有黑名单系统,但是黑名单系统从底层看是禁止了特定 MAC 地址的设备连接。这样就有一个问题,不可能每次生产一批设备,都要去改变之前卖给客户的设备的黑名单吧???所以需要在连接时进行快速认证,认证结果将保存在进程中,掉电后会重新认证。这是考虑到我们的设备用于远距离基站互联,一般不会掉电,并且约定了后续会不断提供升级版本,并且特殊的机制可以预防一切客户的奇葩操作。

2023-09-06 16:47:20 104

原创 SPI驱动理论与实例分析

实例部分分为几个部分:1、正点原子 imx6ull 陀螺仪模块驱动,非常经典,基本满足所有 SPI 驱动开发;2、瑞芯微官方 SPI 设备驱动例程;由于文章长度,以下两个实战例子放在另一篇文章。3、高通 DACx0501 (ADC)模块驱动;4、高通 IDT8V97003 (无线发射接收器)模块驱动。SPI,是英语Serial Peripheral interface的缩写,顾名思义就是串行外围设备接口。是Motorola首先在其MC68HCXX系列处理器上定义的。

2023-09-06 11:58:08 894

原创 LCD驱动理论与实例分析

基础篇和驱动篇使用 I.MX6U-ALPHA 开发板。实例篇使用 RK3568 开发板和 mipi LCD 模块。

2023-09-04 18:33:19 1346

原创 TSP驱动理论与实例分析

文章目录前言一、设备树编写IIC设备地址:复位管脚配置中断管脚配置二、驱动分析数据设定和数据结构probe 解析硬件相关基础设定IIC读取函数解析设备模型添加中断服务函数总结本驱动相对于原版驱动的改动将驱动添加到内核tslib 移植与使用使用内核自带的驱动前言如果是从IIC协议跳转过来的,那么还需要了解一个 input 子系统。触摸屏驱动虽然用的协议是 IIC,也就是说驱动架构是 IIC 驱动,但是在IIC驱动中又把任务都丢给了 input 子系统,而且还要再 IIC 消息中还包装硬件业务。内核未

2023-09-04 17:24:48 182

原创 IIC驱动理论与实例分析

不啰嗦,直接从驱动开讲,需要学习IIC协议基础知识的可以先看这篇文章:https://www.rstk.cn/news/369263.html?提示:需要了解 IIC 的帧格式、读写/命令模式才能彻底了解 i2c_msg 的使用。不想进半导体厂的驱动工程师直接看 设备驱动和设备驱动编写!!!

2023-09-01 02:45:51 164 1

原创 input子系统理论与实例分析

直接上图:(图片来源于正点原子笔记)(输入子系统对触摸屏狠重要,会用 TS Handler 狠重要!驱动层:输入设备的具体驱动程序,比如按键驱动程序,向内核层报告输入内容。核心层:承上启下,为驱动层提供输入设备注册和操作接口。通知事件层对输入事件进行处理。事件层:和用户空间进行交互。驱动触发消息,内核收集后产生对应的回调任务,事件层就可以执行内核发布的回调任务。为什么不直接内核执行任务?你当内核傻啊,内核主要就是调度任务,这个更重要。任务下发后就可以被更重要的任务阻塞。

2023-09-01 01:51:47 177 1

原创 如何在内核中获取当前进程状态

每个进程都有维护了一个 task_struct 结构体,这个结构体有运行进程所需要的一切。内核那么多好东西,完全是超出人脑记忆极限的。需要的时候再去找一下才是最正确的做法。一般需要的数据也不多,状态和ID才是经常用到的。

2023-08-30 16:11:05 222 1

原创 热插拔理论与实例分析

热插拔:带电的情况下装卸设备。热插拔是内核与用户空间之间,通过调用用户空间程序来实现的。当内核发生了某种热插拔事件时,内核就会调用用户空间的程序实现交互。产生机制主要有 udev、mdev,mdev 是 udev 的简化版本。udev 通过 netlink 监听内核发送的 uevent 执行相应的回调。mdev 基于 uevent_helper 机制,内核产生的 uevent_helper 所指的用户程序 mdev 来执行热插拔操作。

2023-08-29 00:44:07 107 2

原创 设备模型理论与实例分析

Linux 系统内部开启了一个监视进程,负责接收和归类注册的设备和模块,然后给新设备匹配驱动,匹配了就能用,道理就这么简单。

2023-08-29 00:11:51 64 1

原创 根文件系统构建后的第三方软件移植

SSH 全称为 Secure Shell(安全外壳协议,简称 SSH),是一种加密的网络传输协议,用于在不安全的网络中为网络服务提供安全的传输环境。ssh:ssh 软件用于替换 rlogin 与 Telnetscp 和 sftp:将文件复制到其他主机上,用于替换 rcpsshd:SSH 服务器。

2023-08-23 18:17:48 232

原创 Linux三大根文件系统移植

buildroot、yocto、ubuntu base

2023-08-23 17:29:18 452

原创 中断子系统理论与实例分析

使用自定义工作队列需要构建一个 workqueue_struct 结构体name:工作队列名create_workqueue() 可以给每个 CPU 都创建一个工作队列,创建成功返回 workqueue_struct 结构体指针,失败返回 NULL。create_singlethread_workqueue() 只给一个 CPU 创建工作队列。调度和取消调度工作队列queue_work_on() 用来调度自定义工作队列;

2023-08-04 21:45:04 69 1

原创 驱动中的高级IO处理

在驱动的 read() 中,先判断 file->f_flags 是否带有 O_NONBLOCK,即是否为非阻塞 IO,如果是,则继续判断数据就绪条件 condition 的值,数据没有就绪就直接退出 read(),并返回 -EAGAIN。timeout:为超时时间,单位为 ms,timeout 大于 0,poll 等待时间直到指定的时间,timeout 为 0,poll 立即返回,timeout 为 -1,一直等待,直到时间发生。当数据就绪后,内核才会将数据拷贝到用户空间,最后返回用户线程,开始处理数据。

2023-08-02 14:56:46 59

原创 并发竞争理论与实例分析

这么做之后,当一个线程打开该设备,如果未关闭该设备,另一个线程也打开该设备时就会陷入阻塞,直到第一个线程关闭了该设备,第二个线程才能打开设备。相应的,多线程中打开同一个设备,慢打开的时候会被阻塞,等到先打开的设备的线程执行完临界操作后关闭设备时,慢打开设备的线程才能唤醒打开设备。就是说,如果某线程需要获取锁,但该锁已经被其他线程占用时,该线程不会被挂起,而是在。相应的解决办法是,在自旋锁的使用过程中要尽可能短的时间内拥有自旋锁,而且。信号量是操作系统中最典型的用于同步和互斥的手段,本质上是一个全局变量。

2023-08-02 14:19:57 55

原创 关于VMware Ubuntu明明有大量硬盘空间却提示硬盘空间不足的问题

实际上就和window上磁盘管理工具一样,扩展的空间是未分配的,未分配的当然无法使用。起因:我编译RK3568的SDK时,编译停止了,提示硬盘空间不足。可以看到主存最大也就50G左右啊,那么大的分配空间都去哪里了?然后就查了一下ubuntu的硬件情况,这才发现了问题。15G全用上,选择创建为:扩展分区。空间应该是足够的啊,为什么会提示硬盘空间不足?将文件系统类型选择为:linux-swap。可以看到未分配的空间居然有250G。最后点击操作栏的 √ 就完成分配了。剩下15G作为 swap 分区。

2023-08-01 15:00:19 2153 4

原创 所以真的了解GPIO了吗?

以点亮LED为例。GPIO0_A2 管脚输出高电平时,VCC和地极导通,LED1点亮。

2023-07-23 12:13:33 303 1

原创 pthread_cond_t 究竟有什么花样?

pthread_cond_wait 函数一旦调用,则线程立即被阻塞,同时所拥有的互斥锁也被释放,线程一直停止在pthread_cond_wait 函数中,直到 pthread_cond_singal 函数通知对应的条件变量时接触阻塞,pthread_cond_wait 运行结束,但是返回的时会申请之前释放的互斥锁。pthread_cond_wait返回时,互斥量再次被锁住。wait 的写法多种多样,但是最常见的还是在 while 中,在 while 被唤醒的线程会因为不满足条件而再次被阻塞!

2023-07-10 17:50:31 116 1

原创 字符驱动程序设计的思路

ioctl() 传送的变量 cmd 是应用程序用于区别向设备驱动程序请求处理的内容的值,cmd 除了可区别的数字外,还包含有助于处理的几种相应的信息。首先,Linux 系统的应用层活动于用户态,用户态无法直接访问硬件。想要在应用层访问硬件就需要切换到内核态,内核态访问硬件后又切换回用户态继续工作。可能会有学完STM32的杆精说中断,应用程序哪来的途径直接使用中断,中断都是在驱动中配好的,轮不到应用层调用。触发内核态的方式有很多,系统调用是驱动中用得最广泛的一种。

2023-07-10 15:19:34 83 1

原创 设备树基础语法与实例分析

* 自定义一个管脚标号的属性 pinnum */ pinnum = < 0 1 2 3 4 >;驱动可以拿到设备树中的任意节点的任意数据,至于有没有用,用来做什么,都是驱动开发的事情了,所以开放自定义属性合理。中断控制器中,必须有一个属性 #interrupt-cells 表示其他节点使用这个中断控制器需要几个 cell 来表示使用哪一个中断。中断控制器中,必须有一个属性 interrupt-controller 表示它是中断控制器。

2023-07-10 14:31:19 562 1

原创 pthread_mutex_t 究竟有什么花样?

自己动手画了个图,一张图胜过1000行注释。

2023-07-04 20:17:14 102

原创 Linux内核双链表的用法

任何地址存放的数据是可以转换成任意类型的(存放什么类型的数据,就需要用什么类型的指针去读取),但是读写就另说了。得到的地址减去它在结构体中的偏移量,就得到了它所属的结构体的首地址。随后,取转换后的数据类型中指定的成员 MEMBER 的地址,好巧不巧,从 0 地址出发到 MEMBER 的步进长度就是 MEMBER 在结构体中的偏移量。那要看 const 在谁前面呀,在类型前面,类型不能变,在指针前面,指向的地址不能变,这里明显是在类型前面)删除结点:抓住某个结点,获取它的前后结点,再让其前后结点互相指向。

2023-06-22 11:40:54 97 1

原创 如何优雅地传递指针?

实例1的第一段代码之所以很多人没有看出问题,是因为把字符串当做了普通的字符变量,而忽略了它的一个本质,传递时是字符串的地址。change函数根本不起作用,很多新人会以为 p = “bbb” 是给字符指针变量赋值,实际上是给 p 的地址赋值,赋予了字符串 “bbb” 的地址。我的理解是对待指针参数是使用一个新的临时指针去指向参数,对待非指针变量只是新建一个值相同的变量来供内部使用。实例:写一个函数让输入指针指向一个另一个地址并对指向的内容进行处理。实例2:修改数字指针指向的内容。实例1:修改字符串内容。

2023-06-07 17:42:36 76 1

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除