Chinaunix首页 | 论坛 | 博客
  • 博客访问: 383793
  • 博文数量: 57
  • 博客积分: 2299
  • 博客等级: 大尉
  • 技术积分: 1109
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-27 23:12
文章分类
文章存档

2011年(4)

2010年(53)

分类: 嵌入式

2010-08-08 15:25:44

#include <linux/module.h>/*__init, __exit, module_init*/
#include <linux/platform_device.h>/*platform_driver*/
#include <linux/miscdevice.h>/*struct miscdevice*/
#include <linux/fs.h>/*file_operations*/

#include <asm/arch/hardware.h>/*GPCR2*/
#include <asm/arch/pxa-regs.h>

#include <asm/uaccess.h>/*copy_from_user()*/
#include <linux/delay.h>/*mdelay()*/

spinlock_t lock;/*声明一个自旋锁*/
static char ctrl[3];
static int mgc270_stepmotor_ctrl[] = {
    81,    //---A
    82,    //---B
    83,    //---C
    84,    //---D
};
static int mgc270_stepmotor_open(struct inode *inode, struct file *file)
{
    unsigned int i;
    /* Set ALl pins GPO Low */
    for( i = 0; i < 4; i++)
        pxa_gpio_mode(mgc270_stepmotor_ctrl[i] | GPIO_OUT | GPIO_DFLT_LOW);
    printk("mgc270-stepmotor opened!\n");
    return 0;
}
static ssize_t mgc270_stepmotor_write(struct file *file, const char __user *buffer, size_t len, loff_t *ppos)
{
    unsigned char n, i;
    unsigned long flags;

    printk("mgc270-stepmotor write!\n");
    spin_lock_irqsave(&lock, flags)    ;
    if (copy_from_user(&ctrl, buffer, sizeof(ctrl)) )
        return -EFAULT;
    printk("ctrl data is %d %d %d \n", ctrl[0]-0x30, ctrl[1]-0x30, ctrl[2]-0x30);
    for( n = 0; n < ctrl[2]-0x30; n++ )
    {
        if(!(ctrl[0]-0x30))    //anticlockwise
        {//步进电机顺时针转
    //        printk("ANTI CLOCKWISE!!\n");
            for( i = 0; i < 4; i++ )
            {
                GPCR2 |= 0x0F << 17;/*GPCRx:Pin置高*/
                GPSR2 |= 3 << ( 17 + i );/*GPSRx:Pin置低*/
                if( i == 3 )
                    GPSR2 |= 1 << 17;
                mdelay((ctrl[1]-0x30)*100);
            }
        } else {    //clockwise
            /*逆时针*/
    //        printk("CLOCK WISE!!\n");
            for( i = 0; i < 4; i++ )
            {
                GPSR2 |= 0x0F << 17;
                GPCR2 |= 3 << ( 20 - i );
                if( i == 3 )
                    GPCR2 |= 1 << 20;
                mdelay((ctrl[1]-0x30)*100);
            }
        }
    }
    spin_unlock_irqrestore(&lock, flags);
    return sizeof(ctrl);
}
static int mgc270_stepmotor_release(struct inode *inode, struct file *file)
{
    unsigned int i;
    /* Set ALl pins GPO Low */
    for( i = 0; i < 4; i++)
        //设置GPIO模式
        pxa_gpio_mode(mgc270_stepmotor_ctrl[i] | GPIO_OUT | GPIO_DFLT_LOW);
    printk("mgc270-stepmotor released!\n");
    return 0;
}
static int mgc270_stepmotor_ioctl(struct inode *inode, struct file *file,unsigned int cmd, unsigned long arg)
{
    printk("mgc270-stepmotor ioctl\n");
    /* you can write code for ioctl() here */
    return 0;
}
static const struct file_operations mgc270_stepmotor_fops = {
    .owner = THIS_MODULE,
    .write = mgc270_stepmotor_write,
    .ioctl     = mgc270_stepmotor_ioctl,
    .open = mgc270_stepmotor_open,
    .release = mgc270_stepmotor_release,
};
static struct miscdevice mgc270_stepmotor_miscdev =
{
    .minor    = MISC_DYNAMIC_MINOR,
    .name    = "mgc270-stepmotor",
    .fops    = &mgc270_stepmotor_fops/*miscdevice设备的file_operations,参考字符设备中的*/
};
static int mgc270_stepmotor_probe(struct platform_device *dev)
{
    int ret;
    printk("probing mgc270-stepmotor!\n");
    ret = misc_register(&mgc270_stepmotor_miscdev);
    /*注册misc设备,miscdevice结构体提供操作函数入口*/
    if (ret)
        printk("Failed to register miscdev for MagicARM270 stepmotor.\n");
    return ret;
}
static int mgc270_stepmotor_remove(struct platform_device *dev)
{/*卸载misc设备函数,在platform_driver_unregister()中被调用*/
    printk(KERN_ALERT"remove!\n");
    misc_deregister(&mgc270_stepmotor_miscdev);
    printk("mgc270-stepmotor removed!\n");
    return 0;
}
struct platform_device *mgc270_stepmotor_device;
static struct platform_driver mgc270_stepmotor_driver = {
    .driver = {
        .name = "mgc270-stepmotor",
        .owner = THIS_MODULE,
    },
    .probe = mgc270_stepmotor_probe,/*第二级初始化入口,注册misc设备*/
    .remove = mgc270_stepmotor_remove,/*移出函数入口,__exit调用*/
};
static int __init mgc270_stepmotor_init(void)
{//平台设备初始化,第一级初始化
    int rc;
    printk("mgc270-stepmotor init......\n");
    mgc270_stepmotor_device = platform_device_alloc("mgc270-stepmotor", -1);
    /*申请设备空间*/
    if (!mgc270_stepmotor_device)
        return -ENOMEM;
    rc = platform_device_add(mgc270_stepmotor_device);
    /*在platform_device总线上添加stepmotor设备[添加device]*/
    if (rc < 0) {
        platform_device_put(mgc270_stepmotor_device);
        /*失败了则释放设备空间*/
        return rc;
    }
    rc = platform_driver_register(&mgc270_stepmotor_driver);
    /*在driver总线上注册驱动*/
    if (rc < 0)
        platform_device_unregister(mgc270_stepmotor_device);
    /*失败了则删除device*/
    spin_lock_init(&lock);/*初始化自旋锁*/
    return rc;
}
static void __exit mgc270_stepmotor_exit(void)
{
    printk(KERN_ALERT"exit!\n");
    platform_driver_unregister(&mgc270_stepmotor_driver);

/*这里面调用*remove*/
    printk(KERN_ALERT"driver_unregiste!\n");
    platform_device_unregister(mgc270_stepmotor_device);
    printk("mgc270-stepmotor exit!\n");
}

module_init(mgc270_stepmotor_init);
module_exit(mgc270_stepmotor_exit);

MODULE_AUTHOR("Abing ");
MODULE_DESCRIPTION("ZHIYUAN MagicARM270 stepmotor Driver");
MODULE_LICENSE("GPL");


在本次试验中初始misc设备驱动的建立方式:

1、注册platform_device和platform_driver,在分析驱动的时候一定要时时刻刻分清楚到底是在处理设备device还是驱动程序driver,二者相对应又有区别,一条是设备总线,一条是驱动总线;

static int __init mgc270_stepmotor_init(void)
{//平台设备初始化,第一级初始化
    int rc;
    mgc270_stepmotor_device = platform_device_alloc("mgc270-stepmotor", -1);
    /*申请设备空间*/
    if (!mgc270_stepmotor_device)
        return -ENOMEM;
    rc = platform_device_add(mgc270_stepmotor_device);
    /*在platform_device总线上添加stepmotor设备[添加device]*/
    if (rc < 0) {
        platform_device_put(mgc270_stepmotor_device);
        /*失败了则释放设备空间*/
        return rc;
    }
    rc = platform_driver_register(&mgc270_stepmotor_driver);
    /*在driver总线上注册驱动*/
    if (rc < 0)
        platform_device_unregister(mgc270_stepmotor_device);
    /*失败了则删除device*/
    return rc;
}

定义platform_device 和 platform_driver :

struct platform_device *mgc270_stepmotor_device;
static struct platform_driver mgc270_stepmotor_driver = {
    .driver = {
        .name = "mgc270-stepmotor",
        .owner = THIS_MODULE,
    },
    .probe = mgc270_stepmotor_probe,/*第二级初始化入口,注册misc设备*/
    .remove = mgc270_stepmotor_remove,/*移出函数入口,__exit调用*/
};

2、注册并初始化misc设备

static int mgc270_stepmotor_probe(struct platform_device *dev)
{
    int ret;
    printk("probing mgc270-stepmotor!\n");
    ret = misc_register(&mgc270_stepmotor_miscdev);
    /*注册misc设备,miscdevice结构体提供操作函数入口*/
    if (ret)
 printk("Failed to register miscdev for MagicARM270 stepmotor.\n");
    return ret;
}

定义misc设备结构:

static const struct file_operations mgc270_stepmotor_fops = {
    .owner = THIS_MODULE,
    .write = mgc270_stepmotor_write,
    .ioctl     = mgc270_stepmotor_ioctl,
    .open = mgc270_stepmotor_open,
    .release = mgc270_stepmotor_release,
};
static struct miscdevice mgc270_stepmotor_miscdev =
{
    .minor    = MISC_DYNAMIC_MINOR,
    .name    = "mgc270-stepmotor",
    .fops    = &mgc270_stepmotor_fops/*miscdevice设备的file_operations,参考字符设备中的*/
};

移除misc设备:

static int mgc270_stepmotor_remove(struct platform_device *dev)
{/*卸载misc设备函数,在platform_driver_unregister()中被调用*/
    misc_deregister(&mgc270_stepmotor_miscdev);  
    return 0;
}

3、移除platform设备和驱动

static void __exit mgc270_stepmotor_exit(void)
{
    platform_driver_unregister(&mgc270_stepmotor_driver);

/*这里面调用*remove*/
    platform_device_unregister(mgc270_stepmotor_device);
}

执行的时候,先是__exit,然后在platform_driver_unregister()中调用mgc270_stepmotor_remove()移除misc设备。
阅读(2854) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~