Linux内核驱动开发-字符设备驱动框架

1前置条件

(1)【linux】内核编译结束
(2)【linux】目录配置跳转文件:

在这里插入图片描述

补充:配置的跳转文件只能在【linux】目录下使用,子目录无法使用

2驱动框架

2.1编写驱动程序

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>#define DEVICE_MAJOR 200
#define DEVICE_NAME  "first_device"int first_driver_open(struct inode *node, struct file *fp)
{printk("first_driver_open\n");return 0;
}ssize_t first_driver_read(struct file *fp, char __user *user_buffer, size_t len, loff_t *offset)
{printk("first_driver_read\n");return 0;
}ssize_t first_driver_write(struct file *fp, const char __user *user_buffer, size_t len, loff_t *offset)
{printk("first_driver_write\n");return 0;
}int first_driver_close(struct inode *node, struct file *fp)
{printk("first_driver_close\n");return 0;
}static struct file_operations fops = 
{.owner = THIS_MODULE,.open = first_driver_open,.read = first_driver_read,.write = first_driver_write,.release = first_driver_close
};static int __init first_driver_init(void)
{	register_chrdev(DEVICE_MAJOR, DEVICE_NAME, &fops);printk("first_driver_init OK\n");return 0;
}static void __exit first_driver_exit(void)
{	unregister_chrdev(DEVICE_MAJOR, DEVICE_NAME);printk("first_driver_exit OK\n");
}module_init(first_driver_init);
module_exit(first_driver_exit);MODULE_LICENSE("GPL");
MODULE_AUTHOR("XXX");

2.2 编译驱动程序

2.2.1编译方式1

【step1】:将编写完成的驱动程序放至【linux/drivers/char】目录下
【cp ./file_name.c linux/drivers/char】
【step2】:修改内核配置文件
【vi linux/drivers/char/Kconfig】

在这里插入图片描述

【step3】:修改编译规则,添加工程文件
【vim linux/drivers/char/Makefile】

在这里插入图片描述

在这里插入图片描述

【step4】:菜单配置
【make menuconfig】

在这里插入图片描述

在这里插入图片描述

修改为<M>模式

在这里插入图片描述
附:3种模式讲解

当然,也可以使用【help】选项查看相关信息

在这里插入图片描述
在这里插入图片描述

【step5】:调用编译命令,进行驱动程序的编译
【make modules】	

在这里插入图片描述

至此,采用方式1编译完成。当然,也可以查看编译后文件是否存在:

在这里插入图片描述

这是一个需要手动添加到操作系统的文件。

2.2.2编译方式2

【step1】:创建一个文件夹:是linux目录下的任意目录
【mkdir my_drivers】

在这里插入图片描述

【step2】:将驱动程序源码放入该目录

在这里插入图片描述

【step3】:该目录下创建【Makefile】文件
【vim Makefile】
KERNELDIR := /home/linux/s3c2440/linux-2.6.32.2/
CURRENT_PATH := $(shell pwd)
obj-m := first_driver.obuild: kernel_moduleskernel_modules:$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) modulesclean:$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean
【step4】:编译
【make】

在这里插入图片描述

至此,采用方式2编译完成。当然,也可以查看编译后文件是否存在:

在这里插入图片描述

这是一个需要手动添加到操作系统的文件。

2.3移植驱动程序

(1)将编译产生的【filename.ko】文件移植到开发板
【cp drivers/char/first_driver.ko ~/nfs/rootfs】

在这里插入图片描述

在开发板种可以看到文件移植成功:

在这里插入图片描述

2.4加载驱动程序

(1)加载被移植到开发板的【filename.ko】文件
【insmod filename.ko】

在这里插入图片描述

补充:
查看加载成功的驱动:【lsmod】

2.5卸载驱动程序

(1)卸载被移植到开发板的【filename.ko】文件【rmmod filename】

2.6创建设备文件

2.6.1创建设备文件方式1

手动创建设备文件
【mknod[options] name type major minor】
【options】:
【name】:【/dev】下的设备文件名
【type】:设备型号,【c】
【major】:主设备号
【minor】:子设备号
eg:【mknod /dev/first_driver c 200 0】

在这里插入图片描述

设备创建完毕,可以使用【ls】命令查看是否成功创建设备文件。

在这里插入图片描述

补充:
应用程序就是以【name】为入口点来调用驱动程序的。
【mknod ?】:查看命令帮助
【cat /proc/devices/】:查看设备
【ls /dev】:查看设备文件删除设备文件:

在这里插入图片描述

2.7调用驱动程序

【step1】:其实就是在开发板上编写一个应用程序(主要是指main函数)
编写应用程序:打开设备文件->调用文件I/O(系统I/O)->
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>int main(void)
{int fd=0;fd=open("dev/first_device",O_RDWR);if(fd<0){printf("opening is error\n");return -1;}while(1){int n=123;read(fd,&n,4);sleep(1);write(fd,&n,4);sleep(1);}return 0;
}
【step2】:编译应用程序

在这里插入图片描述

【step3】:关闭开发板原有的设备驱动程序
通过菜单配置命令:【make menuconfig】
将对应的驱动模块的模式【<>】改为图中所标记的模式。

在这里插入图片描述

2.8编译并移植内核文件

【make uImage】

在这里插入图片描述

编译完成之后,将产生的镜像文件移植到开发板:
【cp arch/arm/boot/uImage ~/tftpboot/】

在这里插入图片描述

2.9运行操作系统内核

接下来,将操作系统运行在开发板上:
【tftp 0x30008000 uImage】
【bootm 0x30008000】

2.10开发板文件配置

当新的内核文件在开发板上成功运行之后,接下来需要对开发板上的一个文件进行配置:

在这里插入图片描述

关闭led相关配置:

在这里插入图片描述

补充:
(1)【reboot】:该命令将重启开发板,让开发板回到初始状态,从运行内核文件之后的所有操作需要重新配置。

在这里插入图片描述

(2)通过配置环境变量可以让开发板上电以后自动运行操作系统并挂载根目录:
【setenv bootcmd 'tftp 0x30008000; bootm 0x30008000'】
注意:环境变量配置完成一定要进行保存操作!!!

在这里插入图片描述

(3)环境变量配置完成之后可以重启开发板:可以看到开发板将自动运行操作系统并挂载根文件系统。
【reset】:重启开发板

在这里插入图片描述

3板载驱动程序示例

路径:【linux-2.6.32.2/drivers/char/mini2440_hello_module.c 】

#include <linux/kernel.h>
#include <linux/module.h>static int __init mini2440_hello_module_init(void)
{printk("Hello, Mini2440 module is installed !\n");return 0;
}static void __exit mini2440_hello_module_cleanup(void)
{printk("Good-bye, Mini2440 module was removed!\n");
}module_init(mini2440_hello_module_init);
module_exit(mini2440_hello_module_cleanup);
MODULE_LICENSE("GPL");

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/645317.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

手撕sql面试题:计算出在校人数,字段中含有学生的学制

今天分享一道面试题!如下&#xff1a; 有一个录取学生人数表&#xff0c;记录的是每年录取学生人数和入学学生的学制 以下是表结构&#xff1a; CREATE TABLE admit ( id int(11) NOT NULL AUTO_INCREMENT, year int(255) DEFAULT NULL COMMENT 入学年度, num int(255) …

工业相机和镜头参数和选型

工业相机和镜头参数和选型 文章目录 工业相机和镜头参数和选型前言一、相机参数解释和选型1.相机参数1.1快门-shutter1.2曝光-exposure1.3增益-gain1.4 感光芯片类型&#xff08;CCD/CMOS&#xff09;1.5 感光芯片&#xff08;靶面&#xff09;尺寸1.6 分辨率1.7 像元尺寸1.8 帧…

前端补充17(JS)

一、JS组成成分 JS的组成成分&#xff0c;由三部分组成 第一、ECMAScript&#xff1a;语法规则&#xff0c;如何定义变量&#xff0c;数据类型有哪些&#xff0c;如何转换数据类型&#xff0c;if判断 if-else while for for-in forEach do-while switch 数组 函数 对…

SpringSecurity授权流程(自己做笔记用的)

目录 一、RABC表的设计 二、查询权限并添加Security中 三、通过注解进行授权 四、授权进行前端访问 一、RABC表的设计 基本概念就是五个表&#xff1a; 用户表&#xff1a;users 角色表&#xff1a;role 权限表&#xff1a;permission 还需要两种关系表&#xff0c;才能通过…

LDA主题模型

在文本挖掘领域&#xff0c;大量的数据都是非结构化的&#xff0c;很难从信息中直接获取相关和期望的信息&#xff0c;一种文本挖掘的方法&#xff1a;主题模型&#xff08;Topic Model&#xff09;能够识别在文档里的主题&#xff0c;并且挖掘语料里隐藏信息&#xff0c;并且在…

Hbase学习笔记

Hbase是什么 HBase是一个高可靠、高性能、面向列、可伸缩的分布式存储系统。它利用Hadoop HDFS作为其文件存储系统,并提供实时的读写的数据库系统。HBase的设计思想来源于Google的BigTable论文,是Apache的Hadoop项目的子项目。它适合于存储大表数据,并可以达到实时级别。HB…

Java基础知识(一)

1. Java语言跨平台原理 1.1 Java语言的特点 完全面向对象&#xff1a; Java语言支持封装、继承、多态&#xff0c;面向对象编程&#xff0c;让程序更好达到高内聚&#xff0c;低耦合的标准。支持分布式&#xff1a; Java语言支持Internet应用的开发&#xff0c;在基本的Java应…

实现ALV页眉页脚

1、文档介绍 在ALV中&#xff0c;可以通过增加页眉和页脚&#xff0c;丰富ALV的展示。除了基本的页眉和页脚&#xff0c;还可以通过插入HTML代码的方式展示更加丰富的页眉和页脚&#xff0c;本篇文章将介绍ALV和OOALV中页眉页脚的使用。 2、ALV页眉页脚 效果如下 2.1、显示内…

贝叶斯网络(概念、应用、实例)

目录 一、贝叶斯网络基本概念 1.1主要组成 1.2概率模型 1.3应用场景 1.4推理方法 1.5学习 二、贝叶斯网络在机器学习中的应用 三、应用实例 3.1分类 3.2推荐系统 3.3自然语言处理 一、贝叶斯网络基本概念 贝叶斯网络&#xff0c;也称为信念网络或有向无环图模型&am…

JMeter压测

1.创建线程组 2.创建http请求 填写接口基本信息。&#xff08;我这里用的是我自己的一个demo项目&#xff0c;大家也可以换成自己的试一试&#xff09; 填写完毕之后我们点击绿色箭头运行。由于没有配置请求头信息&#xff0c;所以显示认证失败。 3.创建信息头管理器 3.1为什么…

基于激光雷达的作物表型研究论文汇总

文章目录 2018How Universal Is the Relationship between Remotely Sensed Vegetation Indices and Crop Leaf Area Index? A Global Assessment[J] 2021结合移动式激光雷达和 CropQuant-3D 对不同氮素处理小麦的大规模田间表型分析[M] 2023基于地基激光雷达和 RGB 相机对小麦…

MySQL多版本并发控制mvcc原理浅析

文章目录 1.mvcc简介1.1mvcc定义1.2mvcc解决的问题1.3当前读与快照读 2.mvcc原理2.1隐藏字段2.2版本链2.3ReadView2.4读视图生成原则 3.rc和rr隔离级别下mvcc的不同 1.mvcc简介 1.1mvcc定义 mvcc(Multi Version Concurrency Control)&#xff0c;多版本并发控制&#xff0c;是…