全志orangepi-zero2驱动编写

文章目录

  • 编译内核
    • 拓展一下,如果是其他板子内核编译有几种方式(可以不用看):以下是树莓派板子的内核编译
  • 驱动编写框架
    • 驱动框架
  • 结束

编译内核

编写驱动之前先去官网下载,手册,跳到5.几章先弄好内核编译
照着手册来,没问题。(文章说需要切换清华的源)(我没切换)(反而切换出了很多错误)

http://www.orangepi.cn/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-Pi-Zero-2.html

必须内核编译,驱动编写,需要一个编译好的内核
编译成功后,看到源码树目录多了vmlinux,失败则无此文件

拓展一下,如果是其他板子内核编译有几种方式(可以不用看):以下是树莓派板子的内核编译

ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make bcm2709_defconfig
指定ARM架构   指定编译器                      树莓派          主要核心指令
第一种方式:cp 厂家.config .config
第二种方式:make menuconfig 一项项配置,通常是基于厂家的config来配置
第三种方式:完全自己来

编译

ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make -j4 zImage modules dtbs

编译成功后,看到源码树目录多了vmlinux,失败则无此文件
成功后,目标zImage镜像arch/arm/boot底下

打包zImage成树莓派可用的xxx.img
./scripts/mkknlimg arch/arm/boot/zImage ./kernel_new.img

这里作为一个拓展吧,每个内核编译都可能不同,具体找商家手册来看

驱动编写框架

驱动两种加载方式:

  • *编译进内核 zImage包含了驱动
  • M 模块方式生成驱动文件xxx.ko 系统启动后,通过命令inmosd xxx.ko 加载

驱动框架

#include <linux/fs.h>				//file_operations声明
#include <linux/module.h>			//module_init module_exit声明
#include <linux/init.h>				//__init__exit 宏声明
#include <linux/device.h>			//class device 声明
#include <linux/uaccess.h>			//copy_from_user的头文件
#include <linux/types.h>			//设备号dev_t类型声明
#include <asm/io.h>					//ioremap iounmap的头文件static struct class *pin4_class;
static struct device *pin4_class_dev;static dev_t devno;            //设备号
static int major =231;       //主设备号
static int minor =0;          //次设备号
static char *module_name="pin4";   //模块名//ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
static ssize_t pin4_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{printk("pin4_read\n");return 0;
}static int pin4_open(struct inode *inode,struct file *file)
{printk("pin4_open\n");		//内核打印函数,和printf类似return 0;
}static ssize_t pin4_write(struct file *file,const char __user *buf,size_t count, loff_t *ppos)
{printk("pin4_write\n");return 0;
}static struct file_operations pin4_fops = {.owner = THIS_MODULE,.open  = pin4_open,.write = pin4_write,.read  = pin4_read,
};
//static int __init
static int  pin4_drv_init(void)
{int ret;devno = MKDEV(major,minor);ret   = register_chrdev(major, module_name,&pin4_fops);pin4_class=class_create(THIS_MODULE,"myfirstdemo");pin4_class_dev =device_create(pin4_class,NULL,devno,NULL,module_name);return 0;
}static void pin4_drv_exit(void)
{device_destroy(pin4_class,devno);class_destroy(pin4_class);unregister_chrdev(major, module_name);
}module_init(pin4_drv_init);
module_exit(pin4_drv_exit);
MODULE_LICENSE("GPL v2");

这个框架需要和用户态的open等函数进行配合,需要知道linux内核框图可明白
这里直接放上代码,去和驱动框架进行配合

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>int main()
{int fd;fd = open("/dev/pin4",O_RDWR);if(fd < 0){printf("open fail\n");}else {printf("open success\n");}fd = write(fd,'1',1);
}

这里俩个文件,放入先放入虚拟机交叉编译。
驱动代码需要内核编译成模块,再用scp上传开发板。
普通代码编译完,也上传到开发板就可以。

编译成模块方法:

使用aarch64-none-linux-gnu-先设置环境变量
cd ~
vi .bashrc
最后一行添加export PATH = $PATH: /……/bin//aarch64-none-linux-gnu-命令所在地位置
(在内核编译完成之后个toolchain文件夹在里面找)

在这个文件夹下,放入你的驱动代码

orangepi-build-main/kernel/orange-pi-4.9-sun50iw9/drivers/char

修改Makefile文件

vi Makefile

添加咱们写的驱动

obj-m +=pin4Dev.o(文件名是啥就写啥后缀为.o即可)

在这里插入图片描述
保存退出wq

使用命令编译

回到内核源码这里的路径进行编译

orangepi-build-main/kernel/orange-pi-4.9-sun50iw9

输入命令

ARCH=arm64 CROSS_COMPILE=aarch64-none-linux-gnu- KERNEL=kernel make modules

将.ko文件放到(没有ko就是内核编译有问题,重新编译去)

通过以下命令配合

sudo insmod 文件.ko	//加载驱动
//加载驱动以后,在/dev/pin4就会看到//但是此时运行我们的测试代码是打不开的,需要添加权限
sudo chmod 666 /dev/pin4	//所有用户可读可写
./a.out//测试文件,看到打开成功
//如果看不到输出信息可以输入dmesg |grep pin4//可查看内核态输出信息lsmod //查看驱动
sudo rmmod 文件//卸掉驱动

成功;

结束

如有问题欢迎提出,共同进步

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

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

相关文章

openGauss学习笔记-45 openGauss 高级数据管理-物化视图

文章目录 openGauss学习笔记-45 openGauss 高级数据管理-物化视图45.1 全量物化视图45.1.1 全量物化视图语法格式45.1.2 全量物化视图参数说明45.1.3 全量物化视图示例 45.2 增量物化视图45.2.1 增量物化视图语法格式45.2.2 增量物化视图参数说明45.2.3 增量物化视图示例 openG…

工厂模式并不难理解

文章目录 工厂模式简单工厂模式简单工厂模式使用的场景 工厂方法模式工厂方法模式使用场景 抽象工厂模式抽象工厂模式使用场景 工厂模式 功能&#xff1a;将对象的创建交给工厂&#xff0c;我们只需要告诉工厂我们要什么对象就可以得到该对象。 目的&#xff1a;实现创建对象…

【算法刷题之链表篇(1)】

目录 1.leetcode-82. 删除排序链表中的重复元素 II&#xff08;1&#xff09;题目描述&#xff08;2&#xff09;方法及思路&#xff08;一次遍历&#xff09;&#xff08;3&#xff09;代码实现 2.leetcode-19. 删除链表的倒数第 N 个结点&#xff08;1&#xff09;题目描述&a…

无需公网IP——搭建web站点

文章目录 概述使用 Raspberry Pi Imager 安装 Raspberry Pi OS设置 Apache Web 服务器测试 web 站点安装静态样例站点将web站点发布到公网安装 Cpolar内网穿透cpolar进行token认证生成cpolar随机域名网址生成cpolar二级子域名将参数保存到cpolar配置文件中测试修改后配置文件配…

认识容器,走进Docker

文章目录 容器技术简介容器的核心技术容器平台技术容器的支持技术 Docker理念Docker安装配置阿里云镜像加速器 容器技术简介 一切在云端&#xff0c;万物皆容器&#xff0c;说到容器&#xff0c;大家都会想到Docker,Docker现在几乎是容器的代名词&#xff0c;什么是Docker&…

网络通信原理TCP的四次断开连接(第四十九课)

FIN:发端完成发送任务标识。用来释放一个连接。FIN=1表明此报文段的发送端的数据已经发送完毕,并要求释放连接。 SEQ:序号字段。 TCP链接中传输的数据流中每个字节都编上一个序号。序号字段的值指的是本报文段所发送的数据的第一个字节的序号。 序列号为X ACK :确认号 。 …

ViT模型架构和CNN区别

目录 Vision Transformer如何工作 ViT模型架构 ViT工作原理解析 步骤1&#xff1a;将图片转换成patches序列 步骤2&#xff1a;将patches铺平 步骤3&#xff1a;添加Position embedding 步骤4&#xff1a;添加class token 步骤5&#xff1a;输入Transformer Encoder 步…

【Rust】Rust学习 第十五章智能指针

指针 &#xff08;pointer&#xff09;是一个包含内存地址的变量的通用概念。这个地址引用&#xff0c;或 “指向”&#xff08;points at&#xff09;一些其他数据。Rust 中最常见的指针是第四章介绍的 引用&#xff08;reference&#xff09;。引用以 & 符号为标志并借用…

C# Linq源码分析之Take (三)

概要 本文在前两篇Take源码分析的基础上&#xff0c;着重分析Range参数中有倒数的情况&#xff0c;即分析TakeRangeFromEndIterator的源码实现。 源码及分析 TakeRangeFromEndIterator方法用于处理Range中的开始和结束索引存在倒数的情况。该方法位于Take.cs文件中。通过yie…

Lnton羚通算法算力云平台在环境配置时 OpenCV 无法显示图像是什么原因?

问题&#xff1a; cv2.imshow 显示图像时报错&#xff0c;无法显示图像 0%| | 0/1 [00:00<…

构建 NodeJS 影院微服务并使用 docker 部署【01/4】

图片来自谷歌 — 封面由我制作 一、说明 构建一个微服务的电影网站&#xff0c;需要Docker、NodeJS、MongoDB&#xff0c;这样的案例您见过吗&#xff1f;如果对此有兴趣&#xff0c;您就继续往下看吧。 在本系列中&#xff0c;我们将构建一个 NodeJS 微服务&#xff0c;并使用…

qt初入门0:结构体中QString用memset导致崩溃分析及QLatin1String简单查看源码

初识Qt,进行开发时遇到一个崩溃问题 简单整理 1&#xff1a;问题描述如下&#xff0c;结构体中QString成员&#xff0c;然后对结构体调用了memset导致问题&#xff1a; 2&#xff1a;问题分析&#xff0c;加断点调试的方式可以明确分析到行数 可以明确看出&#xff0c;初始化…

Windows下问题定位

1、内存相关知识点&#xff1b; 1&#xff09;windows下32位进程&#xff0c;用户态为2G内存&#xff0c;内核态也为2G内存&#xff1b;却别于linux操作系统&#xff1b; 备注&#xff1a;可以通过命令行与管理员权限&#xff0c;启动3G的用户态空间&#xff0c;但是部…

git权限问题解决方法Access denied fatal: Authentication failed

文章目录 遇到Access denied 的权限问题解决方法1、git的密码修改过&#xff0c;但是本地没更新。2、确定问题&#xff0c;然后增加配置① 查询用户信息②如果名称和email不对&#xff0c;设置名称&#xff1a;③ 检查ssh-add是否链接正常④ 设置不要每次都输入用户名密码 3、配…

【校招VIP】CSS校招考点之选择器优先级

考点介绍&#xff1a; 选择器是CSS的基础&#xff0c;也是校招中的高频考点&#xff0c;特别是复合选择器的执行优先级&#xff0c;同时也是实战中样式不生效的跟踪依据。 因为选择器的种类较多&#xff0c;很难直接记忆&#xff0c;可以考虑选择一个相对值&#xff0c;比如id类…

人大进仓数据库ksql命令基础

测试环境信息: 系统为银河麒麟V10 数据库为Kingbase ES V8 数据库安装目录为/opt/Kingbase/ES/V8 ksql命令位于/opt/Kingbase/ES/V8/Server/bin下 使用--help获取帮助 续上图 1.查看数据库列表 ./ksql -U system -l 2.查看数据库版本 ./ksql -V 3.连接指定的数据库tes…

【GAMES202】Real-Time Shadows2—实时阴影2

一、PCSS回顾 上一篇我们说了如何用PCSS是实现软阴影&#xff0c;这个过程是没有任何问题的&#xff0c;但是有一个速度的问题&#xff0c;因为PCSS涉及到非常多次对纹理特定某一块区域遍历的操作&#xff08;工业界一般都是用在该区域采样的方式&#xff0c;会因此产生噪声&am…

Zookeeper集群单节点启动成功但未同步其他节点数据

首先排查节点启动是否正常&#xff1a; 在zookeeper的bin目录下执行&#xff1a;sh zkServer.sh status 判断当前节点数据leader 还是follower 节点都启动正常&#xff0c;但某一个zookeeper集群节点&#xff08;下面简称“异常节点”&#xff09;不同步其他节点数据&#xf…

SQL-每日一题【1321. 餐馆营业额变化增长】

题目 表: Customer 你是餐馆的老板&#xff0c;现在你想分析一下可能的营业额变化增长&#xff08;每天至少有一位顾客&#xff09;。 计算以 7 天&#xff08;某日期 该日期前的 6 天&#xff09;为一个时间段的顾客消费平均值。average_amount 要 保留两位小数。 结果按 …

最新两年工作经验总结

最新两年工作经验总结 前言URP的使用1&#xff1a;如何开启URP1、老项目升级为URP2、创建新项目时选择URP创建 2&#xff1a;URP阴影的设置 PolyBrush的使用&#xff08;地图编辑插件&#xff09;制作山峰or低谷边缘柔化雨刷上色制造场景中的物体贴图地形创建容易踩坑的点ProBu…