免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 10070 | 回复: 11
打印 上一主题 下一主题

Linux菜鸟关于gpio驱动的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-03-10 10:37 |只看该作者 |倒序浏览
请问各位大侠:
      小弟我刚学Linux驱动开发,自己尝试着写了一个gpio驱动,功能就是简单控制GPIO的输出电平
      随内核一起编译后下载到目标板运行,打印显示驱动加载成功,但在 /dev下没有生成相应的设备节点
      不知道是什么原因,希望各位高人能指导一下,内核版本为2.6.20.1 驱动源码如下:

#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/highmem.h>
#include <linux/pagemap.h>
#include <asm/arch/gpio.h>

#include <asm/arch/at91_pio.h>
#include <asm/arch/hardware.h>
#define GPIO_MAJOR 220





#undef DEBUG_GPIO

/* ......................................................................... */

/*
* GPIO read .
*/
static ssize_t gpio_rd (struct file *file, char *buf, size_t count, loff_t *offset)
{


        return count;
}

/*
* GPIO Write .
*/
static ssize_t gpio_wr(struct file *file, char *buf, size_t count, loff_t *offset)
{

        return count;
}

static int gpio_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
        int io_status;

        switch (cmd)
                {
                         case 0:
                                *(long *)(AT91_PIOC+PIO_CODR)         |= (1<<13);
                                break;
                        case 1:
                                *(long *)(AT91_PIOC+PIO_SODR) |= (1<<13);
                                break;                               
                        case 2:
                                io_status = *(long *)(AT91_PIOC+PIO_PDSR);
                                break;
                        default:
                                break;
                }
        return io_status;
                               
}

/*
* Open the GPIO device
*/
static int gpio_open(struct inode *inode, struct file *file)
{


        //AT91_PMC |= 1<<AT91RM9200_ID_PIOC;
        *(long *)(AT91_PIOC+PIO_OER)|= (1<<13);
        *(long *)(AT91_PIOC+PIO_PUDR) |= (1<<13);


        return 0;
}

/*
* Close the GPIO device
*/
static int gpio_close(struct inode *inode, struct file *file)
{
       
        return 0;
}

/* ......................................................................... */

static struct file_operations gpio_fops = {
        .owner                = THIS_MODULE,
        .llseek                = no_llseek,
        .read                = gpio_rd,
        .write                = gpio_wr,
        .ioctl                = gpio_ioctl,
        .open                = gpio_open,
        .release        = gpio_close,
};

/*
* Install the gpio /dev interface driver
*/
static int __init at91_gpio_init(void)
{
       
        printk(KERN_INFO "gpio /dev entries driver\n");
        if (register_chrdev(GPIO_MAJOR, "gpio", &gpio_fops)) {
                printk(KERN_ERR "at91_spidev: Unable to get major %d for gpio\n", GPIO_MAJOR);
                return -EIO;
        }


        printk(KERN_INFO "AT91 GPIO driver loaded\n");

        return 0;
}

/*
* Remove the gpio /dev interface driver
*/
static void __exit at91_gpio_exit(void)
{


        if (unregister_chrdev(GPIO_MAJOR, "gpio")) {
                printk(KERN_ERR "at91_gpio: Unable to release major %d for gpio\n", GPIO_MAJOR);
                return;
        }
}

module_init(at91_gpio_init);
module_exit(at91_gpio_exit);

MODULE_LICENSE("GPL")
MODULE_AUTHOR("Guo Shuqiang")
MODULE_DESCRIPTION("GPIO /dev interface for Atmel AT91RM9200")

/*end of at91_gpioctl.c */

系统启动的打印消息:
io scheduler noop registered
io scheduler anticipatory registered (default)
AT91 GPIO driver loaded
at91_spi: Baud rate set to 5990400
AT91 SPI driver loaded
AT91 Watchdog Timer enabled (5 seconds, nowayout)
atmel_usart.0: ttyS0 at MMIO 0xfefff200 (irq = 1) is a ATMEL_SERIAL
atmel_usart.1: ttyS1 at MMIO 0xfffc4000 (irq = 7) is a ATMEL_SERIAL

论坛徽章:
0
2 [报告]
发表于 2009-03-10 10:43 |只看该作者
节点要自己加的

论坛徽章:
0
3 [报告]
发表于 2009-03-10 10:47 |只看该作者
比如 mknod /dev/gpio1 c 220 0
这样你在测试函数中就可以打开节点调用ioctl函数了
比如fd = open("/dev/gpio1" O_RDWR);
ioctl(;1;

论坛徽章:
0
4 [报告]
发表于 2009-03-10 10:47 |只看该作者

回复 #2 zhongfrank 的帖子

大家回复的很快啊,此地果然高人不少,谢谢!
我是Linux菜鸟对驱动开发流程不熟,有没有专门的函数实现设备节点的添加?

[ 本帖最后由 guode0724 于 2009-3-10 10:49 编辑 ]

论坛徽章:
0
5 [报告]
发表于 2009-03-10 10:51 |只看该作者
就是mknod

论坛徽章:
0
6 [报告]
发表于 2009-03-10 11:01 |只看该作者

回复 #5 zhongfrank 的帖子

能不能在驱动里面添加代码然后加载后自动在/dev生成设备节点呢?

论坛徽章:
0
7 [报告]
发表于 2009-03-10 11:05 |只看该作者

回复 #6 guode0724 的帖子

写驱动和加节点是两码事,况且节点添加之后如果不是手动删除的话也会一直在。
如果你觉得麻烦,可以写一个shell脚本,一次完成模块加载、节点添加,运行测试等等

论坛徽章:
0
8 [报告]
发表于 2009-03-10 11:34 |只看该作者

回复 #7 zhongfrank 的帖子

Linux下如何实现设备节点的自动添加和删除呢?

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
9 [报告]
发表于 2009-03-10 11:40 |只看该作者
原帖由 guode0724 于 2009-3-10 11:34 发表
Linux下如何实现设备节点的自动添加和删除呢?


自己写一个脚本实现啊。建议LZ看一下LDD3源码中关于scull模块的自动加载和卸载的脚本scull_load/unload

论坛徽章:
0
10 [报告]
发表于 2009-03-10 11:42 |只看该作者
好的,谢谢指点!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP