There is a example about how to register a character device.
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
int init_module(void);
void cleanup_module(void);
static intdevice_open(struct inode*, struct file*);
static intdevice_release(structinode*, struct file*);
static ssize_tdevice_read(struct file*, char*, size_t, loff_t*);
static ssize_tdevice_write(struct file*, constchar*, size_t, loff_t*);
#define SUCCESS 0
#define DEVICE_NAME "chardev" /*Dev name as it appears in /proc/devices */
#define BUF_LEN 80 /*Max length of the message from the device*/
/*
* Global variables are declared as static, so are global within the file.
*/
static int Major; /*Major number assigned to our device driver*/
static int Device_Open=0; /*Is device open?
* Used to prevent multiple access to device */
staticcharmsg[BUF_LEN]; /*The msg the device will give when asked*/
staticchar*msg_Ptr;
static struct file_operations fops = {
.read = device_read,
.write = device_write,
.open = device_open,
.release = device_release,
};
int init_module(){
Major = register_chrdev(0, DEVICE_NAME, &fops);
if (Major < 0){
printk("Registering the character device failed with %d/n", Major);
return Major;
}
printk("<1>I was assigned major number%d. To talk to/n",Major);
printk("<1>the driver, create a devfile with/n");
printk("'mknod/dev/helloc%d0'./n",Major);
printk("<1>Try various min or numbers. Try to cat and echo to/n");
printk("the device file./n");
printk("<1>Remove the device file and module when done./n");
return 0;
}
void cleanup_module(){
int ret = unregister_chrdev(Major, DEVICE_NAME);
if (ret < 0)
printk("Error in unregister_chrdev: %d/n", ret);
}
/*
* Called when a process tries to open the device file, like
* "cat /dev/mycharfile"
*/
static int device_open(struct inode *inode, struct file *file){
static int counter=0;
if(Device_Open)
return -EBUSY;
Device_Open++;
sprintf(msg,"I already told you %d times Hello world!/n", counter++);
msg_Ptr=msg;
try_module_get(THIS_MODULE);
return SUCCESS;
}
/*
* Called when a process closes the device file.
*/
static int device_release(struct inode *inode, struct file *file){
Device_Open--; /*We're now ready for our next caller*/
/*
* Decrement the usage count, or else once you opened the file, you'll
* never get get rid of the module.
*/
module_put(THIS_MODULE);
return0;
}
/*
* Called when a process, which already opened the dev file, attempts to
* read from it.
*/
static ssize_t device_read(struct file *filp, /*see include/linux/fs.h */
char *buffer, /*buffer to fill with data*/
size_t length, /*length of the buffer */
loff_t *offset){
/*
* Number of bytes actually written to the buffer
*/
intbytes_read=0;
/*
* If we're at the end of the message,
* return 0 signifying end of file
*/
if(*msg_Ptr==0)
return 0;
/*
* Actually put the data into the buffer
*/
while(length && *msg_Ptr){
/*
* The buffer is in the user data segment,not the kernel
* segment so "*" assignment won't work. We have to use
* put_user which copies data from the kernel data segment to
* the user data segment.
*/
put_user(*(msg_Ptr++),buffer++);
length--;
bytes_read++;
}
/*
* Most read functions return the number of bytes put into the buffer
*/
return bytes_read;
}
/*
* Called when a process writes to dev file: echo "hi" > /dev/hello
*/
static ssize_t device_write(struct file *filp,const char *buff,size_t len,loff_t *off){
printk("<1>Sorry, this operation isn't supported./n");
return -EINVAL;
}
2008 May 8th Thursday (五月 八日 木曜日)
最新推荐文章于 2021-12-22 12:48:17 发布