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

📄 hpi_driver.c

📁 linux dsp hpi driver
💻 C
字号:
/********************************************************************* *             *     * Filename:      HPI_Driver.c * Version:       0.0.1 * Description:   Implementation for the kernel module debug * Status:        Experimental. * Author:        snowerlist (snowerlist@163.com) * Created at:    WuHan * Based on code by:  snower *  *     Copyright (c) 2008.12  WH, All Rights Reserved.  *     This file is for ARM chip of DSP project xxx  *     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. *   ********************************************************************/#include <linux/module.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/interrupt.h>#include <linux/time.h>#include <linux/timer.h>#include <linux/fs.h>#include <linux/miscdevice.h>#include <linux/string.h>#include <linux/errno.h>#include <linux/init.h>#include <asm/uaccess.h>#include <asm/irq.h>#include <asm/mach-types.h>#include "HPI_Driver.h"static stDSPHPIInfo    DSPHPIInfo;/*  *  Send singal to application who set his pid through ioctl, then the applicatioon will wakeup for this singal. *  This is always used in interrupt! */ static void DSP_HPI_Signal_Send(void){            DSPHPIInfo.m_InterfaceSingal.si_signo = SIGRTMIN;	DSPHPIInfo.m_InterfaceSingal.si_code = SI_KERNEL;	DSPHPIInfo.m_InterfaceSingal.si_value.sival_int = DSP_HPI_ALARM;	send_sig_info(SIGRTMIN, &DSPHPIInfo.m_InterfaceSingal, DSPHPIInfo.m_pstInterfaceTask);	#ifdef debug		printk("\nopsm irq detected!\n");#endif      return;}/*  *  If interrupt function is used in this module, please implement this! */ static irqreturn_t DSP_HPI_Interrupt_Handler (int irq, void *dev_id, struct pt_regs *regs){      /*Add your interrupt handle code here!*/	         DSP_HPI_Signal_Send(); /*Inform apps something happened!*/	return IRQ_HANDLED;}/* * This function is called when a user space program attempts to read * /dev/DSP_HPI. It puts the device to sleep on the wait queue until * button_sequence_finished writes some data to the buffer and flushes * the queue, at which point it writes the data out to the device and * returns the number of characters it has written. This function is * reentrant, so that many processes can be attempting to read from the * device at any one time. */static int DSP_HPI_Open(struct inode *inode, struct file *file){     int retval=0;      MOD_INC_USE_COUNT;	      return retval;}static int DSP_HPI_Release (struct inode *inode, struct file *filp){       int retval=0;	           MOD_DEC_USE_COUNT;       return retval;}static int DSP_HPI_Ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){       int err = 0,ret_value=0;	  		switch(cmd) 		{		case INTERFACE_SET_CUR_PID:			DSPHPIInfo.m_tInterfaceProcessID = arg;			DSPHPIInfo.m_pstInterfaceTask = find_task_by_pid(DSPHPIInfo.m_tInterfaceProcessID);#ifdef debug			printk("set current process pid %d\n", interface_process_id);#endif			break;		break;				case READ_HPI_REG1:			ret_value = (*(volatile u32 *)(DSPHPIInfo.m_stVirtualAddrSpace.m_pViturAddrReg1));			return ret_value;			break;			              case READ_HPI_REG2:					       break;				       case READ_HPI_REG3:		   			       break;		case READ_HPI_REG4:		   			       break;              case WRITE_HPI_REG1:						break;			              case WRITE_HPI_REG2:					       break;				       case WRITE_HPI_REG3:		   			       break;		case WRITE_HPI_REG4:		   			       break;			   		default:              return -ENOTTY;			break;		}	return 0;}static ssize_t DSP_HPI_Read (struct file *filp, char __user *buffer, size_t count, loff_t *ppos){	u32    u32ReadLength;       ssize_t    retval = 0;	       if(down_interruptible(&DSPHPIInfo.m_stProctoolSem))        return -ERESTARTSYS;	    if(count > (MAX_BUFFER_LEN))    {        u32ReadLength = MAX_BUFFER_LEN;    }    /*Copy you data to m_pacBuffer*/   if (copy_to_user(buffer, DSPHPIInfo.m_stBufInfo.m_pacBuffer, u32ReadLength))    {            retval = -EFAULT;#ifdef debug            printk(KERN_INFO "DSP_HPI_Read: No enough buffer!\n");#endif            goto out;    }    retval = u32ReadLength;    out:    up(&DSPHPIInfo.m_stProctoolSem);    return retval;/* Return the number of bytes "read" */}static ssize_t DSP_HPI_Write (struct file *filp, char __user *buffer, size_t count, loff_t *ppos){    u32 u32WriteLength;    ssize_t retval = -ENOMEM; /* value used in "goto out" statements */    if(down_interruptible(&DSPHPIInfo.m_stProctoolSem))        return -ERESTARTSYS;	    if(MAX_BUFFER_LEN <= count)    {#ifdef debug        printk(KERN_INFO "DSP_HPI_Write: No enough buffer!\n");        #endif        goto out;    }    u32WriteLength = count;   if(copy_from_user(DSPHPIInfo.m_stBufInfo.m_pacBuffer, buffer, u32WriteLength))   {          retval = -EFAULT;#ifdef debug          printk(KERN_INFO "DSP_HPI_Write: Get from Userspace fault!\n");#endif          goto out;   }    DSPHPIInfo.m_stBufInfo.m_NewDataCount = u32WriteLength;   retval = u32WriteLength;    out:    up(&DSPHPIInfo.m_stProctoolSem);	    return retval;}/*  * This structure is the file operations structure, which specifies what * callbacks functions the kernel should call when a user mode process * attempts to perform these operations on the device. */static const struct file_operations DSP_HPI_fops = {	.owner		= THIS_MODULE,       .open             = DSP_HPI_Open,	.release         = DSP_HPI_Release,	.ioctl              = DSP_HPI_Ioctl,	.read		= DSP_HPI_Read,	.write             = DSP_HPI_Write,};/*  * This structure is the misc device structure, which specifies the minor * device number (158 in this case), the name of the device (for /proc/misc), * and the address of the above file operations structure. */static struct miscdevice DSP_HPI_misc_device = {	DSP_HPI_MINOR,	DSP_HPI_DEV,	&DSP_HPI_fops,};/*For this function you should check whether ioremap is successed by */static  void   Set_Vitual_Address(void){   DSPHPIInfo.m_stVirtualAddrSpace.m_pViturAddrReg1 = (u32  *)ioremap(PHY_ADDR_REG1, REGISTER_LENGTH);   DSPHPIInfo.m_stVirtualAddrSpace.m_pViturAddrReg2 = (u32  *)ioremap(PHY_ADDR_REG2, REGISTER_LENGTH);   DSPHPIInfo.m_stVirtualAddrSpace.m_pViturAddrReg3 = (u32  *)ioremap(PHY_ADDR_REG3, REGISTER_LENGTH);   DSPHPIInfo.m_stVirtualAddrSpace.m_pViturAddrReg4 = (u32  *)ioremap(PHY_ADDR_REG4, REGISTER_LENGTH);   return;}static int __init DSP_HPI_Init(void){	printk (KERN_INFO "DSP_HPI Driver Version %s (C) snowerlist "			"<snowerlist@163.com> 2008.12.\n", DRIVER_VERSION);       Set_Vitual_Address();	if (misc_register (&DSP_HPI_misc_device)) {		printk (KERN_WARNING "DSP_HPI: Couldn't register device, "				"%d.\n", DSP_HPI_MINOR);		return -EBUSY;	}	if (request_irq (DSP_HPI_IRQ_NUM, DSP_HPI_Interrupt_Handler, DSP_HPI_IRQ_FLAG, DSP_HPI_DEV, NULL))	{		printk (KERN_WARNING "DSP_HPI: IRQ %d is not free.\n", DSP_HPI_IRQ_NUM);		misc_deregister (&DSP_HPI_misc_device);		return -EIO;	}	return 0;}static void __exit DSP_HPI_Exit (void) {	free_irq (DSP_HPI_IRQ_NUM, NULL);	misc_deregister (&DSP_HPI_misc_device);}module_init(DSP_HPI_Init);module_exit(DSP_HPI_Exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("snowerlist <snower@163.com>");MODULE_DESCRIPTION("Kernel Driver for DSP HPI Interface");

⌨️ 快捷键说明

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