Linux设备驱动总结(二)-----Linux让LED灯闪起来

树莓派通过libgpiod控制Led三色灯 为方便Linux用户能够在应用程序空间直接使用命令行来操作控制GPIO,Linux内核 GPIOlib 使用/sys伪文件系统导出了一个文件夹, 这样用户在命令行通过echo命令就可以直接操作这些GPIO口了。接下来我们以控制RGB三色灯的红灯为例,讲解 sysfs接口的 GPIO操作。从前面的分析我们知道,RGB三色灯的红灯连到了树莓派的物理引脚33#引脚上,该引脚为BCM编码的GPIO13。使用下面命令我们可以导出GPIO13的相应接口。成功执行上面命令后,我们可以看到路径下多了一个gpio13。 阅读详情


众所周知,LED灯闪烁实验,就相当于编程中的helloworld,是最简单入门,也是可以帮助广大爱好学习者建立自信的,看了设备驱动一个多月,终于我也让自己的led灯闪亮了。

要让led灯闪烁,就是要控制引脚输入高低电平,不断交替变化,然而Linux中,上面的文章提到,驱动和应用是分开的,驱动层对硬件直接操作,应用层通过调用驱动层接口,来实现逻辑功能。

我们先来看驱动程序:(驱动程序涉及太多知识,建议大家去看国嵌Linux的设备驱动的视频,讲的很详细,基础知识不赘述,只是简单总结一下)

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/cdev.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <mach/gpio.h>

//定义命令
#define LED_ON		_IOW('h',0x01,unsigned long)		//LED开的命令
#define LED_OFF		_IOW('h',0x02,unsigned long)		//LED关的命令


int major_no = 255;			//定义主设备号
struct cdev cdev;			//字符设备的数据结构
dev_t devno;					//设备号
int open_state = 0;			//1为打开,0为关闭

/*-----------------------------------------------------------------------------
  函数名:      led_open
  参数:        struct inode *inode,struct file *filp
  返回值:      int
  描述:        open对应的驱动函数
 *-----------------------------------------------------------------------------*/
int led_open(struct inode *inode,struct file *filp )
{
	if(open_state == 0)
	{
		open_state =  1;
		printk("Open file suc!\n");
		return 0;
	}
	else
	{
		printk("The file has opened!\n");
		return -1;
	}
}

/*-----------------------------------------------------------------------------
  函数名:      led_ioctl
  参数:        struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg
  返回值:      int
  描述:        ioctl对应的驱动函数
 *-----------------------------------------------------------------------------*/
int led_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg)
{
	switch(cmd)
	{
		case LED_ON: printk("ON!\n");
						at91_set_gpio_value(AT91_PIN_PC0, 1); 			//灯亮起来
						break;

		case LED_OFF:printk("OFF\n");
						at91_set_gpio_value(AT91_PIN_PC0, 0); 			//灯灭掉
						break;

		default :printk("Error command!\n");
	}
	return 0;
}

const struct file_operations led_fop =
{
	.owner = THIS_MODULE,
	.open  = led_open,
	.ioctl = led_ioctl,
};
/*-----------------------------------------------------------------------------
  函数名:      gpio_init
  参数:        void
  返回值:      int
  描述:        模块初始化函数,在安装模块时候执行
 *-----------------------------------------------------------------------------*/
static int __init gpio_init(void)  
{
	int ret;

	printk("------GPIO test init-----\n");
	printk("Register the char dev!\n");

	/**
	 * 静态创建前,可以查看/proc/devices 查看已经被使用的设备号
	 */
	devno = MKDEV(major_no,0);
	ret = register_chrdev_region(devno,1,"led");		//向内核注册设备号
	if(ret < 0)
	{
		printk("Register Error!\n");
		return ret;
	}

	/**
	 * 初始化字符设备
	 */
	cdev_init(&cdev,&led_fop);
	cdev.owner = THIS_MODULE;
	cdev.ops   = &led_fop;
	cdev_add(&cdev,devno,1);						//向内核注册添加字符设备

	at91_set_gpio_output(AT91_PIN_PC0,1);		//设置引脚为输出功能,且为高电平
	return 0;	
}

/*-----------------------------------------------------------------------------
  函数名:      gpio_exit
  参数:        void
  返回值:      void
  描述:        模块卸载函数,在卸载模块时候执行
 *-----------------------------------------------------------------------------*/
static void __exit gpio_exit(void)	
{
	unregister_chrdev_region(devno,1);
	open_state = 0;
	printk("GPIO test End\n");
}

module_init(gpio_init);
module_exit(gpio_exit);

MODULE_LICENSE("GPL");

这是笔者自己写的驱动程序,注释非常详细,这里也只是做几个简单说明:

1.笔者的LED灯连接的是AT91sam9260芯片的PC0引脚,高电平点亮,而at91_set_gpio_value类似的函数,就是Linux封装好的,可以清楚的看到,第一个参数是引脚编号,第二个参数是要输出的电平,其它的我们都不用管。不用再对寄存器初始化什么的了。前面提过,这些函数就分装在linux内核源代码下的arch/arm/mach_at91下,在arch/arm/下有很多的目录,里面都封装着对应芯片实现相同功能的函数,读者可以自己去看看。

2.一般设备初始化步骤,首先先申请一个设备号,然后想内核注册字符设备,主要就是关联file_operations这个结构,每次应用程序调用open,其实是通过VFS系统调用成我上面驱动的led_open(这个国嵌的视频讲的也很清楚,看完视频再来看这个驱动程序,一切都很明了)

3.应用程序通过ioctl发送命令给驱动,实际是调用了led_ioctl,这个函数就是解析各种命令,执行相应的动作,就是典型的命令-反应模型!

可能你会觉得很烦,但是不急,看看应用程序,你就会知道,这种分而治之的形式其实很好:

#include <stdio.h>
#include <sys/ioctl.h>
#include <signal.h>
#include <stdlib.h>
#include <time.h>

#define LED_ON		_IOW('h',0x01,unsigned long)		//LED开的命令
#define LED_OFF		_IOW('h',0x02,unsigned long)		//LED关的命令

int fd;

void close_file(int sig_no)
{
	if(SIGINT == sig_no)
	{
		close(fd);
		printf("Close the file suc!\n");
		exit(0);
	}
}
int main(void)
{

	fd = open("/dev/led",0);
	if(fd < 0)
	{
		perror("Open file Error:");
		return -1;
	}

	signal(SIGINT,close_file);
    while(1)
    {
	ioctl(fd,LED_ON);		//led on
	usleep(500000);		//delay 500 ms
	ioctl(fd,LED_OFF);		//led off
	usleep(500000);
    }
	return 0;
}
应用程序,真的就像操作文件一样操作设备了,先打开了设备文件,然后只要往驱动程序发送命令就行了,应用层开发者完全不用理会设备是怎么实现的,这样大大加快开发速度,驱动和应用可以并行。

 

运行结果如下:

首先要创建设备文件:mknod /dev/led c 255 0

c 代表是字符设备,255 是主设备号,0是次设备号

root@at91sam9260ek:/mnt/char_dev# insmod char_dev.ko
------GPIO test init-----
Register the char dev!
root@at91sam9260ek:/mnt/char_dev# mknod /dev/led c 255 0
root@at91sam9260ek:/mnt/char_dev# ./test
Open file suc!
ON!
OFF
ON!
OFF
ON!
OFF
ON!
OFF
ON!
OFF
ON!
OFF
ON!
OFF
ON!
OFF
ON!
OFF
ON!
OFF
ON!
OFF
ON!
OFF
ON!
OFF
ON!
OFF
ON!
OFF
Close the file suc!


 

PS:linux延迟真是简单!

linux设备驱动之我是led灯-基于OK6410开发板 原创作品转载请注明出处 http://blog.youkuaiyun.com/cediy2088long?viewmode=contents 学习嵌入式linux编程,我们接触到的大多是linux设备驱动程序的编程。今天我就给大家简单的分析一下飞凌的led驱动程序,有了我们前面led的裸机的程序的基础,这个led的驱动也就简单多了。 大家最好是看一下linux设备驱动程序一书的前六章,这 阅读详情

相关推荐

Linux设备驱动开发 - 三色LED呼吸灯分析

Linux设备驱动开发 - 三色LED呼吸灯分析

fulinux的博客 1058

Linux下LED设备驱动开发(LED灯实现闪烁)

前面我们介绍了Linux设备模型、平台设备驱动、设备树(device tree)、GPIO子系统以及pinctrl子系统等,大家看这篇文章之前需要提前知道的基础都在这篇文章中:Linux设备模型、平台设备驱动、设备树(device tree)、GPIO子系统以及pinctrl子系统介绍 有部分函数没有涉及到的最后会讲解。

m0_51429770的博客 3102

陀螺仪选型避坑指南:为什么IMU660RA是智能车竞赛的性价比之选?

本文针对智能车竞赛场景,提供陀螺仪选型避坑指南,并深度解析为何IMU660RA成为性价比之选。文章指出,竞赛选型应避免盲目追求高性能“黑盒”模块,而应注重原始数据获取与算法开发。IMU660RA以其良好的常温稳定性、适中的噪声水平、极致的性价比和丰富的生态支持,成为帮助参赛者深入理解姿态解算原理、进行“白盒开发”的理想教学与实践平台。

tech5的博客 883

基于Linux的串口控制LED灯,Linux驱动开发--通过按键控制led灯

/*说明:通过OK6410开发板自带的user key 的前四个控制led的开关,对应的,按key1,led1亮,亲自验证无误*/#include #include #include #include #include /*包含struct file_operations,MAJOR等*/#include /*kmalloc*/#include /*class_creat,device_creat...

weixin_29798025的博客 402

如何搭建一个vue项目(完整步骤)

查看版本的两种方式 出现版本号则说明安装成功(最新的以官网为准) 这里注意:安装vue-cli对node.js的版本是有要求的 装的两种方式:输入cmd命令 查看安装的版本(显示版本号说明安装成功) 如果你原来有版本或者版本比较低,可以升级...

m0_67392661的博客 5590

SimpleFOC STM32实战:基于F103与HAL库,剖析速度环与电流环的协同控制

本文详细介绍了基于STM32F103与HAL库的SimpleFOC实战应用,重点剖析速度闭环控制与电流环的协同工作原理。通过开发环境搭建、参数调试技巧及性能优化方案,帮助开发者高效实现无刷电机精准控制,适用于机器人、无人机等高精度应用场景。

weixin_29170327的博客 478

通过linux命令来控制板上GP_LED灯亮灭

通过linux命令来控制板上GP_LED灯亮灭 下图是在某网站找到的,这里我们可以看到GP_LED 是跟GPIO3相连。至于GPIO13,在此图上看,跟GP_LED没有啥关系,但为什么在blink草案中,却能控制GP_LED,这个留在下一帖。这里主要是通过对GPIO3的控制来实现GP_LED的亮灭。 下图是从开机到控制GP_LED亮灭的过程。 1、进入gpio的目录...

weixin_30508241的博客 551

ODBC 连接数据库 SQL server 2008

1、打开【控制面板】-> 【系统和安全】 -> 【管理工具】-> 【数据源(ODBC)】  2、双击【数据源(ODBC)】-> 选中【系统DSN】 3、单击【添加】,会弹出如下对话框,选中【SQL server】->【完成】 4、弹出如下对话框,在【名称】中填入数据源名称 例如:我命名为: LocalServer,在【服务器】中填入计算机名或者IP地址,我连接

Christine的专栏 8518

Linux内核自带的 LED 灯驱动实验:Led设备节点添加闪烁

Linux内核自带的 LED 灯驱动实验:Led设备节点添加闪烁

wojiaxiaohuang2014的博客 1172

如何实现电路级别的CDM ESD防护

采用先进制程的CMOS工艺,可能具有比以前更薄的栅极氧化物和更大的芯片尺寸,大的衬底可能积累大量的电荷,导致CDM事件期间的高ESD放电峰值电流。传统CDM保护器件使用栅极接地NMOS被添加到输入级的栅极。然而,这种方法通常会在信号路径上引入显著的寄生电容,这不适合RF应用。

weixin_42693135的博客 2504

10.2 在新能源、储能及电网节点的应用实践

构网型变流器技术在电力系统中的应用进展 构网型变流器技术正从理论研究走向规模化工程应用,为新能源并网提供主动支撑能力。该技术在光伏电站采用"部分构网"混合架构,由构网单元实现黑启动和弱网稳定;在风电场利用叶轮动能提供惯量响应。储能系统是理想的构网载体,可提供快速调频和动态电压支撑。在电网节点,构网型STATCOM可增强弱电网电压稳定性,大容量变流器可替代传统调相机。当前面临标准滞后、宽频振荡风险等共性挑战,需在可靠性、经济性间取得平衡。系统级协调控制和精确阻抗建模是应用成功的关键。

技术工作者 1112

Linux驱动开发三:点亮LED

 韦东山驱动之第12课       2.3节 字符设备驱动程序及LED驱动程序   目的 写一个点灯LED驱动 平台 QT6410开发板 驱动程序 框架 static intfirst_led_open(struct inode *inode,struct file *file)

long123bin的专栏 787

Qt垂直滚动条QVerticalScrollBar详解:从基础到实战的控件开发指南

本文系统解析Qt中QVerticalScrollBar的用法,从基础概念到进阶技巧。主要内容包括:1)基础认知:介绍其继承关系、作用及典型应用场景;2)核心用法:创建方法、关键属性配置和信号槽连接;3)进阶技巧:自定义样式表美化外观,以及与自定义内容区域的联动实现;4)实战注意事项,如避免循环触发和高DPI适配等。文章强调掌握QVerticalScrollBar对提升Qt滚动类功能开发效率的重要性,并建议通过自定义文本编辑器实践巩固知识点。

专注现代C++实战,从核心语法到高性能编程,助力开发者深入掌握系统级编程精髓。 759

linux下Led的设备驱动程序实验总结,Linux让LED灯闪起来

众所周知,LED灯闪烁实验,就相当于编程中的helloworld,是最简单入门,也是可以帮助广大爱好学习者建立自信的,看了设备驱动一个多月,终于我也让自己的led灯闪亮了。要让led灯闪烁,就是要控制引脚输入高低电平,不断交替变化,然而Linux中,上面的文章提到,驱动和应用是分开的,驱动层对硬件直接操作,应用层通过调用驱动层接口,来实现逻辑功能。我们先来看驱动程序:(驱动程序涉及太多知识,建议大...

weixin_31725659的博客 850

使用R语言获取data.frame中指定列的数据

这里以"df"为例,包含三列数据:“列1”、“列2"和"列3”。通过以上代码,我们成功获取了"列1"和"列3"的数据,并将它们分别存储在了变量"column1"和"column3"中。假设我们有一个名为"df"的data.frame,其中包含了多个列,我们想要提取其中的某一列。符号,我们可以从data.frame中提取出"列2"的数据,并将其赋值给变量"column2"。符号,我们可以轻松提取出data.frame中特定列的数据,并将其存储在变量中供进一步的分析和处理使用。假设我们要获取"列2"的数据。

DevRevolt的博客 2321

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Linux设备驱动开发之LED

path:带有全路径的节点名,返回值:找到的节点,如果为 NULL 表示查找失败。

m0_53955705的博客 1454

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

Linux设备驱动开发——3.点亮LED灯

三、点亮LED灯 通过前面的学习,我们便大致了解了如何操作4412,最直观的方面就是操作开发板来点亮一个LED灯了。 工具文件: E4412_N.bl1.bin:   三星公司提供的,bl1代码 V310-EVT1-mkbl2.c :三星公司提供的,BL2制作工具(mkbl2)源码 E4412_tzsw.bin:    三星公司提供的,安全保密代码 sd_fusing.sh  

小权的博客 1390

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

十三、(正点原子)Linux自带的LED灯驱动

LED 灯驱动文件为,可以打开# LED Core...........如果定义了的话就会编译这个文件,选择将 LED 驱动编译进 Linux 内核,在.config 文件中就会有“”这一行,因此驱动文件就会被编译。接下来我们看一下{},},/* 驱动注册函数 */为LED驱动的匹配表,compatible属性就是匹配的对象,我们在设备中LED灯节点的compatible属性要与匹配表一致,函数才能执行,否者驱动没法工作。Linux 内核自带的 LED 驱动采用了platform框架。

Tofu_Cabbage的博客 1602

Linux驱动之Linux自带的LED灯驱动

每日一个简单的驱动,日久方长,对Linux驱动就越来越熟悉,也越来容易学会写驱动程序。今日进行第六个Linux自带的led设备驱动。

Wang_XB_3434的博客 2077

Linux 内核自带的 LED 灯驱动

学习如何使用 Linux 内核自带的 LED 驱动来驱动 I.MX6U-ALPHA 开发板上的 LED0。 LED 灯这样非常基础的设备驱动, Linux 内核已经集成了。 Linux 内核的 LED 灯驱动采用 platform 框架 因此我们只需要按照要求在设备树文件中添加相应的 LED 节点即可 linux 自带LED驱动理解 内核配置: -> Device Drivers -> LED Support (NEW_LEDS [=y]) ->LED Support for GPI

3714

Linux 自带的LED 灯驱动实验

目录Linux 内核自带LED 驱动使能Linux 内核自带LED 驱动简介LED 灯驱动框架分析module_platform_driver 函数简析gpio_led_probe 函数简析设备树节点编写运行测试 前面我们都是自己编写LED 灯驱动,其实像LED 灯这样非常基础的设备驱动,Linux 内核已经集成了。Linux 内核的LED 灯驱动采用platform 框架,因此我们只需要按照要求在设备树文件中添加相应的LED 节点即可,本章我们就来学习如何使用Linux 内核自带的LED 驱动来驱动I.M

zhuguanlin121的博客 3659

linux设备驱动--LED驱动

linux设备驱动--LED驱动 最近正在学习设备驱动开发,因此打算写一个系列博客,即是对自己学习的一个总结,也是对自己的一个督促,有不对,不足,需要改正的地方还望大家指出,而且希望结识志同道合的朋友一起学习技术,共同进步。 作者:liufei_learning(转载请注明出处) email:flying0216@foxmail.com  IT学习交流群:160855096

liufei_learning--脚踏实地,戒骄戒躁! 1万+

Linux应用层例程1 点亮LED灯

⚫应用层控制外设的两种不同的方式;⚫应用层控制外设的两种不同的方式;在Linux系统下,一切皆文件!方法一:驱动层设备文件控制外设包括字符设备文件和块设备文件,,应用层通过对设备文件的 I/O 操作来操控硬件设备,譬如 LCD显示屏、串口、按键、摄像头等等,所以设备文件其实是与硬件设备相互对应的。目录下,我们也把/dev目录下的文件称为设备节点。

internetv的博客 2196

基于GEC6818智能家居的实现--点亮LED灯

嵌入式Linux学习篇: Linux内核模块 Linux内核模块----Linux Kernel Module。 在Linux内核中,驱动程序是以模块的形式存在,每个驱动程序都是一个个独立的模块。模块之间可以是独立的,不相关的。 通俗而言:Linux的设备驱动程序是存放在Linux内核模块中的,我们设计驱动程序之前,先要设计一个Linux内核模块。 在一般情况Linux设备驱动程序通过环境编译后会生成一个后缀为ko的文件,该文件可以通过命令进行安装或卸载。 本次以LED灯的驱动程序为例进行安装或卸

weixin_46664039的博客 6745

设备驱动框架之LED

为了尽量降低驱动开发者难度以及接口标准化,就出现了设备驱动框架的概念;Linux 针对每个种类的驱动设计一套成熟的、标准的、典型的驱动实现, 然后把不同厂家的同类硬件驱动中相同的部分抽出来自己实现好,再把不同部分留出接口给具体的驱动开发工程师来实现,这就叫驱动框架。说白了,设备驱动框架就是对原始的驱动开发接口进行了封装,不同种类的设备有不同的封装和实现方法,驱动开发工程师根据这些封装好的接口来编写自己的驱动程序,这就是设备驱动框架。

qq_40514606的博客 1568
上一篇: Linux设备驱动编程编程总结(一)-------模块编程
下一篇: Linux设备驱动程序设计(三)----Linux的特殊字符设备:混杂设备,依旧让LED闪烁起来
memoryjs
博客等级 码龄18年 240粉丝 113原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值