字符设备驱动

来源:互联网 发布:复旦大学梁永安知乎 编辑:程序博客网 时间:2024/05/17 23:19

驱动源码:

#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 既 mknodprintk("=========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;}