驱动程序:
#include
#include
#include
#include
#include
#include
#include //虽然我这里没有用到中断,但是一定要包含这个文件夹的,不清楚为什么
#define DEVICE_NAME "HJF"
dev_t dev;
struct cdev *p_cdev;
struct tasklet_struct my_tasklet;
void hjf_handle(unsigned long data)
{
printk("<1>in tasklet_handle\n\n");
}
int hjf_iotcl(struct inode*inode,struct file*filp,unsigned int cmd,unsigned long arg)
{
printk("<1>in kernel_iotcl\n");
tasklet_schedule(&my_tasklet);
return 0;
}
struct file_operations hjf_fops={
.ioctl=hjf_iotcl,
};
static int hjf_init(void)
{
int ret;
ret=alloc_chrdev_region(&dev,0,1,DEVICE_NAME);
if(ret<0){
printk("<1>alloc_chrdev_region fail!\n");
return ret;
}
p_cdev=cdev_alloc();//动态申请的步骤
//p_cdev->ops=&hjf_fops;
cdev_init(p_cdev,&hjf_fops);//这里的fops与cdev联系起来的两种方法
ret=cdev_add(p_cdev,dev,1);
if(ret<0){
printk("<1>cdev_add fail!\n");
return ret;
}
devfs_mk_cdev(dev,S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP,DEVICE_NAME);
tasklet_init(&my_tasklet,hjf_handle,0);
printk("<1>register sucessful!\n");
return 0;
}
static void hjf_exit(void)//容易错的地方:写成:tasklet_exit,因为tasklet_exit和tasklet_init是有这样的函数的
{
tasklet_kill(&my_tasklet);
unregister_chrdev_region(dev,1);//无论动态还是静态,都是一种方法注销的
cdev_del(p_cdev);
devfs_remove(DEVICE_NAME);
printk("tasklet exit sucessful!\n");
}
MODULE_LICENSE("GPL");
module_init(hjf_init);
module_exit(hjf_exit);
————————————————————————————————————————————
应用程序:
#include
#include //这个头文件是一定要包含的
int main(void)
{
int fd;
fd=open("/dev/HJF",O_RDWR);
if(fd<0){
printf("open file fail!\n");
return fd;
}
while(1){
sleep(3);
ioctl(fd,0,0);//对应的ioctl函数的格式
}
close(fd);
return 0;
}
============================================================================================
驱动程序:
#include
#include
#include
#include
#include
#include
#include
static unsigned long data=2;
static struct tasklet_struct mytasklet;
static void mylet(unsigned long data)
{
printk(KERN_ALERT "tasklet running.\n");
printk("data=%d\n",(int)data);
return;
}
static int __init mytasklet_init(void)
{
tasklet_init(&mytasklet,mylet,data);
printk(KERN_ALERT "init mytasklet\n");
tasklet_schedule(&mytasklet);
return 0;
}
static void __exit mytasklet_exit(void)
{
tasklet_kill(&mytasklet);
printk(KERN_ALERT "exit mytasklet\n");
return;
}
MODULE_LICENSE("GPL");
module_init(mytasklet_init);
module_exit(mytasklet_exit);
_______________________________________________________________________________
说明:不需要应用程序,在PC机上用命令dmesg就可以查看结果了,和上面的tasklet程序不同的地方是这里多了一个函数参数。
阅读(991) | 评论(0) | 转发(0) |