2.字符设备模板

这篇博客介绍了如何在Linux下编写一个简单的驱动程序,包括注册字符设备、分配设备号以及实现open和close函数。同时,博主分享了在Android平台上加载模块的步骤,如insmod、创建设备文件,并提供了测试程序的编译和执行方法。

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

1.驱动代码

#include <linux/module.h>
#include <linux/init.h>
//纯模块

#include <linux/cdev.h>
#include <linux/fs.h>
//字符设备

static dev_t led_num;
static struct cdev led_cdev;
static int status;

static int led_open(struct inode *ip, struct file *fp){
	printk("led_open status:%d\n led_num:%d",status,led_num);
	return 0;  //得返回0
}

static int led_close (struct inode *ip, struct file *fp){
	printk("led_close\n");
	return 0;  
}

static struct file_operations led_fops={
    .owner = THIS_MODULE,
    .open = led_open,
    .release = led_close,
};

static int __init q4_init(void){
    int ret;
    //led_num = MKDEV(239,0);
    status = 0;
    ret = alloc_chrdev_region(&led_num,0,1,"myled");
    //自动分配好,如果手动的话,设备号没搞对会出现
    // can‘t execute: Permission denied
    if(ret < 0){
        printk("register_chrdev_region \n");
		goto dev_number_error;
    }
    printk("major:%d min:%d\n",MAJOR(led_num),MINOR(led_num));

    cdev_init(&led_cdev,&led_fops);
    ret = cdev_add(&led_cdev,led_num,1);
    if(ret < 0){
		printk("cdev_add \n");
		goto err_cdev_add;
	}

    return 0;

err_cdev_add:
    cdev_del(&led_cdev);
dev_number_error:
	unregister_chrdev_region(led_num,1);
    
    return ret;
}

static void __exit q4_exit(void){
    cdev_del(&led_cdev);
    unregister_chrdev_region(led_num,1);
    printk("q4_exit exit\n");
}

module_init(q4_init);

module_exit(q4_exit);

MODULE_AUTHOR("oncethings");
MODULE_DESCRIPTION("q4 module ex");
MODULE_LICENSE("GPL");

注意事项:

1.手动分配设备号的话容易出现:can‘t execute: Permission denied  并不是说没有root权限,而是是设备号重复了。改成自动分配就好了

2.open函数返回0;不然会影响open时得不到fd。

2.安卓驱动

平台安卓 debug版本:

1.把module.ko 放到/data/ 目录。 其他目录可能不可操作。

2.insmod module.ko  如果出现签名问题,就得去安卓源码编辑kernel ,去掉签名认证的选项,才能insmod。

cat /proc/devices 

 cat /proc/modules

(这个是编译成模块在insmod才有,如果直接编译在内核没有)

3. 手动创建设备文件

ps:无论是编译在内核,还是编译成模块都需要手动创建设备文件。当然可以用自动创建函数class_create&device_create,下一章会介绍;重启后依旧得重新手动创建;设备号就看 cat /proc/devices的设备号。

mknod /dev/my_led c 215 0

mknod 设备文件 设备类型 主设备号 次设备号

chmod 777 /dev/my_led

3.测试

test.c:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc,char **argv)
{
	
	//访问myled设备
	printf("oncethings\n");
	int fd_led = open("/dev/my_led",O_RDWR);
	printf("oncethings led_fd:%d\n",fd_led);
	if(fd_led < 0)
	{
		printf("oncethings <0\n");
		perror("open");
		return -1;
	
	}else{
		printf("oncethings success\n");
	}

	printf("oncethings 111111\n");
	//睡眠一会
	sleep(3);
	printf("oncethings 222222222\n");
	
	//关闭myled设备
	close(fd_led);
	
	printf("oncethings 4444444\n");
	return 0;	
}

2.编译  

只用交叉编译链  编译时用静态库  否则执行时可能会出现:No such file or directory

arm-linux-gnueabi-gcc test.c -o test -static

3.推入到data 分区并chmod 777

4.执行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值