⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 de2_switches.c

📁 Altera DE2开发板的LED、LCD、SEG7和按键的linux下的设备驱动程序
💻 C
字号:
/*  	Copyright (C) 2007 Philipp Lutz	This program is free software; you can redistribute it and/or modify	it under the terms of the GNU General Public License as published by	the Free Software Foundation; either version 2 of the License, or 	(at your option) any later version.	This program is distributed in the hope that it will be useful,	but WITHOUT ANY WARRANTY; without even the implied warranty of	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the	GNU General Public License for more details.	You should have received a copy of the GNU General Public License	along with this program; if not, write to the Free Software	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*/////////////////////////////////////////////////////////////////////////////////////////////////////*Description:------------This device driver is capable of reading out the values of the switches found on the DE2 board.It uses the major number SWITCHES_MAJOR to be able to create a corresponding device file to read from.In uClinux for NIOS2 the automatic creation of device files is found in the script located at "vendors/Altera/nios2nommu/romfs_list".In uClinux it works with the following command:mknod /dev/switches 666 c 242 0*///////////////////////////////////////////////////////////////////////////////////////////////////////// Debug defines:// --------------//// uncomment following line to use the kernelmodule without// io (inb / outb) functions, needed for debug purposses on host machine.//#define TEST// enables debug-kernel-messages (viewed via "dmesg" command)//#define DEBUG///////////////////////////////////////////////////////////////////////////////////////////////////#include "de2_includes.h"// major numbers for identifying the device files#define SWITCHES_MAJOR		242// base-adress mapping to device names according to linux-2.6.x/include/nios2_system.h#define SWITCHES_BASE		na_Switch// define buffers for the strings sended to userchar switches_string[STRING_LEN] = "0\0";char* switches_ptr = switches_string;// device files open?int switches_is_open = 0;/////////////////////////////////////////////////////////////////////////// Open handler/////////////////////////////////////////////////////////////////////////static int switches_open(struct inode *inode, struct file *file){#ifdef DEBUG	printk("switches_open called\n");#endif		unsigned long int value = 0;	np_pio *pio_switches  = (np_pio *)(SWITCHES_BASE);		if (switches_is_open++) {		printk("device busy...\n");		return -EBUSY;	}		// get new information from register#ifndef TEST	value = inl(&pio_switches->np_piodata);#endif	ltoa(switches_string,value);#ifdef DEBUG	printk("read value: %i\n",value);#endif		switches_ptr = switches_string;	try_module_get(THIS_MODULE);	return 0;}/////////////////////////////////////////////////////////////////////////// Release/Close handler/////////////////////////////////////////////////////////////////////////static int switches_release(struct inode *inode, struct file *file){#ifdef DEBUG	printk("switches_release called\n");#endif	--switches_is_open;			module_put(THIS_MODULE);	return 0;}/////////////////////////////////////////////////////////////////////////// Read handler/////////////////////////////////////////////////////////////////////////static ssize_t switches_read(struct file *filp, char *buffer, size_t length, loff_t * offset){	// Number of bytes actually written to the buffer	int bytes_read = 0;#ifdef DEBUG	printk("switches_read called\n");#endif	// If we're at the end of the message, return 0 signifying end of file	if (*switches_ptr == 0)		return 0;	while (length-- && *switches_ptr) {		/* The buffer is in the user data segment, not the kernel 		segment so "*" assignment won't work.  We have to use 		put_user which copies data from the kernel data segment to		the user data segment. */		put_user(*(switches_ptr++), buffer++);		bytes_read++;	}#ifdef DEBUG	printk("bytes read: %i\n",bytes_read);#endif	// return count of bytes, sent to user	return bytes_read;}// definitions, which functions are called for /dev/switchesstatic struct file_operations fops_switches = {	.read		= switches_read,	.open		= switches_open,	.release	= switches_release};/////////////////////////////////////////////////////////////////////////// Init funktion/////////////////////////////////////////////////////////////////////////static int __init mod_init(void){	np_pio *pio_switches = (np_pio *)(SWITCHES_BASE);	// reserving memory regions for the I/O port	if(!request_mem_region((unsigned long)SWITCHES_BASE, sizeof(np_pio), "de2_switches"))		return -1;		// registering PIO port as character device to the kernel	if(register_chrdev(SWITCHES_MAJOR, "de2_switches", &fops_switches))	{		printk("register_chrdev of de2_switches failed!\n");		release_mem_region((unsigned long)SWITCHES_BASE, sizeof(np_pio));		return -EIO;	}	#ifdef DEBUG	printk("de2_switches registered successfully!\n");#ifdef	TEST	print("TEST mode active, so no I/O interaction is possible!\n");#endif#endif		// set PIO port as input#ifndef TEST	outl(0, &pio_switches->np_piodirection);#endif	return 0;}/////////////////////////////////////////////////////////////////////////// Exit function (will be spared if build-in device driver selected)/////////////////////////////////////////////////////////////////////////static void __exit mod_exit(void){	// unregistering character device	unregister_chrdev(SWITCHES_MAJOR,"de2_switches");	// releasing memory region	release_mem_region((unsigned long)SWITCHES_BASE, sizeof(np_pio));}// declaring the init/exit functions of the modulemodule_init( mod_init );module_exit( mod_exit );MODULE_LICENSE("GPL");MODULE_AUTHOR("Philipp Lutz");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -