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

news2024/12/24 9:41:47

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.o

build: kernel_modules

kernel_modules:
	$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) modules

clean:
	$(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】:重启开发板

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ConcurrentHashMap 源码分析(二)

一、序言 本文和大家探讨一下 ConcurrentHashMap#get() 方法的源码。 二、源码概览 public V get(Object key) {// 定义变量Node<K,V>[] tab; Node<K,V> e, p; int n, eh; K ek;// 计算键的哈希值int h spread(key.hashCode());// 检查哈希表是否为空&#xff…

前端三大件速成 02 CSS(1)CSS是什么、CSS的四种引入方式、CSS的选择器和优先级、继承

文章目录 一、CSS是什么二、CSS的四种引入方式1、行内式2、嵌入式3、链接式&#xff08;推荐&#xff09;4、导入式 三、CSS的选择器1、基本选择器2、组合选择器3、属性选择器4、伪类 四、选择器的优先级1、选择器的权值2、附加说明 五、继承 一、CSS是什么 CSS为层叠样式表&a…

伪分布Hadoop下安装Hive

一、下载并安装Mysql &#xff08;1&#xff09;下载mysql安装包&#xff08;mysql-8.0.26-1.el7.x86_64.rpm-bundle.tar&#xff09; 下载官网&#xff1a;MySQL :: Download MySQL Community Server (Archived Versions)https://downloads.mysql.com/archives/community/ &…

在centos系统中使用boost库

打开MobaXterm软件 下载 boost_1_85_0.tar.gz tar -zxvf boost_1_85_0.tar.gz解压缩成boost_1_85_0文件夹 双击arrayDemo.cpp 在里面可以编写代码 arrayDemo.cpp #include <boost/timer/timer.hpp> #include <boost/array.hpp> #include <cmath> #inc…

Linux 系统systemd(pid=1)占用80端口导致web程序无法启动

背景 linux系统内安装了例如nginx的网站程序&#xff0c;但是无法正常启动&#xff0c;netstat 查看下 80端口被 systemd 占用。 处理方法 注意务必组好快照备份后再操作。 做好备份后将/usr/lib/systemd/system 内http相关的配置文件重命名后重启主机恢复正常。 重启后正常 sy…

51、图论-岛屿数量

思路&#xff1a; 该问题要求在一个由 1&#xff08;表示陆地&#xff09;和 0&#xff08;表示水&#xff09;组成的二维网格中&#xff0c;计算岛屿的数量。岛屿被水包围&#xff0c;并且通过水平或垂直连接相邻的陆地可以形成。这个问题的核心是识别并计数网格中相连的陆地…

网盘——文件操作之界面设计

关于网盘实现部分&#xff0c;文件操作包含三个部分&#xff1a;界面设计、文件夹操作、常规文件操作。本文主要讲解界面设计&#xff0c;后续文章后讲解后两部分。 1、界面设计 最终的界面如下 1.1、创建类&#xff0c;并添加头文件 #include <QListWidget> #include…

spring boot3单模块项目工程搭建-上(个人开发模板)

⛰️个人主页: 蒾酒 &#x1f525;系列专栏&#xff1a;《spring boot实战》 &#x1f30a;山高路远&#xff0c;行路漫漫&#xff0c;终有归途 目录 写在前面 上文衔接 常规目录创建 common目录 exception.handle目录 result.handle目录 controller目录 service…

探索NDWI:归一化水体指数的意义与应用

随着遥感技术的不断发展&#xff0c;NDWI&#xff08;Normalized Difference Water Index&#xff0c;归一化水体指数&#xff09;作为一种重要的植被指数&#xff0c;被广泛应用于水资源管理、湿地监测和环境保护等领域。本文将介绍NDWI的意义、计算方法以及在不同领域的应用。…

什么是0-day漏洞,怎么防护0-day漏洞攻击

随着信息技术的快速发展&#xff0c;网络安全问题日益凸显&#xff0c;其中0day漏洞攻击作为一种高级威胁手段&#xff0c;给企业和个人用户带来了极大的风险。下面德迅云安全就对0day漏洞攻击进行简单讲解下&#xff0c;并分享相应的一些安全措施&#xff0c;以期提高网络安全…

设计模式-创建型-抽象工厂模式-Abstract Factory

UML类图 工厂接口类 public interface ProductFactory {Phone phoneProduct();//生产手机Router routerProduct();//生产路由器 } 小米工厂实现类 public class XiaomiFactoryImpl implements ProductFactory {Overridepublic Phone phoneProduct() {return new XiaomiPhone…

【Interconnection Networks 互连网络】Flattened Butterfly 扁平蝶形拓扑

Flattened Butterfly 扁平蝶形拓扑 1. 传统蝶形网络 Butterfly Topology2. 扁平蝶形拓扑 Flattened Butterfly3.On-Chip Flattened Butterfly 扁平蝶形拓扑应用于片上网络 Flattened Butterfly 扁平蝶形拓扑 扁平蝶形拓扑是一种经济高效的拓扑&#xff0c;适用于高基数路由器…

向量数据库的崛起:如何改变数据存储与机器学习的未来

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

基于 Spring Boot 博客系统开发(一)

基于 Spring Boot 博客系统开发&#xff08;一&#xff09; 本系统是简易的个人博客系统开发&#xff0c;为了更加熟练地掌握SprIng Boot 框架及相关技术的使用。&#x1f913;&#x1f913;&#x1f913; 本系统开发所需的环境及相关软件 操作系统&#xff1a;Windows Java…

20240330-1-词嵌入模型w2v+tf-idf

Word2Vector 1.什么是词嵌入模型&#xff1f; 把词映射为实数域向量的技术也叫词嵌⼊ 2.介绍一下Word2Vec 谷歌2013年提出的Word2Vec是目前最常用的词嵌入模型之一。Word2Vec实际是一种浅层的神经网络模型&#xff0c;它有两种网络结构&#xff0c;分别是连续词袋&#xff…

iOS 全平台矢量动画库:体积小巧、功能丰富 | 开源日报 No.227

airbnb/lottie-ios Stars: 24k License: NOASSERTION lottie-ios 是一个用于在 iOS 平台上本地渲染 After Effects 矢量动画的库。 该项目主要功能、关键特性、核心优势包括&#xff1a; 跨平台支持&#xff1a;可在 iOS, macOS, tvOS, visionOS, Android 和 Web 上使用实时渲…

NewStarCTF 2023 web

目录 week1 泄漏的秘密 Begin of Upload Begin of HTTP ErrorFlask Begin of PHP R!C!E! EasyLogin week2 游戏高手 include 0。0 ez_sql Unserialize&#xff1f; Upload again! R!!C!!E!! week3 Include &#x1f350; medium_sql POP Gadget GenShin wee…

jvm调优的命令和工具总结与分析

目录 1 前置启动程序 2 Jmap查看内存信息 2.1 jmap ‐histo查看历史实例信息 2.2 jmap ‐heap查看堆信息&#xff1a; 2.3 jmap ‐dump导出堆内存信息 2 Jstack查找死锁 2.1 用jstack加进程id查找死锁 2.2 还可以用jvisualvm自动检测死锁 3 Jinfo查看参数配置值 3.1 …

Hadoop1X,Hadoop2X和hadoop3X有很大的区别么?

Hadoop的演进从Hadoop 1到Hadoop 3主要是为了提供更高的效率、更好的资源管理、更高的可靠性以及对更多数据处理方式的支持。下面是Hadoop 1, Hadoop 2, 和 Hadoop 3之间的主要区别和演进的原因&#xff1a; Hadoop 1 特点&#xff1a; 主要包括两大核心组件&#xff1a;HDFS&a…

kettle从入门到精通 第五十三课 ETL之kettle MQTT/RabbitMQ consumer实战

1、上一节课我们学习了MQTT producer 生产者步骤&#xff0c;MQTT consumer消费者步骤。该步骤可以从支持MRQTT协议的中间件获取数据&#xff0c;该步骤和kafka consumer 一样可以处理实时数据交互&#xff0c;如下图所示&#xff1a; 2、双击步骤打开MQTT consumer 配置窗口&a…