首页 > 其他分享 >九鼎RK3399笔记三:测试迅为电子的杂项设备驱动

九鼎RK3399笔记三:测试迅为电子的杂项设备驱动

时间:2022-10-20 09:36:59浏览次数:68  
标签:struct int misc RK3399 file 迅为 杂项 设备

Linux三大设备驱动

字符设备:IO的传输过程是以字符为单位的,没有缓冲。比如I2C,SPI都是字符设备。
块设备:IO的传输过程是以块为单位的。跟存储相关的,都属于块设备,比如TF卡。
网络设备:与前两个不一样,是以socket套接字来访问的。

杂项设备(misc device)

1、 本小节讲述的杂项设备是属于字符设备的一种。可以自动生成设备节点。
  我们的系统中有许多杂项设备,可以输入cat /proc/misc来查看。
image

2、杂项设备除了比字符设备代码简单,还有什么区别?
  杂项设备的主设备号是相同的,均为10,次设备号是不同的。主设备号相同就可以节省内核的资源。

3、主设备号和次设备号是什么?
  设备号包括主设备号和次设备号,主设备号在Linux系统里是唯一的,次设备号不一定唯一。
  设备号是计算机识别设备的一种方式,主设备号相同的就被视作为同一类设备。
  主设备号可以比作成电话号码的区号,比如北京的区号是010.
  次设备号可以比作电话号码。
  主设备号可以通过命令cat /proc/devices来查看。
image

4、杂项设备的描述
定义在内核源码路径:include/linux/miscdevice.h

struct miscdevice  {
    int minor;//次设备号
    const char *name;//设备节点名字
    const struct file_operations *fops;//文件操作集
    struct list_head list;
    struct device *parent;
    struct device *this_device;
    const char *nodename;
    mode_t mode;
};

include/linux/fs.h讲述了文件操作集的结构体file_operations定义

struct file_operations {
    struct module *owner;
    loff_t (*llseek) (struct file *, loff_t, int);
    ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
    ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
    ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
    ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
    int (*readdir) (struct file *, void *, filldir_t);
    unsigned int (*poll) (struct file *, struct poll_table_struct *);
    long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
    long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
    int (*mmap) (struct file *, struct vm_area_struct *);
    int (*open) (struct inode *, struct file *);
    int (*flush) (struct file *, fl_owner_t id);
    int (*release) (struct inode *, struct file *);
    int (*fsync) (struct file *, loff_t, loff_t, int datasync);
    int (*aio_fsync) (struct kiocb *, int datasync);
    int (*fasync) (int, struct file *, int);
    int (*lock) (struct file *, int, struct file_lock *);
    ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
    unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
    int (*check_flags)(int);
    int (*flock) (struct file *, int, struct file_lock *);
    ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
    ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
    int (*setlease)(struct file *, long, struct file_lock **);
    long (*fallocate)(struct file *file, int mode, loff_t offset,
              loff_t len);
};

里面的一个结构体成员都要对应一个调用。

extern int misc_register(struct miscdevice * misc);//注册杂项设备
extern int misc_deregister(struct miscdevice *misc);//注销杂项设备

5、注册杂项设备的流程
  (1)填充miscdevice这个结构体。
  (2)填充file_operations这个结构体。
  (3)注册杂项设备并生成设备节点。

杂项设备注册实践

按照5中讲述的注册杂项设备的流程实现代码misc.c

#include<linux/init.h>
#include<linux/module.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>

struct file_operations  misc_fops =
{
    .owner = THIS_MODULE
};

struct miscdevice misc_dev = {
    .minor = MISC_DYNAMIC_MINOR,
    .name = "hello_misc",
    .fops = &misc_fops
};

static int misc_init(void)
{
    int ret;
    ret = misc_register(&misc_dev);//注册
    if (ret<0)
    {
        printk("misc_register is error\n");
        return -1;
    }
    printk("misc_register is successful\n");
    return 0;
}
static void misc_exit(void)
{
    misc_deregister(&misc_dev);//卸载
    printk("bye bye misc\n");
    return;
}

module_init(misc_init);
module_exit(misc_exit);
MODULE_LICENSE("GPL");

使用如下的Makefile,编译成外部模块(不和内核一起编译)

# -m 的意思是把我们的驱动编译成模块,后面接文件名.o
obj-m += misc.o
KDIR:=/test/doc/x3399/x3399_linux_new/kernel/
#获取当前目录的变量
PWD?=$(shell pwd)
#make 会进入内核源码的路径,然后把当前路径下的代码编译成模块
#make 指令前面必须按tab,不能用4个空格代替
all:
	make -C $(KDIR) M=$(PWD) modules

使用如下的自动编译脚本

export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
make

编译成功后,加载模块到板子上
insmod misc.ko

查看现象,ls /dev/路径下有hello_misc
image

这样,一个最简单的杂项设备就完成了。

标签:struct,int,misc,RK3399,file,迅为,杂项,设备
From: https://www.cnblogs.com/solo666/p/16808582.html

相关文章

  • GTK构件之杂项构件
    GTK构件之杂项构件1.标签lable  标签(Labels)是GTK中最常用的构件,实际上它很简单。因为没有相关联的X窗口,标签不能引发信号。如果需要获取或引发信号,可以将它放在一个事......
  • rk3399 使用 debian ubuntu 固件
    android是非常好用,但是有的时候,需要用到一些linux的时候,而PI树莓派性能又太弱,debian相比ubuntu占用资源更少。开发板:x3399pcubuntu14.04x64:远程仓库地址:htt......
  • [杂项]罗斯福对日宣战演讲
    Yesterday,December7,1941-adate,whichwillliveininfamy-theUnitedStatesofAmericawassuddenlyanddeliberatelyattackedbynavalandairforces......
  • [杂项]Moon Halo
    \[\large\mathit{Some~deserts~on~this~planet~were~oceans~once}\]\[\large\mathit{Somewhere~shrouded~by~the~night,~the~sun~will~shine}\]\[\large\mathit{Sometime......
  • 迅为i.MX8MM开发板使用命令控制GPIO
    在文件系统的/sys目录下给用户提供了许多接口,比如在/sys下面的bus目录,这个目录下放置的都是和总线相关的,比如I2C,usb等。如下图所示:​​​​本章我们需要重点关注下cl......
  • Android系统10 RK3399 init进程启动(四十) 开机自启动脚本init.rc执行逻辑框架
    说明系统:Android10.0设备:FireFlyRK3399(ROC-RK3399-PC-PLUS)前言这个章节我们开始学习新的知识点,init.rc相关概念,也就是Android开机自启动的脚本,这个脚本能启动shell脚......
  • 迅为RK3588开发板编译环境Ubuntu20.04 编译配置增加交换内存
    迅为提供的编译环境Ubuntu20.04默认配置了交换内存是9G,如果在编译过程中,因内存不够而编译报错,可以参考本小节进行设置。这里举例分配5G交换内存。在开始之前,使用命令检......
  • 算法数学笔记-零、常用数表及杂项
    目录零、常用数表及杂项常用数表牛顿迭代牛顿广义二项式定理一些结论范德蒙德卷复数相乘突然发现博客园可以存笔记,这样就可以避免出门没带电脑而又想看笔记的情况了,还方便......
  • 迅为龙芯2K1000核心板国产Linux工业板卡适用于工控电力能源行业方案
     龙芯2k1000采用40nm工艺,片内集成2个GS264处理器核,主频1GHz,64位DDR3控制器,以及各种系统IO接口。       商业级参数           ......
  • 迅为RK3568开发板Busybox制作最小文件系统编译busybox
    保存退出之后,我们需要设置临时环境变量如下图所示:exportPATH=/usr/local/arm64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin:$PATH输入“echo$PATH”,查看环......