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

📄 de2_leds.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 rudimentary device driver controlls the red and green LEDs on the DE2 board.It uses major numbers (LEDS_RED_MAJOR / LEDS_GREEN_MAJOR) for both LEDs lines (red and green) to be ableto create a corresponding device file to access the LEDs. In uClinux for NIOS2 the automatic creation ofdevice files is found in the script located at "vendors/Altera/nios2nommu/romfs_list".In uClinux it works with the following command:mknod /dev/leds_red 666 c 240 0TODO:-----* Make just one routine for each device-handler of both LED lines to reduce code size* Assign one major number and different minor numbers for both LED lines* Read support from device? (if hardware is capable of this feature)*////////////////////////////////////////////////////////////////////////////////////////////////////// // 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 directly in the shell or via "dmesg" command)//#define DEBUG///////////////////////////////////////////////////////////////////////////////////////////////////#include "de2_includes.h"// major numbers for identifying the device files#define LEDS_RED_MAJOR		240#define LEDS_GREEN_MAJOR	241// base-adress mapping to device names according to linux-2.6.x/include/nios2_system.h from SOPC builder#define LEDS_RED_BASE		na_LEDR#define LEDS_GREEN_BASE		na_LEDG// define buffers for the strings sended to userchar leds_red_string[STRING_LEN]="\0";char leds_green_string[STRING_LEN]="\0";char* leds_red_ptr	= leds_red_string;char* leds_green_ptr	= leds_green_string;// are device files open?int leds_red_is_open 	= 0;int leds_green_is_open	= 0;///////////////////RED LEDS//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Open handler/////////////////////////////////////////////////////////////////////////static int leds_red_open(struct inode *inode, struct file *file){#ifdef DEBUG	printk("leds_red_open called\n");#endif	if (leds_red_is_open++) {		printk("device busy...\n");		return -EBUSY;	}	try_module_get(THIS_MODULE);	return 0;}/////////////////////////////////////////////////////////////////////////// Release/Close handler/////////////////////////////////////////////////////////////////////////static int leds_red_release(struct inode *inode, struct file *file){#ifdef DEBUG	printk("leds_red_release called\n");#endif		--leds_red_is_open;				module_put(THIS_MODULE);	return 0;}/////////////////////////////////////////////////////////////////////////// Write handler/////////////////////////////////////////////////////////////////////////static ssize_t leds_red_write(struct file *filp, const char *buff, size_t len, loff_t * off){#ifdef DEBUG	printk("leds_red_write called\n");	printk("buffer to copy: %s\n", buff);#endif		int not_copied = 0;	unsigned long int value = 0;	np_pio *pio_leds_red =(np_pio *)(LEDS_RED_BASE);	if(len > (STRING_LEN-1))		len = STRING_LEN-1;	/* copy data from user into buffer leds_red_string */	ltoa(leds_red_string,value);	not_copied = copy_from_user(leds_red_string,buff,len);	leds_red_string[len] = '\0';#ifdef DEBUG	printk("write to LED: %s\ncopied: %i\nnot_copied: %i\n", leds_red_string, len-not_copied,not_copied);#endif#ifndef TEST	outl((unsigned long int)atol(leds_red_string),&pio_leds_red->np_piodata);#endif	return len-not_copied;}///////////////////GREEN LEDS//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Open handler/////////////////////////////////////////////////////////////////////////static int leds_green_open(struct inode *inode, struct file *file){#ifdef DEBUG	printk("leds_green_open called\n");#endif	if (leds_green_is_open++) {		printk("device busy...\n");		return -EBUSY;	}	try_module_get(THIS_MODULE);	return 0;}/////////////////////////////////////////////////////////////////////////// Release/Close handler/////////////////////////////////////////////////////////////////////////static int leds_green_release(struct inode *inode, struct file *file){#ifdef DEBUG	printk("leds_green_release called\n");#endif		--leds_green_is_open;				module_put(THIS_MODULE);	return 0;}/////////////////////////////////////////////////////////////////////////// Write handler/////////////////////////////////////////////////////////////////////////static ssize_t leds_green_write(struct file *filp, const char *buff, size_t len, loff_t * off){#ifdef DEBUG	printk("leds_green_write called\n");	printk("buffer to copy: %s\n", buff);#endif		int not_copied = 0;	np_pio *pio_leds_green =(np_pio *)(LEDS_GREEN_BASE);	if(len > (STRING_LEN-1))		len = STRING_LEN-1;	// copy data from user into buffer leds_red_string	not_copied = copy_from_user(leds_red_string,buff,len);	leds_red_string[len] = '\0';#ifdef DEBUG	printk("write to LED: %s\ncopied: %i\nnot_copied: %i\n", leds_red_string, len-not_copied,not_copied);#endif#ifndef TEST	// set pins to output	outl(-1,&pio_leds_green->np_piodirection);	outl((unsigned long int)atol(leds_red_string),&pio_leds_green->np_piodata);#endif	return len-not_copied;}// Structure which assigns handler functions to hardware operations (red LEDs)static struct file_operations fops_leds_red = {	.write		= leds_red_write,	.open		= leds_red_open,	.release	= leds_red_release};// Structure which assigns handler functions to hardware operations (green LEDs)static struct file_operations fops_leds_green = {	.write		= leds_green_write,	.open		= leds_green_open,	.release	= leds_green_release};/////////////////////////////////////////////////////////////////////////// Init funktion/////////////////////////////////////////////////////////////////////////static int __init mod_init(void){	np_pio *pio_leds_red 	= (np_pio *)(LEDS_RED_BASE);	np_pio *pio_leds_green 	= (np_pio *)(LEDS_GREEN_BASE);	// reserving memory regions for both PIO ports	if(!request_mem_region((unsigned long)LEDS_RED_BASE, sizeof(np_pio), "de2_leds_red"))		return -1;	if(!request_mem_region((unsigned long)LEDS_GREEN_BASE, sizeof(np_pio), "de2_leds_green"))		return -1;		// registering both PIO ports as character devices to the kernel	if(register_chrdev(LEDS_RED_MAJOR, "de2_leds_red", &fops_leds_red))	{		printk("register_chrdev of de2_leds_red failed!\n");		release_mem_region((unsigned long)LEDS_RED_BASE, sizeof(np_pio));		return -EIO;	}	if(register_chrdev(LEDS_GREEN_MAJOR, "de2_leds_green", &fops_leds_green))	{		printk("register_chrdev of de2_leds_green failed!\n");		release_mem_region((unsigned long)LEDS_GREEN_BASE, sizeof(np_pio));		return -EIO;	}	#ifdef DEBUG	printk("de2_leds registered successfully!\n");#ifdef	TEST	print("TEST mode active, so no I/O interaction is possible!\n");#endif#endif		// set both PIO ports as outputs	outl(-1, &pio_leds_red->np_piodirection);	outl(-1, &pio_leds_green->np_piodirection);	return 0;}/////////////////////////////////////////////////////////////////////////// Exit function (will be spared if build-in device driver selected)/////////////////////////////////////////////////////////////////////////static void __exit mod_exit(void){	// unregistering character devices	unregister_chrdev(LEDS_RED_MAJOR,"de2_leds_red");	unregister_chrdev(LEDS_GREEN_MAJOR,"de2_leds_green");	// releasing memory regions	release_mem_region((unsigned long)LEDS_RED_BASE, sizeof(np_pio));	release_mem_region((unsigned long)LEDS_GREEN_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 + -