通过上一节Linux设备驱动字符设备(一)了解了Linux设备驱动的分类,设备号的构成,设备号的申请以及设备号的释放。
在上一篇文章中Linux驱动实践:你知道【字符设备驱动程序】的两种写法吗?我们说过:字符设备的驱动程序,有两套不同的API函数,并且在文中详细演示了利用旧的API函数来编写驱动程序。
① 实例化platform_driver结构体probe成员 ② 实例化platform_driver结构体remove成员 ③ 选择一种方式匹配(设备树,ACPI,名字,ID四选一)
本文介绍了如何利用驱动开发技术实现一个字符设备,并利用操作结构体来处理不同的功能。通过调用驱动程序API,可以在用户空间程序中实现对字符设备的打开、关闭、读写等操作。同时,文章还介绍了一种简化注册过程的方法,利用宏定义可以快速实现设备节点的创建和注册。
上篇文章(【i.MX6ULL】驱动开发1——字符设备开发模板)介绍了字符设备的开发模板,但那是一种旧版本的驱动开发模式,设备驱动需要手动分配设备号再使用 register_chrdev进行注册,加载成功以后还需要手动使用mknod命令创建设备节点,比较麻烦。
在Linux设备驱动之字符设备(一)中学习了设备号的构成,设备号的申请与释放。在Linux设备驱动之字符设备(二)中学习了如何创建一个字符设备,初始化,已经注册到系统中和最后释放该字符设备。
__init__宏:被修饰的函数会被链接器链接放入.init.text段中(本来默认情况下函数是被放入.text段中)。对内核而言是一种暗示,表示该函数仅在初始化期间使用,内核启动时统一会加载.init.text段中的这些模块安装函数,加载完后就会把这个段给释放掉以节省内存。 __exit__宏:被修饰的函数仅用于模块卸载,链接器会将其放入特殊的ELF段。如果模块被直接内嵌到内核中,或内核的配置不允许卸载模块,则被修饰的函数将被简单的丢弃。 prink函数:模块在被加载到内核后,它能调用的函数仅仅是由内核导出的那些函数。KERN_INFO是printk的打印级别,其实只是一个字符串(如<1>)。操作系统的命令行中也会有一个打印级别的设置(值为0-7),当前操作系统中执行printk的时候会去对比printk中的打印级别和操作系统命令行中设置的打印级别,小于命令行设置级别的信息会被打印出来,大于的会被拦截。 module_init宏:该宏声明的函数会在模块被装载到内核中调用。 module_exit宏:该宏声明的函数会在模块被卸载时调用。 MODULE_LICENSE宏:指定该代码所使用的许可证协议。 MODULE_AUTHOR:描述模块作者。
在linux中,每一个设备都有一个对应的主设备号和次设备号,linux在内核中使用dev_t持有设备编号,传统上dev_t为32位,12位为主设备号,20位为次设备号,主编号用来标识设备使用的驱动,也可以说是设备类型,次编号用来标识具体是那个设备,使用动态分配函数alloc_chrdev_region可以让内核自动为我们分配一个主设备号,同时在设备停止使用后,应当释放这些设备编号,释放设备编号的工作应该在卸载模块时完成,释放设备编号可以使用unregister_chrdev_region函数,分配和释放的部分如下:
/************************************************************************************
使用命令建立一个设备 s 驱动代码 #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/fs.h> #include <linux/device.h> #include <linux/cdev.h> #include <linux/major.h> static ssize_t flash_env_dev_open(struct inode *i
在linux设备驱动第一篇:设备驱动程序简介中简单介绍了字符驱动,本篇简单介绍如何写一个简单的字符设备驱动。本篇借鉴LDD中的源码,实现一个与硬件设备无关的字符设备驱动,仅仅操作从内核中分配的一些内存。 下面就开始学习如何写一个简单的字符设备驱动。首先我们来分解一下字符设备驱动都有那些结构或者方法组成,也就是说实现一个可以使用的字符设备驱动我们必须做些什么工作。 1、主设备号和次设备号 对于字符设备的访问是通过文件系统中的设备名称进行的。他们通常位于/dev目录下。如下: xxx@ubuntu:~$ ls
此类驱动适合于大多数简单的硬件设备。比如并口打印机,我们通过在/dev下建立一个设备文件(如/dev/printer)来访问它。
使用字符设备里的write 驱动代码 #include <linux/module.h> #include <linux/slab.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/fs.h> #include <linux/device.h> #include <linux/cdev.h> #include <linux/major.h> #include <asm/uaccess.h> static ssi
linux系统操作: 1.通过make 编译出gpioled.ko文件 2.通过 /home/tina-d1-h/prebuilt/gcc/linux-x86/riscv/toolchain-thead-glibc/riscv64-glibc-gcc- thead_20200702/bin/riscv64-unknown-linux-gnu-gcc -o ledapp ledApp.c 编译出ledgpio 软件 MQpro: 1.通过insmod gpioled.ko加载gpioled驱动,通过ls /dev 查看是否有gpioled 2.通过 chmod 777 ledapp 添加权限 3.通过 ./ledapp /dev/gpioled 0 点亮LED 4.通过 ./ledapp /dev/gpioled 1 熄灭LED 注:以上命令没有跟LED高低电平相对应可以通过修改 gpioled.c led_write函数进行修改就好了
https://devarea.com/understanding-linux-kernel-preemption/#.XrKLcfnx05k
字符设备驱动中的 read接口的使用,简单实例 驱动部分代码
上一篇文章学习了字符设备的注册,操作过的小伙伴都知道上一篇文章中测试驱动时是通过手动创建设备节点的,现在开始学习怎么自动挂载设备节点和设备树信息的获取,这篇文章中的源码将会是我以后编写字符驱动的模板。
要理解这些接口,记住一句话:APP通过I2C Controller与I2C Device传输数据。
上次跟大家分享了设备模型的一些东西,包括总线、设备、驱动等的一些概念,还有他们之间的联系。今天要分享的是platform总线驱动,platform总线是总线的一种,这是相对于物理总线来说的,这是一种虚拟的总线。
查看 V3S 原理图,查看 RGB LED对应的引脚 PG0 -> green LED PG1 -> blue LED PG2 -> red LED
本章的目的是编写一个完整的字符设备驱动,我们开发一个字符驱动是因为这一类适合大部分简单硬件设备,字符驱动也比块驱动易于理解。
也就是说,在应用程序中,可以通过open,write,read等函数来操作底层的驱动。
"原子操作(atomic operation)是不需要synchronized",这是多线程编程的老生常谈了。所谓原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会有任何 context switch (切换到另一个线程)。
在LED子系统中,硬件驱动层相关文件在包括:kernel/drivers/leds/ 目录下,其主要的函数有:led-gpio.c、led-xxx.c,其中led-gpio.c为通用的平台驱动程序,led-xxx.c为不同厂家提供的平台驱动程序。
最近在搞IoT的时候,因为没有设备,模拟跑固件经常会缺/dev/xxx,所以我就开始想,我能不能自己写一个驱动,让固件能跑起来?因此,又给自己挖了一个很大坑,不管最后能不能达到我的初衷,能学到怎么开发Linux驱动,也算是有很大的收获了。
上篇文章(【i.MX6ULL】驱动开发3——GPIO寄存器配置原理),介绍了i.MX6ULL芯片的GPIO的工作原理与寄存器配置。
“我叮咛你的 你说 不会遗忘 你告诉我的 我也全部珍藏 对于我们来说 记忆是飘不落的日子 永远不会发黄 相聚的时候 总是很短 期待的时候 总是很长 岁月的溪水边 捡拾起多少闪亮的诗行 如果你要想念我 就望一望天上那 闪烁的繁星 有我寻觅你的 目光” 谢谢你,曾经来过~ 中断与定时器是我们再熟悉不过的问题了,我们在进行裸机开发学习的 时候,这几乎就是重难点,也是每个程序必要的模块信息,那么在Linux中,我们又怎么实现延时、计数,和中断呢? 一、中断 1.概述 所谓中断是指cpu在执行程序的过程中,出现了某些
因为近期用到了Linux内核的相关知识,下面随笔将给出内核模块的编写记录,供大家参考。
硬件定时器产生的周期性中断,中断频率就是系统频率(拍率)。系统拍率可以设置,单位是HZ,可在编译内核时通过图形化界面设置,设置路径如下:Kernel Features -> Timer frequency([=y])
工作队列常见的使用形式是配合中断使用,在中断的服务函数里无法调用会导致休眠的相关函数代码,有了工作队列机制以后,可以将需要执行的逻辑代码放在工作队列里执行,只需要在中断服务函数里触发即可,工作队列是允许被重新调度、睡眠。
很早之前就有网友建议写一篇关于Linux驱动的文章。之所以拖到现在才写,原因之一是我之前没有在工作中遇到需要自己手动去写驱动的需求,主要是现在Linux内核驱动的支持已经比较完善了,另外一个原因是自己水平实在有限,不敢写驱动这个话题,Linux驱动里涉及到的东西太多了,很多年前专门买过驱动相关的书籍,厚厚的,看的云里雾里。借此机会,在这里给大家做个非常非常入门级的介绍,希望对大家有所帮助。
嵌入式系统一般要求低功耗,出于这个原因,一般只把需要使用到的外设时钟源打开,其他不需要使用到的模块,则默认关闭它们。
ARM和FPGA的交互是这个芯片最重要的部分,PL和PS的交互使用中断是较为快捷的方法,本文使用bram存储数据并通过外部pl端发出中断通知ps端读写数据。程序思路是按键产生中断,按键是直接连到pl端的,驱动产生异步通知,应用开始往BRAM写数据,然后再读取数据(阻塞读取),均打印出来比较
大家好,我是道哥,今天我为大伙儿解说的技术知识点是:【中断程序如何发送信号给应用层】。
如何点亮一个LED灯,等同于驱动一个LED灯,再复杂一些可以控制LED灯亮灭,更复杂的是远程控制LED灯。
众所周知,Linux内核主要包括三种驱动模型,字符设备驱动,块设备驱动以及网络设备驱动。
在前几篇文章中,我们一块讨论了:在 Linux 系统中,编写字符设备驱动程序的基本框架,主要是从代码流程和 API 函数这两方面触发。
Linux应用层想要操作kernel层的API,比方想操作相关GPIO或寄存器,能够通过写一个字符设备驱动来实现。
这些函数的名字基本都可以自解释。 再介绍下misc 设备,linux 内核将一些不符合预先确定的字符设备划分为杂项设备,使用的数据结构如下;
在linux系统中许多外围设备都被规定为字符设备,诸如按键、触摸屏、重力传感器、LED、光敏传感器等,这些设备都需要字符设备驱动才能正常工作。本章就来实现一个标准的字符设备驱动框架模板,目的是为以后的设备驱动提供标准模板,提高开发效率与代码整洁度。
内核中驱动维护者针对每种驱动设计一套【成熟的、标准的、典型的】驱动实现,并把不同厂家的同类硬件驱动中相同的部分抽出来实现好,再把不同部分留出接口给具体的驱动工程师来实现,这就叫驱动框架。
从图中可以看到按键断开时,由于接了上拉电阻,所以CPU检测到默认是高电平的,当按键被按下时,电路导通,所以KEY0引脚变成低电平,即低电平有效。
最近项目上需要用到 LED 子系统,在嵌入式 Linux 里面点个灯还是比较简单的,只要在某个灯对应的目录里,向相应文件写入特定值,就可以让 LED 亮/灭/闪烁。
在Linux中,可以对GPIO进行相关的控制,具体的做法就是利用字符设备驱动程序对相关的gpio进行控制。由于操作系统的限制,在Linux上又无法直接在应用程序的层面上对底层的硬件进行操作。本文主要通过一个点亮红外灯的实例,再次理解Linux下的应用程序与驱动程序的交互,同时加深驱动程序编写流程的理解。
大家好,我是道哥,今天我为大伙儿解说的技术知识点是:【驱动层中,如何发送信号给应用程序】。
本文介绍了如何通过Linux内核定时器实现LED灯的闪烁,从硬件的配置、驱动程序以及示例代码方面进行了详细的阐述。通过申请GPIO、配置GPIO、编写驱动程序以及添加设备到内核和加载设备,最终实现了LED灯的闪烁。
前言 Linux的IIC驱动想必大家都耳熟能详,网上也有很多相关的教程。 网上的教程总结,比如: 方法问题描述Linux 3.X.X版本之后,设备树+驱动此方法是比较符合linux驱动的写法的。当对于不熟悉设备树的小伙伴,写起来比较棘手使用 i2c-tools,并通过脚本或者应用程序编写设备驱动(简单粗暴)此方法是将设备驱动丢到用户态中,对于一些的设备除了I2C通信还有一些引脚也要控制的,此方法写起来将非常痛苦直接操作i2c总线驱动。(简单粗暴)此方法是将设备驱动丢到用户态中,对于一些的设备除了I2C通信还
原文出处:http://www.cnblogs.com/jacklu/p/4722563.html
领取专属 10元无门槛券
手把手带您无忧上云