Chinaunix首页 | 论坛 | 博客
  • 博客访问: 308822
  • 博文数量: 59
  • 博客积分: 1410
  • 博客等级: 上尉
  • 技术积分: 570
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-21 09:31
文章分类

全部博文(59)

文章存档

2011年(1)

2009年(58)

我的朋友

分类: LINUX

2009-04-06 19:28:17

    把字符设备驱动看了个大概,就把板子上的数码管驱动给完成了,一开始驱动的时候没有考虑到延时,数码管点亮的效果总是有问题,加了延时就好了。
下面贴出源码,希望对初学者有帮助。
#include   //必须包含
#include   //必须包含
#include //return -XXXXXX
#include //printk
#include // 版本控制
#include   //包含很多API
#include     //文件操作
//#include   //struct cdev 这是2.6的产物
#include //这里包含了内核空间与用户空间进行数据交换时的函数宏
#include      //I/O访问
#include
#include
#include
#include
#include
#include

MODULE_LICENSE("GPL");

#define DEVICE_NAME  "8lcd"
#define NUM1   0x01
#define NUM2   0x02
#define NUM3   0x03
#define NUM4   0x04
#define NUM5   0x06
//#define SEG_CS1    0x10200000  //A22,a21,a20 = 010->ledcs1
#define SEG_CS2    0x10300000  //a22,a21,a20 = 011->ledcs2
#define SEG_CS3    0x10400000  //            = 100->ledcs3



//unsigned long *cs1_address;
unsigned long *cs2_address;
unsigned long *cs3_address;





    
static int Emdoor_8Seg_open(struct inode *inode,struct file *filp)
{
    
    
    
     MOD_INC_USE_COUNT; //current module counter add 1;
     return 0;
    
}

static ssize_t Emdoor_8Seg_write(struct file *file,const char *buffer,size_t count,loff_t *ppos)
{
   

   
     return 0;
    
}

static int Emdoor_8Seg_ioctl(struct inode *ip,struct file *fp,unsigned int cmd,
                 unsigned long arg)
{
     int i;

     int  cmd_low;
     int  cmd_high;
    
     cmd_low = cmd & 0x0000ffff;
     cmd_high= cmd & (0xffff0000) >>16;
    
     writew(cmd_low,cs2_address);
     for(i = 0; i< 10000;i++);
     writew(cmd_high,cs3_address);
     for(i =0 ;i< 10000;i++);
    
     /*
     switch(cmd)
     {
     case NUM1:
        writew(0x7979,cs2_address);
         for(i = 0; i<10000;i++);
        writew(0x7979,cs3_address);
         for(i = 0; i<10000;i++);
        break;
     case NUM2:
       writew(0x2424,cs2_address);
 for(i = 0; i<10000;i++);
       writew(0x2424,cs3_address);
 for(i = 0; i<10000;i++);
       break;
     case NUM3:
       writew(0x3030,cs2_address);
        for(i = 0; i<10000;i++);
       writew(0x3030,cs3_address);
        for(i = 0; i<10000;i++);
       break;
     case NUM4:
       writew(0x1919,cs2_address);
        for(i = 0; i<10000;i++);
       writew(0x1919,cs3_address);
        for(i = 0; i<10000;i++);
        break;
     case NUM5:
       writew(0x1212,cs2_address);
        for(i = 0; i<10000;i++);
       writew(0x1212,cs3_address);
 for(i = 0; i<10000;i++);
        break;
     default:
      return -EINVAL;
     
       
     }
    
     */
    
  
     return 0;
    
    
}

static int Emdoor_8Seg_release(struct inode *inode,struct file *filp)
{
     kfree(filp->private_data);
     MOD_DEC_USE_COUNT; //current module counter substract 1
     return 0;
    
    
}

static struct file_operations Emdoor_fops={

open:   Emdoor_8Seg_open,            //open operation function
write:  Emdoor_8Seg_write,
release: Emdoor_8Seg_release,
ioctl:  Emdoor_8Seg_ioctl,

owner: THIS_MODULE,

};


    
static int __init Emdoor_8Seg_init(void)
{
     int ret;
     int i = 0;
    
     //    cs1_address = ioremap(SEG_CS1,32); //distribute IO memory map address
      cs2_address = ioremap(SEG_CS2,4); 
      cs3_address = ioremap(SEG_CS3,4); 
   
     
     ret = register_chrdev(61,DEVICE_NAME,&Emdoor_fops);
     if(ret<0)
     {
      printk(DEVICE_NAME "can't get major number\n");
      return ret;
     
     }
     //驱动加载时候初始化全部显示1
     writew(0x7979,cs2_address);
     for(i = 0; i<10000;i++);
    
     writew(0x7979,cs3_address);
    
      for(i = 0; i< 10000;i++);
     
    
     return 0;
    
}


static void __exit Emdoor_8Seg_exit(void)
{
     //  iounmap(cs1_address);
      iounmap(cs2_address);
      iounmap(cs3_address);
    
     unregister_chrdev(61,DEVICE_NAME);//unregister device
}


module_init(Emdoor_8Seg_init);
module_exit(Emdoor_8Seg_exit);


没有什么好说的,实践才是硬道理,下一步驱动按键键盘,。加以!
阅读(1328) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2009-09-11 10:58:18

能不能也写个测试程序呢,我也正在做这个,有点不明白,谢谢~~