Linux --- 泰山派RK3566驱动开发 --- 环境搭建+内核编译

Linux --- 泰山派RK3566驱动开发 --- 环境搭建+内核编译

目录

前言

一、获取官方资料

二、环境准备

1.内核源码获取及编译

1.0 源码获取

1.1 配置交叉编译环境

1.2 编译内核(至少编译一次)

2.完成一个驱动

2.0 第一个无硬件的驱动

2.1 部署到板卡        



前言

        早些时候,我拿到了泰山派2+16G版本,中间学习了一些相关应用,用2K0300做了车赛,最近才开始正式使用这块板子,拿来学习驱动开发。

        官方资料站:立创开发板技术文档中心


一、获取官方资料

        开发驱动我们需要完整的软硬件资料才行,立创官方则是提供了完整的资料。

        - 本次板子上是Ubuntu系统

        - 使用WSL2作为开发机,Ubuntu18.04

二、环境准备

1.内核源码获取及编译

1.0 源码获取

        首先我们需要从官方SDK中获取内核源码kernel,我是在官方SDK -Linux \tspi那个无repo压缩包中找到kernel文件夹。1.1 配置交叉编译环境

        开发arm64架构,安装如下工具链即可,若是其他的比如龙芯的架构,需要下载解压官方提供的工具链。

        检查1.2 编译内核(至少编译一次)

        这时需要. config文件来确保我们编译出的东西放到板子上不会出问题甚至导致板子变砖。此时可以去板子上查找这个文件,并获取我们需要的东西

        通过如下命令获取配置文件到编译板子上运行的内核时所用到的配置文件。

        然后需要配置一些编译所需的软件。官方教程在编译SDK时也提到了所需的包,也可以参考那个。如果忘了自己安装了什么,查看apt日志即可

        开始编译,接下来就是export创建临时环境,然后写入配置、开始编译。编译时间会长一些,需耐心等待

        最后我出现了如下内容

        检查编译结果

2.完成一个驱动

        此处涉及的方面较多且复杂,本人边学边做,记录时也是多个文章同时进行的。建议首先学一些语言和工具。

        首先是git,每当进入新阶段时一定要保存好自己的代码,用于管理内核源码、自己的驱动代码、实验版本。。

        然后是TFTPNFSSSH等等 ,网络传输能极大提高开发效率,不用反复烧写存储介质。

        学一些shell脚本和Makefile基础,方便进行一些重复操作,更快捷有效,也方便借鉴学习内核中的Makefile等等。

        然后需要掌握设备树语法和C/C++语言,必须掌握。为使使驱动与硬件匹配,需要在设备树中添加一个节点,设备树相关信息可以查看官方的胖妞手机的实战案例,其中涉及了详细的设备树开发教程。至于C/C++语言则是重中之重,编写驱动代码需要用到,要能熟练阅读内核中复杂的宏定义和链表操作。
2.0 第一个无硬件的驱动

        我们尝试写一个驱动版本的hello world,它本身不控制任何硬件,确保硬件安全,也不提供用户空间交互接口,但能通过内核日志让我们知道,这个模块代码被正确执行了。它如果还未掌握设备树语法或者想先尝试一下看看自己搭建的环境对不对也可以写一个简单的驱动,其中只包含一些调试用的内核函数。



        一个驱动需要许多文件,总结如下

        首先是编写一个内核模块源代码.c文件实现驱动的核心逻辑:初始化、退出、文件操作接口(如 open/read/write)、中断处理、与硬件交互等。定义驱动与设备树的匹配表(of_device_id),声明驱动支持的设备兼容字符串。注册 platform 驱动或其他总线驱动(如 I2C、SPI)。

        其次是Makefile文件利用内核构建系统将 .c 文件编译成内核模块 .ko。指定模块名称、源文件、依赖的内核源码路径等。

        设备树源文件(.dts 或 .dtsi->独立文件)此处不控制硬件,不需要,但也给一个示例,保证流程的完整性,且一般是修改板子的主设备树文件。描述硬件在系统中的连接方式:寄存器地址、中断号、使用的 GPIO 引脚、时钟、电源等。为驱动提供硬件配置信息,使驱动代码不依赖硬编码,提高可移植性。

        设备树覆盖文件,(.dts 编译为 .dtbo)若不希望修改主设备树,创建这个如果不希望修改主设备树,可以创建设备树覆盖(overlay),动态加载设备节点。适用于模块化硬件或实验性开发,避免反复烧写整个设备树。

        

        编译为.dtbo,并在板子上通过configfs 加载覆盖

        Kconfig文件(Kconfig,可选,用于内核配置菜单)如果希望将驱动集成到内核的配置系统中(例如可以通过 make menuconfig 选择是否编译),需要编写 Kconfig 条目。定义驱动的名称、依赖、帮助信息等。

        在源码目录的 Kconfig 中 source 该文件,并在 Makefile 中添加条件编译:

        内核配置文件(.config)内核编译时的全局配置文件,用于启用或禁用驱动、子系统等。如果你在 Kconfig 中添加了驱动,需要确保 .config 中对应的 CONFIG_MY_LED 被设置为 y(内置)或 m(模块)。

        使用 make menuconfig 或直接编辑 .config 来设置。2.1 部署到板卡        

        完成以上操作后,可以尝试将.ko文件通过U盘或者网络(ssh等工具)传输到泰山派上,并在存放.ko文件的目录下加载卸载内核模块,通过内核日志来查看效果。注意这时需要管理员权限。

        # 加载内核模块

        # 查看内核模块列表

        # 查看内核日志

        # 卸载内核模块

        我们已经成功运行了第一个模块,接下来可以:添加参数传递:学习 module_param 让模块接受参数。创建 /proc 或 /sys 文件:用 proc_create 或 device_create 与用户空间交互。操作 GPIO:结合设备树,用 GPIO 子系统点个灯。编写 Makefile 进阶:支持多文件模块、条件编译等。

总结

从零到第一个驱动,核心步骤就是:准备好内核源码并编译一次(生成 Module.symvers 等)。编写模块代码(遵循内核 API)。编写 Makefile 利用内核构建系统。交叉编译生成 .ko 文件。传输到开发板并加载测试。

Read more

【C++】C++中内存管理的利器“智能指针”

【C++】C++中内存管理的利器“智能指针”

各位大佬好,我是落羽!一个坚持不断学习进步的学生。 如果您觉得我的文章还不错,欢迎多多互三分享交流,一起学习进步! 也欢迎关注我的blog主页:落羽的落羽 文章目录 * 一、智能指针的场景需求 * 二、智能指针的设计思路 * 三、C++标准库中的智能指针 * 1. auto_ptr * 2. unique_ptr * 3. shared_ptr * 4. weak_ptr * 5. 特殊说明 * 四、智能指针的实现原理 * 五、shared_ptr的循环引用问题与weak_ptr的使用 一、智能指针的场景需求 如果一个程序中手动new了对象,申请了空间资源,然后下面抛出了异常,就会导致申请的资源没有手动释放,造成内存泄露了。我们就需要在捕捉到异常后在catch语句里先delete资源。可是,new本身也可能抛异常的,导致我们处理起来就会很麻烦。智能指针在这样的场景下处理就十分轻松了。 doubledivide(int

By Ne0inhk
【C++初阶】C++入门相关知识(1):C++历史 & 第一个C++程序 & 命名空间

【C++初阶】C++入门相关知识(1):C++历史 & 第一个C++程序 & 命名空间

🎈主页传送门:良木生香 🔥个人专栏:《C语言》 《数据结构-初阶》 《程序设计》 🌟人为善,福随未至,祸已远行;人为恶,祸虽未至,福已远离 前言:我们在此之前已经学习了C语言和数据结构,明白了C语言的基本概念,同时也学习了初阶的数据结构,现在,我们已经具备了学习初阶c++的能力了,那么,从今天开始,我们就正式进入到C++的学习中了,本专栏会记录下小编的学习C++的历程,有什么讲的不对的地方还请大佬们指出错误,那么,现在我们就正式进入到C++的学习吧 本专栏介绍:在我们之前已经学习过的C语言和数据结构的基础上,我们将会在本C++专栏上继续学习C++语法、STL、以及高阶数据结构 目录 一、C++历史介绍 1.1、起源与诞生(1979~1983) 1.2、核心 1.3发展与完善(

By Ne0inhk
C++ 类与对象:封装特性的实现与实战应用

C++ 类与对象:封装特性的实现与实战应用

C++ 类与对象:封装特性的实现与实战应用 💡 学习目标:掌握类与对象的核心概念,理解封装的本质与价值,能够独立设计并实现具有封装特性的 C++ 类。 💡 学习重点:类的定义与对象实例化、访问权限控制、构造函数与析构函数的使用、封装的实战场景应用。 一、类与对象的核心概念 ✅ 结论:类是 C++ 面向对象编程的核心载体,是对一类事物属性和行为的抽象描述;对象是类的具体实例,是内存中实际存在的实体。 1.1 类的组成 一个完整的 C++ 类通常包含两部分: * 成员变量:描述类的属性,如人的姓名、年龄,圆的半径等。 * 成员函数:描述类的行为,如人的吃饭、跑步,圆的面积计算等。 1.2 类的定义格式 #include<iostream>#include<string>

By Ne0inhk