写linux字符设备驱动的过程:
1、module_init()和module_exit(),这两个函数是驱动程序的入口函数和退出函数,然后就是补充init函数和exit函数了
2、在initi函数中,需要进行设备的注册,说白了,就是需要申请设备号和注册设备
3、然后写文件操作函数,比如write、read、ioctl等函数
/*************************************
NAME: led.c
COPYRIGHT: XMG
*************************************/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define DEVICE_NAME "leds"
/* module name */
struct cdev cdev;
static struct class *led_class;
static led_major = 0;
static unsigned long led_table[]=
{
S3C2410_GPB5,
S3C2410_GPB6,
S3C2410_GPB7,
S3C2410_GPB8,
};
static int leds_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg)//ioctl函数
{
if(arg > 4)
{
return -EINVAL;
}
switch(cmd)
{
case 1:
s3c2410_gpio_setpin(led_table[arg],0);
return 0;
case 0:
s3c2410_gpio_setpin(led_table[arg],1);
return 0;
default:
return -EINVAL;
}
}
static struct file_operations leds_fops = //文件操作结构体
{
.owner = THIS_MODULE,
.ioctl = leds_ioctl,
};
static int __init leds_init(void)//入口函数
{
int result;
dev_t dev = MKDEV(led_major,0);
if(led_major)
{
result = register_chrdev_region(dev,1,DEVICE_NAME);//由固定设备号,直接申请
if(result < 0)
{
printk(DEVICE_NAME"can't register major number\n");
return result;
}
printk("aaaa %d\n",led_major);
}
else
{
result = alloc_chrdev_region(&dev,0,1,DEVICE_NAME);//没有固定的设备号,动态申请
led_major = MAJOR(dev);//得到主设备号
printk("MAJOR IS %d",led_major);
}
cdev_init(&cdev,&leds_fops);//设备结构体的初始化
cdev.owner = THIS_MODULE;
cdev.ops = &leds_fops;
cdev_add(&cdev,MKDEV(led_major,0),1);
led_class = class_create(THIS_MODULE,DEVICE_NAME);
if(IS_ERR(led_class))
{
printk("Err:failed in leds class.\n");
return -1;
}
device_create(led_class,NULL,MKDEV(led_major,0),NULL,DEVICE_NAME);//创建设备
printk(DEVICE_NAME "initialized\n");
return 0;
}
static void __exit leds_exit(void)
{
unregister_chrdev_region(MKDEV(led_major,0),1);
device_destroy(led_class,MKDEV(led_major,0));
class_destroy(led_class);
cdev_del(&cdev);
}
module_init(leds_init);//入口
module_exit(leds_exit);//出口
MODULE_AUTHOR("XMG");
MODULE_DESCRIPTION("TQ2440");
MODULE_LICENSE("GPL");
以下是测试程序:
/*******************************************
* NAME:test.c
* COPYRIHT: XMG
******************************************/
#include
#include
#include
#include
int main(int argc,char **argv)
{
int on;
int led_no;
int fd;
if(argc != 3 || sscanf(argv[1],"%d",&led_no)!= 1 || sscanf(argv[2],"%d",&on)!=1||on < 0 || on > 1 || led_no< 1 || led_no > 4){
fprintf(stderr,"Usage:leds led_no 0|1 \n");
exit(1);
}
fd = open("/dev/leds",0);
if(fd < 0){
perror("open device leds");
exit(1);
}
ioctl(fd,on,(led_no-1));
close(fd);
return 0;
}