基于arm的一个简单的led驱动
2014-01-16 16:27
387 查看
在学写驱动的时候一定不要盲目的跟从,要有自己的方法。要记住一点,学习驱动要学习驱动的模板,每个驱动程序其结构基本上都是一样的。只要大家掌握了驱动的结构以后在写驱动的时候就相对来说要简单一些。只要大家学会写驱动过后后头来看其实驱动都是大同小异的。在这里我给大家介绍一个简单的led驱动的写法,
#define DEVICE_NAME "DRVTEST"//宏定义 定义出这个驱动程序的名字为DRVTEST 这是为我们以后写应用程序的时候做准备,我们所写的应用程序就是通过这个名字来调用这个驱动程序的。
/*这两句是定义了两个指针只要大家学习了一些裸机编程的话都知道,如果想要操作arm上的硬件其实要处理的数据至少有两个寄存器 一个是控制控制寄存器 一个是数据寄存器*/
全部代码和测试程序在http://download.csdn.net/detail/langzhong520123/6855737下载
volatile unsigned int *gpecon=NULL;//用来指向控制寄存器
volatile unsigned int *gpedat=NULL;//用来指向数据寄存器
//
static struct class *drv_test_class;
struct device *dev;
int major,err;
static int drvtest_open(struct inode *inode, struct file *file)
{
/*
* nothing special to do here
* We do accept multiple open files at the same time as we
* synchronize on the per call operation.
*/
printk("open Drvfile\n");
return 0;
}
ssize_t drvtest_write(struct file *file, const char __user *data,size_t len, loff_t *ppos)
{
char tmp;
copy_from_user(&tmp,data,1);
if(tmp==1)
*gpedat=1<<11;
else
*gpedat=0;
return 1;
}
ssize_t drvtest_read(struct file *file, char __user * buf,size_t len, loff_t * ppos)
{
char tmp;
if(*gpedat & (1<<11))
tmp=1;
else
tmp=0;
copy_to_user(buf,&tmp,1);
return 1;
}
static const struct file_operations drvtest_fops = {
.owner
= THIS_MODULE,
.open = drvtest_open,
.read = drvtest_read,
.write = drvtest_write,
};
static int __init drv_test_init(void)
{
printk("hello drv test \n");
//注册字符驱动,创建设备节点
drv_test_class = class_create(THIS_MODULE, "drvtest");
printk("111111111111111111111111111111 \n");
if (IS_ERR(drv_test_class))
{
printk("Err:failed in creating class.\n");
return -1;
}
major=register_chrdev (0, "drvtest", &drvtest_fops);
printk("2222222222222222222222222222222 \n");
dev=device_create(drv_test_class, NULL, MKDEV(major, 0), NULL, "drvtest");
printk("33333333333333333333333333333333 \n");
/*struct device *device_create(struct class *class, struct device *parent,
dev_t devt, void *drvdata, const char *fmt, ...)
device_create(my_class,NULL, devno, NULL,"hello");*/
printk("DRVTEST installed OK\n");
//硬件控制 通过指针去指向硬件地址
gpecon=(volatile unsigned int *)ioremap(0x56000010,16);
gpedat=gpecon+1;
*gpecon=1<<22;
*gpedat=0;
//0x56000040
return 0;
}
static void __exit drv_test_exit(void)
{
printk("88 drv test \n");
unregister_chrdev(major, "drvtest");
device_destroy(drv_test_class, MKDEV(major, 0));
class_destroy(drv_test_class);
*gpedat=1<<11;
iounmap(gpecon);
/* not yet used */
}
module_init(drv_test_init);
module_exit(drv_test_exit);
MODULE_LICENSE("GPL");
#define DEVICE_NAME "DRVTEST"//宏定义 定义出这个驱动程序的名字为DRVTEST 这是为我们以后写应用程序的时候做准备,我们所写的应用程序就是通过这个名字来调用这个驱动程序的。
/*这两句是定义了两个指针只要大家学习了一些裸机编程的话都知道,如果想要操作arm上的硬件其实要处理的数据至少有两个寄存器 一个是控制控制寄存器 一个是数据寄存器*/
全部代码和测试程序在http://download.csdn.net/detail/langzhong520123/6855737下载
volatile unsigned int *gpecon=NULL;//用来指向控制寄存器
volatile unsigned int *gpedat=NULL;//用来指向数据寄存器
//
static struct class *drv_test_class;
struct device *dev;
int major,err;
static int drvtest_open(struct inode *inode, struct file *file)
{
/*
* nothing special to do here
* We do accept multiple open files at the same time as we
* synchronize on the per call operation.
*/
printk("open Drvfile\n");
return 0;
}
ssize_t drvtest_write(struct file *file, const char __user *data,size_t len, loff_t *ppos)
{
char tmp;
copy_from_user(&tmp,data,1);
if(tmp==1)
*gpedat=1<<11;
else
*gpedat=0;
return 1;
}
ssize_t drvtest_read(struct file *file, char __user * buf,size_t len, loff_t * ppos)
{
char tmp;
if(*gpedat & (1<<11))
tmp=1;
else
tmp=0;
copy_to_user(buf,&tmp,1);
return 1;
}
static const struct file_operations drvtest_fops = {
.owner
= THIS_MODULE,
.open = drvtest_open,
.read = drvtest_read,
.write = drvtest_write,
};
static int __init drv_test_init(void)
{
printk("hello drv test \n");
//注册字符驱动,创建设备节点
drv_test_class = class_create(THIS_MODULE, "drvtest");
printk("111111111111111111111111111111 \n");
if (IS_ERR(drv_test_class))
{
printk("Err:failed in creating class.\n");
return -1;
}
major=register_chrdev (0, "drvtest", &drvtest_fops);
printk("2222222222222222222222222222222 \n");
dev=device_create(drv_test_class, NULL, MKDEV(major, 0), NULL, "drvtest");
printk("33333333333333333333333333333333 \n");
/*struct device *device_create(struct class *class, struct device *parent,
dev_t devt, void *drvdata, const char *fmt, ...)
device_create(my_class,NULL, devno, NULL,"hello");*/
printk("DRVTEST installed OK\n");
//硬件控制 通过指针去指向硬件地址
gpecon=(volatile unsigned int *)ioremap(0x56000010,16);
gpedat=gpecon+1;
*gpecon=1<<22;
*gpedat=0;
//0x56000040
return 0;
}
static void __exit drv_test_exit(void)
{
printk("88 drv test \n");
unregister_chrdev(major, "drvtest");
device_destroy(drv_test_class, MKDEV(major, 0));
class_destroy(drv_test_class);
*gpedat=1<<11;
iounmap(gpecon);
/* not yet used */
}
module_init(drv_test_init);
module_exit(drv_test_exit);
MODULE_LICENSE("GPL");
相关文章推荐
- ARM嵌入式编程(无操作系统、基于MDK)之最简单的程序:点亮一个LED灯
- 基于ARM_contexA9 led驱动编程
- 基于WinCE的一个简单的流程序驱动模板
- 基于ARM_contexA9 led驱动编程
- linux设备驱动入门,最简单的LED驱动,基于tq2440
- 基于ARM_contexA9 led驱动编程
- lLinux驱动学习之编写一个简单的led驱动
- 基于ARM_contexA9 led驱动编程
- 一个基于简单USB过滤驱动。。
- [TED] 一个简单的LED驱动
- 一个简单的LED驱动
- 一个简单的基于 DirectShow 的播放器 2(对话框类)
- 基于MVC框架+IOC+Rhino Mocks的一个简单项目介绍
- 基于ARM含SD控制器的SD卡的SDIO模式驱动解析
- 基于 aLi Lua Web Server 的一个简单例子
- 一个基于mini2440的测试按键与led灯的测试程序
- 一个基于Java的简单分组处理算法
- 基于ARM-LINUX的温度传感器驱动18B20(1)
- LED驱动程序相关头文件简单介绍
- 一个最简单的基于PHP+jQuery的AJAX例子