初次动手编写驱动——LED在linux中的驱动。
今天第一次自己尝试编写驱动,看了这么长时间视频,第一次动手,编写的是简单的LED的程序。从简单到复杂一个一个来。编写驱动的顺序是先从注册函数和卸载函数起始:static int led_init(){cdev_init(&cdev, &led_fops);alloc_chrdev_region(&devno, 0, 1,"led");cdev_add(&cdev, devn
今天第一次自己尝试编写驱动,看了这么长时间视频,第一次动手,编写的是简单的LED的程序。从简单到复杂一个一个来。
编写驱动的顺序是先从注册函数和卸载函数起始:
static int led_init()
{
cdev_init(&cdev, &led_fops);
alloc_chrdev_region(&devno, 0, 1,"led");
cdev_add(&cdev, devno, 1);
return 0;
}
static int led_exit()
{ cdev_del(&cdev);
unregister_chrdev_region(devno,1);
}
module_init(led_init);
module_exit(led_exit);
先把框架撘起来,然后在填充。在模块init的函数中如定义cdev,定义file_operations,初始化cdev,添加cdev,因为添加cdev要用到设备编号,所以在添加cdev前要注册设备号 devno。在模块卸载函数中需要删除cdev,注销设备号。
本次LED驱动十分简单,只用到了open和ioctl函数。建立LED.h 文件,定义ioctl要用的到命令:
#define LED_MAGIC 'L' //定义L作为幻数
#define LED_ON _IO(LED_MAGIC,1) //不需要传递参数,所以用_IO来定义两个命令
#define LED_OFF _IO(LED_MAGIC,0)
然后编写led_open 函数和led_ioctl函数,完成驱动
源码:
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/io.h>
#include "LED.h"
#define LEDCON 0x56000010
#define LEDDATA 0x56000014
unsigned int *led_config;
unsigned int *led_data;
struct cdev cdev;
dev_t devno;
static int led_open (struct inode *inode, struct file *filp)
{
led_config=ioremap(LEDCON,4);
iowrite32(0x00015400,led_config);
led_data=ioremap(LEDDATA,4);
return 0;
}
static int led_ioctl(struct inode *inode, struct file *flip, unsigned int cmd, unsigned long arg)
{
switch(cmd){
case LED_ON :
iowrite32(0x00,led_data);
return 0;
case LED_OFF :
iowrite32(0xff,led_data);
return 0;
default :
return -EINVAL;}
}
struct file_operations led_fops=
{
.open = led_open,
.ioctl = led_ioctl,
};
static int led_init()
{
cdev_init(&cdev, &led_fops);
alloc_chrdev_region(&devno, 0, 1,"led");
cdev_add(&cdev, devno, 1);
return 0;
}
static int led_exit()
{ cdev_del(&cdev);
unregister_chrdev_region(devno,1);
}
module_init(led_init);
module_exit(led_exit);
其中struct file_operations led_fops的赋值和初始化要放到led_open和led_ioctl的后面,如果放在前面编译时会提示没有定义。如下:
关于ioctl:
ioctl命令:
http://blog.chinaunix.net/uid-25014876-id-59419.html ioctl的学习
在开发板中运行应用程序时,可能会提示你缺少权限如图:
使用chmod 777 led_app 就可以解决了
在应用程序运行的过程中出现了一下错误
这种错误说是由于内存泄露什么的,在网上百度了几篇关于Oops的文章,大概看懂了,但是对于新手来说,具体操作还是有点难有兴趣的可以看一下这个http://blog.chinaunix.net/uid-14753126-id-2980100.html
由于驱动简单,我选择了一个比较笨又好用的方法,因为我的驱动是根据视频一步一步写的,所以直接和视频中的程序对照,果然发现了,我驱动函数中的open函数和模块初始化函数都少了一句return 0; 加上之后问题就解决了。这里就有疑惑了,为什么这个return 0 必须要?为什么模块卸载函数里面不用要呢?没有百度到结果,先记下来,以后问高手。加上之后
更多推荐
所有评论(0)