Skip to content

Instantly share code, notes, and snippets.

@junfenglx
Created December 8, 2013 14:39
Show Gist options
  • Save junfenglx/7858405 to your computer and use it in GitHub Desktop.
Save junfenglx/7858405 to your computer and use it in GitHub Desktop.
char driver demo
#include "chardev.h"
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
//global varibles
static int unused=1;
static int number=0;
static char msg[N]="13111387\0";
static char *cur;
static int cdv_open(struct inode *inode,struct file *filp)
{
printk(KERN_INFO "unused:%d\n",unused);
if (!unused)
return -EBUSY;
unused=0;
cur=msg;
try_module_get(THIS_MODULE);
return 0;
}
static int cdv_release(struct inode *inode,struct file *file)
{
unused=1;
cur=msg;
module_put(THIS_MODULE);
return 0;
}
static ssize_t cdv_read(struct file *filp,char *buffer,size_t length,loff_t *offset)
{
int notread=strlen(cur);
if (!notread)
return 0;
if (length>notread)
length=notread;
copy_to_user(buffer,cur,length);
cur+=length;
return length;
}
static ssize_t cdv_write(struct file *filp,const char *buffer,size_t length,loff_t *offset)
{
int canwrite=strlen(cur);
if (length>N-(cur-msg))
length=N-(cur-msg);
copy_from_user(cur,buffer,length);
cur+=length;
return length;
}
static int cdv_ioctl(struct file *filp,unsigned int cmd,unsigned long arg)
{
printk(KERN_INFO "ioctl CLEAR.\n");
printk(KERN_INFO "cmd:%d\nCLEAR:%d\n",cmd,CDV_CLEAR);
if (cmd==CDV_CLEAR)
{
printk(KERN_INFO "ioctl CLEAR.\n");
*msg='\0';
}
return 0;
}
//file_operations
struct file_operations fops={
.open=cdv_open,
.release=cdv_release,
.read=cdv_read,
.write=cdv_write,
.unlocked_ioctl=cdv_ioctl,
.compat_ioctl=cdv_ioctl
};
int init_cdv(void)
{
number=register_chrdev(number,NAME,&fops);
if(number<0)
{
printk(KERN_INFO "Registering char device failed with %d\n",number);
return number;
}
printk(KERN_INFO "ok\n");
printk(KERN_INFO "I was assigned major number %d. To talk to\n", number);
printk(KERN_INFO "the driver, create a dev file with\n");
printk(KERN_INFO "'mknod /dev/%s c %d 0'.\n", NAME, number);
printk(KERN_INFO "Try various minor numbers. Try to cat and echo to\n");
printk(KERN_INFO "the device file.\n");
printk(KERN_INFO "Remove the device file and module when done.\n");
return 0;
}
void cleanup_cdv(void)
{
unregister_chrdev(number,NAME);
printk(KERN_INFO "bye\n");
}
module_init(init_cdv);
module_exit(cleanup_cdv);
#ifndef H_CHARDEV
#define H_CHARDEV
#define NAME "chardev"
#define CDV_CLEAR 0x909090
#define N 1024
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include "chardev.h"
int main(int argc,char *argv[])
{
int fd,ret;
fd=open("/dev/chardev",O_RDWR);
if(fd<0)
{
printf("open error.\n");
exit(1);
}
ret=ioctl(fd,CDV_CLEAR,0);
if (ret<0)
{
printf("ioctl error.\n");
exit(1);
}
close(fd);
printf("ioctl success.\n");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment