Compile app program :
root@chaozang:/xxx/2012-12-07chaozang_drv1# arm-linux-gcc -o chaozang_drv1_test chaozang_drv1_test.c
----------------------app part-------------------------
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
//chaozang_drv1_test on
//chaozang_drv1_test off
#include <stdio.h>
//chaozang_drv1_test on
//chaozang_drv1_test off
int main(int argc,char ** argv)
{
int fd;
int val = 1;
fd = open("/dev/chaozang_drv1", O_RDWR);
if( fd < 1)
{
printf("fd < 1,can`t open");
}
if (argc != 2)
{
printf("Usage :\n");
printf("%s <on|off>\n", argv[0]);
return 0;
}
if(strcmp(argv[1],"on") == 0)
{
val =1;
}
else
{
val =0;
}
write(fd,&val,4);
return 0;
}
------------------------------------commands-------------------------------------------
# ls
Makefile chaozang_drv1.ko chaozang_drv1.o
Module.symvers chaozang_drv1.mod.c chaozang_drv1_test.c
chaozang_drv1.c chaozang_drv1.mod.o
Makefile chaozang_drv1.ko chaozang_drv1.o
Module.symvers chaozang_drv1.mod.c chaozang_drv1_test.c
chaozang_drv1.c chaozang_drv1.mod.o
# cat /proc/
/proc/1/ /proc/cmdline /proc/misc
/proc/2/ /proc/cpu/ /proc/modules
/proc/3/ /proc/cpuinfo /proc/mounts
/proc/4/ /proc/devices /proc/mtd
/proc/43/ /proc/diskstats /proc/net/
/proc/44/ /proc/driver/ /proc/partitions
/proc/47/ /proc/execdomains /proc/self/
/proc/49/ /proc/fb /proc/slabinfo
/proc/5/ /proc/filesystems /proc/stat
/proc/6/ /proc/fs/ /proc/swaps
/proc/61/ /proc/ide/ /proc/sys/
/proc/62/ /proc/interrupts /proc/sysrq-trigger
/proc/63/ /proc/iomem /proc/sysvipc/
/proc/64/ /proc/ioports /proc/timer_list
/proc/695/ /proc/irq/ /proc/tty/
/proc/718/ /proc/kallsyms /proc/uptime
/proc/735/ /proc/kmsg /proc/version
/proc/738/ /proc/loadavg /proc/vmstat
/proc/buddyinfo /proc/locks /proc/yaffs
/proc/bus/ /proc/meminfo /proc/zoneinfo
# cat /proc/devices
Character devices:
1 mem
2 pty
3 ttyp
4 /dev/vc/0
4 tty
4 ttyS
5 /dev/tty
5 /dev/console
5 /dev/ptmx
6 lp
7 vcs
10 misc
13 input
29 fb
90 mtd
99 ppdev
128 ptm
136 pts
180 usb
189 usb_device
204 s3c2410_serial
253 usb_endpoint
254 rtc
1 mem
2 pty
3 ttyp
4 /dev/vc/0
4 tty
4 ttyS
5 /dev/tty
5 /dev/console
5 /dev/ptmx
6 lp
7 vcs
10 misc
13 input
29 fb
90 mtd
99 ppdev
128 ptm
136 pts
180 usb
189 usb_device
204 s3c2410_serial
253 usb_endpoint
254 rtc
Block devices:
1 ramdisk
7 loop
31 mtdblock
1 ramdisk
7 loop
31 mtdblock
# insmod chaozang_drv1.ko
# cat /proc/devices
Character devices:
1 mem
2 pty
3 ttyp
4 /dev/vc/0
4 tty
4 ttyS
5 /dev/tty
5 /dev/console
5 /dev/ptmx
6 lp
7 vcs
10 misc
13 input
29 fb
90 mtd
99 ppdev
128 ptm
136 pts
180 usb
189 usb_device
204 s3c2410_serial
252 chaozang_drv1
253 usb_endpoint
254 rtc
Block devices:
1 ramdisk
7 loop
31 mtdblock
1 ramdisk
7 loop
31 mtdblock
# cd /dev
# ls
chaozang_drv1 ptys3 tty20 ttyq9
console ptys4 tty21 ttyqa
fb0 ptys5 tty22 ttyqb
full ptys6 tty23 ttyqc
kmem ptys7 tty24 ttyqd
kmsg ptys8 tty25 ttyqe
loop0 ptys9 tty26 ttyqf
loop1 ptysa tty27 ttyr0
loop2 ptysb tty28 ttyr1
loop3 ptysc tty29 ttyr2
loop4 ptysd tty3 ttyr3
loop5 ptyse tty30 ttyr4
loop6 ptysf tty31 ttyr5
loop7 ptyt0 tty32 ttyr6
mem ptyt1 tty33 ttyr7
mice ptyt2 tty34 ttyr8
mtd0 ptyt3 tty35 ttyr9
mtd0ro ptyt4 tty36 ttyra
mtd1 ptyt5 tty37 ttyrb
mtd1ro ptyt6 tty38 ttyrc
mtd2 ptyt7 tty39 ttyrd
mtd2ro ptyt8 tty4 ttyre
# ls
chaozang_drv1 ptys3 tty20 ttyq9
console ptys4 tty21 ttyqa
fb0 ptys5 tty22 ttyqb
full ptys6 tty23 ttyqc
kmem ptys7 tty24 ttyqd
kmsg ptys8 tty25 ttyqe
loop0 ptys9 tty26 ttyqf
loop1 ptysa tty27 ttyr0
loop2 ptysb tty28 ttyr1
loop3 ptysc tty29 ttyr2
loop4 ptysd tty3 ttyr3
loop5 ptyse tty30 ttyr4
loop6 ptysf tty31 ttyr5
loop7 ptyt0 tty32 ttyr6
mem ptyt1 tty33 ttyr7
mice ptyt2 tty34 ttyr8
mtd0 ptyt3 tty35 ttyr9
mtd0ro ptyt4 tty36 ttyra
mtd1 ptyt5 tty37 ttyrb
mtd1ro ptyt6 tty38 ttyrc
mtd2 ptyt7 tty39 ttyrd
mtd2ro ptyt8 tty4 ttyre
---------------------------------------------------------------
// #mknod /dev/chaozang_drv1 c 252 0
# ./chaozang_drv1_test on
chaozang_drv1_open
chaozang_drv1_write
# ./chaozang_drv1_test off
chaozang_drv1_open
chaozang_drv1_write
chaozang_drv1_open
chaozang_drv1_write
# ./chaozang_drv1_test off
chaozang_drv1_open
chaozang_drv1_write
---------------------------------------------------------------
# cd /sys/
/sys/block/ /sys/class/ /sys/firmware/ /sys/kernel/ /sys/power/
/sys/bus/ /sys/devices/ /sys/fs/ /sys/module/
/sys/block/ /sys/class/ /sys/firmware/ /sys/kernel/ /sys/power/
/sys/bus/ /sys/devices/ /sys/fs/ /sys/module/
# cd /sys/class/
/sys/class/chaozang_drv1/ /sys/class/printer/
/sys/class/graphics/ /sys/class/rtc/
/sys/class/hwmon/ /sys/class/spi_master/
/sys/class/i2c-adapter/ /sys/class/tty/
/sys/class/input/ /sys/class/usb_device/
/sys/class/mem/ /sys/class/usb_endpoint/
/sys/class/misc/ /sys/class/usb_host/
# cd /sys/class/
# ls
chaozang_drv1 input net spi_master usb_host
graphics mem ppdev tty vc
hwmon misc printer usb_device vtconsole
i2c-adapter mtd rtc usb_endpoint
# cd chaozang_drv1/
# ls
chaozang_drv1
# cd chaozang_drv1/
# ls
dev subsystem uevent
# ls -l
-r--r--r-- 1 0 0 4096 Jan 1 00:04 dev
lrwxrwxrwx 1 0 0 0 Jan 1 00:40 subsystem -> ../../../class/chaozang_drv1
--w------- 1 0 0 4096 Jan 1 00:40 uevent
# cat dev
252:0
--------------------------------driver part---------------------------------------
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/arch/regs-gpio.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/arch/regs-gpio.h>
#include <asm/hardware.h>
volatile unsigned long *gpbcon = NULL;
volatile unsigned long *gpbdat = NULL;
volatile unsigned long *gpbdat = NULL;
static int chaozang_drv1_open(struct inode *inode, struct file *file)
{
printk("chaozang_drv1_open\n");
*gpbcon &= ~((0x3<<(5*2)) | (0x3<<(6*2)) | (0x3<<(7*2)) | (0x3<<(8*2)));
*gpbcon |= ((0x1<<(5*2)) | (0x1<<(6*2)) | (0x1<<(7*2)) | (0x1<<(8*2)));
return 0;
}
{
printk("chaozang_drv1_open\n");
*gpbcon &= ~((0x3<<(5*2)) | (0x3<<(6*2)) | (0x3<<(7*2)) | (0x3<<(8*2)));
*gpbcon |= ((0x1<<(5*2)) | (0x1<<(6*2)) | (0x1<<(7*2)) | (0x1<<(8*2)));
return 0;
}
static ssize_t chaozang_drv1_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
printk("chaozang_drv1_write\n");
int val;
copy_from_user(&val, buf, count);
if( val == 1 )
{
// light on
*gpbdat &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8));
}
else
{
// light off
*gpbdat |= (1<<5) | (1<<6) | (1<<7) | (1<<8);
}
return 0;
}
{
printk("chaozang_drv1_write\n");
int val;
copy_from_user(&val, buf, count);
if( val == 1 )
{
// light on
*gpbdat &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8));
}
else
{
// light off
*gpbdat |= (1<<5) | (1<<6) | (1<<7) | (1<<8);
}
return 0;
}
static struct file_operations chaozang_drv1_fops = {
.owner = THIS_MODULE,
.open = chaozang_drv1_open,
.write = chaozang_drv1_write,
};
.owner = THIS_MODULE,
.open = chaozang_drv1_open,
.write = chaozang_drv1_write,
};
int major;
static struct class *chaozang_drv1_class;
static struct class_device *chaozang_drv1_class_dev;
static struct class *chaozang_drv1_class;
static struct class_device *chaozang_drv1_class_dev;
static int chaozang_drv1_init(void)
{
printk("chaozang_drv1_init\n");
major = register_chrdev(0,"chaozang_drv1",&chaozang_drv1_fops);
chaozang_drv1_class = class_create(THIS_MODULE, "chaozang_drv1");
chaozang_drv1_class_dev = class_device_create(chaozang_drv1_class, NULL, MKDEV (major,0),NULL,"chaozang_drv1");
gpbcon = (volatile unsigned long *)ioremap(0x56000010,16);
gpbdat = gpbcon +1;
return 0;
}
{
printk("chaozang_drv1_init\n");
major = register_chrdev(0,"chaozang_drv1",&chaozang_drv1_fops);
chaozang_drv1_class = class_create(THIS_MODULE, "chaozang_drv1");
chaozang_drv1_class_dev = class_device_create(chaozang_drv1_class, NULL, MKDEV (major,0),NULL,"chaozang_drv1");
gpbcon = (volatile unsigned long *)ioremap(0x56000010,16);
gpbdat = gpbcon +1;
return 0;
}
static void chaozang_drv1_exit(void)
{
printk("chaozang_drv1_exit\n");
unregister_chrdev(major,"chaozang_drv1");
class_device_unregister(chaozang_drv1_class_dev);
class_destroy(chaozang_drv1_class);
iounmap(gpbcon);
}
{
printk("chaozang_drv1_exit\n");
unregister_chrdev(major,"chaozang_drv1");
class_device_unregister(chaozang_drv1_class_dev);
class_destroy(chaozang_drv1_class);
iounmap(gpbcon);
}
module_init(chaozang_drv1_init);
module_exit(chaozang_drv1_exit);
module_exit(chaozang_drv1_exit);
MODULE_AUTHOR("chaozang, copy from weidongshan");
MODULE_VERSION("0.1.0");
MODULE_DESCRIPTION("linux char device driver skeleton");
MODULE_LICENSE("GPL");
---------------------------------------Makefile-----------------------------------------
Makefile:
KERN_DIR = /xxx/linux-2.6.25.8
all:
make -C $(KERN_DIR) M=`pwd` modules
clean:
make -C $(KERN_DIR) M=`pwd` modules clean
rm -rf modules.order
obj-m +=chaozang_drv1.o
make -C $(KERN_DIR) M=`pwd` modules
clean:
make -C $(KERN_DIR) M=`pwd` modules clean
rm -rf modules.order
obj-m +=chaozang_drv1.o
--------------------------------------filesystem configuration----------------------------------
# cat /etc/
/etc/fstab /etc/init.d/ /etc/inittab
/etc/fstab /etc/init.d/ /etc/inittab
# cat /etc/init.d/rcS
#mount -t proc none /proc
mount -a
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
#
#mount -t proc none /proc
mount -a
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
#
--------------------------------
Contact:
zangchao.cn@gmail.com