树莓派驱动开发

为什么要进行驱动开发?

有的平台没有所谓“wiringPi”库,为了驱动引脚需要编写自己的“wiringPi”库

如何找到驱动?

1:文件名

2:设备号: Linux的设备管理是和文件系统紧密结合的,各种设备都以文件的形式存放在/dev目录下,称为设备文件。使用open系列打开。为了管理这些设备,系统为设备编了号

①主设备号:区分不同种类的设备

②次设备号:区分同一类型的多个设备

查看设备号:ls -l 红圈是 主 黄圈是 次

驱动调用或添加步骤参考

 用户进行open时linux进行系统调用的过程:

在这里插入图片描述

 自己总结:用户调用open,open调用sys_call(系统调用),sys_call调用sys_open去打开驱动

open -> sys_call -> sys_open -> 驱动

参考别人的驱动:

#include <linux/fs.h>		 //file_operations声明
#include <linux/module.h>    //module_init  module_exit声明
#include <linux/init.h>      //__init  __exit 宏定义声明
#include <linux/device.h>	 //class  devise声明
#include <linux/uaccess.h>   //copy_from_user 的头文件
#include <linux/types.h>     //设备号  dev_t 类型声明
#include <asm/io.h>          //ioremap iounmap的头文件

static struct class *pin4_class;  
static struct device *pin4_class_dev;

static dev_t devno;                //设备号
static int major = 231;  		   //主设备号
static int minor = 0;			   //次设备号
static char *module_name = "pin4";   //模块名

//led_open函数
static int pin4_open(struct inode *inode,struct file *file)
{
    printk("pin4_open\n");  //内核的打印函数和printf类似
      
    return 0;
}

//led_write函数
static ssize_t pin4_write(struct file *file,const char __user *buf,size_t count, loff_t *ppos)
{
	printk("pin4_write\n");
	
	return 0;
}

static struct file_operations pin4_fops = {
    .owner = THIS_MODULE,
    .open  = pin4_open,
    .write = pin4_write,
};

int __init pin4_drv_init(void)   //真实驱动入口
{
    int ret;
    devno = MKDEV(major, minor);  //创建设备号
    ret   = register_chrdev(major, module_name, &pin4_fops);  //注册驱动  告诉内核,把这个驱动加入到内核驱动的链表中

    pin4_class=class_create(THIS_MODULE, "myfirstdemo");		//用代码在dev自动生成设备
    pin4_class_dev =device_create(pin4_class, NULL, devno, NULL, module_name);  //创建设备文件
    
    return 0;
}

void __exit pin4_drv_exit(void)
{
    device_destroy(pin4_class, devno);
    class_destroy(pin4_class);
    unregister_chrdev(major, module_name);  //卸载驱动

}

module_init(pin4_drv_init);  //入口,内核加载该驱动(insmod)的时候,这个宏被使用
module_exit(pin4_drv_exit);
MODULE_LICENSE("GPL v2");

编译阶段:

1.进入linux-rpi-4.14.y/drivers/char,编辑好文件pin_4.c

2.修改一下Makefile:vi Makefile

 3.回到linux-rpi-4.14.y 编译代码:

ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make modules

4.生成的驱动pin_4发给树莓派:

 

scp /home/lzy/SYSTEM/linux-rpi-4.14.y/drivers/char/pin_4.ko pi@192.168.0.21:/home/pi

5.驱动传到树莓派后,需要加载驱动

加载驱动:sudo insmod hello_drv.ko
驱动卸载:sudo rmmod hello_drv 不需要写ko
查看驱动模块:lsmod

在/dev底下就能看到:

 6.写一个测试程序,编译并运行测试程序

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{       
        int fd;

        fd=open("/dev/my_pin4",O_RDWR);
        if(fd==-1){
                printf("open failed\n");
        }else{
                printf("open success\n");
        }
        
        write(fd,"1",1);
        
        return 0;
}

运行测试程序,一定要加超级用户权限sudo

 在用户态是看不到内核态的东西的使用:dmesg查看:

 总结:

调用流程:我们上层空间的①open去查找dev下的驱动(文件名),文件名背后包含了驱动的主设备号和次设备号,此时用户open触发一个②系统调用(sys_call),系统调用经过③vfs(虚拟文件系统),vfs根据文件名背后的设备号去调用④sys_open去判断,找到内核中驱动链表的驱动位置,再去调用驱动里面自己的⑤dev_open函数

验证步骤:
①装载驱动
②查看驱动装载后是否生成设备
③运行测试程序调试驱动
④内核的printk打印在内核层,通过dmesg查看内核打印信息

 

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值