字元裝置驅動第八課 訊號量

2021-07-25 06:25:33 字數 4337 閱讀 6691

用於同步,猶如紅綠燈,訊號量為0時則阻塞,訊號量大於0則往下走,可對訊號量進行加減(pv操作)

struct semaphore sem;

//定義訊號量

/*

* 功能:設定訊號量sem的初始值為val

*/void sema_init(struct semaphore *sem, int val)

void up(struct semaphore *sem);
/*先做減1操作,然後判斷是否為0,為0則阻塞,不為0則往下走*/

void down(struct semaphore *sem);

/*先做減1操作,然後判斷是否為0,為0則阻塞,不為0則往下走

* 可被中斷

*/down_interruptible(struct semaphore *sem);

/*先做減1操作,然後判斷是否為0,不管為0不為0都返回*/

int down_trylock(struct semaphore *sem);

/*先做減1操作,然後判斷是否為0,為0則阻塞,不為0則往下走,超時時間到也返回往下走

* 返回值: 0:減成功且不阻塞 負數:超時

*/int down_timeout(struct semaphore *sem, long jiffies);

#include 

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

static struct class *cls = null;

#include "mycmd.h"

static int major = 0;

static int minor = 0;

const int count = 6;

#define devname "demo"

static struct cdev *demop = null;

#define kmax 1024

static int counter = 0;

static char kbuf[kmax];

static atomic_t tv;

struct semaphore sem;//定義訊號量

//開啟裝置

static int demo_open(struct inode *inode, struct file *filp)

memset(kbuf, 0, kmax);

counter = 0;

return0;}

//關閉裝置

static int demo_release(struct inode *inode, struct file *filp)

//讀裝置

//ssize_t read(int fd, void *buf, size_t count)

static ssize_t demo_read(struct file *filp, char __user *buf, size_t size, loff_t *offset)

if(counter < size)

if(copy_to_user(buf, kbuf, size))

return size;

}//寫裝置

static ssize_t demo_write(struct file *filp, const char __user *buf, size_t size, loff_t *offset)

if(copy_from_user(kbuf, buf, size))

counter = size;

up(&sem); //訊號量加1(v操作)

return counter;}/*

* read/write param

* read status

* contrl device

*/static long demo_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)

, };

struct karg *usrarg;

switch(cmd)

usrarg = (struct karg *)arg;

if(copy_to_user(usrarg, &karg, sizeof(karg)))

printk(kern_info "cmdr: %s : %s : %d ---done.\n", __file__, __func__, __line__);

break;

case cmdw:

printk(kern_info "cmdw: %s : %s : %d\n", __file__, __func__, __line__);

if(_ioc_size(cmd) != sizeof(karg))

usrarg = (struct karg *)arg;

if(copy_from_user(&karg, usrarg, sizeof(karg)))

printk(kern_info "cmdw: %d : %s\n", karg.kval, karg.kbuf);

break;

default:;};

return0;}

static struct file_operations fops = ;

static int __init demo_init(void)

//2. init cdev obj

cdev_init(demop, &fops);

ret = alloc_chrdev_region(&devnum, minor, count, devname);

if(ret)

major = major(devnum);

//3. register cdev obj

ret = cdev_add(demop, devnum, count);

if(ret)

cls = class_create(this_module, devname);

if(is_err(cls))

for(i = minor; i < (count+minor); i++)

}// init atomic_t

atomic_set(&tv, 1);

// init sem

sema_init(&sem, 0); //初始化訊號量

//get command and pid

printk(kern_info "(%s:pid=%d), %s : %s : %d - ok.\n",

current->comm, current->pid, __file__, __func__, __line__);

return

0;err_step2:

for(--i; i >= minor; i--)

class_destroy(cls);

err_step1:

unregister_chrdev_region(devnum, count);

err_step:

cdev_del(demop);

//get command and pid

printk(kern_info "(%s:pid=%d), %s : %s : %d - fail.\n",

current->comm, current->pid, __file__, __func__, __line__);

return ret;

}static void __exit demo_exit(void)

class_destroy(cls);

unregister_chrdev_region(mkdev(major, minor), count);

cdev_del(demop);

}module_init(demo_init);

module_exit(demo_exit);

module_license("gpl");

module_author("farsight");

module_description("demo for kernel module");

字元裝置驅動第八課 file

裝置驅動中的操作方法集中所有的函式,第乙個引數都是struct file filp。這個結構體中有個成員,專門標識阻塞和非阻塞。struct file f u struct path f path 路徑 struct inode f inode cached value const struct f...

字元裝置驅動第八課 讀寫鎖

忙等鎖,臨界區盡量不休眠。rwlock init lock write lock lock write unlock lock read lock lock read unlock lock 搶得到就搶。搶不到鎖也返回往下走,一般下面會對其返回值做判斷 功能 嘗試上讀鎖,不管搶到鎖還是搶不到鎖都返回...

字元裝置驅動第八課 自旋鎖

原始碼目錄下include linux spinlock.hstatic spinlock t lock 定義乙個自旋鎖spin lock init lock spin lock lock spin unlock lock include include include include includ...