作者:刘洪涛,华清远见嵌入式学院讲师.
本文主要介绍一个linux内核线程的实例,以及在QEMU平台上测试的过程.
一、内核线程的创建
编写一个字符设备驱动,在驱动注册时,开启一个内核线程.在用户向设备写入数据时,字符设备的wirte方法能够激活此内核线程,并在线程中实现打印用户输入的数据.
驱动代码如下(在2.6.22内核上测试通过),关键部分加上了注释:
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h> /* printk(), min() */
#include <linux/slab.h> /* kmalloc() */
#include <linux/fs.h> /* everything... */
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/fcntl.h>
#include <linux/cdev.h>
#include <asm/uaccess.h>
#include <linux/device.h>
#include <linux/kthread.h>
#include <linux/spinlock.h>
static int kthread_major = 0;
module_param(kthread_major, int, 0);
MODULE_AUTHOR("farsight");
MODULE_LICENSE("Dual BSD/GPL");
struct kthread_dev {
struct task_struct *thread;
struct cdev cdev;
char* name;
int data_size;
char data[100];
spinlock_t queue_lock;
};
int kthread_open(struct inode *inode,struct file *filp)
{
return 0;
}
ssize_t kthread_read(struct file *file, char __user *buff, size_t count, loff_t *offp)
{
return 0;
}
ssize_t kthread_write(struct file *file, const char __user *buff, size_t count, loff_t *offp)
{
int ret;
ret=sizeof(kthread_dev_obj->data);
if(count>(ret-1))
count=ret-1;
if(copy_from_user(kthread_dev_obj->data,buff,count)<0)//获取用户数据
{
goto out1;
}
spin_lock(&kthread_dev_obj->queue_lock);
kthread_dev_obj->data_size=count;
spin_unlock(&kthread_dev_obj->queue_lock);
wake_up_process(kthread_dev_obj->thread);//唤醒内核线程
return count;
out1:
return 0;
}
static int kthread_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
return 0;
}
static int kthread_release(struct inode *node, struct file *file)
{
return 0;
}
/*
* Set up the cdev structure for a device.
*/
static void kthread_setup_cdev(struct cdev *dev, int minor,struct file_operations *fops)
{
int err, devno = MKDEV(kthread_major, minor);
cdev_init(dev, fops);
dev->owner = THIS_MODULE;
err = cdev_add (de |