您的位置:首页 > 其它

04clock_06semqphore

2017-02-19 17:06 176 查看
#include <linux/module.h>  //MODULE_LICENSE("GPL");
#include <linux/init.h>   //module_init  module_exit
#include <linux/kernel.h>  //printk
#include <linux/io.h>    //ioremap  iounremap
#include <linux/ioport.h>  //request_mem_region

#include <linux/miscdevice.h>
#include <linux/fs.h>   //file_operations  结构体的定义
#include <linux/slab.h>  //kmalloc
#include <linux/delay.h>

#include <asm/uaccess.h>    //copy_to_user  copy_form_user

#include <linux/spinlock.h>  //自旋锁
#include <linux/rwlock.h>  //读写自旋锁
#include <linux/semaphore.h>

/*
该设备只能同时被一个进程打开
*/

#define   DEVNAME  "my_led"
#define  MEMSIZE  100

int test = 1;

struct ldm_info
{
struct  miscdevice dev;       //设备节点
struct  file_operations  ops;  //文件操作
unsigned char mem[MEMSIZE] ;  //数组, 内核的空间
//rwlock_t  myrwlock;
struct semaphore sema;
};

//struct ldm_info  ldm;
struct ldm_info  ldm;  //结构体的指针,分配空间

static  int ldm_open(struct inode * inode, struct file * file)
{
//printk("kernel: ldm_open\n");
test++;
//如何传递私有变量
//Linux任何一个文件,都会有一个file指针,
//有一个成员  private_data  void *   通用指针
file->private_data =    (void *)&test;

return 0;
}

/*
copy_to_user
copy_form_user
*/

static  ssize_t ldm_write(struct file * file, const char __user * buf, size_t size, loff_t *   offt)
{
int i =0;

int val = *(int *)file->private_data;

//write_lock(&ldm.myrwlock);
down(&ldm.sema);
for(;i < size; i++) {
//每拷贝一个字节,睡眠1s
copy_from_user(ldm.mem + i, buf + i, 1);
printk("write:%c  val = %d\n",  ldm.mem[i], val);
ssleep(1); //延迟1s
}
//write_unlock(&ldm.myrwlock);
up(&ldm.sema);

return 0;
}

ssize_t ldm_read(struct file * file, char __user *  buf, size_t size, loff_t * offt)
{
//每隔一秒拷贝一个字节到用户层
int i =0;

int val = *(int *)file->private_data;

//read_lock(&ldm.myrwlock);
down(&ldm.sema);
for(;i < size; i++) {
//每拷贝一个字节,睡眠1s
copy_to_user(buf + i, ldm.mem + i, 1);
printk("read:%c, val = %d\n",  ldm.mem[i], val);
ssleep(1); //延迟1s
}
//read_unlock(&ldm.myrwlock);
up(&ldm.sema);
return 0;
}

int ldm_release(struct inode * inode, struct file *file)
{
//printk("kernel: close\n");
test--;
return 0;
}

static int test_init(void)
{
int ret = 0;

printk("%s:%s:%d   init\n", __FILE__, __FUNCTION__, __LINE__);

ldm.dev.minor  = MISC_DYNAMIC_MINOR;  //系统自动分配次设备
ldm.dev.name = DEVNAME;//该名称将决定节点名称, 成功注册 linux 系统中
ldm.dev.fops = &ldm.ops;  //关联文件操作
ldm.ops.open = ldm_open;
ldm.ops.write = ldm_write;
ldm.ops.read = ldm_read;
ldm.ops.release = ldm_release;

ret = misc_register(&ldm.dev);

//rwlock_init(&ldm.myrwlock);
sema_init(&ldm.sema, 1);

if(ret < 0) {
printk("misc_register  failed\n");
goto  err_misc_register;
}

return 0;
err_misc_register:
return ret;

}

//卸载
static void test_exit(void)
{
printk("%s:%s:%d   init\n", __FILE__, __FUNCTION__, __LINE__);

//注销misc
misc_deregister(&ldm.dev);
//释放映射的虚拟地址

}

module_init(test_init);
module_exit(test_exit);

MODULE_LICENSE("GPL");  //加入GPL许可
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: