linux驱动之LED驱动_1
步骤:
1、框架
2、完好硬件的操作:
a.看原理图、引脚
b.看2440手冊
c.写代码: IO口须要用ioremap映射
我的板子电路例如以下所看到的
1、配置GPBCON 寄存器,配置输出 在open函数中去配置
2、配置GPBDAT 寄存器 在write函数中去配置
#########################################################################
手冊资料:
GPBCON 寄存器的物理地址为:0x56000010
GPBDAT 寄存器的物理地址为:0x56000014
#########################################################################
1、首先声明全局变量:
volatile unsigned long *gpbcon = NULL;
volatile unsigned long *gpbdat = NULL;
2、在入口函数中对引脚进行映射
/*映射物理地址*/
gpbcon = (volatile unsigned long *) ioremap(0x56000010,16);
gpbdat = gpbcon + 1;
3、在出口函数中取消映射
iounmap(gpbcon);
4、在open函数中将引脚设置为输出
/*配置 GPB 5 6 7 8为输出*/
*gpbcon &=~((0x3<<(5*2))|(0x3<<(6*2))|(0x3<<(7*2))|(0x3<<(8*2)));//先清零
*gpbcon |=((0x1<<(5*2))|(0x1<<(6*2))|(0x1<<(7*2))|(0x1<<(8*2)));// 配置为1 (输出)
5、在写函数中对用户空间数据进行简单处理
int val;
copy_from_user(&val,buf,count);//从用户空间向内核空间拷贝数据
if(val == 1)
{
//点灯
*gpbdat &=~((1<<5)|(1<<6)|(1<<7)|(1<<8));
}
else
{
//灭灯
*gpbdat|=(1<<5)|(1<<6)|(1<<7)|(1<<8);
}
完整的驱动代码例如以下:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <asm/io.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <asm/uaccess.h> static struct class *firstdrv_class;
static struct class_devices *firstdrv_class_dev; volatile unsigned long *gpbcon = NULL;
volatile unsigned long *gpbdat = NULL; MODULE_LICENSE("Dual BSD/GPL");
static int first_dev_open(struct inode *inode,struct file *file)
{
/*配置 GPB 5 6 7 8为输出*/
*gpbcon &=~((0x3<<(5*2))|(0x3<<(6*2))|(0x3<<(7*2))|(0x3<<(8*2)));//先清零
*gpbcon |=((0x1<<(5*2))|(0x1<<(6*2))|(0x1<<(7*2))|(0x1<<(8*2)));// 配置为1 (输出)
//printk("first dev open\n");
return 0;
}
static ssize_t first_dev_write(struct file *file,const char __user *buf,size_t count,loff_t *ppos)
{
int val;
copy_from_user(&val,buf,count);//从用户空间向内核空间拷贝数据
if(val == 1)
{
//点灯
*gpbdat &=~((1<<5)|(1<<6)|(1<<7)|(1<<8));
}
else
{
//灭灯
*gpbdat|=(1<<5)|(1<<6)|(1<<7)|(1<<8);
} //printk("first dev write\n");
return 0;
}
static struct file_operations first_sdv_fops =
{
.owner = THIS_MODULE,
.open = first_dev_open,
.write = first_dev_write,
};
int major;
int first_drv_init(void)
{ major = register_chrdev(0,"first_drv",&first_sdv_fops);//注冊
firstdrv_class = class_create(THIS_MODULE,"first_drv");
if(IS_ERR(firstdrv_class))
return PTR_ERR(firstdrv_class);
firstdrv_class_dev = device_create(firstdrv_class,NULL,MKDEV(major,0),NULL,"wq_device");
if(unlikely(IS_ERR(firstdrv_class_dev)))
return PTR_ERR(firstdrv_class_dev); /*映射物理地址*/
gpbcon = (volatile unsigned long *) ioremap(0x56000010,16);
gpbdat = gpbcon + 1;
//printk("init major= %d\n",major);
return 0;
} void first_dev_exit(void)
{
//printk("exit\n");
unregister_chrdev(major,"first_drv");//卸载 device_unregister(firstdrv_class_dev);
class_destroy(firstdrv_class);
iounmap(gpbcon);
}
module_init(first_drv_init);
module_exit(first_dev_exit);
完整的測试代码例如以下:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
/*wq_device on 打开
*wq_device off 关闭
*/
int main(int argc, char **argv)
{
int fd;
int val = 1;
fd = open("/dev/wq_device", O_RDWR);
if(fd < 0)
{
printf("can't open \n");
}
if(argc != 2)
{
printf("Usage :\n");
printf("%s <on|off>\n",argv[0]);
return 0;
}
if(strcmp(argv[1],"on") == 0)
{
val =1;
}
else
{
val =0;
}
write(fd,&val,4);
return 0;
}
linux驱动之LED驱动_1的更多相关文章
- Linux驱动之LED驱动编写
从上到下,一个软件系统可以分为:应用程序.操作系统(内核).驱动程序.结构图如下:我们需要做的就是写出open.read.write等驱动层的函数.一个LED驱动的步骤如下: 1.查看原理图,确定需要 ...
- linux驱动之LED驱动
通过之前的学习,了解到linux驱动编写的流程是:先通过注册函数注册我们编写的入口函数,然后在入口函数中获取设备号->注册字符设备->自动创建设备节点->获取设备树信息,最后通过销毁 ...
- 【Linux 驱动】简单字符设备驱动架构(LED驱动)
本文基于icool210开发板,内核版本:linux2.6.35: 驱动代码: (1)头文件:led.h #ifndef __LED_H__ #define __LED_H__ #define LED ...
- 字符设备驱动之Led驱动学习记录
一.概述 Linux内核就是由各种驱动组成的,内核源码中大约有85%的各种渠道程序的代码.一般来说,编写Linux设备驱动大致流程如下: 1.查看原理图,数据手册,了解设备的操作方法. 2.在内核中找 ...
- 字符设备驱动之LED驱动
实现 ①编写驱动框架 ②编写硬件实现代码 (在Linux系统下操作硬件,需要操作虚拟地址,因此需要先把物理地址转换为虚拟地址 ioremap()) 如何实现单个灯的操作: 实现方法之一--操作次设备号 ...
- Linux驱动之按键驱动编写(中断方式)
在Linux驱动之按键驱动编写(查询方式)已经写了一个查询方式的按键驱动,但是查询方式太占用CPU,接下来利用中断方式编写一个驱动程序,使得CPU占有率降低,在按键空闲时调用read系统调用的进程可以 ...
- Linux驱动之按键驱动编写(查询方式)
在Linux驱动之LED驱动编写已经详细介绍了一个驱动的编写过程,接着来写一个按键驱动程序,主要是在file_operations结构中添加了一个read函数.还是分以下几步说明 1.查看原理图,确定 ...
- linux设备驱动归纳总结(五):4.写个简单的LED驱动【转】
本文转载自:http://blog.chinaunix.net/uid-25014876-id-84693.html linux设备驱动归纳总结(五):4.写个简单的LED驱动 xxxxxxxxxxx ...
- Linux下实现流水灯等功能的LED驱动代码及测试实例
驱动代码: #include <linux/errno.h> #include <linux/kernel.h> #include <linux/module.h> ...
随机推荐
- 对Oracle 、SQL Server、MySQL、PostgreSQL数据库优缺点分析
对Oracle .SQL Server.MySQL.PostgreSQL数据库优缺点分析 Oracle Database Oracle Database,又名Oracle RDBMS,或简称Oracl ...
- Fiddler——抓包工具的使用
fiddler安装 pc端安装fiddler,自行从百度下载即可 Fiddler是强大且好用的Web调试工具之一,它能记录客户端和服务器的http和https请求,允许你监视,设置断点,甚至修改输入输 ...
- (转) 淘淘商城系列——redis-desktop-manager的使用
http://blog.csdn.net/yerenyuan_pku/article/details/72849791 实际工作环境中,redis会安装在服务器上,我们想使用redis服务就要使用re ...
- redis源码(一):为redis添加自己的列表类型
本文档分为三大部分: 环境介绍与效果演示 redis接收命令到返回数据的执行逻辑 代码实现 文档的重点和难点在第三部分,完全阅读本文档需要读者具备基本的c语言和数据结构知识. 环境介绍和效果演示环境介 ...
- ocelot+consul+identity4的使用demo
Ocelot网关搭建 搭建core控制台项目 本demo采用2.1版本 命名为APPIGateWay 在Nuget包中添加Ocelot引用 选用8.0.0版本 添加Ocelot.json 文件 内容为 ...
- 基于APE物理引擎的管线容积率计算方法
容积率一般应用在房地产开发中,是指用地范围内地上总建筑面积与项目总用地面积的比值,这个参数是衡量建设用地使用强度的一项非常重要的指标.在其他行业,容积率的计算也非常重要,如产品利用率.管道使用率等等. ...
- case when里的like功能 ////// 截取(substr)
case when里的like功能 假如要用到case when又要用到like这样的功能,即如果字符串包含‘语文’就怎么怎么样,包含‘数学’就怎么怎么样,包含‘英语’就怎么怎么样,like是用于wh ...
- Gym - 101670A Amusement Anticipation(CTU Open Contest 2017 签到题)
题目&题意: 倒着找处于最后位置的等差数列的开头的位置. 例: 1 5 3 4 5 6 3 4 5 6是等差数列,它的开头的位置是3 PS: 读题真的很重要!!!!多组输入,上来就读错了!! ...
- 运行/调试你的PHP代码
前言 没有任何一名程序员可以一气呵成.完美无缺的在不用调试的情况下完成一个功能或模块.调试实际分很多种情况.本篇文章我分享下自己在实际开发工作中的经验,我个人理解,调试分三种,注意我所讲的是调试并非测 ...
- Turtle-可视化界面画圣诞树
圣诞节(Christmas)又称耶诞节.耶稣诞辰,译名为“基督弥撒”,是西方传统节日,起源于基督教,在每年公历12月25日.弥撒是教会的一种礼拜仪式.圣诞节是一个宗教节,因为把它当作耶稣的诞辰来庆祝, ...