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

📄 led2410.c

📁 一个在linux下的驱动程序的例子
💻 C
字号:
//#define MODULE
#include <linux/kernel.h>
#include <linux/module.h>

#include <asm/uaccess.h>


#include <linux/mm.h>
#include <linux/ioport.h>

#include <asm/io.h>
#include <linux/ioport.h>


#include <linux/fs.h>
#include <linux/wrapper.h>


#define DRAM_MEM_MAJOR 102
#define DEVICE_NAME  "io_pb"
#define SUCCESS   0
/*
#define LLSB(x)  ((x)&0xff)
#define LNLSB(x) (((x)>>8) & 0xff)
#define LNMSB(x) (((x)>>16) & 0xff)
#define LMSB(x)  (((x)>>24)&0xff)
#define LONGSWAP(x) ((LLSB(x)<<24) | (LNLSB(x) <<16) | (LNMSB(x) <<8)|(LMSB(x)))
*/

static int Device_Open = 0;

int io_pb_init(void);
static int device_open(struct inode *,struct file *);
static int device_release(struct inode *,struct file *);
static ssize_t device_read(struct file *,char *,size_t,loff_t *);
static ssize_t device_write(struct file *,const char *,size_t,loff_t *);
static loff_t device_seek(struct file *,loff_t,int);
int init_module(void);
void cleanup_module(void);


struct file_operations  io_pb_ops =
{
      llseek:    device_seek,
      read:      device_read,
      write:     device_write,
      open:      device_open,
      release:   device_release
};

static int Major;

unsigned long gpf_con,gpf_dat,gpf_up,gpg_con,gpg_dat,gpg_up;

int io_pb_init(void)
{
/*X_up:使能;x_con:控制输入输出00:input,01:output;X_dat:数据,初始为全亮;*/
     gpf_up= (unsigned long)ioremap((unsigned long)0x56000058,4);
    *(unsigned long *)gpf_up &= 0xffffff1f;
    gpg_up= (unsigned long)ioremap((unsigned long)0x56000068,4);
    *(unsigned long *)gpg_up &= 0xfffffffe;  
    
   gpf_con = (unsigned long)ioremap((unsigned long)0x56000050,4);
    *(unsigned long *)gpf_con &= 0xffff03ff;
    *(unsigned long *)gpf_con |= 0x5400;//将10-15位置为010101 
   gpg_con = (unsigned long)ioremap((unsigned long)0x56000060,4);
    *(unsigned long *)gpg_con &= 0xfffffffc;
    *(unsigned long *)gpg_con |= 0x01;//将0-1位置为01LED=OUTPUP

   gpf_dat= (unsigned long)ioremap((unsigned long)0x56000054,4);
    *(unsigned long *)gpf_dat &= 0xffffff1f;
    gpg_dat= (unsigned long)ioremap((unsigned long)0x56000064,4);
    *(unsigned long *)gpg_dat &= 0xfffffffe;   

 
    
    

    Major = register_chrdev(DRAM_MEM_MAJOR,DEVICE_NAME,&io_pb_ops);

    if(Major <0)
    {
        iounmap((void *)gpf_con);
        iounmap((void *)gpf_dat);
        iounmap((void *)gpf_up);
        iounmap((void *)gpg_con);
        iounmap((void *)gpg_dat);
        iounmap((void *)gpg_up);        
        printk("DRAM_MEM init_module:failed with %d\n",Major);
        return Major;
    }
    Major = DRAM_MEM_MAJOR;
    printk("DRAM_MEM_MAJOR registred: Major = %d\n",Major);
    return 0;
}

static int device_open(struct inode * inode,struct file *file)
{
    if(Device_Open)
    {
        return -EBUSY;
    }
    Device_Open++;
    MOD_INC_USE_COUNT;
    return SUCCESS;
}

static int device_release(struct inode * inode,struct file *file)
{
    Device_Open --;
    MOD_DEC_USE_COUNT;

    return 0;
}

static ssize_t device_read(struct file *file,
                            char * buffer,
                            size_t length,
                            loff_t * offset)
{
    unsigned char num,num1;
    unsigned long len;
    return(len);

}

static ssize_t device_write(struct file *file,
                            const char * buffer,
                            size_t  length,
                            loff_t * offset)
{

	struct gpf{
		unsigned long        :5;//跳过前5位;
		unsigned long led1:1;
		unsigned long led2:1;
		unsigned long led3:1;
	}*led1_3;
	struct gpg{
		unsigned long int led4:1;
	}*led_4;
	
	led1_3=(struct gpf *)gpf_dat;
	led_4=(struct gpg *)gpg_dat;

	led1_3->led1=(*buffer)&1;
	led1_3->led2=((*buffer)>>1)&1;
	led1_3->led3=((*buffer)>>2)&1;
	led_4->led4=((*buffer)>>3)&1;
    //volatile unsigned int intx;
    //unsigned long len;
    //unsigned long * address = (unsigned long *)virt_addr0;
    //unsigned long * address1 = (unsigned long *)virt_addr1;
    //len = 0;
    // *gpf_dat=(*buffer)<<10;
    //*gpg_dat=(*buffer)>>6
    
    
        
     
    
   return 0;
}

static loff_t device_seek(struct file *filp,loff_t off,int whence)
{
    loff_t newpos;
    switch(whence)
    {
    case 0:
        newpos = off;
        break;
    case 1:
        newpos = filp->f_pos +off;
        break;
    case 2:
        return -EINVAL;
        break;
    default:
        return -EINVAL;
    }
    
    if((unsigned long)newpos <0) return -EINVAL;
    filp->f_pos = newpos;
    return newpos;

}
#ifdef  MODULE
int init_module()
{

    return io_pb_init();
}

void cleanup_module()
{
    int ret;
        iounmap((void *)gpf_con);
        iounmap((void *)gpf_dat);
        iounmap((void *)gpf_up);
        iounmap((void *)gpg_con);
        iounmap((void *)gpg_dat);
        iounmap((void *)gpg_up);  
    
    ret = unregister_chrdev(Major,DEVICE_NAME);
    if(ret < 0)
    {
        printk("unregister_chrdev:error %d\n",ret);
    }  
}
#endif

⌨️ 快捷键说明

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