驱动源码:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/errno.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/system.h>
typedef unsigned int uint32;
ssize_t bbu_read(struct file *filp, char __user *buf, size_t len, loff_t *off)
{
uint32 g_value=0;
ssize_t n=0;
g_value = inl_p(0x50c);
if (((g_value >> 8) & 0x1) == 1) {
n=0;
if(copy_to_user(buf,&n,sizeof(n))){
printk(KERN_INFO"bbu-----copy_to_user func error !");
return -EFAULT;
}//flag=0;bbu start to discharge
}
else {
n=1;
if(copy_to_user(buf,&n,sizeof(n))){
printk(KERN_INFO"bbu-----copy_to_user func error !");
return -EFAULT;
}//flag=1; bbu state is charge
}
return sizeof(n);
}
struct file_operations bbu_fops = {
.owner = THIS_MODULE,
.read = bbu_read,
};
struct cdev bbu_cdev;
int bbu_major;
dev_t dev = 0;
static int __init BBU_init(void)
{
int result;
uint32 g_value;
printk(KERN_INFO"insmod the uitbbu module!\n");
result = alloc_chrdev_region(&dev, 0, 1,"uitbbu");
bbu_major = MAJOR(dev);
if (result < 0) {
printk(KERN_INFO"bbu: can't get major %d \n", bbu_major);
return result;
}
printk(KERN_INFO"cdev register is ok! devno=%d, major=%d \n", dev,bbu_major);
cdev_init(&bbu_cdev,&bbu_fops);
bbu_cdev.owner = THIS_MODULE;
//bbu_cdev.ops=&bbu_fops;
result = cdev_add (&bbu_cdev, dev, 1);
if (result){
printk (KERN_INFO"Error %d adding uitbbu %d ! \n", result,dev);
return 0;
}
//class_create() ;创见一个CALSS
//device_create();自动创见设备 //有了这以后就不需要后面的makefile 既 mknod
printk("=========cdev add success! %d \n", result);
g_value = inl_p(0x504);
g_value =g_value&( ~(1 << 31));
outl_p(g_value, 0x504);
g_value = inl_p(0x50c);
g_value =g_value&( ~(1 << 31));
outl_p(g_value, 0x50c);
return 0;
}
static void __exit BBU_exit(void)
{
printk(KERN_INFO"=======rmmod uitbbu module! \n");
cdev_del(&bbu_cdev);
unregister_chrdev_region(dev,1);
return ;
}
module_init(BBU_init);
module_exit(BBU_exit);
MODULE_LICENSE("GPL");
Makefile脚本:
ifneq ($(KERNELRELEASE), )
obj-m := bbu.o
else
KDIR :=/lib/modules/2.6.32/build
PWD :=$(shell pwd)
default:
$(MAKE) -C $(KDIR) M=$(PWD) modules
endif
clean:
rm -rf *.o *.mod.c *.order *.symvers .* *.ko.unsigned
模块加载脚本:
#!/bin/sh
module="uitbbu"
mode="664"
/sbin/insmod /home/bbu/bbu.ko ||exit 1
rm -f /dev/$module
major=$(awk "\$2==\"$module\"{print \$1}" /proc/devices)
mknod /dev/$module c $major 0
chmod $mode /dev/$module
应用层测试程序:
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
int fd, num;
ssize_t n,m;
fd=open("/dev/uitbbu", O_RDONLY);
if(fd!=-1){
for(num=0; num<100; num++)
{
m=read(fd, &n, sizeof(ssize_t));
printf("m=%d ;The var is %d\n",m,n);
}
close(fd);
}else{
printf("Device open failure\n");
}
return 0;
}