linux驱动开发笔记

linux驱动开发, 有特定的模式, 在我看来linux驱动只做了一件事,
将设备统一转换成了统一的3类虚拟设备
分别是:
1. 字符设备
2. 块设备
3. 网络设备

linux驱动开发, 需要在Ubuntu系统中

(一般是在Ubuntu下开发, 然后编译. 当然也可以在windows下交叉编译, 但是为了避免横生事端, 一般都是在Ubuntu下面开发. )

环境准备
开发的时候需要先下载 linux SDK
压缩包目前是15GB, 解压需要11GB,(What? 越压缩越大?)
为啥需要 Linux SDK? 因为里面包含调用 Linux所需要的各种头文件.c++写的.做linux驱动开发得会c++, 虽然我不会c++只会c, 但是看了驱动开发之后, 反而让我学会了c++. 我看的视频教程是 正点原子提供的视频. 对于新手来讲最好先学会c并且会用c语言的 struct 和指针. 然后在看linux驱动开发, 你的c++功底会更上一层楼. 否则有可能让你崩溃.

开发步骤.
linux驱动程序的文件形式
1. linux驱动程序可以编译到kernel 中, 也就是zimage文件中,
2.也可以单独编译成 .ko文件,测试的时候只需要加载ko文件即可

驱动加载
驱动编译好之后文件扩展名为.ko, 有两种命令可以加载模块,insmod和modprobe

insmod led.ko 

或者

modprobe led

两种方法的区别
modprobe和insmod类似,都是用来动态加载驱动模块的,区别在于modprobe可以解决load module时的依赖关系,它是通过/lib/modules/#uname -r/modules.dep(.bb)文件来查找依赖关系的;而insmod不能解决依赖问题。

也就是说,如果你确定你要加载的驱动模块不依赖其他驱动模块的话,既可以insmod也可以modprobe,当然insmod可以在任何目录下执行,更方便一些。而如果你要加载的驱动模块还依赖其他ko驱动模块的话,就只能将模块拷贝到上述的特定目录,depmod后再modprobe。

模型加载之前要先执行一下:

depmod

depmod 会在/lib/modules/#uname -r#/目录下生成modules.dep和modules.dep.bb文件,表明模块的依赖关系

然后执行命令,加载led.ko驱动

modprobe led

lsmod 是用来查询有哪些驱动.

lsmod

卸载驱动

modprobe -r led.ko

或者

rmmod led.ko

以上是准备工作, 下面开始正式开始写驱动
经过1天的测试发现, Firefly-RK3399pro开发板和正点原子讲的不一样.
遇到各种问题, 这些问题就不一一列举了, 直接上正确的代码和步骤.

第一步下载Linux SDK, 我是下载的 Firefly提供的Linux SDK
开发环境的准备, 参照 Firefly 编译 Ubuntu 固件 ( GPT )

官方给的文档写的不清楚.
我这里重新修正一下
搭建 SDK 编译环境

sudo apt-get update

sudo apt-get install repo git-core gitk git-gui gcc-arm-linux-gnueabihf u-boot-tools device-tree-compiler \
gcc-aarch64-linux-gnu mtools parted libudev-dev libusb-1.0-0-dev python-linaro-image-tools \
linaro-image-tools gcc-arm-linux-gnueabihf libssl-dev liblz4-tool genext2fs lib32stdc++6 \
gcc-aarch64-linux-gnu g+conf autotools-dev libsigsegv2 m4 intltool libdrm-dev curl sed make \
binutils build-essential gcc g++ bash patch gzip bzip2 perl tar cpio python unzip rsync file bc wget \
libncurses5 libqt4-dev libglib2.0-dev libgtk2.0-dev libglade2-dev cvs git mercurial rsync openssh-client \
subversion asciidoc w3m dblatex graphviz python-matplotlib libssl-dev texinfo fakeroot \
libparse-yapp-perl default-jre patchutils swig chrpath diffstat gawk time expect-dev

我这里还遇到了需要安装openssl和另外一个压缩工具lz4,建议直接执行下面两个命令

sudo apt-get install libssl-dev
sudo apt-get install liblz4-tool

注意: Ubuntu17.04 或者更高的系统还需要如下依赖包:

sudo apt-get install lib32gcc-7-dev g++-7 libstdc++-7-dev

下载 Firefly_Linux_SDK 分卷压缩包
由于 Firefly_Linux_SDK 源码包比较大,部分用户电脑不支持4G以上文件或单个文件网络传输较慢, 所以我们采用分卷压缩的方法来打包SDK。用户可以通过如下方式获取 Firefly_Linux_SDK源码包:Firefly_Linux_SDK源码包

下载完成后先验证一下 MD5 码:

$ md5sum rk3399pro_linux_release_v2.5.1_20210304_split_dir/*firefly_split*
结果应该如下
743e23a6119eb83b1f877db815c5031c  rk3399pro_linux_release_v2.5.1_20210304_firefly_split.file0
3bb8b245377e659b225019dfcedce7a9  rk3399pro_linux_release_v2.5.1_20210304_firefly_split.file1
88c368a0b62058dbe500cc626bd8b01f  rk3399pro_linux_release_v2.5.1_20210304_firefly_split.file2
3b7b379da70e2fee785117e1ae2610bf  rk3399pro_linux_release_v2.5.1_20210304_firefly_split.file3
eaccf65d80c8f70ad781d2b876361e34  rk3399pro_linux_release_v2.5.1_20210304_firefly_split.file4
81eaafd1e511e29474fe4445e78d2862  rk3399pro_linux_release_v2.5.1_20210304_firefly_split.file5

解压 Firefly_Linux_SDK 分卷压缩包
md5校验无误后可以解压.

cat rk3399pro_linux_release_v2.5.1_20210304_split_dir/*firefly_split* | tar -xzv

# 本SDK文件夹内包含一个 .repo 目录,解压之后,在当前目录下执行以下操作
cd rk3399pro_linux_release_v2.5.1_20210304
ls -al

.repo/repo/repo sync -l
.repo/repo/repo sync -c --no-tags
.repo/repo/repo start firefly --all

更新 Firefly_Linux_SDK

后续可以使用以下命令更新 SDK

.repo/repo/repo sync -c --no-tags

Linux_SDK 目录介绍

├── linux_sdk
│   ├── app
│   ├── buildroot buildroot                                      根文件系统的编译目录
│   ├── build.sh -> device/rockchip/common/build.sh              全自动编译脚本
│   ├── device                                                   编译相关配置文件
│   ├── distro debian                                            根文件系统生成目录
│   ├── docs                                                     文档
│   ├── envsetup.sh -> buildroot/build/envsetup.sh
│   ├── external
│   ├── kernel                                                   内核
│   ├── Makefile -> buildroot/build/Makefile
│   ├── mkfirmware.sh -> device/rockchip/common/mkfirmware.sh    rockdev链接更新脚本
│   ├── prebuilts
│   ├── rkbin
│   ├── rkflash.sh -> device/rockchip/common/rkflash.sh          烧写脚本
│   ├── rootfs                                                   debian根文件系统编译目录
│   ├── tools                                                    烧写、打包工具
│   └── u-boot

到此为止, 环境基本上是准备好了. 官方给的文档里面, 后面还有一些乱七八糟的说明, 可以分别编译kernel,u-boot,recovery , rootfs. 有需要的朋友可以去官网看. 但是这不是本文的重点. 我们要的是如何编写驱动程序 . 下面开始介绍如何开始编写自己的驱动.

我采取的是make 一个ko文件, 然后把ko文件复制到板子上, 然后在板子上加载驱动. 这样的套路户比较简单一些. 不需要全部重新烧写. 我担心烧写会搞坏了我写好的东西. 毕竟很多代码都在上面呢.

下文主要是参考了 Firefly-RK3399 第一个驱动程序编制 这篇文章

正式开始编写驱动

新建一个自己的文件夹, 放在自己的项目目录下, 不需要放在Linux SDK目录下.
编写主驱动程序 led.c

#include <linux/init.h>
#include <linux/module.h>



static int  __init led_init(void){
    printk("led_init ");
    return 0; 
}

static void  __exit  led_exit(void){

    printk("led_exit ");
    return  ;

}


module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL");

编写Makefile
注意这里的makefile中最大的问题, 可能是KERNELDIR 一定要指定到kernel 目录下.才行.

 #!/bin/bash

# CROSS_COMPILE:= aarch64-linux-gnu-
# ARCH:= arm64
# CC:= $(CROSS_COMPILE)gcc
# LD:= $(CROSS_COMPILE)ld
PWD :=$(shell pwd)

obj-m += led.o 


KERNELDIR :=/home/roota/Desktop/AI/LinuxSDK/rk3399pro_linux_release_v2.5.1_20210304/kernel


all: 
	make -C $(KERNELDIR) M=$(PWD) modules
	rm -f *.o
	rm -f *.symvers
	rm -f *.order
	rm -f *.mod.c
	rm -f .led.ko.cmd
	rm -f .led.mod.o.cmd
	rm -f .led.o.cmd

clean:
# $(MAKE) -C $(KERNELDIR) M=$(CURRENT_DIR) clean
	rm -f *.o
	rm -f *.symvers
	rm -f *.order
	rm -f *.ko
	rm -f *.mod.c
	rm -f .led.ko.cmd
	rm -f .led.mod.o.cmd
	rm -f .led.o.cmd

# ————————————————
# 版权声明:本文为CSDN博主「八喜.王」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
# 原文链接:https://blog.csdn.net/zwwang2014/article/details/88394210

编译

make 

编译程序结果会出现led.ko

执行
把led.ko文件复制到开发板上.
加载模块

sudo insmod led.ko 

查看模块

cat /proc/modules 
 或
 lsmod

卸载模块

sudo rmmod led

另外firefly 给推进了一个比较不错的视频教程.
https://dev.t-firefly.com/thread-100207-1-1.html

上一篇:Centos6无法使用yum源的问题 /var/cache/yum/x86_64/6/base/mirrorlist


下一篇:vim手动加载插件