📄 de2_seg7.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 controlling the 7-segment display found on the DE2 board.It uses the major number SEG7_MAJOR to be able to create a corresponding device file to access the device.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/leds_red 666 c 240 0The device driver reads hex values!*/////////////////////////////////////////////////////////////////////////////////////////////////////* Debug defines:--------------uncomment following line to use the kernelmodule withoutio (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 SEG7_MAJOR 243// base-adress mapping to device names according to linux-2.6.x/include/nios2_system.h#define SEG7_BASE na_SEG7/* define buffers for the strings sended to user */char seg7_string[STRING_LEN] = "\0";char* seg7_ptr = seg7_string;/* device files open? */int seg7_is_open = 0;void seg7_write_value(unsigned long int value){ np_pio *pio_seg7 =(np_pio *)(SEG7_BASE);#ifndef TEST outl(value,&pio_seg7->np_piodata);#endif}/////////////////////////////////////////////////////////////////////////// Open handler/////////////////////////////////////////////////////////////////////////static int seg7_open(struct inode *inode, struct file *file){#ifdef DEBUG printk("seg7_open called\n");#endif if (seg7_is_open++) { printk("device busy...\n"); return -EBUSY; } try_module_get(THIS_MODULE); return 0;}/////////////////////////////////////////////////////////////////////////// Release/Close handler/////////////////////////////////////////////////////////////////////////static int seg7_release(struct inode *inode, struct file *file){#ifdef DEBUG printk("seg7_release called\n");#endif --seg7_is_open; module_put(THIS_MODULE); return 0;}/////////////////////////////////////////////////////////////////////////// Write handler/////////////////////////////////////////////////////////////////////////static ssize_t seg7_write(struct file *filp, const char *buff, size_t len, loff_t * off){#ifdef DEBUG printk("seg7_write called\n"); printk("buffer to copy: %s\n", buff);#endif int not_copied = 0; if(len > (STRING_LEN-1)) len = STRING_LEN-1; /* copy data from user into buffer seg7_string */ not_copied = copy_from_user(seg7_string,buff,len); seg7_string[len] = '\0';#ifdef DEBUG printk("write to SEG7: %s\ncopied: %i\nnot_copied: %i\n", seg7_string, len-not_copied,not_copied);#endif seg7_write_value((unsigned long int)atolx(seg7_string)); return len-not_copied;}// Structure which assigns handler functions to hardware operationsstatic struct file_operations fops_seg7 = { .write = seg7_write, .open = seg7_open, .release = seg7_release,};/////////////////////////////////////////////////////////////////////////// Init funktion/////////////////////////////////////////////////////////////////////////static int __init mod_init(void){ np_pio *pio_seg7 = (np_pio *)(SEG7_BASE); // reserving memory regions for the PIO port if(!request_mem_region((unsigned long)SEG7_BASE, sizeof(np_pio), "de2_seg7")) return -1; // registering PIO port as character device to the kernel if(register_chrdev(SEG7_MAJOR, "de2_seg7", &fops_seg7)) { printk("register_chrdev of de2_seg7 failed!\n"); release_mem_region((unsigned long)SEG7_BASE, sizeof(np_pio)); return -EIO; } #ifdef DEBUG printk("de2_seg7 registered successfully!\n");#ifdef TEST print("TEST mode active, so no I/O interaction is possible!\n");#endif#endif // set PIO port as output#ifndef TEST outl(-1, &pio_seg7->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(SEG7_MAJOR,"de2_seg7"); // releasing memory region release_mem_region((unsigned long)SEG7_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 + -