硬件平台: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驱动程序,这样可以自动创建和删除设备结点了
- #include
- #include
-
- #include
- #include /*创建设备节点*/
- #include
- #include /*定义DECLARE_WAIT_QUEUE_HEAD*/
- #include /*定义了irqreturn_t等*/
- #include /*request_irq disable_irq enable_irq*/
-
- #include
- #include
- #include /*其中包含了#include "mach/irqs.h" */
-
- #include
- #include
-
- #define ADC_MAJOR 102
- #define ADC_NAME "my_adc"
- #define SUCCESS 0
-
- static int adc_open(struct inode *,struct file *);
- static int adc_release(struct inode *,struct file *);
- static int __init adc_init(void);
- static int __exit adc_exit(void);
- static ssize_t adc_read(struct file *,char *,size_t,loff_t *);
-
- volatile unsigned long adc_con;
- unsigned long adc_dat0;
-
- int flag;
-
- unsigned long buf;
-
-
- DECLARE_WAIT_QUEUE_HEAD(adc_wait);
-
- struct clk *adc_clk;
-
-
- static irqreturn_t adc_interrupt(int irq,void * dev_id)
- {
- if(flag==0)
- {
- buf=(readw(adc_dat0) & 0x3ff );
- flag=1;
- wake_up_interruptible(&adc_wait);
- printk("Read value is %ld\n",buf);
- }
- return IRQ_HANDLED;
- }
-
- static struct file_operations adc_ops =
- {
- .owner = THIS_MODULE,
- .read = adc_read,
- .open = adc_open,
- .release = adc_release,
- };
- static struct miscdevice adc_misc =
- {
- .name = ADC_NAME,
- .minor = ADC_MAJOR,
- .fops = &adc_ops,
- };
- static int __init adc_init(void)
- {
- int ret;
- adc_clk = clk_get(NULL,"adc");
- clk_enable(adc_clk);
-
- ret=misc_register(&adc_misc);
- if(ret<0)
- {
- printk("register device fail\n");
- return ret;
- }
- adc_con=(unsigned long)ioremap(0x58000000,4);
- adc_dat0=(volatile unsigned long)ioremap(0x58000000+S3C2410_ADCDAT0,4);
- if( !(adc_con & adc_dat0) )
- {
- printk("Failed to ioremap\n");
- goto handle;
- }
- printk("Initialized...\n");
- return SUCCESS;
- handle:
- misc_deregister(&adc_misc);
- return -1;
- }
-
- static int adc_open(struct inode * inode,struct file * file)
- {
-
- int ret;
-
-
- ret=request_irq(IRQ_ADC,adc_interrupt,IRQF_SHARED,ADC_NAME,1);
- if(ret<0)
- {
- printk("IRQ %d can not request\n",IRQ_ADC);
- return ret;
- }
- return SUCCESS;
- }
-
- static int adc_release(struct inode * inode,struct file * file)
- {
- free_irq(IRQ_ADC,1);
- return SUCCESS;
- }
-
- static ssize_t adc_read(struct file *file,
- char * buffer,
- size_t length,
- loff_t * offset)
- {
-
- writew((1<<14)|(0x31<<6),adc_con);
- writew((readw(adc_con) | 0x1),adc_con);
- wait_event_interruptible(adc_wait,flag);
- flag=0;
- }
-
- static int __exit adc_exit(void)
- {
- iounmap(adc_con);
- iounmap(adc_dat0);
- misc_deregister(&adc_misc);
- clk_disable(adc_clk);
- clk_put(adc_clk);
- printk("The adc is unintialized\n");
- return SUCCESS;
- }
-
- module_init(adc_init);
- module_exit(adc_exit);
- MODULE_LICENSE("GPL");
阅读(1167) | 评论(0) | 转发(0) |