【Linux】驱动的基本架构和编译
驱动源码
/** Silicon Integrated Co., Ltd haptic sih688x haptic driver file** Copyright (c) 2021 kugua <daokuan.zhu@si-in.com>** This program is free software; you can redistribute it and/or modify it* under the terms of the GNU General Public License version 2 as published by* the Free Software Foundation*/#include <linux/init.h> //包含宏定义的头文件
#include <linux/module.h> //包含初始化加载模块的头文件static int __init haptics_init(void)
{//内核层只能使用printk,不能使用printfprintk(KERN_EMERG "[ KERN_EMERG ] Haptics Init\n"); //输出等级为0printk("[ default ] Haptics Init\n");return 0;
}static void __exit haptics_exit(void)
{printk(KERN_EMERG "[ KERN_EMERG ] Haptics Exit\n"); //输出等级为0printk("[ default ] Haptics Exit\n");
}module_init(haptics_init);//驱动入口
module_exit(haptics_exit);//驱动出口MODULE_AUTHOR("<daokuan.zhug@si-in.com>");//声明作者信息
MODULE_DESCRIPTION("Haptic Driver V1.0.0"); //对这个模块作一个简单的描述
MODULE_LICENSE("GPL v2");//声明开源许可证// "GPL" 是指明 这是GNU General Public License的任意版本// “GPL v2” 是指明 这仅声明为GPL的第二版本
- linux驱动基本框架就是包含入口函数和出口函数,加载驱动时会运行入口函数,卸载驱动时会运行出口函数。
- 入口函数的作用是加载驱动时做一些初始化工作,比如注册设备、申请设备号、生成设备节点等,上文代码中这些都还没有实现。
- 出口函数的作用是卸载驱动时做一些善后操作,比如注销设备、注销设备号、注销类等。
- 在内核态下的打印函数是“printk”函数。KERN_EMERG是打印优先级,这里采用了最高优先级。
一般情况下,驱动源码会放在kernel/drivers,里面会有很多文件夹存放不同的驱动代码,我们自己的驱动需要新建一个目录。

Kconfig文件
这个文件时用来对内核进行配置的,当执行make arch=ARM64 menuconfig指令的时候,这个文件就被解析。该文件和源码文件在同一目录下,文件内容可如下:
menu "haptics driver"config HAPTICS
tristate "haptics driver"
helpjust a simplest driver.
default yendmenu
#endmenu后一定要加空行
- 第一行内容表示菜单名
- 第二行内容
config HAPTICS,在执行配置的时候,将会生成一个变量CONFIG_HAPTICS,而这个变量,将会在编译的时候,被Makefile引用。 - 第三行内容
tristate声明选项的类型,"haptics driver"声明选项的名称 - 第四行内容表示帮助信息
- 第五行的
default y,就表示把CONFIG_HAPTICS的值设置成y,从而让这个驱动被编译到内核中。 - 第六行是结束菜单
- 第七行是需要加的空行
其中第三行内容的选项支持tristate和bool。
tristate支持三个选项:
- < >不编译
- <*>编译到内核
- 编译成模块
bool支持两个选项:
- < >不编译
- <*>编译到内核
这个在菜单配置时我们会碰到。
现在,haptics驱动中的KConfig配置文件已经准备好了,但是还需要这个配置文件登记到 Linux内核的整体配置文件中。也就是把它登记到kernel/drivers/Kconfig 文件的末尾:
source "drivers/haptics/Kconfig"endmenu // 加在这一句的上面
然后在kernel目录下执行make ARCH=arm64 menuconfig命令,


我们可以看到haptics driver前面显示的是星号*,这表示:该驱动将会编译进内核。我们可以按下空格键切换标记。M标记意思是编译成驱动模块。
我们暂时先选择星号编译进内核,其他的选项后续再介绍。最后选择save即可。
有一点需要注意的,如果Kconfig是在Windows系统上编辑的然后放在开发服务器中,我们会发现报警了
zhudk@vm1:/expand/zhudk/rk3588_9tripod/x3588_linux_20220620/kernel$ make ARCH=arm64 menuconfig
'rivers/haptics/Kconfig:1:warning: ignoring unsupported character '
'rivers/haptics/Kconfig:2:warning: ignoring unsupported character '
'rivers/haptics/Kconfig:3:warning: ignoring unsupported character '
'rivers/haptics/Kconfig:5:warning: ignoring unsupported character '
'rivers/haptics/Kconfig:6:warning: ignoring unsupported character '
这是因为在Windows和Linux系统中,存在换行符的差异。这个小问题可以自行解决。
Makefile文件
Makefile文件是make工具的脚本,也是和源码放在同一目录下,其内容只有一行。
obj-$(CONFIG_HAPTICS) += haptics.o
CONFIG_HAPTICS可以看做一个变量,在编译的时候,这个变量的值可能是:y, n 或者 m。- 在刚才的
Kconfig参数配置中,CONFIG_HAPTICS被设置为 y,于是这句话就被翻译成:obj-y += haptics,表示把 haptics驱动编译进内核。
现在,haptics驱动程序的Makefile已经创建好了,我们还要让linux内核的编译框架知道这个文件才行。在文件kernel/drivers/Makefile 中的末尾,添加如下内容:
obj-$(CONFIG_HAPTICS) += haptics/
编译进内核

现在,整个准备工作已经做好了,只需编译即可。因为本篇教程是基于ARM开发板的,所以使用开发板中SDK的编译脚本进行内核编译。
./build.sh kernel
然后将编译的镜像文件烧录至开发板中,关于编译烧录等可参考【rk3588】环境搭建及系统编译_rk3588 arm64-CSDN博客。在启动日志中,我们可以看到如下信息:

这个正好是我们在驱动入口函数中的打印信息,所以也证明了我们的驱动程序编译进内核并且正常运行了。
编译为驱动模块
上文我们介绍的是将驱动编译进内核,如果需要编译为驱动模块,直接在Kconfig文件中将default y修改为default m。然后执行
./build.sh modules
表示编译内核模块,也仅仅编译设置为模块的驱动,然后会在驱动目录下生成haptics.ko文件。这个文件需要我们手动安装卸载,但首先得发送到开发板上。

总结
驱动的编译分为两种方式:
编译进内核:
Kconfig文件中配置为default y- 执行
./build.sh kernel指令进行编译 - 上述指令是编译整个内核,编译后将镜像文件烧录至开发板,驱动会自动加载
编译为模块:
Kconfig文件中配置为default m- 执行
./build.sh modules指令进行编译 - 上述指令是编译驱动模块,编译结果只有
.ko文件,需要上传至开发板手动加载(开发板提前烧录好不含驱动的镜像)
这两种方式具体使用哪一个呢,需要视具体情况。但是好像可以不需要使用界面配置,还是直接修改配置文件比较方便。
相关文章:
【Linux】驱动的基本架构和编译
驱动源码 /** Silicon Integrated Co., Ltd haptic sih688x haptic driver file** Copyright (c) 2021 kugua <daokuan.zhusi-in.com>** This program is free software; you can redistribute it and/or modify it* under the terms of the GNU General Public Licen…...
1013. 将数组分成和相等的三个部分 数组切分
1013. 将数组分成和相等的三个部分 已解答 简单 相关标签 相关企业 提示 给你一个整数数组 arr,只有可以将其划分为三个和相等的 非空 部分时才返回 true,否则返回 false。 形式上,如果可以找出索引 i 1 < j 且满足 (arr[0] arr[…...
【深度学习】—— 自动微分、非标量变量的反向传播、 分离计算、 Python控制流的梯度计算
【深度学习】—— 自动微分 自动微分一个简单的例子 非标量变量的反向传播分离计算Python控制流的梯度计算 自动微分 求导是⼏乎所有深度学习优化算法的关键步骤。虽然求导的计算很简单,只需要⼀些基本的微积分。但对于复杂的模型,⼿⼯进⾏更新是⼀件很…...
Java项目实战II基于Java+Spring Boot+MySQL的大学城水电管理系统(源码+数据库+文档)
目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发,CSDN平台Java领域新星创作者 一、前言 随着大学城规模的不断扩大和学生数量的急剧增加,大学城内的水电管理面临着前所未有的挑战…...
Vue 组件的三大组成部分详解
文章目录 模板(template)脚本(script)样式(style)总结 在 Vue.js 中,组件是构建用户界面的重要基石。一个 Vue 组件通常由三个主要部分组成:模板(template)、…...
深入理解Java内部类
一、什么是内部类 内部类是定义在另一个类内部的类。内部类与外部类(Enclosing Class)之间存在着紧密的联系,可以访问外部类的成员变量和方法,这使得它们在某些场景下非常有用。 1.1 内部类的分类 Java中的内部类主要有以下几种…...
fiddler抓包12_篡改请求(请求前断点)
课程大纲 原理 正常“客户端-服务器”通信,即发送请求,接收返回。 Fiddler抓包是「客户端-浏览器」进行交互时,请求和响应都会从Fiddler通过,Fiddler可以捕获并展示。 请求前断点(BreakPoint Before Request࿰…...
Webpack和GuIp打包原理以及不同
Webpack打包原理 Webpack的打包原理主要基于模块化的概念,它将应用程序中的所有资源(如JS、CSS、图片等)视为模块,并根据模块间的依赖关系进行静态分析。Webpack会递归地构建一个依赖关系图(dependency graph…...
c++与Python用笛卡尔的心形函数输出爱心
我突然想到输出爱心是否可以用笛卡尔的心形函数 在IDLE里用Python输出下面这个图形 在小熊猫c里用c输出下面这个图形 如果当你要输出这些的时候会怎么办 低级:纯输出 print( ********* ********* ***************** ***************** …...
Mybatis 9种动态 sql 标签使用
MyBatis提供了9种动态SQL标签:trim、where、set、foreach、if、choose、when、otherwise、bind; 1.if 标签 <select id"getUser">select * from User<where><if test" age ! null ">and age > #{age}</if…...
OpenHarmony(鸿蒙南向)——平台驱动开发【PIN】
往期知识点记录: 鸿蒙(HarmonyOS)应用层开发(北向)知识点汇总 鸿蒙(OpenHarmony)南向开发保姆级知识点汇总~ 持续更新中…… 概述 功能简介 PIN即管脚控制器,用于统一管理各SoC的…...
南平自闭症寄宿制学校:让孩子自信绽放
在繁华与喧嚣交织的都市之中,有一片静谧而充满希望的土地——广州星贝育园自闭症儿童寄宿制学校,这里不仅是知识的殿堂,更是自闭症儿童心灵成长的温馨家园。星贝育园,以其独特的教育理念与细致入微的关怀,为这些特殊的…...
汽车总线之---- LIN总线
Introduction LIN总线的简介,对于传统的这种点对点的连接方式,我们可以看到ECU相关的传感器和执行器是直接连接到ECU的,当传感器和执行器的数量较少时,这样的连接方式是能满足要求的,但是随着汽车电控功能数量的不断增…...
Android开发MPAndroidChart两条折线图
Android开发MPAndroidChart两条折线图 Android开发两条折线图效果,还是有一定难度的,难点它的起点不是坐标0的开始,还有数值上有背景图 一、思路: 用的是MPAndroidChart的BarChart 二、效果图: 三、关键代码&#…...
HTML-ES6.0核心技术
1.ES6简介 ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在2015年6月正式发布了。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。ECMAScript 和 JavaScri…...
车间调度问题数学建模与CPLEX优化
完成了这些基础研究工作,整理成文档以供参考 序言... i 第一章 引言... 1 1.1 车间调度问题概述... 1 1.2 车间调度问题分类表示法... 5 1.3 车间调度对制造企业的作用... 6 1.4 本章小结... 7 第二章 CPLEX基础... 8 2.1 CPLEX概述... 8 2.1.1 CPLEX简介.…...
< 基础物理 >
SI国际单位制 常见的公制单位 为什么需要单位,是统一衡量的标准 通过国际单位,以及单位的拓展,以及单位的组合,形成一系列新的测量单位 面积 m^2 速率 m/s 米每二次方秒,m / s, delta表示增量, 每秒移动多少米 加…...
【web开发】Spring Boot 快速搭建Web项目(三)
Date: 2024.08.31 18:01:20 author: lijianzhan 简述:根据上篇原文Spring Boot 快速搭建Web项目(二),由于已经搭建好项目初始的框架,以及自动创建了一个启动类文件(TestWebApplication.java) …...
无人机之战斗机的详解!
一、高性能飞行能力 高速飞行:具备较高的巡航速度和最大飞行速度,以便快速抵达任务区域并灵活应对战场情况。 长航程:拥有足够的航程以执行远程任务,覆盖广阔的作战区域 高升限:能够飞行到较高的高度,以…...
Verilog基础:时序调度中的竞争(四)(描述时序逻辑时使用非阻塞赋值)
相关阅读 Verilog基础https://blog.csdn.net/weixin_45791458/category_12263729.html?spm1001.2014.3001.5482 作为一个硬件描述语言,Verilog HDL常常需要使用语句描述并行执行的电路,但其实在仿真器的底层,这些并行执行的语句是有先后顺序…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...
