LINUX2.6.26.6内核下的第一个LED驱动程序测试成功!

本文介绍了一个具体的GPIO驱动程序实现过程,包括驱动程序的源代码、Makefile文件的配置及测试程序的设计。通过加载模块和创建设备节点,实现了LED灯的控制。

驱动程序gpio_driver.c:

#include <linux/fs.h>
//#include <linux/iobuf.h>
#include <linux/major.h>
#include <linux/blkdev.h>
#include <linux/capability.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/hardware.h>
//#include <asm/arch/AT91RM9200.h>
#include <asm/arch/at91rm9200.h>
//#include <asm/arch/lib_AT91RM9200.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>

#include <linux/kernel.h>
#include <linux/init.h>
//#include <linux/config.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/ioport.h>
#include <linux/sched.h>
#include <asm/io.h>
#include <asm/arch/gpio.h>
#include <linux/delay.h>

MODULE_LICENSE("GPL");

#define IOPORT_MAJOR 220 //定义主设备号
#define IOWRITE                1
#define IOCLEAR                2

#define LED1            AT91C_PIO_PB17

typedef char ioport_device_t;

static ioport_device_t gpio_devices[257];

static int  gpio_open(struct inode *inode,struct file *filp)
{
        int minor;
        minor = MINOR(inode->i_rdev);

 at91_set_gpio_output(AT91_PIN_PB17,0 );
        gpio_devices[minor]++;
        return 0;
}

static int  gpio_release(struct inode *inode,struct file *filp)
{
        int minor;
        minor = MINOR(inode->i_rdev);
        if(gpio_devices[minor])
                gpio_devices[minor]--;
        return 0;
}

static int  gpio_ctl_ioctl(struct inode *inode, struct file *filp,

unsigned int command, unsigned long arg)
{
        int err = 0;
        int minor = MINOR(inode->i_rdev);
      
        switch(command)
        {
        case IOWRITE:
                err = at91_set_gpio_value(AT91_PIN_PB17,1);//输出1高电平
                break;
        case IOCLEAR:
                err = at91_set_gpio_value(AT91_PIN_PB17,0);//输出0低电平
                break;
}

        return err;
}

static struct file_operations gpio_ctl_fops={
    owner:                THIS_MODULE,
        ioctl:                gpio_ctl_ioctl,
        open:                gpio_open,
        release:        gpio_release,
};

static int __init gpio_init(void)
{
        register_chrdev(IOPORT_MAJOR ,"gpio_driver",&gpio_ctl_fops);
        return 0;
}

static void __exit gpio_exit(void)
{
        unregister_chrdev(IOPORT_MAJOR,"gpio_driver");

}

module_init(gpio_init);
module_exit(gpio_exit);

驱动程序的Makefle文件:

# Makefile2.6
ifneq ($(KERNELRELEASE),)
#kbuild syntax. dependency relationship of files and target modules are listed here.
#obj-m +=hello.o
obj-m :=gpio_driver.o
else
PWD :=$(shell pwd)
KEVER ?=$(shell uname -r)
#KDIR :=/home/wfg/linux-2.6.26.3/$(KEVER)/build
#KDIR :=/home/wfg/linux-2.6.26.3
KDIR :=/home/wuyan/download/linux-2.6.26
default:
 #$(MAKE) -C $(KDIR) M=$(PWD)
 make -C $(KDIR) M=$(PWD) modules
clean:
 rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions *.order *symvers
endif

执行上面的Makefile文件,生成gpio_driver.ko驱动程序。

测试程序:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define DEVICE_GPIOTEST                "/dev/gpio_driver"

#define IOWRITE                1
#define IOCLEAR                2

int main()
{
        int fd;
        int val=-1;
      
        if( (fd=open(DEVICE_GPIOTEST,0)) < 0 )
        {
                perror("can not open device");
                exit(1);
        }
      
        while(1)
        {
                printf("0:set,1:clear,2:quit;");
                scanf("%d",&val);
              
                if(val==0)
                        ioctl(fd,IOWRITE,0);
                else if(val==1)
                        ioctl(fd,IOCLEAR,0);
                else if(val==2)
                  {
                        close(fd);
                        exit(1);
                }
        }
}

使用交叉编译工具编译该测试程序,生成example文件,使用FTP协议将两种文件下载到板子中运行:

root@WK:tftp -gr example 172.21.26.148

root@WK:tftp -gr gpio_driver.ko 172.21.26.148

将gpio_driver.ko放到/lib/modules/2.6.26.6文件夹下面,原因见《开发全过程》然后加载模块:

root@WK:insmod gpio_driver

然后查看模块是否加载成功:

root@WK:lsmod
gpio_driver 1953 0 - Live 0xbf002000
hello 1376 0 - Live 0xbf000000

发现模块已经加载成功,然后建立设备节点,再运行测试程序,成功点亮了LED:

root@WK:mknod -m 600 /dev/gpio_driver c 220 1
root@WK:./example
0:set,1:clear,2:quit;0
0:set,1:clear,2:quit;1
0:set,1:clear,2:quit;0
0:set,1:clear,2:quit;1
0:set,1:clear,2:quit;2

 

注意:往往生成的example文件拷贝后只有读权限,需要在超级用户下使用如下语句增加权限:

chmod -R a+rwx  .

 

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值