驱动(RK3588S)第四课时:模块化编程

news2024/9/20 0:25:16

目录

  • 一、什么是模块化编程
  • 二、怎么把自己编译代码给加载到开发板上运行
  • 三、驱动编程的框架
  • 四、驱动编程具体实例
    • 1、编写单模块化驱动代码
    • 2、编写多模块化驱动代码
    • 3、编写向模块传参驱动代码
    • 4、编写多模块化驱动代码另一种方式

一、什么是模块化编程

在嵌入式里所谓的模块化编程指的是你后期加载的这些驱动代码,就是所谓的模块化,你去编写这些驱动,就是在编译模块化编程,这里的模块化编程和你学习的 C 语言和 STM32 里的模块化还有所不同,那个模块化的意思就是说他一个.C 给拆分了多个.c 或是是.h,一般都是一个.c 对应一个.h,驱动里的模块化指的是你操作系统已经运行起来了,你后期去加载的这些驱动就会成为模块化,好处就是极大的缩小的内核的镜像大小。前期就给你提供一个最基本的嵌入式操作系统,后期你需要什么驱动你就去加载或者是编写什么驱动。

二、怎么把自己编译代码给加载到开发板上运行

驱动代码他编译生成的二进制文件的后缀名是固定的,是 xxx.ko,这个.ko 就是你要加载到驱动里去运行的驱动代码,怎么把一个驱动代码给加载到正在运行的一个操作系统里。
这里就通过指令来进行操作
加载指令:所谓加载指令指的就是把你自己编写的 xxx.ko 驱动文件,给放到内核里运行。insmod xxx.ko 当你执行完这指令之后,那么你自己编写驱动代码就会在内核里运行。
卸载指令:就是把你写的驱动代码,从内核里去删除掉,rmmod xxx.ko
查看指令: 就是查看当前你加载的驱动程序的加载情况 lsmod
驱动加载到内核里有两种方法:
第一种:静态编译
就是你编译的代码就直接集成到了内核镜像里,缺点就是你每次都需要从新编译内核,从新烧写内核,优点稳定。
第二种:动态编译
就是不用每次去编译内核,烧写内核,就是通过一个 makefile 去单独的编译你自己写的驱动码,优点 :效率高 缺点:有可能出现不稳定的情况,这种情况极少出现。
前期开发板一般都是使用的动态编译。

三、驱动编程的框架

驱动代码他和你编写的 C 语言和 STM32 有所不同,驱动还是很大的。这里不管里是编写 C 语言还好,还是编写 STM32 也罢,你们首先都会搞一个自己的 main 函数,驱动代码根本就不需要你编写 main 函数,因为内核的源码已经给你写好了。你只需要编写自动驱动的代码的入口和出口即可,当你去加载自己的代码到驱动里的时候,他会自动的去调用你代码里的加载函数(入口函数),当你去卸载驱动代码的时候,他会自动的去调用你自己写的卸载函数(出口函数)。
任何人只要你写的是 Linux 嵌入式驱动的代码,他们的框架都是一样的。
加载函数的声明:
module_init(加载函数的名字); 这里是声明加载函数的
卸载函数的声明
module_exit(卸载函数的名字); 这里是声明卸载函数的
开源协议的声明
MODULE_LICENSE(“GPL”);//声明开源协议
在内核里只要这个函数他不是 void 那么就需要要有返回值,哪怕你返回的是 0,否则内核在编译的时候会报警告
变量在使用的时候一定要先定义,并且要在函数最前面去定义。否则可能报错
具体框架:
#include <linux/module.h>
#include <linux/kernel.h>
//加载函数的定义
static int __init myhello_init(void)
{
return 0;
}
//卸载函数的定义
static void __exit myhello_exit(void)
{
}
module_init(myhello_init);//加载函数的声明
module_exit(myhello_exit);//卸载函数的声明
MODULE_LICENSE(“GPL”);//开源协议的声明
其中必须要有#include <linux/module.h> #include <linux/kernel.h>这两个头文件。
使用insmod xxx.ko 的时候就会自动的去调用你加载函数
使用rmmod xxx.ko 的时候就会自动的去调用你卸载函数
加载函数和卸载函数的命名规则
加载函数 xxx_init
卸载函数 xxx_exit

四、驱动编程具体实例

1、编写单模块化驱动代码

在这里插入图片描述
在这里插入图片描述
其中obj-m+=led.o相当于最后生成的.ko文件,是要推到板子上的。
在这里插入图片描述
使用make生成.ko文件
在这里插入图片描述
使用虚拟机连接到开发板上,将.ko推到开发板中。
在这里插入图片描述
可以看到代码在开发板运行结果,即内核中运行的结果。
在这里插入图片描述

2、编写多模块化驱动代码

leda调用ledb的函数。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3、编写向模块传参驱动代码

内核的传递参数没有这么简单,因为内核的主函数是人家已经写好的,是不不可以随便改变的,这里内核给咱们提供了你专门传递参数的函数,你想给自己编写的驱动代码里的某一个参数传递参数,你就要使用内核提供的函数进行声明,然后在 insmod xxx.ko 后加你要给那个变量传递什么值
int num = 5;这里代码原本里边的内容
insmod xxx.ko num=x;这是想修改的内容

向模块传递参数的函数
module_param(name,type,perm)
参数:
name:你给内核里的一个变量传递参数
Type:他是你传递变量的类型
*注意:如果你传递的这个变量是一个 char 类型的
这里的类型你就要写 charp

Perm:你要对这个变量进行什么操作
S_IRUGO|S_IWUSR — 可读可写
你传递的是一个动态的,就是他不会改变原来的内容,只是动态改变本次值的内容。如果你定义这个变量是一个数组类型的此时你就需要使用另一个函数做声明了
module_param_array(name,type,num,perm)
参数:
name:你要传递数组的变量名
Type:数组的类型
Num:记录你给数组传递的参数的个数 — 这个变量需要取地址
Perm:你要对这个变量进行什么操作
S_IRUGO|S_IWUSR — 可读可写
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
开始时传入的参数:
在这里插入图片描述
传入后现象:
在这里插入图片描述
在这里插入图片描述

4、编写多模块化驱动代码另一种方式

多个.c 编译生成一个.ko,就像 C 语言里的模块化一样,把一个.c 里内容给筛分了多个.c,最终编译还是一个.ko
b中函数被a调用:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
obj-m := ledc.o #最终生成模块的名字就是 ledc.ko
ledc-objs = leda.o ledb.o#意思是生成的ledc.o是依赖于leda.o和ledb.o生成的。

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

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

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

相关文章

Vue——day07之条件渲染、列表渲染以及监测数据

目录 1.template标签 2.条件渲染 3.列表渲染 4.v-for中的key的作用以及原理 5.列表过滤 placeholder 前端空字符串 使用数据监视watch实现 使用计算属性实现 6.列表排序 7.Vue更新数据检测失败 原因 总结 1.template标签 template标签是Vue.js中的一个特殊元素&am…

kube-scheduler调度策略之预选策略(三)

一、概述 摘要&#xff1a;本文我们继续分析源码&#xff0c;并聚焦在预选策略的调度过程的执行。 二、正文 说明&#xff1a;基于 kubernetes v1.12.0 源码分析 上文我们说的(g *genericScheduler) Schedule()函数调用了findNodesThatFit()执行预选策略。 2.1 findNodesTha…

Truncated incorrect max_connections value: ‘999999‘

MySQL 的最大连接数&#xff08;max_connections&#xff09;可以设置的上限值在不同的资料中有所不同。以下是一些关键信息&#xff1a; 默认值和默认范围&#xff1a; MySQL 的默认最大连接数通常为 100 。一些资料提到默认值为 151 。 最大允许值&#xff1a; MySQL 的最大…

ant-design-vue:a-table表格中插入自定义按钮

本文将介绍如何使用ant-design-vue在a-table表格中加入自定义按钮和图标的代码。 结果如下图所示&#xff0c; 一、简单示例 <template><a-table:columns"columns":data-source"data":row-selection"rowSelection":ellipsis"tru…

对称密码学

1. 使用OpenSSL 命令行 在 Ubuntu Linux Distribution (发行版&#xff09;中&#xff0c; OpenSSL 通常可用。当然&#xff0c;如果不可用的话&#xff0c;也可以使用下以下命令安装 OpenSSL: $ sudo apt-get install openssl 安装完后可以使用以下命令检查 OpenSSL 版本&am…

深度学习基础案例4--构建CNN卷积神经网络实现对猴痘病的识别(测试集准确率86.5%)

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 前言 下一周会很忙&#xff0c;更新可能不及时&#xff0c;请大家见谅这个项目我感觉是一个很好的入门案例&#xff0c;但是自己测试的时候测试集准确率只比较…

mcu loader升级固件原理与实现

1 mcu loader升级固件原理 mcu 固件有两部分&#xff0c;如下图所示&#xff0c;一部分是 loader.bin&#xff0c;一部分是 app.bin&#xff0c;将两部分的固件合并在一起烧录进 mcu 的 flash 当中。mcu 上电进入loader 模式执行 loader.bin 部分的程序&#xff0c;然后读取 fl…

前端踩坑记录:javaScript复制对象和数组,不能简单地使用赋值运算

问题 如图&#xff0c;编辑table中某行的信息&#xff0c;发现在编辑框中修改名称的时候&#xff0c;表格中的信息同步更新。。。 检查原因 编辑页面打开时&#xff0c;需要读取选中行的信息&#xff0c;并在页面中回显。代码中直接将当前行的数据对象赋值给编辑框中的表单对…

51单片机——I2C总线

1、I2C总线简介 I2C总线&#xff08;Inter IC BUS&#xff09;是由Philips公司开发的一种通用数据总线 两根通信线&#xff1a;SCL&#xff08;Serial Clock&#xff09;、SDA&#xff08;Serial Data&#xff09; 同步、半双工&#xff0c;带数据应答 通用的I2C总线&#…

Linux基础(包括centos7安装、linux基础命令、vi编辑器)

一、安装CentOS7 需要&#xff1a;1、VMware Workstation&#xff1b;2、CentOS7镜像 1、安装镜像 2、虚拟机配置 开启虚拟机&#xff0c;鼠标从vm中移出来用快捷键ctrlalt 点击开始安装&#xff0c;设置密码&#xff0c;等待安装完成,&#xff0c;重启。 3、注意事项 如果没…

通往RAG之路(二):版面结构检测方法介绍

一、基于yolov5的版面结构检测 AG系统搭建过程中&#xff0c;版面分析是不可缺少的一个步骤&#xff0c;本文介绍用yolov5进行版面结构信息识别&#xff0c;后续再搭配表格识别、公式识别、文字识别等模块进行版面还原&#xff0c;完成PDF结构化输出。 1.1、环境搭建 conda c…

解决方案:在autodl环境下为什么已安装torch打印出来版本号对应不上

文章目录 一、现象二、解决方案 一、现象 平台&#xff1a;autodl 镜像&#xff1a;PyTorch 2.0.0 Python 3.8(ubuntu20.04) Cuda 11.8 GPU&#xff1a;A40(48GB) * 1 CPU&#xff1a;15 vCPU AMD EPYC 7543 32-Core Processor 内存&#xff1a;80GB 安装torch:1.13.0环境&a…

深入理解指针(6)

目录&#xff1a; 1.字符指针变量 2.数组指针变量 3.二维数组传参本质 4.函数指针变量 5.函数指针的应用 1.字符指针变量 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> int main() {char a w;char* p &a;printf("%p ", p);} 当我们想取出…

UE 【材质编辑】自定义材质节点

使用UE的材质编辑器&#xff0c;蓝图提供了大量的节点函数&#xff1a; 实际上&#xff0c;这是一段封装好的包含一串HLSL代码的容器。打开“Source/Runtime/Engine/Classes/Material”&#xff0c;可以看到很多不同节点的头文件&#xff1a; 照葫芦画瓢 以UMaterialExpressi…

ORM 编程思想

一、ORM简介 对象关系映射&#xff08;英语&#xff1a;Object Relational Mapping&#xff0c;简称ORM&#xff0c;或 O/R mapping&#xff09;是一种为了解决面向对象语言与关系数据库存在的 互不匹配的现象。 二、实体类 实体类就是一个定义了属性&#xff0c;拥有getter、…

51单片机——存储器

1、存储器简介 RAM优点存储速度非常快&#xff0c;缺点成本高&#xff0c;掉电丢失数据。 ROM优点掉电不丢失数据&#xff0c;缺点存储速度比较慢。 所以在实际应用中&#xff0c;我们都是采用两者结合的方式。程序运行时&#xff0c;数据存储在RAM中&#xff0c;需…

自己开发完整项目一、登录功能-04(集成jwt)

一、说明 前面文章我们写到了通过数据库查询出用户信息并返回&#xff0c;那么在真实的项目中呢&#xff0c;后端是需要给前端返回一个tocken&#xff0c;当前端通过登录功能认证成功之后&#xff0c;我们后端需要将用户信息和权限整合成一个tocken返回给前端&#xff0c;当前端…

【Python技术】使用langchain、fastapi、gradio生成一个简单的智谱AI问答界面

前几天&#xff0c;智谱AI BigModel开放平台宣布&#xff1a;GLM-4-Flash 大模型API完全免费了&#xff0c;同时开启了GLM-4-Flash 限时免费微调活动。对想薅免费大模型羊毛的个人玩家&#xff0c;这绝对是个好消息&#xff0c;我们不仅可以免费使用BigModel开放平台上的GLM-4-…

产品入门篇笔记

产品和产品经理 产品&#xff1a;解决某个问题的物品&#xff0c;无形、有形都可以。 产品经理&#xff1a;简单而言就是想清楚怎么做的人&#xff0c;需要想清楚产品怎么设计&#xff0c;要分析什么用户、在什么场景、怎么样的需求&#xff1b;然后考虑产品的功能、优势、价值…

LeetCode_sql_day20(1398.购买了产品A和产品B却没有购买产品C的顾客)

描述: Customers 表&#xff1a; ------------------------------ | Column Name | Type | ------------------------------ | customer_id | int | | customer_name | varchar | ------------------------------ customer_id 是这张表中具有唯一…