linux驱动
文章平均质量分 74
温人之周.
这个作者很懒,什么都没留下…
展开
-
Linux应用程序、shell脚本程序、驱动程序参数传递的方法
我们可以在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$n。n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推……/bin/bashecho "Shell 传递参数!echo "文件名:$0";echo "第一个参数为:$1";echo "第二个参数为:$2";echo "第三个参数为:$3";原创 2023-08-29 20:56:15 · 7937 阅读 · 0 评论 -
linux操作gpio的一些记录
设备都是以节点的形式“挂”到设备树上的,因此要想获取这个设备的其他属性信息,必须先获取到这个设备的节点。此函数获取 GPIO 编号,因为 Linux 内核中关于 GPIO 的 API 函数都要使用 GPIO 编号,此函数会将设备树中类似<&gpio5 7 GPIO_ACTIVE_LOW>的属性信息转换为对应的 GPIO 编号,此函数在驱动中使用很频繁!gpio:要申请的 gpio 标号,使用 of_get_named_gpio 函数从设备树获取指定 GPIO 属性信息,此函数会返回这个 GPIO 的标号。原创 2023-07-26 20:42:31 · 8031 阅读 · 0 评论 -
基于ubuntu的驱动开发
一般的linux驱动开发都是基于交叉编译来进行的,本文尝试着从另一个角度:基于ubuntu的本地驱动开发来学习一下驱动的开发。原创 2023-07-05 18:04:23 · 12170 阅读 · 1 评论 -
linux应用层操控硬件的方式
应用层想要对底层硬件进行操控,通常可以通过两种方式:(1)、/dev/目录下的设备文件(设备节点);(2)、 /sys/目录下设备的属性文件。具体使用哪种方式需要根据不同功能类型设备进行选择,有些设备只能通过设备节点进行操控,而有些设备只能通过 sysfs 方式进行操控;原创 2022-09-16 13:19:26 · 11780 阅读 · 0 评论 -
linux异步IO通知
Linux 应用程序可以通过阻塞或者非阻塞这两种方式来访问驱动设备,通过阻塞方式访问的话应用程序会处于休眠态,等待驱动设备可以使用,非阻塞方式的话会通过 poll 函数来不断的轮询,查看驱动设备文件是否可以使用。这两种方式都需要应用程序主动的去查询设备的使用情况。“信号”却可以使内核主动通知应用程序,信号类似于我们硬件上使用的“中断”,只不过信号是软件层次上的。原创 2022-09-15 11:09:24 · 11769 阅读 · 0 评论 -
linux阻塞IO与非阻塞IO在应用层和驱动层的实现(一)
linux的 IO 指的是 Input/Output,也就是输入/输出,是应用程序对驱动设备的输入/输出操作。当应用程序对设备驱动进行操作的时候,如果不能获取到设备资源,那么阻塞式 IO 就会将应用程序对应的线程挂起,直到设备资源可以获取为止。阻塞其实就是进入了休眠状态,交出了 CPU 控制权。对于非阻塞 IO,应用程序对应的线程不会挂起,它要么一直轮询等待,直到设备资源可以使用,要么就直接放弃。原创 2022-09-11 15:27:32 · 12111 阅读 · 0 评论 -
Linux 自带按键驱动
Linux 内核自带了 KEY 驱动,使用时只需要按照如下路径配置 一下Linux 内核,选中“GPIO Buttons”选项即可。-> Device Drivers-> Input device support-> Generic input layer (needed for keyboard, mouse, ...) (INPUT [=y])-> Keyboards (INPUT_KEYBOARD [=y])->GPIO Buttons Linux 内原创 2022-05-18 19:04:35 · 12661 阅读 · 0 评论 -
Linux 按键输入驱动
按键驱动是操作 GPIO,在驱动程序中使用一个整形变量来表示按键值,应用程序通过 read 函数来读取按键值,判断按键有没有按下。因为保存按键值的变量是个共享资源,驱动程序要向其写入按键值,应用程序要读取按键值。所以要对其进行保护,对于整形变量而言首选的是原子操作,使用原子操作对变量进行赋值以及读取。 读取按键一般采用中断的方式,并且采用定时器来实现按键消抖。此外在编写驱动的时候一定要考虑到阻塞和非阻塞的情况。对于按键输入驱动程序,最好的方式就是驱动程序能主动向应用程序发出通知,报告自己可以访问,原创 2022-05-18 10:54:42 · 13712 阅读 · 0 评论 -
以动态库的形式编写linux驱动
在具体的工程实践中,可能因为种种的原因无法重新编译linux内核,此时嵌入式工程师可以通过linux的API编写驱动代码,并将驱动以动态库的形式呈现给上层开发人员。本文提供一个工程实例的框架,来实现linux动态库的编译和装载。一、创建工程文件夹目录 首先创建lib文件夹存放整个工程的文件,然后在lib文件夹下创建project文件夹存放工程的源文件,再创建obj文件夹存放工程的编译文件。二、创建编译文件 1、首先在lib文件夹下创建如下三个文件: ①、build文件,控制编译和装载的s原创 2021-09-25 13:30:32 · 18844 阅读 · 1 评论 -
将驱动程序编译进linux内核
在linux驱动开发时,一般的做法是将驱动程序编译成.ko文件,然后使用“modprobe”命令将驱动模块加载到内核中。但在驱动开发完成后,就需要将驱动程序编译进Linux内核里面。一、直接将驱动写死进linux内核 1、以led字符设备驱动为例,首先在linux内核源码的/drivers/char/文件夹下创建一个mytest_led文件夹,将驱动文件存放在此文件夹下。 2、修改/drivers/char/文件夹下的Makefile文件,添加一句:obj-y += mytest_le原创 2021-09-25 12:45:08 · 20825 阅读 · 0 评论 -
树莓派linux led字符设备驱动( linux自带)
树莓派的Linux 内核已经集成了LED 灯驱动。 Linux 内核的 LED 灯驱动采用 platform 框架。编译树莓派linux内核时,会输入配置命令构建配置linux内核,如:cd linuxKERNEL=kernel7lmake bcm2711_defconfig linux内核的makefile会从arch/arm/configs 目录中寻找默认配置文件: bcm2711_defconfig,配置完成后会生成.config 文件。打开.config 文件,有“CONFIG_L原创 2021-09-24 20:43:57 · 19244 阅读 · 0 评论 -
树莓派linux led字符设备驱动( platform)
Linux 系统要考虑到驱动的可重用性,因此提出了驱动的分离与分层这样的软件思路,在这个思路下诞生了platform 设备驱动,也叫做平台设备驱动。platform引入了总线(bus)、驱动(driver)和设备(device)模型。1.1、platform 总线Linux系统内核使用bus_type结构体表示总线,此结构体定义在文件include/linux/device.h中。platform 总线是 bus_type 的一个具体实例,定义在文件 drivers/base/platform.c中s原创 2021-09-23 19:01:18 · 19039 阅读 · 0 评论 -
树莓派linux led字符设备驱动(互斥)
一、互斥体 互斥访问表示一次只有一个线程可以访问共享资源,不能递归申请互斥体。Linux 内核使用 mutex 结构体表示互斥体。使用 mutex 之前要先定义一个 mutex 变量。在使用 mutex 的时候要注意如下几点: ①、 mutex 可以导致休眠,因此不能在中断中使用 mutex,中断中只能使用自旋锁。 ②、和信号量一样, mutex 保护的临界区可以调用引起阻塞的 API 函数。 ③、因为一次只有一个线程可以持有 mutex,因此,必须由 mutex 的持有者释放 mutex。原创 2021-09-23 14:47:01 · 18344 阅读 · 0 评论 -
树莓派linux led字符设备驱动(信号量)
一、信号量 Linux 内核提供了信号量机制,信号量常常用于控制对共享资源的访问。相比于自旋锁,信号量可以使线程进入休眠状态,使用信号量会提高处理器的使用效率。但是,信号量的开销要比自旋锁大,因为信号量使线程进入休眠状态以后会切换线程,切换线程就会有开销。总结一下信号量的特点: ①、因为信号量可以使等待资源线程进入休眠状态,因此适用于那些占用资源比较久的场合。 ②、因此信号量不能用于中断中,因为信号量会引起休眠,中断不能休眠。 ③、如果共享资源的持有时间比较短,那就不适合使用信号量了,因为频原创 2021-09-22 20:26:35 · 18493 阅读 · 0 评论 -
树莓派linux led字符设备驱动(自旋锁)
一、自旋锁 当一个线程要访问某个共享资源的时候首先要先获取相应的锁, 锁只能被一个线程持有,只要此线程不释放持有的锁,那么其他的线程就不能获取此锁。对于自旋锁而言,如果自旋锁正在被线程 A 持有,线程 B 想要获取自旋锁,那么线程 B 就会处于忙循环-旋转-等待状态,线程 B 不会进入休眠状态或者说去做其他的处理。 自旋锁的“自旋”也就是“原地打转”的意思,“原地打转”的目的是为了等待自旋锁可以用,可以访问共享资源。把自旋锁比作一个变量 a,变量 a=1 的时候表示共享资源可用,当 a=0的时候表示原创 2021-09-22 20:07:57 · 18412 阅读 · 0 评论 -
树莓派linux led字符设备驱动(原子操作)
一、原子操作 linux驱动中为了处理对共享资源的并发访问,引入了原子操作。原子操作就是指不能再进一步分割的操作,一般原子操作用于变量或者位操作。 Linux 内核提供了两组原子操作 API 函数,一组是对整形变量进行操作的,一组是对位进行操作的。1.1、原子整形操作 API 函数 Linux 内核定义了叫做 atomic_t 的结构体来完成整形数据的原子操作,在使用中用原子变量来代替整形变量,此结构体定义在 include/linux/types.h 文件中。常用的API有: ATOMIC_原创 2021-09-22 19:50:31 · 18552 阅读 · 0 评论 -
树莓派linux led字符设备驱动(pinctrl 和 gpio 子系统)
一、pinctrl 子系统Linux 内核针对 PIN 的配置推出了 pinctrl 子系统,对于 GPIO的配置推出了 gpio 子系统。pinctrl 子系统就是为了解决配置寄存器比较繁琐且易出错而引入的。要使用 pinctrl 子系统,我们需要在设备树里面设置 PIN 的配置信息。1.1、设备树中添加 pinctrl 节点模板...原创 2021-09-18 15:14:44 · 18804 阅读 · 0 评论 -
树莓派linux led字符设备驱动(设备树)
在嵌入式 Linux驱动开发 中, ARM 相关的驱动全部采用了设备树。所以大量的驱动程序使用设备树开发。原创 2021-09-17 20:25:43 · 19105 阅读 · 0 评论 -
树莓派linux led字符设备驱动(新字符设备)
字符设备驱动开发时使用 register_chrdev 函数注册字符设备,使用unregister_chrdev 函数注销字符设备,驱动模块加载成功以后还需要手动使用 mknod 命令创建设备节点。原创 2021-09-16 20:32:07 · 18620 阅读 · 0 评论 -
树莓派linux led字符设备驱动(传统)
Linux 下的任何外设驱动,最终都是要配置相应的硬件寄存器。所以 LED 灯驱动最终也是对树莓派的 IO 口进行配置,但是在 Linux 下编写驱动要符合 Linux的驱动框架。一、树莓派GPIO原创 2021-09-13 20:27:55 · 18749 阅读 · 0 评论 -
树莓派linux led字符设备驱动(搭建开发环境)
一、在本地搭建环境1.1、获取树莓派Linux内核版本 输入指令:uname -r 结果为:pi@raspberrypi:~ $ uname -r5.10.17-v7l+ 可知Raspber Pi系统的Linux 内核为 5.10.17-v7l+ 版本,所以下载版本为5.10.y。树莓派linux源码在GitHub上,链接地址为:https://github.com/raspberrypi 也可以通过git clone --depth=1 --branch rpi-5.10.y ht原创 2021-09-08 20:40:41 · 18632 阅读 · 1 评论 -
linux内核链接脚本
linux kernel不直接提供链接脚本, 而是提供了一个汇编文件vmlinux.lds.S,经过编译之后会生成vmlinux.lds链接脚本文件。vmlinux.lds.S文件在arch/arm/kernel/文件目录中。linux内核不提供.lds的脚本文件, 却提供一个汇编文件的原因是因为内核编译需要条件编译, 而脚本文件是写死的, 不能条件编译。因此要先写一个有条件编译的汇编文件, 然后再使用这个汇编文件进行条件编译得到.lds链接脚本文件。通过分析 Linux 内核的连接脚本文件 arch/原创 2021-09-07 11:58:33 · 18922 阅读 · 0 评论 -
Linux内核工程目录分析
1、arch 目录这个目录是和架构有关的目录,比如 arm、arm64、avr32、x86 等等架构。每种架构都对应一个目录,在这些目录中又有很多子目录,比如 boot、common、configs 等等。以 arch/arm 为例其子目录用于控制系统引导、系统调用、动态调频、主频设置等。arch/arm/configs 目录是不同平台的默认配置文件:xxx_defconfig。arch/arm/boot/dts 目录里面是对应开发平台的设备树文件。arch/arm/boot 目录下会保存编译出来的原创 2021-09-07 08:20:06 · 19350 阅读 · 0 评论 -
编译树莓派Linux内核
Raspberry Pi 内核Linux代码存储在 GitHub 中,可以在github.com/raspberrypi/linux上查看。一、下载linux内核源码git clone --depth=1 https://github.com/raspberrypi/linux 上面的命令将下载当前的活动分支。省略–depth=1将下载整个存储库,包括所有分支的完整历史记录,但占用更多的存储空间。要下载不同的分支,可以使用以下–branch选项:git clone --depth=1 --b原创 2021-09-03 18:18:53 · 19397 阅读 · 2 评论 -
设备树在linux系统中的体现
Linux 内核启动的时候会解析设备树中各个节点的信息,并且在根文件系统的**/proc/devicetree** 目录下根据节点名字创建不同文件夹,如图 所示: /proc/device-tree 目录下是根节点“/”的所有属性和子节点。1、根节点“/”各个属性 在图中,根节点属性表现为一个个的文件,如图 “#address-cells”、“#size-cells”、“compatible”、“model”和“name”这 5 个文件,它们在设备树中就是根节点的 5个属性。可以输入cat原创 2021-09-02 20:33:36 · 19086 阅读 · 0 评论 -
设备树节点追加内容
设备树是描述PCB硬件信息的文件,如果PCB增加一个六轴芯片fxls8471, fxls8471 要接到PCB的 I2C1 接口上,那么相当于需要在 i2c1 这个节点上添加一个 fxls8471 子节点。对于I2C1 接口对应的节点,在文件 imx6ull.dtsi 文件,有如下所示内容:i2c1: i2c@021a0000 { #address-cells = <1>; #size-cells = <0>; compatible = "fsl,imx6ul-i2c"原创 2021-09-02 20:20:32 · 19593 阅读 · 3 评论 -
设备树简介
描述设备树的文件叫做 DTS(DeviceTree Source),这个 DTS 文件采用树形结构描述板级设备,也就是电路板上的设备信息。比如CPU 数量、 内存基地址、 IIC 接口上接了哪些设备、 SPI 接口上接了哪些设备等等。 设备树(Flattened Device Tree),将描述板级硬件信息的内容从 Linux 内中分离开来,用一个专属的文件格式来描述,这个专属的文件就叫做设备树,文件扩展名为.dts。 一个 SOC 可以作出很多不同的板子,这些不同的板子共同的信息可以提取出来作为一原创 2021-08-31 16:01:45 · 19844 阅读 · 0 评论 -
linux内核的设备匹配方法
一、设备匹配方法1.1、未使用设备树的设备匹配方法在没有使用设备树以前, uboot 会向 Linux 内核传递一个叫做 machine id 的值, machine id也就是设备 ID,告诉 Linux 内核自己是个什么设备,看看 Linux 内核是否支持。 Linux 内核是支持很多设备的,针对每一个设备(板子), Linux内核都用MACHINE_START和MACHINE_END来定义一个 machine_desc 结构体来描述这个设备,比如在文件 arch/arm/mach-imx/mach原创 2021-09-02 10:54:29 · 19591 阅读 · 0 评论 -
根文件系统简介
根文件系统一般也叫做 rootfs,根文件系统首先是内核启动时所 mount(挂载)的第一个文件系统,内核代码映像文件保存在根文件系统中,而系统引导启动程序会在根文件系统挂载之后从中把一些基本的初始化脚本和服务等加载到内存中去运行。根文件系统是 Linux 内核启动以后挂载(mount)的第一个文件系统,然后从根文件系统中读取初始化脚本,比如 rcS, inittab 等。根文件系统和 Linux 内核是分开的,单独的 Linux 内核是没法正常工作的,必须要搭配根文件系统。如果不提供根文件系统, Li原创 2021-08-27 19:54:56 · 20339 阅读 · 0 评论 -
linux驱动框架结构体总结1
Linux字符设备驱动是Linux驱动开发的基础,而 Linux字符设备驱动得开发要遵循一定得模式和规则。对于 Linux 这样一个成熟、庞大、复杂的操作系统,代码的重用性非常重要,所以一般都会采用驱动分隔的方式来简化驱动的开发。其中每个不同的框架关键是实现几个关键的结构体。一 字符设备基础 struct file_operations { struct module *owner; loff_t (*llseek) (struct file *, loff_t, int); ssize原创 2021-08-23 15:08:46 · 18941 阅读 · 3 评论