mutex_lock() -- 互斥鎖

#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <asm/irq.h>
//#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/string.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <asm/unistd.h>
#include <linux/major.h>


#include <mach/map.h>
#include <mach/regs-clock.h>
#include <mach/regs-gpio.h>


#include <plat/gpio-cfg.h>
#include <mach/gpio-bank-e.h>
#include <mach/gpio-bank-k.h>
#include <mach/gpio-bank-h.h>
#include <mach/gpio-bank-n.h>
#include <mach/gpio-bank-l.h>
#include <mach/gpio-bank-p.h>

#include <linux/device.h>

#include <linux/jiffies.h>

#define DEVICE_NAME "led_driver"
#define T_MAJORS 700

static struct cdev fun_cdev;
static dev_t dev;
static struct class    *led_class;

static DEFINE_MUTEX(sem);

static void init_led(void)
{
unsigned temp;
//GPK4-7
temp = readl(S3C64XX_GPKCON);
temp &= ~((0xf << 4) | (0xf << 5) | (0xf << 6) | (0xf<< 7));
temp |= (1 << 16) | (1 << 20) | (1 << 24) | (1 << 28);
writel(temp, S3C64XX_GPKCON);
}

static long led_driver_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
wait_queue_head_t wait;

mutex_lock(&sem);


temp = readl(S3C64XX_GPKDAT);
if (cmd == 0)
{
temp &= ~(1 << (arg + 3));
}
else
{
temp |= 1 << (arg + 3);
}

//t = jiffies;
//while (time_after(jiffies,t + 2 * HZ) != 1);
init_waitqueue_head(&wait);
sleep_on_timeout(&wait,15 * HZ);

writel(temp,S3C64XX_GPKDAT);

printk (DEVICE_NAME"\tjdh:led_driver cmd=%d arg=%d jiffies = %d\n",cmd,arg,jiffies);

mutex_unlock(&sem);

return 0;
}

static struct file_operations io_dev_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = led_driver_ioctl,
};

static int __init dev_init(void)
{
int ret;
unsigned temp;
init_led();

dev = MKDEV(T_MAJORS,0);
cdev_init(&fun_cdev,&io_dev_fops);
ret = register_chrdev_region(dev,1,DEVICE_NAME);
if (ret < 0) return 0;
ret = cdev_add(&fun_cdev,dev,1);
if (ret < 0) return 0;

printk (DEVICE_NAME"\tjdh:led_driver initialized!!\n");

led_class = class_create(THIS_MODULE, "led_class1"); 
if (IS_ERR(led_class)) 

printk(KERN_INFO "create class error\n"); 
return -1; 

device_create(led_class, NULL, dev, NULL, "led_driver"); 

return ret;
}

static void __exit dev_exit(void)
{
unregister_chrdev_region(dev,1);
    device_destroy(led_class, dev); 
    class_destroy(led_class);
}

module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");

MODULE_AUTHOR("JDH");


測試程序:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "stdio.h"
#include "sys/types.h"
#include "sys/ioctl.h"
#include "stdlib.h"
#include "termios.h"
#include "sys/stat.h"
#include "fcntl.h"
#include "sys/time.h"


#include <string.h>  
#include <stdlib.h> 


int main(int argc, char** argv)
{
int fd;
int led_num = 0;
int led_value = 0;
char temp[10];


fd = open("/dev/led_driver",0);
if (fd < 0)
{
perror("open led_driver error");
exit(1);
}

strcpy(temp,argv[1]);  
      led_num = atoi(temp);  

strcpy(temp,argv[2]);  
      led_value = atoi(temp); 


printf("%d %d\n",led_num,led_value);


ioctl(fd,led_num,led_value);


close(fd);

return 0;
}


./led 0 1  1號燈亮

./led 1 1  1號燈滅
注:mutex_lock (name)與mutex_unlock(name)成對出現,前者互斥加鎖,後者互斥解鎖, name 取值爲0 和1  加鎖name的值減一變爲0,解鎖name的值加1變爲1.

發佈了27 篇原創文章 · 獲贊 0 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章