歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux技術 >> linux設備驅動

linux設備驅動

日期:2017/3/3 12:54:23   编辑:Linux技術

#include <linux/module.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include "ioctl_led.h"

#define DEV_NAME	"test-dev"
volatile bool empty = true;
//定義一個進程資源的指針變量
struct task_struct *task;

int test_open(struct inode *inode, struct file *filp)
{
	printk("test open\n");
	return 0;
}

int test_close(struct inode *inode, struct file *filp)
{
	printk("test close\n");
	return 0;
}

ssize_t test_read(struct file *filp, char __user *buf, size_t size, loff_t *off)
{
	int ret;
	//如果為真,那麼就開始讀
	while(empty)
	{
		//f_flags 指的是對應open調用的時候所指定的flag
		//O_NONBLOCK 非阻塞形式打開
		if(filp->f_flags & O_NONBLOCK)
		{
			return 0;	
		}
		//current	(指向當前進程的task_struct)
		//(內核棧的底部thread_info.task)
		task = current;	
		//設置當前進程的狀態為TASK_INTERRUPTIBLE
		//TASK_INTERRUPTIBLE是阻塞態,進程當前正在等待除CPU外的其他系統資源,可以被信號喚醒.
		set_current_state(TASK_INTERRUPTIBLE);
		//通知調度器執行調度。
		schedule();
		if(signal_pending(current))
			return -ERESTARTSYS;
		//	return -EAGAIN;	

		printk("read: wake up\n");
	}

	ret = size;
	empty = true;
	return ret;
}

ssize_t test_write(struct file *filp, const char __user *buf, size_t size, loff_t *off)
{
	int ret;
	
	empty = false;
	wake_up_process(task);
	ret = size;

	return ret;
}

int major = 0;
struct file_operations fops = {
	.open = test_open,
	.release = test_close,
	.read = test_read,
	.write = test_write,
};

//模塊;
int test_init(void)
{
	int ret;
	printk("test init\n");
	//注冊一個字符設備驅動
	ret = register_chrdev(major, DEV_NAME, &fops);
	if(ret < 0)
		return ret;
	else
	{
		if(0 == major)
		{
			major = ret;
			printk("major = %d\n", major);
		}
	}

	return 0;
}

void test_exit(void)
{
	printk("test exit\n");
	//撤銷字符設備
	unregister_chrdev(major, DEV_NAME);
}

module_init(test_init);
module_exit(test_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("yang.yx");
MODULE_VERSION("1.1");
Makefile

obj-m	+= test.o

ROOTFS = /rootfs
KERNEL_SRC	= /lib/modules/`uname -r`/build

all:
	make -C $(KERNEL_SRC) M=`pwd` modules

clean:
	make -C $(KERNEL_SRC) M=`pwd` clean
	rm -rf app

install:
	make -C $(KERNEL_SRC) M=`pwd` modules_install INSTALL_MOD_PATH=$(ROOTFS)

app:
	arm-linux-gcc app.c -o app
ioctl.c
#ifndef	__IOCTL_H__
#define __IOCTL_H__

#include <linux/ioctl.h>

#define LED_TYPE		0x1

#define LED_ALLON		_IO(LED_TYPE, 0)
#define LED_ALLOFF		_IO(LED_TYPE, 1)
#define LED_ON			_IOW(LED_TYPE, 2, int)
#define LED_OFF			_IOW(LED_TYPE, 3, int)

#endif

Copyright © Linux教程網 All Rights Reserved