Chinaunix首页 | 论坛 | 博客
  • 博客访问: 165992
  • 博文数量: 47
  • 博客积分: 1032
  • 博客等级: 少尉
  • 技术积分: 759
  • 用 户 组: 普通用户
  • 注册时间: 2011-01-19 15:47
文章分类
文章存档

2012年(26)

2011年(21)

分类: 嵌入式

2011-12-13 14:55:51

硬件平台:FL2440

内核版本:2.6.28

主机平台:Ubuntu 11.04

内核版本:2.6.39

原创作品,转载请标明出处http://blog.csdn.net/yming0221/archive/2011/06/27/6570072.aspx 

1、首先配置busybox

busybox
Linux System Utilities --->
    [*] mdev
    [*] Support /etc/mdev.conf
    [*] Support command execution at device addition/removal

2、配置内核

3、修改文件系统里的/etc/init.d/rcS

#!/bin/sh
/bin/mount -a
/sbin/ifconfig eth0 192.168.0.3 up
#exec /usr/etc/rc.mouse

4、修改文件系统中/linuxrc文件

#!/bin/sh
#echo "mount /etc as ramfs"
#/bin/mount -n -t ramfs ramfs /etc
#/bin/cp -a /mnt/etc/* /etc

#/bin/mount -n -t ramfs ramfs /var/state/dhcp
#/bin/mount -n -t ramfs ramfs /var/log/boa
#/bin/mount -n -t ramfs ramfs /usr/Setting
#/bin/cp -a /mnt/Setting/* /usr/Setting

#/bin/mount -n -t ramfs ramfs /tmp
#/bin/cp -a /mnt/etc/* /etc

/bin/mount -t proc proc /proc
/bin/mount -t sysfs sysfs /sys
/bin/mount -t tmpfs tmpfs /dev
mkdir /dev/pts
mkdir /dev/shm

/bin/echo /sbin/mdev > /proc/sys/kernel/hotplug
/sbin/mdev -s

exec /sbin/init

4、修改/etcfstab

vi ./etc/fstab
#device mount-point type     options     dump     fsck order
none            /dev/pts        devpts  mode=0622       0 0
tmpfs           /dev/shm        tmpfs   defaults        0 0

这样编写驱动时不用手动创建设备结点文件了

下面是改写的使用混杂设备的ADC驱动程序,这样可以自动创建和删除设备结点了

  1. #include    
  2. #include    
  3.   
  4. #include    
  5. #include  /*创建设备节点*/   
  6. #include    
  7. #include  /*定义DECLARE_WAIT_QUEUE_HEAD*/   
  8. #include  /*定义了irqreturn_t等*/   
  9. #include  /*request_irq disable_irq enable_irq*/   
  10.   
  11. #include    
  12. #include    
  13. #include   /*其中包含了#include "mach/irqs.h" */   
  14.   
  15. #include    
  16. #include    
  17.   
  18. #define ADC_MAJOR 102   
  19. #define ADC_NAME "my_adc"   
  20. #define SUCCESS 0   
  21.   
  22. static int adc_open(struct inode *,struct file *);  
  23. static int adc_release(struct inode *,struct file *);  
  24. static int __init adc_init(void);  
  25. static int __exit adc_exit(void);  
  26. static ssize_t adc_read(struct file *,char *,size_t,loff_t *);  
  27.   
  28. volatile unsigned long adc_con;  
  29. unsigned long adc_dat0;  
  30.   
  31. int flag;//等待任务完成标志   
  32.   
  33. unsigned long buf;//存放转换完成的数据   
  34.   
  35. //声明等待队列   
  36. DECLARE_WAIT_QUEUE_HEAD(adc_wait);  
  37.   
  38. struct clk *adc_clk;   
  39.   
  40.   
  41. static irqreturn_t adc_interrupt(int irq,void * dev_id)//中断处理程序   
  42. {  
  43.     if(flag==0)  
  44.     {  
  45.         buf=(readw(adc_dat0) & 0x3ff );//读取转换完成的数据   
  46.         flag=1;  
  47.         wake_up_interruptible(&adc_wait);//唤醒等待其上的进程   
  48.         printk("Read value is %ld\n",buf);  
  49.     }  
  50.     return IRQ_HANDLED;  
  51. }  
  52.   
  53. static struct file_operations  adc_ops =  
  54. {  
  55.     .owner  =   THIS_MODULE,  
  56.     .read       =   adc_read,  
  57.     .open   =   adc_open,  
  58.     .release    =   adc_release,  
  59. };  
  60. static struct miscdevice adc_misc =   
  61. {  
  62.     .name = ADC_NAME,  
  63.     .minor = ADC_MAJOR,  
  64.     .fops = &adc_ops,  
  65. };  
  66. static int __init adc_init(void)  
  67. {  
  68.     int ret;  
  69.     adc_clk = clk_get(NULL,"adc");//获取时钟   
  70.     clk_enable(adc_clk);//使能时钟   
  71.       
  72.     ret=misc_register(&adc_misc); //注册设备   
  73.     if(ret<0)  
  74.     {  
  75.         printk("register device fail\n");  
  76.         return ret;  
  77.     }  
  78.     adc_con=(unsigned long)ioremap(0x58000000,4);  
  79.     adc_dat0=(volatile unsigned long)ioremap(0x58000000+S3C2410_ADCDAT0,4);  
  80.     if( !(adc_con & adc_dat0) )  
  81.     {  
  82.         printk("Failed to ioremap\n");  
  83.         goto handle;  
  84.     }  
  85.     printk("Initialized...\n");  
  86.     return SUCCESS;  
  87. handle:  
  88.     misc_deregister(&adc_misc);  
  89.     return -1;  
  90. }  
  91.   
  92. static int adc_open(struct inode * inode,struct file * file) //打开设备函数   
  93. {  
  94.     //注册中断   
  95.     int ret;  
  96.     //disable_irq(IRQ_ADC);   
  97.     //enable_irq(IRQ_ADC);   
  98.     ret=request_irq(IRQ_ADC,adc_interrupt,IRQF_SHARED,ADC_NAME,1);//注册中断 IRQ_ADC在 mach/irqs.h中定义   
  99.     if(ret<0)  
  100.     {  
  101.         printk("IRQ %d can not request\n",IRQ_ADC);  
  102.         return ret;  
  103.     }  
  104.     return SUCCESS;  
  105. }  
  106.   
  107. static int adc_release(struct inode * inode,struct file * file) //关闭设备函数   
  108. {  
  109.     free_irq(IRQ_ADC,1);//释放中断   
  110.     return SUCCESS;  
  111. }  
  112.   
  113. static ssize_t adc_read(struct file *file,  
  114.                             char * buffer,  
  115.                             size_t length,  
  116.                             loff_t * offset)//设备读取函数   
  117. {  
  118.       
  119.     writew((1<<14)|(0x31<<6),adc_con);       //设置ADCCON   
  120.     writew((readw(adc_con) | 0x1),adc_con);  //启动AD转换   
  121.     wait_event_interruptible(adc_wait,flag);  
  122.     flag=0;  
  123. }  
  124.   
  125. static int __exit adc_exit(void//驱动卸载函数   
  126. {  
  127.     iounmap(adc_con);  
  128.     iounmap(adc_dat0);  
  129.     misc_deregister(&adc_misc);  
  130.     clk_disable(adc_clk);  
  131.     clk_put(adc_clk);  
  132.     printk("The adc is unintialized\n");  
  133.     return SUCCESS;  
  134. }  
  135.   
  136. module_init(adc_init);           
  137. module_exit(adc_exit);  
  138. MODULE_LICENSE("GPL");  
阅读(1164) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~