首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Linux字符设备驱动编写基本流程(2)

Linux字符设备驱动编写基本流程(2)

static ssize_t s3c6410_leds_write (struct file *file, const char __user *buf, size_t count, loff_t *ppos){  unsigned tmp = count;  unsigned long i = 0;  memset(mem, 0, 4);    if (count > 4)        tmp = 4;  if (copy_from_user (mem, buf, tmp) )        return -EFAULT;  else{    for( i=0; i<4; i++)        {          tmp = ioread32(S3C64XX_GPMDAT);          if (mem[i] == '1')            tmp &= (~(1 << i));          else            tmp |= (1 << i);          iowrite32(tmp, S3C64XX_GPMDAT);        }        return count;  }}static struct file_operations dev_fops = {.owner = THIS_MODULE, .unlocked_ioctl = s3c6410_leds_ioctl, .write = s3c6410_leds_write};static struct cdev leds_cdev;static int leds_create_device(void){  int ret = 0;  int err = 0;    cdev_init (&leds_cdev,  &dev_fops);  leds_cdev.owner = THIS_MODULE;    if (major > 0)  {    dev_number = MKDEV(major,minor);        err = register_chrdev_region(dev_number, DEVICE_COUNT, DEVICE_NAME);        if (err < 0)        {          printk(KERN_WANRING "register_chrdev_region error\n");          return err        }  }  else{    err = alloc_chrdev_region(&leds_cdev.dev, 10, DEVICE_COUNT, DEVICE_NAME);        if(err < 0)        {                printk (KERN_WARNING "alloc_chrdev_region error\n");                return err;        }        major = MAJOR(leds_cdev.dev);        major = MINOR(leds_cdev.dev);        dev_number = leds_cdev.dev;  }  ret = cdev_add(&leds_cdev,dev_number, DEVICE_COUNT);  leds_class = class_create (THIS_MODULE, DEVICE_NAME);  device_create (leds_class, NULL, dev_number, NULL, DEVICE_NAME);  return ret;}static void leds_init_gpm(int leds_default){  int tmp = 0;  tmp = ioread32(S3C64XX_GPMCON);  tmp &= (~0xffff);  tmp |= 0x1111;  iowrite32(tmp,S3C64XX_GPMCON);    tmp = ioread32(S3C64XX_GPMPUD);  tmp &= (~0XFF);  tmp |= 0xaa;  iowrite32(tmp,S3C64XX_GPMPUD);    tmp = ioread32(S3C64XX_GPMDAT);  tmp &= (~0xf);  tmp |= leds_default;  iowrite32(tmp, S3C64XX_GPMDAT);  }static leds_init( void){  int ret;    ret = leds_create_device();  leds_init_gpm (~leds_state);  printk(DEVICE_NAME"\tinitialized\n");    return ret;}static void leds_destroy_device(void){        device_destroy(leds_class, dev_number);        if(leds_class)                class_destroy(leds_class);        unregister_chrdev_region(dev_number, DEVICE_NAME);}static void leds_exit(void){  leds_destroy_device();  printk(DEVICE_NAME"\texit\n");}module_init(leds_init);module_exit(leds_exit);module_param(leds_state, int, S_IRUGO|S_IWUSR);module_param_array(params, charp, ?m_size, S_IRUGO|S_IWUSR);MODULE_LICENSE("GPL");MODULE_AUTHOR("lining");
继承事业,薪火相传
返回列表