Chinaunix首页 | 论坛 | 博客
  • 博客访问: 46001
  • 博文数量: 21
  • 博客积分: 855
  • 博客等级: 准尉
  • 技术积分: 230
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-20 14:19
文章分类
文章存档

2011年(1)

2009年(20)

我的朋友
最近访客

分类: LINUX

2009-03-20 14:42:19

一.编写模块的初始化函数:

static int __init s3c24xx_leds_init(void)

{

    int ret;

   

    ret = register_chrdev(LED_MAJOR, DEVICE_NAME, &s3c24xx_leds_fops);

    if(ret < 0) {

       printk(DEVICE_NAME "can't register major number\n");

       return ret;

    }

   

    printk(DEVICE_NAME "initialized\n");

    return 0;

}

 

二.编写模块的撤销函数

static void __exit s3c24xx_leds_exit(void)

{

    unregister_chrdev(LED_MAJOR, DEVICE_NAME);

}

 

三.指定驱动程序的初始化函数和卸载函数

module_init(s3c24xx_leds_init);

module_exit(s3c24xx_leds_exit);

 

四.定义s3c24xx_leds_fops:

static sturct file_operations s3c24xx_leds_fops = {

    .owner = THIS_MODULE,

    .open  = s3c24xx_leds_open,

    .ioctl = s3c24xx_leds_ioctl

};

 

五.编写s3c24xx_leds_open函数:

static int s3c24xx_leds_open(struct inode *inode, struct file *file)

{

    int i;

   

    for(i=0; i<4; i++) {

       s3c2410_gpio_cfpin(led_table[i], led_cfg_table[i])

    }

   

    return 0;

}

 

六.编写s3c24xx_leds_ioctl函数:

static int s3c24xx_leds_iotcl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)

{

    if (arg > 4) {

       return -EINVAL;

    }

   

    switch(cmd) {

       case IOCTL_LED_ON:

            s3c2410_gpio_setpin(led_table[arg], 0);

            return 0;

        case IOCTL_LED_OFF:

            s3c2410_gpio_setpin(led_table[arg], 1);

            return 0;

        default:

            return -EINVAL;

    }

   

}

 

七.加入描述信息:

MODULE_AUTHOR("ckz");

MODULE_DESCRIPTION("S3C2440 LED Driver");

MODULE_LICENSE("GPL");

 

八.加入头文件信息:

#include

#include

#include

#include

#include

#include

#include

#include

 

九.加入宏定义:

#define DEVICE_NAME     "leds"  /* 加载模式后,执行”cat /proc/devices”命令看到的设备名称 */

#define LED_MAJOR       231     /* 主设备号 */

 

/* 应用程序执行ioctl(fd, cmd, arg)时的第2个参数 */

#define IOCTL_LED_ON    0

#define IOCTL_LED_OFF   1

 

/* 用来指定LED所用的GPIO引脚 */

static unsigned long led_table [] = {

    S3C2410_GPB5,

    S3C2410_GPB6,

    S3C2410_GPB7,

    S3C2410_GPB8,

};

 

/* 用来指定GPIO引脚的功能:输出 */

static unsigned int led_cfg_table [] = {

    S3C2410_GPB5_OUTP,

    S3C2410_GPB6_OUTP,

    S3C2410_GPB7_OUTP,

    S3C2410_GPB8_OUTP,

};

 

十.把源代码s3c24xx_leds.c文件放入内核drivers/char子目录下,drivers/char/Makefile中增加下面一行Obj-m += s3c24xx_leds.o

 

十一.        在内核根目录上执行 make modules,可以生成drivers/char/s3c24xx_leds.ko,把它放到文件系统的/lib/modules/2.6.22目录下,就可以使用insmod s3c24xx_leds, rmmod s3c24xx_leds

 

十二.编写驱动测试程序:

#include

#include

#include

#include

 

#define IOCTL_LED_ON    0

#define IOCTL_LED_OFF   1

 

int main(int argc, char **argv)

{

    unsigned int led_no;

    int fd = -1;

   

    fd = open("/dev/leds", 0);

    if (fd < 0) {

        printf("Can't open /dev/leds\n");

        return -1;

    }

   

    led_no = strtoul(argv[1], 0 , 0) - 1;

    if (led_no > 3) {

        printf("Led number too larger\n");

        close(fd);

        return 0;

    }

   

    if(!strcmp(argv[2], "on")) {

       ioctl(fd, IOCTL_LED_ON, led_no);

    } else {

       ioctl(fd, IOCTL_LED_OFF, led_no);

    }

   

    close(fd);

    return 0;

}

 

十三.测试程序的Makefile:

CROSS=arm-linux-

 

all: led_test

 

led_test: led_test.c

    $(CROSS)gcc -o $@ led_test.c -static

 

clean:

    @rm -rf led_test *.o

 

十四.把生成led_test程序放到文件系统中

 

十五.在板子的根目录中建立设备文件:

Mknod /dev/leds c 231 0

 

测试:

Led_test 1 on

Led_test 1 off

 

阅读(935) | 评论(2) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2009-04-11 12:28:32

Mknod /dev/leds c 231 0 笔误啊!!

chinaunix网友2009-04-11 12:22:13

Led_test 1 on 这个在哪里运行?