linux驱动 自旋锁的运用

linux驱动 自旋锁的运用
//hello.c
#define __NO_VERSION__
#include <linux/module.h>
#include <linux/config.h>
#include <linux/version.h>
#include <asm/uaccess.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <asm/page.h>
#include <linux/poll.h>
#include <linux/kdev_t.h>
#include <asm/semaphore.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
unsigned int test_major = 0;
static int global_var=0;
static int globalvar_count = 0;
char *mystr="wodeshen" ;
static struct semaphore sem;
static spinlock_t spin = SPIN_LOCK_UNLOCKED; //宏定义 已经初始化
static ssize_t read_test(struct file *file,char *buf,size_t count,loff_t *f_pos)
{
int left;
printk(KERN_INFO "read_test/n");
if (verify_area(VERIFY_WRITE,buf,count) == -EFAULT )
return -EFAULT;
if (down_interruptible(&sem))
{
return - ERESTARTSYS;
}
printk("copy_to_user======2=======/n");
copy_to_user(buf, mystr, strlen(mystr));
/*
for(left = count ; left > 0 ; left--)
{
__put_user('1',buf);
buf++;
}
*/
up(&sem);
//return sizeof(int);
return  strlen(mystr);
}

static ssize_t write_test(struct file *file, const char *buf, size_t count, loff_t *f_pos)
{
if (down_interruptible(&sem))
{
return - ERESTARTSYS;
}
if (copy_from_user(&global_var, buf, sizeof(int)))
{
up(&sem);
return - EFAULT;
}
up(&sem);
printk(KERN_INFO "write_test/n");
return sizeof(int);
}
static int open_test(struct inode *inode,struct file *file )
{
spin_lock(&spin);
printk("globalvar open/n");
//临界资源访问
if (globalvar_count)
{
spin_unlock(&spin);
return - EBUSY;
}
globalvar_count++;
//释放自选锁
spin_unlock(&spin);
printk(KERN_INFO "open_test/n");
MOD_INC_USE_COUNT;
return 0;
}
static int release_test(struct inode *inode,struct file *file )
{
printk(KERN_INFO "release_test/n");
MOD_DEC_USE_COUNT;
globalvar_count--;
return 0;
}

struct file_operations test_fops = {
read:read_test,
write:write_test,
open: open_test,
release:release_test
};
int init_module(void)
{
int result;
result = register_chrdev(0, "test", &test_fops);
init_MUTEX(&sem);
if (result < 0) {
printk(KERN_INFO "test: can't get major number/n");
return result;
}
if (test_major == 0) test_major = result; /* dynamic */
return 0;
}

void cleanup_module(void)
{
unregister_chrdev(test_major, "test");
}

MODULE_LICENSE("GPL");
MODULE_AUTHOR("BECKHAM");

//Makefile
CC=gcc
MODCFLAGS:=-Wall -DMODULE -D__KERNEL__ -DLINUX -I /usr/src/linux-2.4.20-8/include
test.o:hello.c
 $(CC) $(MODCFLAGS) -c hello.c
 
//test.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
main()
{
 int testdev;
 int i;
 int j;
 char *buf=malloc(150);
 testdev = open("/dev/test",O_RDWR);
 if ( testdev == -1 ) {
  perror(open);
  printf("Cann't open file /n");
  exit(0);
 }
 j=read(testdev,buf,10);
 strcat(buf,"/0");
 printf("%d===%s/n",j,buf);
 while(1);
 close(testdev);
}
然后顺序执行
先删除设备rm /dev/test -f
卸载模块  rmmode test
make
insmod test.o
mknod /dev/test c 254 0
gcc -o test test.c
./test
再开启一个终端,运行test,结果将失败,显示设备处于忙的状态

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值