字符设备驱动

本文介绍了一个名为 BBU 的 Linux 驱动模块的实现细节,包括其源码结构、文件操作函数 bbu_read 的具体实现,以及如何通过 makefile 构建和加载该模块。此外还提供了模块加载脚本和应用层测试程序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

驱动源码:

#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;
}



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值